ProductPricingCompareCheck your domainDocsDashboardSign inGet started
Docs / REST API

Start

  • Overview
  • Getting started
  • Connect a mailbox

Sending

  • Domains
  • Mailboxes
  • Sending safety

Leads and campaigns

  • Leads
  • Campaigns
  • Write with AI

Replies and results

  • Unibox and AI labels
  • Analytics

Workspace

  • Team and roles
  • Billing and plans
  • Integrations

Developers

  • Connect your AI (MCP)
  • REST API
    • Overview
    • Workspace5
    • Analytics1
    • Campaigns26
    • Leads16
    • Lists4
    • Labels6
    • Suppressions3
    • Unibox6
    • Mailboxes8
    • Warmup3
    • Deliverability Network4
    • Domains4
    • Link domain5
    • Integrations3
    • Webhook endpoints7
    • Offer profile3
    • Billing1
    • Domain checker1
    • API keys1
  • Webhooks

Start

  • Overview
  • Getting started
  • Connect a mailbox

Sending

  • Domains
  • Mailboxes
  • Sending safety

Leads and campaigns

  • Leads
  • Campaigns
  • Write with AI

Replies and results

  • Unibox and AI labels
  • Analytics

Workspace

  • Team and roles
  • Billing and plans
  • Integrations

Developers

  • Connect your AI (MCP)
  • REST API
    • Overview
    • Workspace5
    • Analytics1
    • Campaigns26
    • Leads16
    • Lists4
    • Labels6
    • Suppressions3
    • Unibox6
    • Mailboxes8
    • Warmup3
    • Deliverability Network4
    • Domains4
    • Link domain5
    • Integrations3
    • Webhook endpoints7
    • Offer profile3
    • Billing1
    • Domain checker1
    • API keys1
  • Webhooks

Cold email that keeps your domains steady, with every feature on every plan.

Product

  • Features
  • Pricing
  • Sequences
  • Warmup
  • How it works
  • Docs
  • Changelog
  • Blog

Compare

  • Ballast vs Instantly
  • Ballast vs Smartlead
  • Ballast vs Lemlist
  • Switch from Instantly
  • Switch from Smartlead
  • Switch from Lemlist

Free tools

  • Domain checker
  • MX lookup
  • SPF checker
  • DKIM checker
  • DMARC checker
  • Blacklist check

Legal

  • Terms of Service
  • Privacy Policy
  • Acceptable Use Policy
  • Data Processing Agreement
  • Sub-processors

Developers

  • REST API
  • MCP server
  • OpenAPI spec
© 2026 BallastTermsPrivacy
All systems normal
ProductPricingCompareCheck your domainDocsBlogChangelogSign in

API reference

Leads

Create, import, update, verify and mark leads won. 16 endpoints, each also a tool for your AI through MCP. Authentication and errors are on the overview.

List leads

GET/api/v1/leads

Paged, newest first by default. Filter by list, label, status, verification and ESP, or search email, name and company.

MCP tool list_leadsRead-only

Parameters

searchquery · string
Matches email, name and company
listIdquery · string
labelIdquery · string
Only leads with this label; 'none' for leads without labels
statusquery · "active" | "replied" | "interested" | "won" | "bounced" | "unsubscribed" | "suppressed"[]
verifyquery · "unknown" | "verifying" | "valid" | "risky" | "invalid" | "catch_all"[]
espquery · "google" | "microsoft" | "yahoo" | "proton" | "icloud" | "zoho" | "other" | "unknown"[]
pagequery · integer
pageSizequery · integer
sortquery · "createdAt" | "email" | "name" | "company"
dirquery · "asc" | "desc"

Returns

leadsrequiredobject[]
totalrequirednumber
pagerequirednumber
pageSizerequirednumber
cURL
curl https://ballast.to/api/v1/leads \
  -H "Authorization: Bearer $BALLAST_API_KEY"

