# SendKit ## v1 - [Get started with the SendKit API](https://docs.sendkit.ai/getting-started.md): Authenticate with the SendKit Platform API, call your first endpoints, and understand platform vs workspace API keys and headers. - [Integrate SendKit MCP server](https://docs.sendkit.ai/mcp-server.md): Connect an MCP-capable client to the SendKit MCP server using OAuth and the Streamable HTTP transport, with endpoint, config, and testing guidance. - [SendKit CLI introduction](https://docs.sendkit.ai/cli.md): Install and run the SendKit CLI from your terminal or AI agents that can execute shell commands, with a quick sanity check and common workflow overview. - [Get user profile](https://docs.sendkit.ai/api-reference/get-v1-account.md): Returns user profile and workspace memberships. **Requires a platform API key** (`sk_user_...`). Workspace keys are rejected with 403. - [Update user name](https://docs.sendkit.ai/api-reference/patch-v1-account.md): No description found - [List workspaces](https://docs.sendkit.ai/api-reference/get-v1-workspaces.md): Returns active workspaces the authenticated user belongs to. - **Platform key**: returns all workspaces. - **Workspace key**: returns only the workspace the key belongs to. - [Create workspace](https://docs.sendkit.ai/api-reference/post-v1-workspaces.md): Creates a new workspace. By default the authenticated user becomes the owner and first member. **Requires a platform API key** (`sk_user_...`). Workspace keys are rejected with 403. **Subscription gate** — creating an *additional* workspace (when the caller already has any workspace membership) requires an active or trialing subscription, or a plan in the allowlist. First-time workspace creation is always allowed. - [Get workspace detail](https://docs.sendkit.ai/api-reference/get-v1-workspaces-workspaceid.md): Returns full workspace detail including members, settings, and limits. Workspace keys can only access their own workspace. - [Update workspace](https://docs.sendkit.ai/api-reference/patch-v1-workspaces-workspaceid.md): Update workspace `name`, `billingEmail`, and/or `settings`. Only owners and admins can perform this action. Workspace keys can only update their own workspace. - [Delete workspace (owner only)](https://docs.sendkit.ai/api-reference/delete-v1-workspaces-workspaceid.md): **Hard-deletes** the workspace and cascades deletion across all child collections. Only the workspace owner can perform this action. **Requires a platform API key** (`sk_user_...`). ## What is deleted The workspace document itself plus all rows in the following collections matching `workspaceId`: `campaigns`, `campaignleads`, `leads`, `mailboxes`, `domains`, `webhooks`, `workspaceinvites`, `unsubscribed`, `agents`. Returned counts are reported in `data.deletedCounts`. ## Side effects - The workspace is removed from every user's `workspaces[]` array via `$pull`. - The caller's `currentWorkspaceId` is reassigned to a remaining workspace (returned as `data.newCurrentWorkspaceId`). - The owner's `subscription.usage.leads` counter is resynced to the actual count across the owner's remaining workspaces. ## Guards - Returns 400 `LAST_WORKSPACE` if this is the caller's only workspace. - Returns 403 `WORKSPACE_FORBIDDEN` if the caller is not the owner. ## Irreversibility This is a hard delete. There is no recovery. Frees the `apiKey` and `warmupCode` unique-index slots immediately. - [List members](https://docs.sendkit.ai/api-reference/get-v1-workspaces-workspaceid-members.md): Returns all members with their user profile (name, email) and role. Workspace keys can only list members of their own workspace. - [Invite member](https://docs.sendkit.ai/api-reference/post-v1-workspaces-workspaceid-members.md): Add an existing user to the workspace by email. The user must already have a SendKit account. **Requires a platform API key** (`sk_user_...`). Workspace keys are rejected with 403. Requires invite permission: owner/admin can always invite, members can invite only if `settings.allowMemberInvites` is enabled. - [Remove member](https://docs.sendkit.ai/api-reference/delete-v1-workspaces-workspaceid-members-userid.md): Remove a member from the workspace. Only owners and admins can remove members. The workspace owner cannot be removed. **Requires a platform API key** (`sk_user_...`). Workspace keys are rejected with 403. - [Create workspace API key](https://docs.sendkit.ai/api-reference/post-v1-workspaces-workspaceid-api-key.md): Generate a new API key (`sk_...`) for the workspace. A workspace can only have one API key at a time — returns 409 if one already exists. **Requires a platform API key** (`sk_user_...`). Workspace keys are rejected with 403. Only owners and admins can manage API keys. - [Delete workspace API key](https://docs.sendkit.ai/api-reference/delete-v1-workspaces-workspaceid-api-key.md): Revoke and delete the workspace's API key. The key is immediately invalidated and can no longer be used for authentication. Returns 404 if no key exists. **Requires a platform API key** (`sk_user_...`). Workspace keys are rejected with 403. Only owners and admins can manage API keys. - [Rotate workspace API key](https://docs.sendkit.ai/api-reference/post-v1-workspaces-workspaceid-api-key-rotate.md): Replace the existing workspace API key with a new one. The old key is immediately invalidated and a new key is returned. Returns 404 if no key exists to rotate — use the create endpoint first. **Requires a platform API key** (`sk_user_...`). Workspace keys are rejected with 403. Only owners and admins can manage API keys. - [List campaigns](https://docs.sendkit.ai/api-reference/get-v1-campaigns.md): Returns a paginated list of campaigns for the workspace. Supports filtering by status and searching by name. - [Create campaign](https://docs.sendkit.ai/api-reference/post-v1-campaigns.md): Create a new campaign in draft status. Mailboxes can be assigned using any combination of: - `mailboxes` or `mailboxIds` - direct mailbox IDs - `mailboxEmails` - resolve mailboxes by email address - `mailboxTags` - all mailboxes matching any of these tags - `mailboxProvider` - all mailboxes with this provider (e.g. "gmail", "outlook") - [Get campaign with lead counts](https://docs.sendkit.ai/api-reference/get-v1-campaigns-campaignid.md): Returns full campaign details including lead counts (total and active leads). - [Update campaign](https://docs.sendkit.ai/api-reference/patch-v1-campaigns-campaignid.md): Update campaign name, sequence, schedule, settings, or mailbox assignments. Mailboxes can be reassigned using any combination of mailboxIds, mailboxEmails, mailboxTags, or mailboxProvider. - [Delete campaign](https://docs.sendkit.ai/api-reference/delete-v1-campaigns-campaignid.md): Soft-deletes a campaign by setting its status to "archived". The campaign data is preserved but no longer appears in default listings. - [Start campaign](https://docs.sendkit.ai/api-reference/post-v1-campaigns-campaignid-start.md): Start a campaign that is in "draft" or "paused" status. The campaign must have: - At least one mailbox assigned - At least one sequence step - At least one lead Pending leads are automatically activated when the campaign starts. - [Pause campaign](https://docs.sendkit.ai/api-reference/post-v1-campaigns-campaignid-pause.md): Pause an active campaign. Only campaigns with status "active" can be paused. - [Resume paused campaign](https://docs.sendkit.ai/api-reference/post-v1-campaigns-campaignid-resume.md): Resume a paused campaign. Only campaigns with status "paused" can be resumed. - [Duplicate campaign](https://docs.sendkit.ai/api-reference/post-v1-campaigns-campaignid-duplicate.md): Creates a copy of the campaign with "(Copy)" appended to the name. The duplicate is created in "draft" status with the same sequence, schedule, and settings. Leads are NOT copied. - [Campaign analytics](https://docs.sendkit.ai/api-reference/get-v1-campaigns-campaignid-analytics.md): Returns detailed campaign analytics including: - Overall campaign stats (sent, opened, clicked, bounced, replied, unsubscribed) - Main-sequence step analytics and frontend-compatible A/B variant breakdowns - Lead status breakdown (active, completed, bounced, etc.) - Total replied and positive replied counts Without `from`/`to`, returns all-time data. Supply one or both to filter by date range. Date filters on sent/opened/clicked/bounced step totals are scoped to email send date; replies are scoped to reply date. - [Preview a personalized email](https://docs.sendkit.ai/api-reference/post-v1-campaigns-campaignid-preview-email.md): Returns the fully personalized subject and body for a given sequence step, lead, and mailbox. All variables (`{{firstName}}`, custom fields, `{{senderName}}`, etc.), conditional blocks (IF/ELSE), and spintax (`{option1|option2}`) are resolved. Use `contentOverride` to preview unsaved draft content without modifying the campaign. - [Send a test email](https://docs.sendkit.ai/api-reference/post-v1-campaigns-campaignid-send-test-email.md): Personalizes an email and sends it synchronously via SMTP. Supports two modes: - **Send to lead**: Provide `leadId` - email is personalized with lead data and sent to the lead's email. - **Send to custom email**: Provide `customEmail` and optionally `customVariables` - useful for testing with your own inbox. The email is sent synchronously - the response confirms delivery. Counts toward email usage quota. Requires an active subscription. - [List leads in campaign](https://docs.sendkit.ai/api-reference/get-v1-campaigns-campaignid-leads.md): Returns a paginated list of leads within a campaign. Each lead includes its campaign-specific status, sequence progress, email history, and populated lead details (email, name, company). - [Add leads to campaign](https://docs.sendkit.ai/api-reference/post-v1-campaigns-campaignid-leads.md): Add leads to a campaign using one of three modes: **Mode 1 - Explicit leads** (max 5,000 per request): Provide a `leads` array with objects containing either `leadId` (existing lead) or `email` (creates a new lead if not found). **Mode 2 - Filter-based**: Provide a `filters` object to match workspace leads by tags, search text, email verification status, country, or specific lead IDs. **Mode 3 - Select all**: Set `selectAll: true` to add all workspace leads. Use `excludeIds` to skip specific leads. Duplicate leads (already in the campaign) are automatically skipped. If the campaign is active, new leads are added with "active" status; otherwise they start as "pending". - [Import leads from CSV into campaign](https://docs.sendkit.ai/api-reference/post-v1-campaigns-campaignid-leads-import-csv.md): Upload a CSV file to create leads and add them to the campaign in a single operation. - Maximum file size: 50 MB - Maximum rows: 50,000 - Automatically detects email, firstName, lastName, companyName, jobTitle columns by common aliases - Unrecognized columns are stored as custom fields on the lead - Existing leads (by email) are reused, not duplicated - Duplicate campaign leads are skipped - Processes in batches of 1,000 for performance - [Bulk action on campaign leads](https://docs.sendkit.ai/api-reference/post-v1-campaigns-campaignid-leads-action.md): Perform bulk operations on leads within a campaign. Two selection modes: **Explicit IDs**: Provide `leadIds` array with campaign lead record IDs. **Select all**: Set `selectAll: true` with optional `filters` and `excludeIds`. Available actions: | Action | Description | |--------|-------------| | `pause` | Pause active leads (stops sending to them) | | `resume` | Resume paused leads (re-activates them) | | `remove` | Remove leads from campaign. Leads with no emails sent are hard-deleted; leads with email history are soft-deleted (status set to "removed") | - [Get campaign lead detail](https://docs.sendkit.ai/api-reference/get-v1-campaigns-campaignid-leads-campaignleadid.md): Returns full campaign lead details including populated lead data (email, name, company, job title) and complete email history. - [Update campaign lead](https://docs.sendkit.ai/api-reference/patch-v1-campaigns-campaignid-leads-campaignleadid.md): Update a campaign lead's status or AI tag. Status can only be changed to "active" or "paused". When `aiTag` is set, a `lead.tag_changed` webhook is triggered if the tag value actually changed. The `aiTag` must match an existing tag name in the workspace's AI tagging labels. **Subsequence enrollment / exit**: when the new `aiTag` matches a subsequence whose `trigger.type='ai_tag'` and `trigger.value` equals the tag (case-insensitive): - Lead has no subsequence → **enrolled** in the matching one and any pending main-sequence send is canceled. - Lead is already in the matching subsequence → no-op. - Lead is in a different subsequence with **no** emails sent from it → **switched** into the matching subsequence (state reset). - Lead is in a different subsequence with **at least one** email already sent → no switch (action `skippedInProgress`); tag still updates. When the new tag matches NO subsequence: - Lead has no subsequence → no-op. - Lead is in a subsequence with **no** emails sent from it → **exits** cleanly (`subsequence.status: 'completed'`, `subsequence.completedAt` set, lead `status: 'completed'`, scheduling cleared; `subsequence.id` preserved as a historical pointer). - Lead is in a subsequence with **at least one** email already sent → kept in (action `skippedInProgress`); tag still updates. When enrollment, switch, exit, or skip occurs, the response includes a `subsequenceEnrollment: { action, subsequenceName }` field where `action` is one of `enrolled`, `switched`, `exited`, `skippedInProgress`. If no enrollment change happens, the field is omitted. - [List leads](https://docs.sendkit.ai/api-reference/get-v1-leads.md): Returns a paginated list of leads in the workspace. Supports filtering by search text, tags, and email verification status. - [Create lead](https://docs.sendkit.ai/api-reference/post-v1-leads.md): Create a single lead in the workspace. Returns 409 if a lead with the same email already exists. - [Delete leads](https://docs.sendkit.ai/api-reference/delete-v1-leads.md): Delete leads by explicit IDs or filter-based selection. Two modes: **By IDs**: Provide `leadIds` array with one or more lead IDs. **Delete all**: Set `deleteAll: true` with optional `filters` and `excludeIds`. Leads in active campaigns are protected by default. The API returns a 400 error listing affected campaigns. Pass `force: true` to delete anyway - campaign leads are soft-removed (status set to "removed"). - [Get lead detail](https://docs.sendkit.ai/api-reference/get-v1-leads-leadid.md): Returns the full lead record including all standard fields, custom fields, and enrichment data. The `leadId` parameter accepts either a lead ID or an email address (e.g. `john@acme.com`). - [Update lead](https://docs.sendkit.ai/api-reference/patch-v1-leads-leadid.md): Update lead fields. Custom fields are merged into existing custom fields (not replaced). Email cannot be changed after creation. - [Bulk create/update leads](https://docs.sendkit.ai/api-reference/post-v1-leads-bulk.md): Bulk import leads from a JSON array (max 5,000 per request). Processed in batches of 1,000 with up to 10 concurrent batches. Options: - **skipDuplicates** (default true): When true, existing leads (by email) are skipped. When false, existing leads are updated with the new data. - **dataCleanup** (default true): Normalize emails, phone numbers, LinkedIn URLs, and strip special characters from names. - **tag**: Optional tag to apply to all imported leads. Each lead object must include `email`. Standard fields (firstName, lastName, companyName, etc.) are mapped automatically. Any unrecognized keys become custom fields. - [Import leads from CSV](https://docs.sendkit.ai/api-reference/post-v1-leads-import-csv.md): Upload a CSV file to bulk import leads. Supports: - **Auto-detection** of column mappings (email, firstName, lastName, company, jobTitle, phone, linkedinUrl, city, state, country, timezone, notes, etc.) - **Custom mapping** via the `mapping` field for non-standard column names - **Data cleanup** (default on): normalizes emails, phone numbers, LinkedIn URLs, strips special chars - **Deduplication** (default on): skips leads that already exist by email. Set to false to update existing leads. - Unrecognized columns are stored as custom fields on the lead - Maximum 50,000 rows per file, 50 MB file size limit - Processed in batches of 1,000 with up to 10 concurrent batches - [Advanced lead search](https://docs.sendkit.ai/api-reference/post-v1-leads-search.md): Advanced search with structured filters via POST body. Supports filtering by email, name, company, job title, tags, email verification status, location, and creation date range. Results are paginated. - [Export leads as CSV](https://docs.sendkit.ai/api-reference/get-v1-leads-export-csv.md): Export leads matching filters as a downloadable CSV file. Maximum 50,000 leads per export. Standard fields are always included. Custom fields are added as additional columns (collected across all matching leads). Results are sorted by creation date (newest first). - [List mailboxes](https://docs.sendkit.ai/api-reference/get-v1-mailboxes.md): Returns a paginated list of mailboxes in the workspace with health and warmup data. Sensitive credentials are excluded from responses. - [Add SMTP mailbox](https://docs.sendkit.ai/api-reference/post-v1-mailboxes.md): Add an SMTP mailbox to the workspace. Credentials are encrypted at rest. The mailbox is created in `inactive` status. A background worker verifies the SMTP/IMAP credentials and either flips status to `active` (success) or deletes the mailbox (failure). After this request, poll `GET /v1/mailboxes/{mailboxId}/connection-test` until the status is no longer `pending`. A DNS check (MX/SPF/DKIM/DMARC) runs automatically and populates `setupStatus`. Mailbox usage is incremented against the workspace owner's plan limit. Returns 403 if the workspace owner has no active subscription or has reached the mailbox limit. Returns 409 if a mailbox with the same email already exists in the workspace. - [Poll SMTP connection test status](https://docs.sendkit.ai/api-reference/get-v1-mailboxes-mailboxid-connection-test.md): Poll this after `POST /v1/mailboxes` to learn whether the background SMTP verification has completed. - `pending` — worker has not yet finished testing. - `passed` — SMTP/IMAP credentials verified; mailbox is now `active`. - `failed` — verification failed. The worker may have deleted the mailbox; the response then reports the failure rather than a 404. - [Get mailbox detail](https://docs.sendkit.ai/api-reference/get-v1-mailboxes-mailboxid.md): Returns full mailbox details excluding sensitive credentials (oauthCredentials, smtpCredentials, imapCredentials). - [Update mailbox settings](https://docs.sendkit.ai/api-reference/patch-v1-mailboxes-mailboxid.md): Update display name, daily send limit, signature, sending enabled status, or tags. - [Remove mailbox](https://docs.sendkit.ai/api-reference/delete-v1-mailboxes-mailboxid.md): Permanently deletes a mailbox. Fails if the mailbox is used in any active campaigns - remove it from campaigns first. - [Detailed mailbox health](https://docs.sendkit.ai/api-reference/get-v1-mailboxes-mailboxid-health.md): Returns comprehensive mailbox health data including DNS records status (MX, SPF, DKIM, DMARC), warmup progress and metrics, deliverability stats, and error information. - [Bulk mailbox operations](https://docs.sendkit.ai/api-reference/post-v1-mailboxes-bulk.md): Perform bulk operations on multiple mailboxes. Two selection modes: - **Explicit IDs**: `{ "mailboxIds": ["id1", "id2"] }` - **Filter-based**: `{ "selectAll": true, "filters": { ... }, "excludeIds": ["id3"] }` **Available operations:** | Operation | Extra Fields | Description | |-----------|-------------|-------------| | `enableSending` | - | Enable sending on selected mailboxes | | `disableSending` | - | Disable sending | | `updateDailyLimit` | `dailySendLimit` (1-50) | Set daily send limit | | `updateSignature` | `signatureTemplate` | Set signature with `\{\{firstName\}\}`, `\{\{lastName\}\}`, `\{\{email\}\}` auto-personalized per mailbox | | `addTags` | `tags[]` | Add tags (no duplicates) | | `removeTags` | `tags[]` | Remove specific tags | | `replaceTags` | `tags[]` | Replace all tags | | `checkDNS` | - | Check MX, SPF, DKIM, DMARC records (grouped by domain) | | `startWarmup` | `warmupConfig?` | Start warmup (default: 10 emails/day, +1/day, target 25, max 50) | | `pauseWarmup` | - | Pause active warmup | | `resumeWarmup` | - | Resume paused/stopped warmup | | `stopWarmup` | - | Stop warmup completely | | `updateWarmupSettings` | `warmupConfig` | Update warmup config (startingVolume, dailyIncrease, targetVolume) | | `reactivate` | - | Reactivate errored/suspended mailboxes | | `delete` | - | Delete mailboxes (fails if used in active campaigns) | - [Get Google OAuth consent URL](https://docs.sendkit.ai/api-reference/post-v1-mailboxes-connect-google.md): Returns a Google OAuth authorization URL. The user must open this URL in a browser to grant Gmail access. After authorizing, the mailbox is created automatically via the OAuth callback. Uses workspace-specific OAuth credentials if configured, otherwise falls back to shared platform credentials. - [Get Outlook OAuth consent URL](https://docs.sendkit.ai/api-reference/post-v1-mailboxes-connect-outlook.md): Returns a Microsoft OAuth authorization URL for connecting an Outlook/Office365 mailbox. The user must open this URL in a browser to authorize. - [Bulk import SMTP mailboxes from CSV](https://docs.sendkit.ai/api-reference/post-v1-mailboxes-import-smtp.md): Upload a CSV file to bulk import SMTP mailboxes. Maximum 500 mailboxes per import. **Required columns:** `email`, `password`, `smtphost`, `imaphost` **Optional columns:** `smtpport` (default 587), `imapport` (default 993), `smtpsecure` (default false), `imapsecure` (default true), `displayname` SMTP connections are tested during import (20 concurrent connections). Use `skipConnectionTest=true` to skip testing - mailboxes will be created with "pending" status instead of "active". Duplicate emails (already in workspace) are automatically skipped. - [Bulk import Outlook mailboxes from CSV](https://docs.sendkit.ai/api-reference/post-v1-mailboxes-import-outlook.md): Upload a CSV to import Outlook/Hotmail mailboxes using app passwords (not OAuth). Maximum 1000 per import. **Required columns:** `email`, `password` **Optional columns:** `name` (display name), `totpsecret` (TOTP secret for 2FA) The import runs asynchronously: the CSV is validated, deduplicated against existing workspace mailboxes, and an `outlook_bulk_import` job is queued. A worker creates the mailboxes and tests their connections. Rows whose email already exists in the workspace are skipped (their display name is updated if the CSV provides one). - [Workspace warmup stats](https://docs.sendkit.ai/api-reference/get-v1-warmup-stats.md): Returns aggregated warmup metrics across all warming mailboxes in the workspace, plus per-mailbox summaries with inbox/spam rates and health scores. Health score formula: `inboxRate * 0.5 + (100 - spamRate) * 0.3 + openRate * 0.2` (capped at 100). - [Per-mailbox warmup metrics](https://docs.sendkit.ai/api-reference/get-v1-warmup-stats-mailboxid.md): Returns detailed warmup metrics for a specific mailbox including placement breakdown (inbox/spam/promotions/other/not_detected) and daily stats sorted by date ascending. - [List conversations](https://docs.sendkit.ai/api-reference/get-v1-inbox.md): Returns paginated conversations (campaign leads that have replies). Each conversation includes lead info, campaign info, AI mode/capability flags, last message preview, and message count. Supports filtering by unread status, AI tag, campaign, and search (matches lead email/name). - [Get unread conversation count](https://docs.sendkit.ai/api-reference/get-v1-inbox-unread-count.md): Returns the count of conversations with unread lead replies. Optionally filter by campaign. - [Tag conversations](https://docs.sendkit.ai/api-reference/post-v1-inbox-tag.md): Apply an AI tag to one or more conversations. Use either explicit `conversationIds` or `selectAll: true` with optional filters/excludeIds. - [Mark conversations as read](https://docs.sendkit.ai/api-reference/post-v1-inbox-mark-read.md): Mark unread lead replies as read in one or more conversations. Use either explicit `conversationIds` or `selectAll: true` with optional filters/excludeIds. - [Add conversations' leads to DNC](https://docs.sendkit.ai/api-reference/post-v1-inbox-dnc.md): Adds lead emails from selected conversations to the Do Not Contact list. Skips leads already on the DNC list. Use either explicit `conversationIds` or `selectAll: true` with optional filters/excludeIds. - [Delete conversations](https://docs.sendkit.ai/api-reference/post-v1-inbox-delete.md): Soft-deletes conversations (marks as removed with reason `api_inbox_delete`). Email history is preserved. Use either explicit `conversationIds` or `selectAll: true` with optional filters. - [Get upload URL for attachment upload](https://docs.sendkit.ai/api-reference/post-v1-inbox-attachments-upload.md): Returns a upload URL for direct client upload to R2 cloud storage. The upload URL expires after 5 minutes. Use the returned `url` and `key` when sending a reply with attachments. Max file size is 10MB. **Allowed content types:** `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `application/pdf`, `application/msword`, `application/vnd.openxmlformats-officedocument.wordprocessingml.document`, `application/vnd.ms-excel`, `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`, `text/plain`, `text/csv` - [Delete an attachment](https://docs.sendkit.ai/api-reference/delete-v1-inbox-attachments.md): Deletes an attachment from R2 storage. The key must start with `inbox-attachments/` and belong to the current workspace. - [Get conversation with messages](https://docs.sendkit.ai/api-reference/get-v1-inbox-conversationid.md): Returns a full conversation thread with all messages in chronological order. Messages include sent emails, lead replies, and manual messages. Also includes resolved AI mode/capability flags and any pending/sending/failed scheduled replies. - [Update conversation](https://docs.sendkit.ai/api-reference/patch-v1-inbox-conversationid.md): Update a conversation's read status, AI tag, custom tags, or AI reply-agent mode. Set `markRead: true` or `isRead: true` to mark all unread replies as read. Set `isRead: false` to mark lead replies as unread. Set `aiTag` to a string to apply a tag, or `null` to remove it. Set `aiMode` to `off`, `followups_only`, or `active` to control the campaign AI agent for this conversation. Only modes supported by the campaign's assigned agent are accepted. - [Download attachment](https://docs.sendkit.ai/api-reference/get-v1-inbox-conversationid-attachments-attachmentindex.md): Downloads an attachment from a conversation. Supports both attachments received from leads (replies) and attachments sent by the user (manual messages). The file is fetched on-demand from the email provider (Gmail or Outlook) and proxied through this endpoint. No files are stored on SendKit servers. **Supported providers:** Gmail (OAuth), Outlook/Microsoft 365 (OAuth). SMTP/IMAP mailbox attachments are not supported. Sent attachments are only downloadable if provider attachment IDs were captured at send time. The response is the raw binary file with appropriate `Content-Type` and `Content-Disposition` headers. - [Send or schedule reply](https://docs.sendkit.ai/api-reference/post-v1-inbox-conversationid-reply.md): Sends a reply immediately or schedules it for later. Omit `scheduledFor` for immediate send; pass an ISO 8601 date in the future to schedule. Use the `attachments` array with objects from the attachment upload endpoint. Replies are sent from the conversation's assigned mailbox or original sending mailbox. - [Forward a conversation](https://docs.sendkit.ai/api-reference/post-v1-inbox-conversationid-forward.md): Forwards a conversation to one or more recipients as a new email thread. The server assembles the forwarded chain (Gmail-style `---------- Forwarded message ---------` header followed by the full thread), re-attaches any prior Gmail reply attachments, and sends from the chosen mailbox. - The **first** address in `toEmails` becomes the `To`; the rest are prepended to `cc`. - `body` and `plainText` are both optional — if omitted, only the forwarded chain is sent. If only one of the two is provided, the server derives the other. - `fromMailboxId` overrides the sending mailbox; otherwise the conversation's last-used mailbox is chosen, then any active campaign mailbox as a fallback. - Attachments must have been uploaded via `POST /v1/inbox/attachments/upload` (their `key` must live under `inbox-attachments//`). Asynchronous: returns `202 Accepted` with a `jobId`. Poll the sending-worker status endpoint (`GET /api/jobs/{jobId}` on the workspace's worker host) to observe progress. The job is enqueued onto the workspace's node Redis. - [List scheduled replies](https://docs.sendkit.ai/api-reference/get-v1-inbox-conversationid-scheduled.md): Returns pending, sending, or failed scheduled replies for a conversation, sorted by scheduled time ascending. - [Cancel scheduled reply](https://docs.sendkit.ai/api-reference/delete-v1-inbox-conversationid-scheduled-replyid.md): Cancels a pending scheduled reply. Only replies with status `pending` can be cancelled. Any R2 attachments associated with the reply are also cleaned up. - [Get draft reply](https://docs.sendkit.ai/api-reference/get-v1-inbox-conversationid-drafts.md): Returns the saved draft for this conversation. Drafts are stored per-user with a 72-hour TTL. Returns `null` if no draft exists. - [Save draft reply](https://docs.sendkit.ai/api-reference/post-v1-inbox-conversationid-drafts.md): Saves a draft reply for this conversation (72-hour TTL, per-user). Send empty or whitespace-only `content` to delete the existing draft. - [Delete draft reply](https://docs.sendkit.ai/api-reference/delete-v1-inbox-conversationid-drafts.md): Deletes the saved draft for this conversation. - [List webhooks](https://docs.sendkit.ai/api-reference/get-v1-webhooks.md): Returns a paginated list of webhooks configured for the workspace. - [Create webhook](https://docs.sendkit.ai/api-reference/post-v1-webhooks.md): Creates a new webhook endpoint. If `secret` is not provided, a random 32-byte hex secret is generated. Defaults: `retryAttempts` = 3, `timeoutMs` = 10000. - [Get webhook](https://docs.sendkit.ai/api-reference/get-v1-webhooks-webhookid.md): Returns a single webhook by ID. - [Update webhook](https://docs.sendkit.ai/api-reference/patch-v1-webhooks-webhookid.md): Updates webhook fields. All fields are optional - only provided fields are changed. - [Delete webhook](https://docs.sendkit.ai/api-reference/delete-v1-webhooks-webhookid.md): Permanently deletes a webhook. - [Send test payload](https://docs.sendkit.ai/api-reference/post-v1-webhooks-webhookid-test.md): Sends a test webhook delivery to the configured URL. The payload is signed with the webhook's secret using HMAC-SHA256 (sent via `X-Webhook-Signature` header). The `X-Webhook-Event` header is set to `test`. Uses the webhook's configured `timeoutMs` for the request timeout. - [Workspace analytics overview](https://docs.sendkit.ai/api-reference/get-v1-analytics-overview.md): Returns aggregate email stats across all campaigns in the workspace. Includes totals for sent, opened, clicked, bounced, replied, and positive replied emails, plus campaign counts and calculated rates (as percentages with 1 decimal). Positive replies are determined by the workspace's AI tagging settings — leads tagged with labels marked as `isPositive` are counted. - [Per-campaign analytics](https://docs.sendkit.ai/api-reference/get-v1-analytics-campaigns-campaignid.md): Returns detailed analytics for a single campaign, including: - Campaign info and `stats` — campaign-level totals across the **combined** main sequence + all subsequences (sent/opened/clicked/bounced/replied). - `stepStats` — per-step totals for the **main sequence only**. Subseq step indices live in their own namespace, so combining them here would collide step 0/1/... For per-subseq breakdown, see `subsequences[].stepStats`. - `steps` — frontend-compatible main-sequence step rows with `variants[]`. Per-variant rows are nested under `steps[].variants[]`. - `subsequences[]` — one entry per subsequence with its own `stats`, `stepStats`, `addedCount`, and `currentlyEnrolled` count. - `bySequence` — sent/opened/clicked/bounced split by main vs subseq. - Lead status breakdown (active, paused, completed, bounced, etc.) - Total replied count and positive replied count (based on workspace AI tag settings) Without `from`/`to`, returns all-time data. Supply one or both to filter by date range. With `from`/`to`, top-level `stats` use event-date rollups. Main-sequence step and variant rows are scoped to email send date, while replies are scoped to reply date. Subsequence reply attribution uses the lead's `subsequence.repliedAt` timestamp. - [Mailbox performance](https://docs.sendkit.ai/api-reference/get-v1-analytics-mailboxes.md): Returns performance metrics for all mailboxes in the workspace. Includes send stats, bounce rate, daily limits, warmup status, and aggregated campaign email performance (sent, opened, clicked, bounced, replied) with rates. Without `from`/`to`, returns all-time data. Supply one or both to filter by date range. - [Per-mailbox analytics](https://docs.sendkit.ai/api-reference/get-v1-analytics-mailboxes-mailboxid.md): Returns detailed analytics for a single mailbox, including: - Mailbox info (email, displayName, status) - Aggregated campaign email stats (sent, opened, clicked, bounced, replied) - Computed rates (open, click, bounce, reply) Without `from`/`to`, returns all-time data. Supply one or both to filter by date range. - [Daily breakdown](https://docs.sendkit.ai/api-reference/get-v1-analytics-daily.md): Returns daily email stats aggregated across all campaigns in the workspace. Defaults to the last 30 days if `from`/`to` are not provided. Results are sorted by date ascending. Optional `subsequenceId` query param scopes the breakdown: - omitted → combined main + all subsequences (default) - `main` → main sequence only - `<24-hex ObjectId>` → that specific subsequence only When scoped to a specific subsequence, `replied` per day is bucketed by `subsequence.repliedAt` instead of the lead's top-level `repliedAt`. - [Daily breakdown for a campaign](https://docs.sendkit.ai/api-reference/get-v1-analytics-daily-campaigns-campaignid.md): Returns daily email stats for a single campaign. Defaults to the last 30 days if `from`/`to` are not provided. Results are sorted by date ascending. Optional `subsequenceId` query param scopes the breakdown to main only, a specific subsequence, or combined (default). See `/v1/analytics/daily` for semantics. - [Daily breakdown for a mailbox](https://docs.sendkit.ai/api-reference/get-v1-analytics-daily-mailboxes-mailboxid.md): Returns daily email stats for a single mailbox. Replies are attributed to the last mailbox that sent an email before the reply. Defaults to the last 30 days if `from`/`to` are not provided. Results are sorted by date ascending. - [List DNC entries](https://docs.sendkit.ai/api-reference/get-v1-dnc.md): Returns a paginated list of Do Not Contact entries for the workspace. Optionally filter by entry type. - [Add to DNC](https://docs.sendkit.ai/api-reference/post-v1-dnc.md): Add one or more email addresses or domains to the Do Not Contact list. Entries that already exist are skipped (not duplicated). Emails are lowercased automatically. - [Remove DNC entries](https://docs.sendkit.ai/api-reference/delete-v1-dnc.md): Remove entries from the Do Not Contact list. Two modes: - **By emails**: provide an explicit list of email addresses to remove - **Select all**: set `selectAll: true` with optional `search` and `type` filters - [Bulk import DNC list](https://docs.sendkit.ai/api-reference/post-v1-dnc-import.md): Bulk import up to 10,000 DNC entries at once. Existing entries (by email) are automatically skipped. Emails are lowercased. Uses `insertMany` for efficient bulk insert. Default reason is `import`. - [List AI agents](https://docs.sendkit.ai/api-reference/get-v1-agents.md): Returns all active AI agents for the workspace (excludes soft-deleted agents). Sorted by creation date descending. - [Create agent](https://docs.sendkit.ai/api-reference/post-v1-agents.md): Creates a new AI agent. Costs **10 credits** per agent and includes initial website training when `companyUrl` or `companyInfo.domain` is provided. The first agent created becomes the default agent automatically. Calendar booking settings and selected page controls are not public API fields. Add booking links or other scheduling context to `persona.customInstructions`; website page discovery is automatic. - [Get agent detail](https://docs.sendkit.ai/api-reference/get-v1-agents-agentid.md): Returns the full agent configuration including company info, persona, and usage stats. - [Update agent](https://docs.sendkit.ai/api-reference/patch-v1-agents-agentid.md): Updates whitelisted agent configuration. All fields are optional and only provided fields are changed. For `companyInfo`, `persona`, `autonomousMode`, and `followupSettings`, provided fields are merged into the existing object. Calendar settings and selected page controls are not accepted by the public API. - [Delete agent](https://docs.sendkit.ai/api-reference/delete-v1-agents-agentid.md): Soft-deletes an agent by setting `isActive` to false. The agent will no longer appear in list results. - [Retrain agent](https://docs.sendkit.ai/api-reference/post-v1-agents-agentid-retrain.md): Queues website retraining and re-processes uploaded documents for an agent. Costs **10 credits**. The API does not accept selected pages; website discovery is automatic. - [Upload agent training document](https://docs.sendkit.ai/api-reference/post-v1-agents-agentid-upload-document.md): Either uploads a multipart `file` directly through the API or returns a presigned R2 upload URL for JSON requests. Allowed file types are PDF, DOCX, and TXT. Maximum size is 10MB. - [Process uploaded agent document](https://docs.sendkit.ai/api-reference/post-v1-agents-agentid-process-document.md): Queues document extraction, chunking, embedding, and knowledge-base indexing after a document has been uploaded. - [List agent training documents](https://docs.sendkit.ai/api-reference/get-v1-agents-agentid-documents.md): No description found - [Remove agent training document](https://docs.sendkit.ai/api-reference/delete-v1-agents-agentid-documents.md): REST-only destructive action. This is intentionally not exposed as an MCP tool. - [List AI tagging labels](https://docs.sendkit.ai/api-reference/get-v1-tags.md): Returns all AI tagging labels configured for the workspace. Labels are stored in `workspace.aiTagging.labels`. - [Create tag](https://docs.sendkit.ai/api-reference/post-v1-tags.md): Creates a new AI tagging label for the workspace. Tag names must be unique (case-insensitive). Default color is `#6b7280` (gray) if not provided. - [Update tag](https://docs.sendkit.ai/api-reference/patch-v1-tags-name.md): Updates a tag's description and/or color. The tag name cannot be changed. - [Delete tag](https://docs.sendkit.ai/api-reference/delete-v1-tags-name.md): Deletes a tag label from the workspace. Also removes this tag from all campaign leads that have it assigned (unsets `aiTag` and `aiTaggedAt`). - [Get provider list](https://docs.sendkit.ai/api-reference/get-v1-enrichment-settings.md): Returns all supported enrichment providers with their enabled status, priority order, and whether an API key has been configured. Sorted by priority ascending. The `enrich` provider is enabled by default. - [Update provider priority/enabled](https://docs.sendkit.ai/api-reference/patch-v1-enrichment-settings.md): Update the enabled status and/or priority order of one or more enrichment providers. Only provided fields are updated - omitted fields remain unchanged. - [Check provider config](https://docs.sendkit.ai/api-reference/get-v1-enrichment-settings-provider.md): Returns the configuration status for a specific enrichment provider, including whether it's configured, enabled, and its priority. - [Configure provider API key](https://docs.sendkit.ai/api-reference/post-v1-enrichment-settings-provider.md): Sets the API key for a provider. The key is encrypted before storage. Automatically enables the provider after configuration. - [Remove provider config](https://docs.sendkit.ai/api-reference/delete-v1-enrichment-settings-provider.md): Removes the provider's API key and all configuration. The provider will no longer appear as configured. - [Enrich leads](https://docs.sendkit.ai/api-reference/post-v1-enrichment-enrich.md): Triggers enrichment jobs for the specified leads. Creates one job per enrichment type and queues them for background processing by the enrichment worker. **Supported enrichment types:** - `email` - Email verification (0.2 credits per lead beyond FUP allowance) - `phoneEnrichment` - Multi-provider phone enrichment (20 credits per lead with built-in provider) - `segGateway` - Secure Email Gateway detection (free) - `espDetection` - Email Service Provider detection via MX records (free) — detects Gmail, Outlook, Yahoo, Apple, Zoho, etc. **Provider handling:** - The built-in `enrich` provider is always available at no extra configuration. - External providers (leadmagic, icypeas, hunter, etc.) must be configured via `POST /v1/enrichment-settings/{provider}` before use. External providers use your own API key credits - no Enrich credits are charged. Credits are deducted upfront when using the built-in provider. - [List enrichment jobs](https://docs.sendkit.ai/api-reference/get-v1-enrichment-jobs.md): Returns a paginated list of enrichment jobs for the workspace, ordered by most recent first. - [Get job status](https://docs.sendkit.ai/api-reference/get-v1-enrichment-jobs-jobid.md): Returns the current status and progress of an enrichment job. Jobs expire after 7 days. - [Cancel a job](https://docs.sendkit.ai/api-reference/post-v1-enrichment-jobs-jobid-cancel.md): Cancels an enrichment job that is in `pending` or `processing` status. Jobs that are already `completed`, `failed`, or `cancelled` cannot be cancelled. - [Get all integration statuses](https://docs.sendkit.ai/api-reference/get-v1-integrations.md): Returns a consolidated overview of all integration statuses including Slack, Clay, and all CRM types (attio, hubspot, pipedrive, airtable, salesforce, supabase). - [Get CRM statuses](https://docs.sendkit.ai/api-reference/get-v1-integrations-crm.md): Returns connection status and sync stats for all supported CRM types. - [Get specific CRM status](https://docs.sendkit.ai/api-reference/get-v1-integrations-crm-type.md): Returns connection status and sync stats for a specific CRM type. - [Connect CRM](https://docs.sendkit.ai/api-reference/post-v1-integrations-crm-type.md): Connects a CRM by saving an encrypted API key. Records the connection time and user. - [Disconnect CRM](https://docs.sendkit.ai/api-reference/delete-v1-integrations-crm-type.md): Removes the CRM API key and disconnects the integration. - [Pull contacts from CRM](https://docs.sendkit.ai/api-reference/post-v1-integrations-crm-type-pull.md): Creates an async job to import contacts from the connected CRM into SendKit leads. Returns the job ID to track progress via the jobs endpoint. - [Push leads to CRM](https://docs.sendkit.ai/api-reference/post-v1-integrations-crm-type-push.md): Creates an async job to export selected leads to the connected CRM. Returns the job ID to track progress via the jobs endpoint. - [List CRM sync jobs](https://docs.sendkit.ai/api-reference/get-v1-integrations-crm-jobs.md): Returns a paginated list of all CRM sync jobs (pull and push) for the workspace, sorted by most recent first. - [Get sync job details](https://docs.sendkit.ai/api-reference/get-v1-integrations-crm-jobs-jobid.md): Returns full details of a specific CRM sync job. - [Get Slack status](https://docs.sendkit.ai/api-reference/get-v1-integrations-slack.md): Returns the Slack integration connection status, team name, default channel, and notification settings. - [Disconnect Slack](https://docs.sendkit.ai/api-reference/delete-v1-integrations-slack.md): Disconnects the Slack integration by disabling it and clearing the configuration. - [Get Clay status](https://docs.sendkit.ai/api-reference/get-v1-integrations-clay.md): Returns the Clay integration status, total imported count, and last sync time. - [Configure Clay](https://docs.sendkit.ai/api-reference/post-v1-integrations-clay.md): Enables or configures the Clay integration. Optionally set field mapping for data sync. - [Disable Clay](https://docs.sendkit.ai/api-reference/delete-v1-integrations-clay.md): Disables the Clay integration and clears its configuration. - [List inbox placement tests](https://docs.sendkit.ai/api-reference/get-v1-inbox-placement.md): Returns a paginated list of inbox placement tests for the workspace, sorted by most recent first. Includes test name, status, summary results, and timestamps. - [Create inbox placement test](https://docs.sendkit.ai/api-reference/post-v1-inbox-placement.md): Creates a new inbox placement test. Sends emails from your sender mailboxes to seed accounts and monitors where they land (inbox, spam, promotions, etc.). Optionally specify mailboxTypes to control which seed account categories are used (defaults to all 4 types, 5 receivers per type). Optionally provide customSubject and customBody together for custom email copy, otherwise a random template is used. Max 500 sender mailboxes per test. Subject to monthly FUP limits based on subscription. - [Get test results](https://docs.sendkit.ai/api-reference/get-v1-inbox-placement-testid.md): Returns full details of an inbox placement test including all results data. - [List blacklist tests](https://docs.sendkit.ai/api-reference/get-v1-blacklist-tests.md): Returns a paginated list of blacklist tests for the workspace, sorted by most recent first. Includes test name, status, overall summary, and timestamps. - [Create blacklist test](https://docs.sendkit.ai/api-reference/post-v1-blacklist-tests.md): Creates a new blacklist test to check mailbox IPs/domains against known blacklists. Max 1000 mailboxes per test. Subject to monthly FUP limits based on subscription. - [Get test results](https://docs.sendkit.ai/api-reference/get-v1-blacklist-tests-testid.md): Returns full details of a blacklist test including per-mailbox results. - [Generate report](https://docs.sendkit.ai/api-reference/post-v1-reports.md): Queue a new report for generation. Reports are generated asynchronously by a background worker. **Report types:** - `campaign` — Generate a report for specific campaigns (1-10). Creates one report per campaign. - `workspace` — Generate a report covering all workspace activity. - `organizational` — Generate a report aggregating all workspaces owned by the authenticated user. The report is created with status `queued` and processed in the background. Use webhooks or poll the report status to know when it's ready. - [List report recipients](https://docs.sendkit.ai/api-reference/get-v1-reports-recipients.md): Returns a paginated list of report recipients for the workspace. Supports search by name, email, or company. - [Add report recipient](https://docs.sendkit.ai/api-reference/post-v1-reports-recipients.md): Add a new recipient who can receive generated reports. Each recipient can have an optional delivery schedule. - Set `reportType` to `campaign` and provide `campaignIds` (max 10) for campaign-specific reports. - Set `reportType` to `workspace` for workspace-wide reports. - Enable `schedule` to automatically generate and deliver reports on a recurring basis. Duplicate emails within the same workspace are rejected. - [Delete report recipient](https://docs.sendkit.ai/api-reference/delete-v1-reports-recipients-recipientid.md): Permanently removes a report recipient from the workspace.