API Docs
title: API Docs
description: Reference documentation for the SalesBlink Public API.
SalesBlink API v1.0.0
Use only when someone specifically asks about API.
SalesBlink Public API Documentation
Get Your API Key
Get your API Key here: https://run.salesblink.io/account/integration/api
Authentication
All API endpoints require an API Key passed in the Authorization header:
Authorization: your_salesblink_api_keyBase URL
Rate Limits
The SalesBlink API implements tiered rate limiting based on request type:
Tier | Limit | Applies To |
|---|---|---|
General | 30 requests per minute | GET requests |
Sensitive | 15 requests per minute | POST and PATCH requests |
Restricted | 10 requests per minute | PUT and DELETE requests |
Requesting Rate Limit Increases
Need higher limits? Contact us at https://salesblink.io/contact-us to discuss your requirements.
Support
For support, contact: https://salesblink.io/contact-us
Servers
- Production API Server:
https://run.salesblink.io/api/public/v1.0.0 - Local Development Server:
http://localhost:3000/api/public/v1.0.0
Endpoints
/account/verify
GET — Verify API Key
Verify the provided API key and return basic account/workspace information.
For AI agents: Use this to confirm the API key is valid before making other calls.
Responses:
- 200: API key valid
Content-Type: application/jsonSchema:
success: boolean —data: object —account_id: string —user_id: string —email: string —
/billing/add-card
POST — Get Add Card Login Link
Generate a magic login link that redirects the user to the billing page to add a payment card.
Responses:
- 200: Login link generated successfully
Content-Type: application/jsonSchema:
success: boolean —message: string —data: object —login_link: string —destination: string —purpose: string —
/billing/remove-card
POST — Get Remove Card Login Link
Generate a magic login link that redirects the user to the billing page to remove their saved payment card.
Responses:
- 200: Login link generated successfully
Content-Type: application/jsonSchema:
success: boolean —message: string —data: object —login_link: string —destination: string —purpose: string —
/analytics/daily
GET — Daily Overall Stats
Retrieve day-wise overall stats across all sequences.
For AI agents: Use timezone to align reporting with the workspace's local time.
Parameters:
from(query): integer — Start date timestamp (Unix ms)to(query): integer — End date timestamp (Unix ms)timezone(query): string — IANA timezone (e.g.,America/New_York)
Responses:
- 200: Daily stats retrieved successfully
Content-Type: application/jsonSchema:
/analytics/lead-stats
GET — Lead-Level Stats
Retrieve lead-level engagement stats.
For AI agents: Use limit and skip to paginate through large lead sets.
Parameters:
from(query): integer — Start date timestamp (Unix ms)to(query): integer — End date timestamp (Unix ms)limit(query): integer — Maximum number of leads to returnskip(query): integer — Number of leads to skip
Responses:
- 200: Lead stats retrieved successfully
Content-Type: application/jsonSchema:
/analytics/mailbox-stats
GET — Mailbox Stats
Retrieve overall mailbox-level stats.
For AI agents: Use from/to to narrow results to a specific reporting window.
Parameters:
from(query): integer — Start date timestamp (Unix ms)to(query): integer — End date timestamp (Unix ms)limit(query): integer — Maximum number of mailboxes to returnskip(query): integer — Number of mailboxes to skip
Responses:
- 200: Mailbox stats retrieved successfully
Content-Type: application/jsonSchema:
/analytics/overall
GET — Overall Stats
Retrieve overall stats across all sequences.
For AI agents: Use from/to query params to filter stats by date range.
Parameters:
from(query): integer — Start date timestamp (Unix ms)to(query): integer — End date timestamp (Unix ms)
Responses:
- 200: Overall stats retrieved successfully
Content-Type: application/jsonSchema:
/clicks
GET — Get Clicks Activity
Retrieve link click events to measure engagement.
Parameters:
per_page(query): integer —page(query): integer —sequence_id(query): string —recipient_email_address(query): string —since(query): integer —from(query): integer —to(query): integer —
Responses:
- 200: Clicks activity retrieved successfully
Content-Type: application/jsonSchema:
/contacts
POST — Add Leads to a List
Add multiple leads (contacts) to an existing list.
For AI agents: Maximum 500 leads per request. Set remove_duplicates=true to maintain list quality.
All lead fields must be snake_case: use standard fields like first_name, last_name, email, phone, company_name, job_title, plus any custom fields in snake_case (e.g. lead_score). Requests with non-snake_case field names are rejected with a 400 error. New custom fields are automatically added to the list's columns.
Use the dedicated starred boolean property on each contact to mark/unmark it as starred; starred is a contact setting and is NOT added as a list column. Use PUT /contacts/{id}/archive to archive/unarchive contacts.
Request Body (application/json):
list_id: string (required) (e.g.,list_uuid_here) — The list ID to add leads tocontacts: array of object (required) — Array of lead objects to add (max 500). All field names must be snake_case.first_name: string — Lead's first namelast_name: string — Lead's last nameemail: string (required) — Lead's email address (required)phone: string — Lead's phone numberstarred: boolean — Mark/unmark the contact as starred. This is a contact setting, not a data field/column.
remove_duplicates: boolean — Automatically remove duplicate emails from the list
Responses:
- 200: Leads added successfully
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —- 400: Bad request - invalid input
Content-Type: application/jsonSchema:
/contacts/remove
POST — Remove a Lead from a List
Remove a single lead from a list by their email address.
Request Body (application/json):
list_id: string (required) (e.g.,list_uuid_here) — The list IDemail: string (required) (e.g.,john@example.com) — The email address of the lead to remove
Responses:
- 200: Lead removed successfully
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —
/contacts/{id}/archive
PUT — Archive or Unarchive a Contact
Archive or unarchive a contact. Archiving removes pending tasks for this contact.
Parameters:
id(path): string (required) — The unique identifier of the contact (MongoDB ObjectId)
Request Body (application/json):
archived: boolean — true to archive, false to unarchive
Responses:
- 200: Contact archived/unarchived successfully
Content-Type: application/jsonSchema:
/dfy/orders
POST — Place DFY Order
Purchase domains and provision Google Workspace, Outlook, or Azure mailboxes with full deliverability setup.
Requires a saved payment method. Trial plans are not eligible.
Provider-specific requirements:
- Google: password is required. mailboxes array is required for buy domains.
- Outlook: mailboxes array is required for buy domains.
- Azure: mailboxes array is required for buy domains and must contain 30 to 100 mailboxes per domain. Connect domains are auto-provisioned with an admin mailbox.
Request Body (application/json):
domains: array of object (required) — Array of domain objects. Buy and Connect domains cannot be mixed in the same order.domain: string (required) — Domain name to purchase or connectisConnect: boolean — true = connect your own existing domain (no purchase), false = buy new domain (default)mailboxes: array of object — Mailboxes to provision. Required for buy domains (google/outlook need ≥1, azure needs 30–100). Optional for connect-domain orders; an admin mailbox is auto-provisioned when omitted.username: string (required) — Mailbox username (without @domain)firstName: string —lastName: string —
type: string (required) (enum: google, outlook, azure) — Mailbox provider type. google = Google Workspace, outlook = Microsoft 365, azure = Azure (30 to 100 mailboxes per buy domain)redirectionUrl: string — Redirect URL for the domainmasterInboxEmail: string — Master inbox email for admin accesspassword: string — Common password for ALL mailboxes. REQUIRED for google. Auto-generated if omitted for google buy domains with no custom mailboxes.couponCode: string — Optional Stripe coupon code
Responses:
- 200: DFY order placed successfully
Content-Type: application/jsonSchema:
success: boolean —message: string —data: object —notice: string —
GET — Get DFY Orders
Retrieve all Done-For-You orders.
Responses:
- 200: List of DFY orders
Content-Type: application/jsonSchema:
success: boolean —message: string —data: array of object —
/dfy/orders/{orderId}/mailboxes
POST — Add Mailbox to DFY Order
Add mailboxes to an existing DFY order. Cannot be used for Azure orders.
Parameters:
orderId(path): string (required) — The DFY order ID
Request Body (application/json):
domainName: string (required) — Domain in the order to add mailboxes toemails: array of string (required) — Array of usernames (without @domain)password: string — Password for new mailboxes (Google only)
Responses:
- 200: Mailbox added successfully
Content-Type: application/jsonSchema:
/dfy/orders/{orderId}/mailboxes/{mailboxId}/cancel-link
GET — Get DFY Mailbox Cancel Login Link
Returns a billing management login link where the user can cancel a mailbox from a DFY order.
Parameters:
orderId(path): string (required) — The DFY order IDmailboxId(path): string (required) — The mailbox ID (inboxkit_mailbox_uid) to cancel
Responses:
- 200: Billing management link returned
Content-Type: application/jsonSchema:
success: boolean —message: string —data: object —login_link: string —destination: string —purpose: string —
/domains
GET — Get Custom Domains
Retrieve all custom tracking domains configured in the workspace.
Parameters:
limit(query): integer —skip(query): integer —
Responses:
- 200: List of custom domains
Content-Type: application/jsonSchema:
success: boolean —data: array of object —id: string —domain: string —type: string (enum: click-tracker, redirect) —verified: boolean —owned_by: string —
/domains/search
GET — Search Domains
Search available .com domains for DFY purchase. Only .com TLD is supported.
Parameters:
keyword(query): string (required) — Domain keyword to search (e.g. 'mybrand'). Only .com is supported.
Responses:
- 200: Domain search results
Content-Type: application/jsonSchema:
success: boolean —message: string —data: array of object —domain: string —price: number —status: string (enum: available, unavailable) —google_workspace_available: boolean —ms365_workspace_available: boolean —
/folders
GET — Get All Folders
Retrieve all folders. General folders organize lists, templates, and sequences. Email-sender folders organize email senders only. Omit the type filter to return every folder.
Parameters:
limit(query): integer — Maximum number of folders to returnskip(query): integer — Number of folders to skip for paginationsearch(query): string — Search query to filter folderstype(query): string (optional) (enum: all, general, email-sender) — Folder type filter.allreturns every folder (default),generalreturns folders created without atype(lists, templates, sequences),email-senderreturns email-sender folders only.
Responses:
- 200: A list of folders
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: array of object —id: string —name: string —type: string —owned_by: string — Email of the folder ownerdate_created: string —
POST — Create a Folder
Create a new folder. Only include the type field when creating an email-sender folder. For general folders (lists, templates, sequences), do not include the type field.
Request Body (application/json):
name: string (required) — Name of the foldertype: string (optional) (enum: email-sender) — Folder type. Only include this field for email-sender folders. For general folders, do not include this field.
Responses:
- 200: Folder created successfully
Content-Type: application/jsonSchema:
success: boolean —data: object —id: string —name: string —type: string —
/inbox
GET — Get Inbox Threads
Retrieve email threads from your unified inbox.
For AI agents: Use type=replies to get only replies from leads, type=sent for sent emails.
Parameters:
type(query): string — Type of threads to retrievesequence(query): string — Filter by sequence idsearch(query): string — Search query for thread contentlimit(query): integer — Maximum number of threads to returnskip(query): integer — Number of threads to skip for paginationdays(query): integer — Fetch inbox items from the last X daysoutcome(query): string — Filter by outcome classificationunread(query): boolean — Filter by unread statussender(query): string — Filter by sender emailstarred(query): boolean — Filter by starred statusarchived(query): boolean — Filter by archived statusowned_by(query): string — Filter by owner (admin/owner only)
Responses:
- 200: Thread tasks response with total count and results
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —totalCount: integer — Total number of matching threadsresult: array of object —id: string —messageId: string —task_type: string (e.g.,reply) —email: string —data: object —email: object —subject: string —body: string —
scheduled_time: integer —unread: boolean —sender: string —
/inbox-placement
GET — Get Inbox Placement Tests
Retrieve all inbox placement tests.
For AI agents: Inbox placement tests help verify email deliverability across different providers.
Parameters:
limit(query): integer —skip(query): integer —owned_by(query): string — Filter by owner (admin/owner only)
Responses:
- 200: List of inbox placement tests
Content-Type: application/jsonSchema:
success: boolean —data: array of object —id: string —name: string —status: string —owned_by: string —
POST — Create Inbox Placement Test
Create a new inbox placement test to check email deliverability.
For AI agents: Tests can use sequence content or custom subject/body. Use source='from-salesblink' with subject/body for custom content.
Request Body (application/json):
source: string (enum: from-salesblink, sequence) — Source of test contentsubject: string — Subject line (for from-salesblink source with custom content)body: string — Email body HTML (for from-salesblink source)sequence_id: string — Sequence ID to test (for sequence source)
Responses:
- 200: Test created successfully
Content-Type: application/jsonSchema:
success: boolean —data: object —id: string —name: string —
/inbox-placement/{id}
DELETE — Delete Inbox Placement Test
Delete an inbox placement test.
Parameters:
id(path): string (required) — The unique identifier of the test
Responses:
- 200: Test deleted successfully
Content-Type: application/jsonSchema:
/inbox-placement/{id}/pause
PUT — Pause Inbox Placement Test
Pause an active inbox placement test.
Parameters:
id(path): string (required) — The unique identifier of the test
Responses:
- 200: Test paused successfully
Content-Type: application/jsonSchema:
/inbox/{messageId}
PATCH — Update Mail State
Update the state of an inbox item. Mark emails as read/unread and set conversation outcomes.
For AI agents: Use outcome field to classify replies as "positive", "negative", etc.
Parameters:
messageId(path): string (required) — The unique message ID
Request Body (application/json):
unread: boolean — Mark as read (false) or unread (true)outcome: string (e.g.,positive) — Set conversation outcome (e.g., positive, negative, neutral)
Responses:
- 200: Mail state updated successfully
Content-Type: application/jsonSchema:
/inbox/{messageId}/forward
POST — Forward an Email
Forward an email to one or more recipients.
For AI agents: Provide at least one of email, cc, or bcc. Content is optional; omit to forward the original body.
Parameters:
messageId(path): string (required) — The unique message ID
Request Body (application/json):
email: string — Primary recipient email addresscontent: string — Optional replacement HTML contentcc: string — Optional CC email addressbcc: string — Optional BCC email address
Responses:
- 200: Email forwarded successfully
Content-Type: application/jsonSchema:
/inbox/{messageId}/reply
POST — Send a Reply
Send a reply to a lead's email. The reply will be sent from the same sender that originally contacted the lead.
For AI agents: This maintains conversation continuity automatically.
Parameters:
messageId(path): string (required) — The unique message ID to reply to
Request Body (application/json):
content: string (required) (e.g.,<p>Thanks for getting back to me!</p>) — HTML content of the replycc: string (e.g.,optional@cc.com) — Optional CC email addressbcc: string — Optional BCC email address
Responses:
- 200: Reply scheduled successfully
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string —task_type: string (e.g.,reply) —status: string (e.g.,scheduled) —
/inbox/{messageId}/thread
GET — Get Thread Messages
Retrieve all emails associated with a specific message thread.
Parameters:
messageId(path): string (required) — The unique message ID of the thread
Responses:
- 200: All tasks/emails in the conversation thread
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: array of object —id: string —task_type: string —data: object —scheduled_time: integer —
/keys
GET — Get API Keys
Retrieve all API keys for the account. Use this to audit active integrations or find key IDs for management.
Responses:
- 200: List of API keys
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: array of object —id: string (e.g.,0d061c26-83a5-490c-ab85-c72e46103e21) —name: string (e.g.,test) —key: string (e.g.,key...31f) —date_created: string (e.g.,2026-05-08T05:05:48.672Z) —active: boolean (e.g.,True) —user_id: string (e.g.,772e7879-cb1f-4cc6-9dae-50b3962d302a) —owned_by: string (e.g.,user@example.com) —
POST — Create API Key
Generate a new API key. The full key is only returned once in the response; store it securely.
Request Body (application/json):
name: string (required) (e.g.,New Integration) —
Responses:
- 200: API key created
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string (e.g.,0d061c26-83a5-490c-ab85-c72e46103e21) —name: string (e.g.,test) —api_key: string (e.g.,key-5f3e...) —date_created: string (e.g.,2026-05-08T05:05:48.672Z) —
/keys/{id}
DELETE — Delete API Key
Revoke an API key. This action is irreversible. You cannot delete the key currently used for authentication.
Parameters:
id(path): string (required) —
Responses:
- 200: API key deleted
Content-Type: application/jsonSchema:
/keys/{id}/refresh
POST — Refresh API Key
Generate a new API key and revoke the old one. This is useful for rotating keys without losing the key record's name/metadata.
Parameters:
id(path): string (required) —
Responses:
- 200: API key refreshed
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —message: string (e.g.,API key refreshed) —data: object —id: string (e.g.,0d061c26-83a5-490c-ab85-c72e46103e21) —name: string (e.g.,test) —api_key: string (e.g.,key-5f3e...) —date_created: string (e.g.,2026-05-08T05:05:48.672Z) —
/leads/{id}
PATCH — Update a Lead
Update lead properties.
For AI agents: You can update any custom fields. System fields like _id, accuracy, verification status cannot be modified.
All field names must be snake_case (e.g. first_name, company_name, lead_score). Requests with non-snake_case field names are rejected with a 400 error.
Use the dedicated starred boolean property to mark/unmark the lead as starred; starred is a contact setting and is NOT added as a list column. Use PUT /contacts/{id}/archive to archive/unarchive contacts.
Parameters:
id(path): string (required) — The unique identifier of the lead (contact)
Request Body (application/json):
first_name: string —last_name: string —email: string —phone: string —company_name: string —job_title: string —starred: boolean — Mark/unmark the lead as starred. This is a contact setting, not a data field/column.
Responses:
- 200: Lead updated successfully
Content-Type: application/jsonSchema:
success: boolean —data: object — Updated fields
/leads/{id}/move
PUT — Move Lead to Another List
Move a lead from one list to another.
Parameters:
id(path): string (required) — The unique identifier of the lead to move
Request Body (application/json):
list_id: string (required) — Destination list ID
Responses:
- 200: Lead moved successfully
Content-Type: application/jsonSchema:
/leads/activity
GET — Lead Activity History by Email
Retrieve activity history for a lead using their email address.
For AI agents: Use this when you only know the lead's email and not the lead ID.
Parameters:
email(query): string (required) — The lead email addresssequence_id(query): string — Filter by sequence IDfrom(query): integer — Start date timestamp (Unix ms)to(query): integer — End date timestamp (Unix ms)limit(query): integer — Maximum number of activities to returnskip(query): integer — Number of activities to skip
Responses:
- 200: Lead activity retrieved successfully
Content-Type: application/jsonSchema:
/leads/{id}/activity
GET — Lead Activity History
Retrieve activity history for a specific lead.
For AI agents: Use sequence_id to narrow results to one sequence, or omit for all sequences.
Parameters:
id(path): string (required) — The unique identifier of the leadsequence_id(query): string — Filter by sequence IDfrom(query): integer — Start date timestamp (Unix ms)to(query): integer — End date timestamp (Unix ms)limit(query): integer — Maximum number of activities to returnskip(query): integer — Number of activities to skip
Responses:
- 200: Lead activity retrieved successfully
Content-Type: application/jsonSchema:
/leads/{id}/unsubscribe
POST — Unsubscribe Lead from All Sequences
Unsubscribe a lead from all sequences.
For AI agents: This blocks the lead from receiving future emails across every sequence.
Parameters:
id(path): string (required) — The unique identifier of the lead
Responses:
- 200: Lead unsubscribed successfully
Content-Type: application/jsonSchema:
/lists
GET — Get All Lists
Retrieve all lead lists in your workspace.
For AI agents: Use search parameter to filter by name, use archived=true to see archived lists.
Parameters:
limit(query): integer — Maximum number of lists to return (max 100 for v1.0.0)skip(query): integer — Number of lists to skip for paginationsearch(query): string — Search query to filter lists by name (case-insensitive)starred(query): boolean — Filter by starred statusarchived(query): boolean — Filter by archived statusowned_by(query): string — Filter by owner user ID (admin/owner only)
Responses:
- 200: A list of lead lists with owner information
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: array of object —id: string —name: string —contacts_count: integer —starred: boolean —archived: boolean —owned_by: string — Email of the list ownerlast_modified: string —fields: array of string — List columns from its Complete View, in snake_case (e.g.first_name,email,lead_score)
POST — Create a List
Create a new lead list to organize contacts.
For AI agents: Consider enabling verification for better deliverability.
Request Body (application/json):
name: string (required) (e.g.,My New List) — Name of the list (required)folder: string (e.g.,optional_folder_id) — Optional general folder ID to organize the list. Must be a folder created without atype(i.e., not an email-sender folder).starred: boolean — Whether to star the listverification: boolean — Enable email verification for contacts in this list (can only be enabled, not disabled later)archive_invalid: boolean — Archive contacts with invalid emails after verificationarchive_risky: boolean — Archive contacts with risky emails after verification
Responses:
- 200: List created successfully
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string —name: string —contacts_count: integer —date_created: string —fields: array of string — List columns from its Complete View, in snake_case (e.g.first_name,email,lead_score)
/lists/{id}
GET — Get a Specific List
Retrieve detailed information about a specific lead list.
Parameters:
id(path): string (required) — The unique identifier of the list
Responses:
- 200: List details with owner information
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string —name: string —contacts_count: integer —starred: boolean —archived: boolean —owned_by: string — Email of the list ownerlast_modified: string —fields: array of string — List columns from its Complete View, in snake_case (e.g.first_name,email,lead_score)
PATCH — Update a List
Update list properties. For AI agents: Note that verification settings can only be turned ON, not OFF once enabled.
Use PUT /lists/{id}/archive to archive/unarchive lists instead of this endpoint.
Parameters:
id(path): string (required) — The unique identifier of the list
Request Body (application/json):
name: string — New name for the listfolder: string — General folder ID to move the list into. Must be a folder created without atype(i.e., not an email-sender folder).starred: boolean — Star or unstar the listduplicate_removal: boolean — Remove duplicate contacts from this listduplicate_removal_other_list: boolean — Remove contacts that exist in other listsduplicate_removal_team_list: boolean — Remove contacts that exist in team members listsverification: boolean — Enable email verification (can only be turned ON, not OFF)archive_invalid: boolean — Archive invalid emails (can only be turned ON, not OFF)archive_risky: boolean — Archive risky emails (can only be turned ON, not OFF)
Responses:
- 200: List updated successfully
Content-Type: application/jsonSchema:
/lists/{id}/archive
PUT — Archive or Unarchive a List
Archive or unarchive a list. Archiving removes the list from active views but preserves all data.
For AI agents: When archiving, the list is automatically paused if active.
Parameters:
id(path): string (required) — The unique identifier of the list
Request Body (application/json):
archived: boolean — true to archive, false to unarchive
Responses:
- 200: List archived/unarchived successfully
Content-Type: application/jsonSchema:
/lists/{id}/leads
GET — Get Leads in a List
Retrieve all leads (contacts) in a specific list with pagination.
For AI agents: Use limit parameter (max 100) and skip for pagination.
Parameters:
id(path): string (required) — The unique identifier of the listlimit(query): integer — Maximum number of leads to return (max 100)skip(query): integer — Number of leads to skip for paginationowned_by(query): string — Filter by owner (admin/owner only)
Responses:
- 200: List of leads with pagination info
Content-Type: application/jsonSchema:
success: boolean —data: object —contacts: array of any —total: integer — Total number of contacts in the list
/oauth/google
POST — Initialize Google OAuth
Get the OAuth URL for connecting a Google (Gmail/G Suite) account.
For AI agents: Redirect the user to the returned URL or open it in a browser. After OAuth completion, the sender will be connected.
Request Body (application/json):
redirectUrl: string — URL to redirect after OAuth completion
Responses:
- 200: OAuth URL generated
Content-Type: application/jsonSchema:
success: boolean —data: object —url: string — Google OAuth URL to open
/oauth/outlook
POST — Initialize Outlook OAuth
Get the OAuth URL for connecting a Microsoft Outlook account.
For AI agents: Redirect the user to the returned URL or open it in a browser.
Request Body (application/json):
redirectUrl: string — URL to redirect after OAuth completion
Responses:
- 200: OAuth URL generated
Content-Type: application/jsonSchema:
success: boolean —data: object —url: string — Microsoft OAuth URL to open
/opens
GET — Get Opens Activity
Retrieve email open events to measure engagement.
Parameters:
per_page(query): integer — Number of results per page (max 100)page(query): integer — Page numbersequence_id(query): string — Filter by sequence IDrecipient_email_address(query): string — Filter by recipient emailsince(query): integer — Filter events since timestamp (Unix ms)from(query): integer — Start date timestamp (Unix ms)to(query): integer — End date timestamp (Unix ms)
Responses:
- 200: Opens activity retrieved successfully
Content-Type: application/jsonSchema:
/replies
GET — Get Replies Activity
Retrieve email reply events to track responses.
Parameters:
per_page(query): integer —page(query): integer —sequence_id(query): string —recipient_email_address(query): string —since(query): integer —from(query): integer —to(query): integer —
Responses:
- 200: Replies activity retrieved successfully
Content-Type: application/jsonSchema:
/reports
GET — Get Reports
Retrieve activity reports with filtering.
For AI agents: Use from/to parameters for date range filtering.
Parameters:
limit(query): integer —skip(query): integer — Page number (0-based). The server converts this to skip × limit as the database offset.from(query): integer — Start date timestamp (Unix ms)to(query): integer — End date timestamp (Unix ms)owned_by(query): string — Filter by owner (admin/owner only)
Responses:
- 200: Reports retrieved successfully
Content-Type: application/jsonSchema:
success: boolean —data: array of object —
/senders
GET — Get All Email Senders
Retrieve all email sending accounts (senders) in your workspace.
For AI agents: Senders are email accounts used to send sequence emails. Filter by status to find healthy senders.
Parameters:
limit(query): integer — Maximum number of senders to returnskip(query): integer — Number of senders to skip for paginationsearch(query): string — Search query to filter senders by email/namefolder(query): string — Filter by email-sender folder UUID (a folder created withtype: email-sender)owned_by(query): string — Filter by owner (admin/owner only)has_error(query): boolean — Filter by error statusconnecting(query): boolean — Filter by connecting statusconnected(query): boolean — Filter by connected statuswarmup_active(query): boolean — Filter by warmup active statuswarmup_paused(query): boolean — Filter by warmup paused statusno_custom_tracking_domain(query): boolean — Filter senders without custom tracking domain
Responses:
- 200: A list of email senders grouped by folder
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: array of object —folder: object —id: string —name: string —
senders: array of object —id: string —email: string —name: string —status: string —owned_by: string — Email of the sender ownerdate_created: string —
POST — Add Single Sender (SMTP/IMAP)
Add a single email sender via SMTP/IMAP.
For Gmail and Outlook, OAuth is preferred (use POST /oauth/google or POST /oauth/outlook).
SMTP/IMAP can still be used if the user explicitly provides SMTP/IMAP credentials.
Request Body (application/json):
email: string (required) — Sender email addresssenderName: string — Display name for the sendersmtpHost: string (required) — SMTP server hostnamesmtpPort: integer (required) — SMTP server portsmtpUsername: string — SMTP username (defaults to email)smtpPassword: string (required) — SMTP/IMAP passwordimapHost: string — IMAP server hostname (omit for SMTP-only senders)imapPort: integer — IMAP server port (defaults to 993)imapUsername: string — IMAP username (if different from SMTP)imapPassword: string — IMAP password (if different from SMTP)
Responses:
- 200: Sender added successfully
Content-Type: application/jsonSchema:
/senders/bulk
POST — Add Bulk Senders
Add multiple email senders at once using a CSV file or JSON array.
For AI agents: CSV should have columns like email, password, smtpHost, smtpPort, etc.
Request Body (multipart/form-data):
file: string — CSV file containing sender credentialssenders: array of object — Alternative to file - array of sender objects
Responses:
- 200: Bulk senders upload initiated
Content-Type: application/jsonSchema:
success: boolean —data: object —bulkID: string — ID to track the bulk upload progress
/senders/{id}
PATCH — Update Sender
Update email sender settings including warmup, inbox, signature, tracking domain, and sequence sending configuration.
Only the fields provided are updated.
Parameters:
id(path): string (required) — The sender ID
Request Body (application/json):
warmup_enabled: boolean — Enable/disable warmupwarmup_urls: array of string — Warmup link URLswarmup_templates: array of string — Warmup template IDsauto_ramp_up_enabled: boolean — Enable auto ramp-upramp_up_frequency: integer — Ramp-up incrementmax_daily_frequency: integer — Max daily warmup emailsstarting_warmup_frequency: integer — Starting warmup frequencyopen_rate: integer — Target open rate percentagespam_protection: integer — Spam protection levelread_emulation: integer — Read emulation levelwarmup_keyword: string — Warmup keyword/tagsequence_auto_ramp_up_enabled: boolean — Enable sequence auto ramp-upsequence_initial_daily_frequency: integer — Initial daily sequence sendssequence_ramp_up_frequency: integer — Sequence ramp-up incrementsequence_max_daily_frequency: integer — Max daily sequence sendspause_cold_emails_when_health_low: boolean — Pause cold emails when health is lowpause_cold_emails_health_threshold: integer — Health threshold to pause atinbox_enabled: boolean — Enable inbox monitoringinbox_path: string — Inbox folder pathspam_path: string — Spam folder pathsignature: string — Signature ID or namereply_to: string — Reply-to email addressdkim_identifier: string — DKIM identifieruse_custom_tracking_domain: boolean — Use custom tracking domaintracking_domain: string — Tracking domain IDfolder: string — Email-sender folder ID to move the sender into. Must be a folder created withtype: "email-sender". Pass an empty string to remove the sender from its current folder.
Responses:
- 200: Sender updated successfully
Content-Type: application/jsonSchema:
/senders/{id}/reconnect
POST — Reconnect Sender
Reconnect a failed sender by retrying SMTP/IMAP or OAuth validation.
For AI agents: Use this when a sender shows an error or is not sending/receiving emails.
Parameters:
id(path): string (required) — The sender ID
Responses:
- 200: Reconnect scheduled successfully
Content-Type: application/jsonSchema:
/senders/{id}/fetch-messages
POST — Fetch Sender Messages
Fetch messages from a sender's inbox.
For AI agents: Use this to refresh a sender's inbox before checking for new replies.
Parameters:
id(path): string (required) — The sender ID
Responses:
- 200: Messages fetched successfully
Content-Type: application/jsonSchema:
/senders/{id}/health
GET — Sender Health Score
Get sender health and reputation score.
For AI agents: Use this to identify senders with poor deliverability before launching sequences.
Parameters:
id(path): string (required) — The sender ID
Responses:
- 200: Sender health retrieved successfully
Content-Type: application/jsonSchema:
/senders/{id}/warmup-stats
GET — Sender Warmup Stats
Retrieve date-wise warmup statistics for a sender.
For AI agents: Use days to control how much historical warmup data is returned.
Parameters:
id(path): string (required) — The sender IDdays(query): integer — Number of days of warmup history to retrieve
Responses:
- 200: Warmup stats retrieved successfully
Content-Type: application/jsonSchema:
/senders/multi/fetch-messages
POST — Bulk Fetch Sender Messages
Fetch messages from multiple senders' inboxes in one request.
For AI agents: Provide an array of sender IDs to refresh several inboxes at once.
Request Body (application/json):
ids: array of string (required) — Array of sender IDs
Responses:
- 200: Messages fetched successfully
Content-Type: application/jsonSchema:
/sent
GET — Get Sent Activity
Retrieve a log of all sent emails across your sequences.
For AI agents: Use since parameter to get recent activity. Results are paginated.
Parameters:
per_page(query): integer — Number of results per page (max 100)page(query): integer — Page numbersequence_id(query): string — Filter by sequence IDrecipient_email_address(query): string — Filter by recipient emailsince(query): integer — Filter events since timestamp (Unix timestamp in milliseconds)from(query): integer — Start date timestamp (Unix ms) for date rangeto(query): integer — End date timestamp (Unix ms) for date range
Responses:
- 200: Sent activity retrieved successfully
Content-Type: application/jsonSchema:
/sequences
GET — Get All Sequences
Retrieve all email sequences in your workspace.
For AI agents: Use status filter to find active, paused, or completed sequences.
Parameters:
limit(query): integer — Maximum number of sequences to return (max 100)skip(query): integer — Number of sequences to skip for paginationsearch(query): string — Search query to filter sequences by namestatus(query): string — Filter sequences by status (running,paused,completed,needs-attention)folder(query): string — Filter by folder IDsendAll(query): boolean — Include both archived and active sequencessortBy(query): string — Sort fieldsortType(query): string — Sort direction:ascordescstarred(query): boolean — Filter by starred statusarchived(query): boolean — Filter by archived statusowned_by(query): string — Filter by owner (admin/owner only)
Responses:
- 200: A collection of sequences
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: array of object —id: string —name: string —paused: boolean —starred: boolean —archived: boolean —owned_by: string — Email of the sequence ownersent: integer —opens: integer —clicks: integer —replies: integer —
POST — Create a Sequence
Create a new automated email sequence.
For AI agents:
- Steps array defines the sequence flow with email and delay nodes
- Each email step requires a template_id
- Each delay step requires days (number of days to wait)
- If launchTimingMode is not provided or 'now', sequence starts 5 minutes from now
- If 'schedule', provide scheduledAt as a future UTC timestamp (milliseconds) OR an ISO 8601 datetime with timezone offset (e.g. '2026-07-08T16:30:00+05:30' for 4:30 PM IST)
- When scheduling, always provide the user's timezone in the timezone field (e.g. 'Asia/Calcutta') so the sequence does not default to America/New_York
Request Body (application/json):
name: string (required) (e.g.,Outbound Campaign V1) — Name of the sequence (required)folder: string (e.g.,optional_folder_id) — Optional general folder ID to organize the sequence. Must be a folder created without atype(i.e., not an email-sender folder).starred: boolean — Whether to star the sequencesenders: string (required) (e.g.,uuid1,uuid2,folder_uuid1) — Comma-separated sender/folder UUIDs. Can include both sender IDs and folder IDs. Folder IDs here must be email-sender folders.lists: array of string (required) — Array of list UUIDs to include (required)steps: array of any (required) — Ordered array of sequence steps (required). Mix of email and delay stepslaunchTimingMode: string (enum: now, schedule) (e.g.,now) — When to launch: 'now' (default, starts in 5 mins) or 'schedule' (requires scheduledAt and timezone)scheduledAt: integer or string (e.g.,1699999999999or'2026-07-08T16:30:00+05:30') — UTC Timestamp in milliseconds OR ISO 8601 datetime with timezone offset (required if launchTimingMode=schedule, must be future)timezone: string (e.g.,Asia/Calcutta) — IANA timezone for scheduled sending. Required when scheduling to avoid defaulting to America/New_Yorkpaused: boolean (e.g.,True) — Whether to create the sequence in paused state (default true)delayEnabled: boolean (e.g.,True) — Enable random delay between emailsdelayFrom: integer (e.g.,10) — Minimum delay in minutesdelayTo: integer (e.g.,20) — Maximum delay in minutesstopWhenReplyRecieved: boolean (e.g.,True) — Stop sequence when recipient repliesevergreen: boolean — Enable evergreen sequence (continuously running)bounceThreshold: integer (e.g.,2) — Number of bounces before pausingbouncePause: boolean — Pause sequence on bounce thresholdautoPause: boolean (e.g.,True) — Enable auto-pause on high bounce rateautoTagReplies: boolean — Auto-tag reply outcomesemailSendingHours: array of any — Configure sending hours for each day of the week. Must contain one entry for every day (Monday-Sunday). Example:
[
{ "enabled": true, "name": "Monday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": true, "name": "Tuesday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": true, "name": "Wednesday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": true, "name": "Thursday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": true, "name": "Friday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": false, "name": "Saturday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": false, "name": "Sunday", "fromTime": "09:00", "toTime": "17:00" }
]sendToOnlyVerifiedEmail: boolean — Only send to verified emailsvalidEmail: boolean (e.g.,True) — Send to contacts with valid email statusriskyEmail: boolean (e.g.,True) — Send to contacts with risky email statusinvalidEmail: boolean (e.g.,True) — Send to contacts with invalid email statuscheckEmailOpen: boolean — Check if recipient opened previous email before sending nextcheckEmailClick: boolean — Check if recipient clicked link before sending nextcheckEmailReply: boolean (e.g.,True) — Check if recipient replied before sending nextcheckEmailBeforeSending: boolean (e.g.,True) — Verify email before sendingplainText: boolean (e.g.,True) — Send as plain text emailauto_reply: boolean (e.g.,True) — Enable auto-reply detectionmatchProvider: boolean (e.g.,True) — Match sender email provider with recipientskip_esg: boolean (e.g.,True) — Skip ESG (Email Service Gateway) detectionstopWhenReplyRecievedWhen: string (enum: contact, contact-with-same-domain) (e.g.,contact) — When to stop sequence on replybcc: string — BCC email address for all outgoing emails
Responses:
- 200: Sequence created successfully
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string —name: string —paused: boolean —date_created: integer —
/sequences/{id}
GET — Get a Specific Sequence
Retrieve detailed information about a specific sequence including steps and settings.
Parameters:
id(path): string (required) — The unique identifier of the sequence
Responses:
- 200: Details of the sequence
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string —name: string —paused: boolean —starred: boolean —archived: boolean —owned_by: string — Email of the sequence ownerlists: array of string —senders: string — Comma-separated sender/folder UUIDs. Folder IDs must be email-sender folders.emailSenders: array of object — Selected sender/folder objects derived from senderslaunchTimingMode: string —delayFrom: integer —delayTo: integer —stopWhenReplyRecieved: boolean —evergreen: boolean —sent: integer —opens: integer —clicks: integer —replies: integer —emailSendingHours: array of object — Sending hours for each day of the week (Monday-Sunday). Each object has enabled, name, fromTime, toTime.steps: array of object —
PATCH — Update Sequence Properties and State
Controls pausing/resuming, starring, and updating sequence settings.
For AI agents: Provide steps array to completely rewrite the sequence flow. All existing steps will be replaced.
Use PUT /sequences/{id}/archive to archive/unarchive sequences.
Parameters:
id(path): string (required) — The unique identifier of the sequence
Request Body (application/json):
name: string (e.g.,Updated Campaign Name) — Sequence namepaused: boolean (e.g.,True) — Pause (true) or resume (false) the sequencestarred: boolean — Star the sequencefolder: string — General folder ID to move the sequence into. Must be a folder created without atype(i.e., not an email-sender folder).senders: string (e.g.,uuid1,uuid2) — Comma-separated sender/folder UUIDs. Folder IDs must be email-sender folders.lists: array of string — Array of list UUIDs to associate with sequencelaunchTimingMode: string (enum: now, schedule) (e.g.,now) — Launch timing modescheduledAt: integer or string (e.g.,1699999999999or'2026-07-08T16:30:00+05:30') — UTC Timestamp in milliseconds OR ISO 8601 datetime with timezone offsettimezone: string (e.g.,Asia/Calcutta) — IANA timezone for sending emailsstopWhenReplyRecieved: boolean (e.g.,True) — Stop sequence when recipient repliesevergreen: boolean — Enable evergreen sequencedelayEnabled: boolean (e.g.,True) — Enable sending delaydelayFrom: integer (e.g.,10) — Minimum delay in minutesdelayTo: integer (e.g.,20) — Maximum delay in minutesemailSendingHours: array of any — Configure sending hours for each day of the week. Must contain one entry for every day (Monday-Sunday). Example:
[
{ "enabled": true, "name": "Monday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": true, "name": "Tuesday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": true, "name": "Wednesday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": true, "name": "Thursday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": true, "name": "Friday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": false, "name": "Saturday", "fromTime": "09:00", "toTime": "17:00" },
{ "enabled": false, "name": "Sunday", "fromTime": "09:00", "toTime": "17:00" }
]steps: array of any — Ordered array of steps - replaces all existing stepssendToOnlyVerifiedEmail: boolean — Only send to verified emailsvalidEmail: boolean — Send to contacts with valid email statusriskyEmail: boolean — Send to contacts with risky email statusinvalidEmail: boolean — Send to contacts with invalid email statuscheckEmailOpen: boolean — Check if recipient opened previous emailcheckEmailClick: boolean — Check if recipient clicked a link in previous emailcheckEmailReply: boolean — Check if recipient replied to previous emailcheckEmailBeforeSending: boolean — Verify email before sendingplainText: boolean — Send as plain text emailauto_reply: boolean — Enable auto-reply detectionmatchProvider: boolean — Match email provider when sendingskip_esg: boolean — Skip ESG detectionstopWhenReplyRecievedWhen: string (enum: contact, contact-with-same-domain) — When to stop sequence on replybcc: string — BCC email address for all outgoing emails
Responses:
- 200: Sequence updated successfully
Content-Type: application/jsonSchema:
/sequences/{id}/archive
PUT — Archive or Unarchive a Sequence
Archive or unarchive a sequence. Archiving pauses the sequence and removes pending tasks.
For AI agents: Archiving is the recommended way to stop a sequence rather than deletion.
Parameters:
id(path): string (required) — The unique identifier of the sequence
Request Body (application/json):
archived: boolean — true to archive, false to unarchive
Responses:
- 200: Sequence archived/unarchived successfully
Content-Type: application/jsonSchema:
/sequences/{id}/clone
POST — Clone a Sequence
Create a copy of an existing sequence.
For AI agents: The cloned sequence will be in paused state. You need to update paused=false to activate.
Parameters:
id(path): string (required) — The unique identifier of the sequence to clone
Responses:
- 200: Sequence cloned successfully
Content-Type: application/jsonSchema:
success: boolean —data: object —id: string —name: string —
/sequences/{id}/stats
GET — Get Sequence Stats
Retrieve detailed analytics and performance metrics for a sequence.
For AI agents: Use from/to query params to filter stats by date range (timestamps in milliseconds).
Parameters:
id(path): string (required) — The unique identifier of the sequencefrom(query): integer — Start date timestamp (Unix ms) for date range filteringto(query): integer — End date timestamp (Unix ms) for date range filteringsender(query): string — Filter stats by specific sender email
Responses:
- 200: Provides sent, opens, clicks, and lead progress breakdown
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —sent: integer (e.g.,1500) —opens: integer (e.g.,750) —clicks: integer (e.g.,130) —replies: integer (e.g.,45) —sequenceStats: object —leadsTotal: integer (e.g.,2000) —leadsNotStarted: integer (e.g.,500) —leadsInProgress: integer (e.g.,1000) —leadsCompleted: integer (e.g.,450) —leadsBlocked: integer (e.g.,50) —
/sequences/{id}/export
GET — Export Sequence Leads
Export leads in a sequence as a CSV file.
For AI agents: Returns a downloadable CSV. Use limit to cap the number of leads.
Parameters:
id(path): string (required) — The unique identifier of the sequencelimit(query): integer — Maximum number of leads to export
Responses:
- 200: CSV export ready
Content-Type: text/csvSchema:
/sequences/{id}/leads
GET — List Leads in a Sequence
Retrieve all leads added to a sequence with pagination.
For AI agents: Use limit and skip to walk through large sequences.
Parameters:
id(path): string (required) — The unique identifier of the sequencelimit(query): integer — Maximum number of leads to returnskip(query): integer — Number of leads to skip
Responses:
- 200: Leads in sequence retrieved successfully
Content-Type: application/jsonSchema:
/sequences/{id}/leads/{leadId}/messages
GET — Lead Sequence Messages
Retrieve message history for a specific lead within a sequence.
For AI agents: Use from/to to filter the message history by date range.
Parameters:
id(path): string (required) — The unique identifier of the sequenceleadId(path): string (required) — The unique identifier of the leadfrom(query): integer — Start date timestamp (Unix ms)to(query): integer — End date timestamp (Unix ms)limit(query): integer — Maximum number of messages to returnskip(query): integer — Number of messages to skip
Responses:
- 200: Lead messages retrieved successfully
Content-Type: application/jsonSchema:
/sequences/{id}/leads/{leadId}/unsubscribe
POST — Remove Lead from Sequence
Unsubscribe a lead from a specific sequence.
Parameters:
id(path): string (required) — The unique identifier of the sequenceleadId(path): string (required) — The unique identifier of the lead
Responses:
- 200: Lead removed from sequence successfully
Content-Type: application/jsonSchema:
/sequences/{id}/status
POST — Update Sequence Status
Update the status of a sequence.
Parameters:
id(path): string (required) — The unique identifier of the sequence
Request Body (application/json):
status: string (required) (enum: ACTIVE, PAUSED, STOPPED, ARCHIVED) — New sequence status
Responses:
- 200: Sequence status updated successfully
Content-Type: application/jsonSchema:
/signatures
GET — Get Email Signatures
Retrieve all email signatures configured in the workspace.
Parameters:
limit(query): integer —skip(query): integer —
Responses:
- 200: List of email signatures
Content-Type: application/jsonSchema:
success: boolean —data: array of object —id: string —name: string —content: string —owned_by: string —
/signup
POST — Signup for SalesBlink
Create a new SalesBlink account. This endpoint is public and does not require an API key.
Rate limited to 5 per day per IP. Successful signup returns an API key for immediate use.
Request Body (application/json):
email: string (required) (e.g.,user@example.com) —password: string (required) (e.g.,SecurePassword123) — Password must be 8-48 chars and contain at least one uppercase and one lowercase letter.name: string (required) (e.g.,John Doe) —
Responses:
- 200: Account created successfully
Content-Type: application/jsonSchema:
success: boolean —data: object —account_id: string —user_id: string —api_key: string —
/unsubscribe
GET — List Blocklist Entries
List blocked emails and/or domains.
For AI agents: Use type=email or type=domain to filter by entry type.
Parameters:
limit(query): integer — Maximum number of entries to returnskip(query): integer — Number of entries to skipsearch(query): string — Search querytype(query): string — Filter by type (emailordomain)
Responses:
- 200: Blocklist entries retrieved successfully
Content-Type: application/jsonSchema:
POST — Add to Blocklist
Add emails or domains to the blocklist.
For AI agents: Pass full email addresses or domain names (e.g., example.com).
Request Body (application/json):
emails: array of string (required) — Array of emails or domains to block
Responses:
- 200: Entries added to blocklist successfully
Content-Type: application/jsonSchema:
DELETE — Clear Blocklist
Delete all blocklist entries.
Responses:
- 200: All blocklist entries deleted successfully
Content-Type: application/jsonSchema:
/unsubscribe/check
GET — Check Blocked Email
Check whether a specific email is blocked.
For AI agents: Use this before adding a lead to a sequence to avoid emailing blocked addresses.
Parameters:
email(query): string (required) — Email address to check
Responses:
- 200: Block status retrieved successfully
Content-Type: application/jsonSchema:
/unsubscribe/remove
POST — Remove from Blocklist
Remove emails or domains from the blocklist.
Request Body (application/json):
emails: array of string (required) — Array of emails or domains to unblock
Responses:
- 200: Entries removed from blocklist successfully
Content-Type: application/jsonSchema:
/unsubscribe/{id}
DELETE — Delete Blocklist Entry
Remove a single blocklist entry by its ID.
Parameters:
id(path): string (required) — The blocklist entry ID
Responses:
- 200: Blocklist entry deleted successfully
Content-Type: application/jsonSchema:
/templates
GET — Get All Templates
Retrieve all email templates in your workspace.
For AI agents: Each template includes a cold_email_score field indicating the quality of the template content.
Parameters:
limit(query): integer — Maximum number of templates to returnskip(query): integer — Number of templates to skip for paginationsearch(query): string — Search query to filter templates by namefolder(query): string — Filter by folder IDtype(query): string — Filter by template typetaskType(query): string — Filter by task typesortBy(query): string — Sort fieldsortType(query): string — Sort direction:ascordescstarred(query): boolean — Filter by starred statusarchived(query): boolean — Filter by archived statusowned_by(query): string — Filter by owner ID (admin/owner only)
Responses:
- 200: A collection of email templates with cold email scores
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: array of object —id: string —name: string —subject_line: string —starred: boolean —archived: boolean —cold_email_score: object — Computed score indicating template qualityscore: number —rating: string (enum: Perfect, Good, Poor, Very Poor) —
owned_by: string — Email of the template ownerdate_created: string —
POST — Create a Template
Create a new email template for use in sequences.
For AI agents: The template will be scored automatically. Use personalization variables like {{first_name}}, {{company}}, etc.
Maximum 3 attachments allowed.
Request Body (application/json):
name: string (required) (e.g.,Cold Outreach 1) — Name of the templatesubject_line: string (required) (e.g.,Quick Question) — Email subject linecontent: string (required) (e.g.,<p>Hi {{first_name}}...</p>) — HTML content of the email. Use {{variable}} syntax for personalizationfolder: string (e.g.,optional_folder_id) — Optional general folder ID to organize the template. Must be a folder created without atype(i.e., not an email-sender folder).starred: boolean — Whether to star the templateattachments: array of string — Array of files to attach (max 3 files)
Responses:
- 200: Template created successfully with cold email score
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string —name: string —cold_email_score: object —score: number —rating: string —
date_created: string —
/templates/{id}
GET — Get a Specific Template
Retrieve complete details of a specific email template including cold email score.
Parameters:
id(path): string (required) — The unique identifier of the template
Responses:
- 200: Template details with content and score
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string —name: string —subject_line: string —content: string —starred: boolean —archived: boolean —cold_email_score: object —score: number —rating: string —details: object —word_count: integer —personalization_count: integer —link_count: integer —image_count: integer —question_count: integer —spam_word_count: integer —
PATCH — Update a Template
Update an existing email template.
For AI agents: Existing attachments cannot be removed via attachment field - use remove_attachments array instead.
Parameters:
id(path): string (required) — The unique identifier of the template
Request Body (application/json):
name: string — New name for the templatesubject_line: string — New subject linecontent: string — New HTML contentfolder: string (e.g.,optional_folder_id) — General folder ID to move the template into. Pass an empty string to remove the template from its folder. Must be a folder created without atype(i.e., not an email-sender folder).starred: boolean — Star or unstar the templateattachments: array of string — Array of new files to append (max 3 total)remove_attachments: array of string — Array of existing attachment names to remove
Responses:
- 200: Template updated successfully
Content-Type: application/jsonSchema:
/templates/{id}/archive
PUT — Archive or Unarchive a Template
Archive or unarchive an email template.
Parameters:
id(path): string (required) — The unique identifier of the template
Request Body (application/json):
archived: boolean — true to archive, false to unarchive
Responses:
- 200: Template archived/unarchived successfully
Content-Type: application/jsonSchema:
/users
GET — Get All Users
Retrieve all users in your workspace.
For AI agents: Only owners and admins can view all users. Regular users see limited info.
Parameters:
limit(query): integer — Maximum number of users to returnskip(query): integer — Number of users to skip for paginationsearch(query): string — Search query to filter usersstarred(query): boolean — Filter by starred statusarchived(query): boolean — Filter by archived status
Responses:
- 200: A list of users
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: array of object —id: string —name: string —email: string —role: string —date_created: string —
POST — Add a User
Invite a new user to your account.
For AI agents: Only owners and admins can add users. Role must be one of: client, user, admin, developer.
An invitation email will be sent to the user.
Request Body (application/json):
email: string (required) (e.g.,john@example.com) — Email address of the new user (required)role: string (enum: client, user, admin, developer) (e.g.,user) — User role. client=external client access, user=regular team member, admin=full access, developer=API accessurl: string (e.g.,https://example.com/dashboard) — Optional URL to redirect after accepting invitation
Responses:
- 200: User added successfully
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string —email: string —message: string —
/users/{id}
GET — Get a Specific User
Retrieve detailed information about a specific team member.
Parameters:
id(path): string (required) — The unique identifier of the user
Responses:
- 200: Details of the user
Content-Type: application/jsonSchema:
success: boolean (e.g.,True) —data: object —id: string —name: string —email: string —role: string —
PATCH — Update a User
Update user properties including name and role.
For AI agents: To remove a user, set archived=true via the appropriate archive endpoint.
Parameters:
id(path): string (required) — The unique identifier of the user
Request Body (application/json):
name: string (e.g.,John Doe) — User's display namerole: string (enum: client, user, admin, developer) (e.g.,user) — User role
Responses:
- 200: User updated successfully
Content-Type: application/jsonSchema:
/warmup-links
GET — Get Warmup Links
Retrieve all warmup link configurations.
Parameters:
limit(query): integer —skip(query): integer —
Responses:
- 200: List of warmup links
Content-Type: application/jsonSchema:
success: boolean —data: array of object —
/workspaces
GET — Get All Workspaces
Retrieve all workspaces the authenticated user has access to.
For AI agents: Only workspace owners can view all workspaces. Shows workspace name, ID, and user's permission level.
Responses:
- 200: List of workspaces
Content-Type: application/jsonSchema:
success: boolean —data: array of object —id: string —name: string —permission: string (enum: owner, admin, user, client) —
POST — Create Workspace
Create a new workspace.
For AI agents: Only workspace owners can create new workspaces. Name must be at least 4 characters.
Request Body (application/json):
name: string (required) — Name of the workspace (min 4 characters)
Responses:
- 200: Workspace created successfully
Content-Type: application/jsonSchema:
success: boolean —data: object —id: string —name: string —
/workspaces/{id}
PATCH — Update Workspace
Update workspace name. Only owners can update workspaces.
Parameters:
id(path): string (required) — The unique identifier of the workspace
Request Body (application/json):
name: string (required) — New name for the workspace (min 4 characters)
Responses:
- 200: Workspace updated successfully
Content-Type: application/jsonSchema:
Schemas
Contact
id: string — Unique contact IDemail: string —first_name: string —last_name: string —phone: string —list_id: string —owned_by: string — Email of the ownerarchived: boolean —accuracy: string — Email verification accuracy score
EmailSendingHours
name: string — Day of the week (Monday, Tuesday, etc.)enabled: boolean — Whether sending is enabled on this dayfromTime: string — Start time in 24-hour format (HH:MM)toTime: string — End time in 24-hour format (HH:MM)
ErrorResponse
success: boolean —message: string (e.g.,Error description) —
Step
type: string (required) (enum: email, delay) — Type of step - email or delaytemplate_id: string — Required for email type - the template UUIDdays: integer — Required for delay type - number of days to wait
SuccessResponse
success: boolean (e.g.,True) —message: string (e.g.,Operation completed successfully) —
Updated on: 01/09/2026
Thank you!