Lead counts by status, verification and ESP

GET/api/v1/leads/stats

Read-only

Parameters

listIdquery · string

Returns

totalrequirednumber
statusrequiredobject
verifyrequiredobject
esprequiredobject
importingrequiredboolean
An import is still checking domains or verifying
verifierEnabledrequiredboolean
A verifier API is configured; without it only local checks run
cURL
curl https://ballast.to/api/v1/leads/stats \
  -H "Authorization: Bearer $BALLAST_API_KEY"

Get a lead with custom fields, lists and labels

GET/api/v1/leads/{id}

MCP tool get_leadRead-only

Parameters

idrequiredpath · string

Returns

idrequiredstring
emailrequiredstring
firstNamerequiredstring | null
lastNamerequiredstring | null
companyrequiredstring | null
titlerequiredstring | null
countryrequiredstring | null
timezonerequiredstring | null
esprequired"google" | "microsoft" | "yahoo" | "proton" | "icloud" | "zoho" | "other" | "unknown"
mxHostrequiredstring | null
verifyStatusrequired"unknown" | "verifying" | "valid" | "risky" | "invalid" | "catch_all"
verifyReasonrequiredstring | null
statusrequired"active" | "replied" | "interested" | "won" | "bounced" | "unsubscribed" | "suppressed"
labelsrequiredobject[]
createdAtrequiredstring
countrySourcerequired"timezone" | "phone" | "email" | "website" | null
websiterequiredstring | null
phonerequiredstring | null
linkedinrequiredstring | null
customrequiredobject
listsrequiredobject[]
verifiedAtrequiredstring | null
updatedAtrequiredstring
cURL
curl https://ballast.to/api/v1/leads/<id> \
  -H "Authorization: Bearer $BALLAST_API_KEY"

Add one lead

POST/api/v1/leads

MCP tool create_lead

Parameters

firstNamestring | null
lastNamestring | null
companystring | null
titlestring | null
websitestring | null
phonestring | null
linkedinstring | null
countrystring | null
timezonestring | null
customobject
emailrequiredstring
listIdstring

Returns the same fields as Get a lead with custom fields, lists and labels.

cURL
curl -X POST https://ballast.to/api/v1/leads \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"<email>"}'

Change a lead's fields or status

PATCH/api/v1/leads/{id}

MCP tool update_lead

Parameters

idrequiredpath · string
firstNamestring | null
lastNamestring | null
companystring | null
titlestring | null
websitestring | null
phonestring | null
linkedinstring | null
countrystring | null
timezonestring | null
customobject
status"active" | "replied" | "interested" | "won" | "bounced" | "unsubscribed" | "suppressed"

Returns the same fields as Get a lead with custom fields, lists and labels.

cURL
curl -X PATCH https://ballast.to/api/v1/leads/<id> \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"firstName":{},"lastName":{}}'

Mark a lead won

POST/api/v1/leads/{id}/won

The lead became a customer. Counts toward the won rate on the Overview and sends the lead.won webhook. Give the deal value to track revenue.

MCP tool mark_won

Parameters

idrequiredpath · string
valuenumber | null
campaignIdstring

Returns the same fields as Get a lead with custom fields, lists and labels.

cURL
curl -X POST https://ballast.to/api/v1/leads/<id>/won \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":{},"campaignId":"<campaignId>"}'

Delete leads

POST/api/v1/leads/delete

Deletes leads with their list memberships and labels. Suppressions stay.

MCP tool delete_leadsMCP asks to confirm

Returns

deletedrequirednumber
cURL
curl -X POST https://ballast.to/api/v1/leads/delete \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Add leads to a list

POST/api/v1/leads/lists/add

MCP tool add_leads_to_list

Parameters

targetrequiredobject
listIdrequiredstring

Returns

addedrequirednumber
cURL
curl -X POST https://ballast.to/api/v1/leads/lists/add \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target":{},"listId":"<listId>"}'

Remove leads from a list (the leads stay)

POST/api/v1/leads/lists/remove

MCP tool remove_leads_from_list

Parameters

targetrequiredobject
listIdrequiredstring

Returns

removedrequirednumber
cURL
curl -X POST https://ballast.to/api/v1/leads/lists/remove \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target":{},"listId":"<listId>"}'

Apply a label to leads

POST/api/v1/leads/labels/add

Runs the label's triggers that don't need a campaign: suppress, move to list, auto-remove and apply-after timers.

MCP tool label_leads

Parameters

targetrequiredobject
labelIdrequiredstring

Returns

labeledrequirednumber
cURL
curl -X POST https://ballast.to/api/v1/leads/labels/add \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target":{},"labelId":"<labelId>"}'

Remove a label from leads

POST/api/v1/leads/labels/remove

MCP tool unlabel_leads

Parameters

targetrequiredobject
labelIdrequiredstring

Returns

removedrequirednumber
cURL
curl -X POST https://ballast.to/api/v1/leads/labels/remove \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target":{},"labelId":"<labelId>"}'

Never email these leads again

POST/api/v1/leads/suppress

Adds their addresses to the suppression list.

MCP tool suppress_leads

Parameters

targetrequiredobject
reasonstring

Returns

suppressedrequirednumber
cURL
curl -X POST https://ballast.to/api/v1/leads/suppress \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target":{}}'

Verify lead addresses

POST/api/v1/leads/verify

Runs in the background: mail server lookup, disposable and role checks, then the verifier API when configured. Poll get_lead or list_leads for the result.

MCP tool verify_leadsNeeds an active plan

Parameters

targetrequiredobject

Returns

queuedrequirednumber
apirequiredboolean
False when only local checks run (no verifier configured)
cURL
curl -X POST https://ballast.to/api/v1/leads/verify \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target":{}}'

Import leads in chunks

POST/api/v1/leads/import

Send up to 5,000 rows per call. The first call creates the import and returns its id; pass importId with every next chunk and final: true with the last. Addresses are deduped, suppressed ones skipped, invalid ones counted. ESP detection and verification run in the background after the final chunk.

MCP tool import_leadsNeeds an active planMCP asks to confirm

Parameters

importIdstring
Leave out on the first call; pass the id it returns with every next chunk.
fileNamestring
listobject
List to add every imported lead to: an existing id or a new name
existing"skip" | "update"
Leads already in the workspace: leave them as they are, or fill in the new values
verifyboolean
Verify the new addresses with the verifier API after import
clientInvalidinteger
clientDuplicatesinteger
rowsrequiredobject[]
finalboolean
Last chunk: starts ESP detection and verification

Returns

idrequiredstring
fileNamerequiredstring | null
listIdrequiredstring | null
listNamerequiredstring | null
statusrequired"importing" | "enriching" | "done" | "failed"
verifyrequiredboolean
rowsrequirednumber
createdrequirednumber
updatedrequirednumber
skippedrequirednumber
duplicatesrequirednumber
suppressedrequirednumber
invalidrequirednumber
undeliverablerequirednumber
createdAtrequiredstring
finishedAtrequiredstring | null
enrichedAtrequiredstring | null
cURL
curl -X POST https://ballast.to/api/v1/leads/import \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"rows":[]}'

Import progress and counts

GET/api/v1/leads/imports/{id}

MCP tool get_importRead-only

Parameters

idrequiredpath · string

Returns the same fields as Import leads in chunks.

cURL
curl https://ballast.to/api/v1/leads/imports/<id> \
  -H "Authorization: Bearer $BALLAST_API_KEY"

Recent imports

GET/api/v1/leads/imports

Read-only

Returns

importsrequiredobject[]
cURL
curl https://ballast.to/api/v1/leads/imports \
  -H "Authorization: Bearer $BALLAST_API_KEY"
PreviousCampaignsNextLists