Skip to main content

Documentation Index

Fetch the complete documentation index at: https://katavenai.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

A campaign dials a list of contacts through one phone number, using one agent, with cap-aware concurrency.

Lifecycle

Create a campaign

The create endpoint is multipart/form-data because contacts are uploaded as a CSV file (max 10 MB ≈ 100k contacts).
with open("contacts.csv", "rb") as f:
    campaign = client.campaigns.create(
        name="Q4 follow-ups",
        agent_id="<agent uuid>",
        phone_number_id="<phone number uuid>",
        contacts=f,
        max_concurrent_calls=5,
        retries_per_contact=1,
        retry_delay_seconds=300,
        scheduled_at="2026-05-10T18:00:00Z",  # optional, RFC3339
    )

CSV format

  • First row must be headers; phone_number column is required.
  • Other columns become the contact’s custom_fields (passed to the agent as variables for templating).
phone_number,first_name,order_id
+14155550100,Sam,A-12001
+14155550101,Robin,A-12002

Concurrent budget

When you start (or resume) a campaign, the server checks:
sum of running campaigns’ max_concurrent_calls + this campaign’s max_concurrent_calls ≤ account concurrent_max
Failing this returns 409 with an explanatory message — pause another campaign or reduce max_concurrent_calls. Without this check, two campaigns at concurrency=5 on a tenant with cap=10 would starve everything else.

State transitions

OperationEndpointSDK
Start (or resume)POST /api/v1/campaigns/{id}/startclient.campaigns.start(id)
PausePOST /api/v1/campaigns/{id}/pauseclient.campaigns.pause(id)
ResumePOST /api/v1/campaigns/{id}/resumeclient.campaigns.resume(id)
StopPOST /api/v1/campaigns/{id}/stopclient.campaigns.stop(id)
Delete (drafts only)DELETE /api/v1/campaigns/{id}client.campaigns.delete(id)
Stop marks the campaign completed and skips pending contacts. In-flight calls are NOT aborted — they finish naturally. “Stop” means “no more new dials,” not “kill in-flight.”

Live metrics (SSE)

GET /api/v1/campaigns/{id}/events is a Server-Sent Events stream:
  • 2-second data: {snapshot}\n\n ticks while the campaign runs.
  • 15-second : heartbeat comments to keep proxies from idle-timing out.
  • Closes with event: end when the campaign reaches a terminal status.
for event in client.campaigns.stream_events(campaign_id):
    print(event)

Contact pagination

GET /api/v1/campaigns/{id}/contacts?status=failed&page=0 — paginated, 100 per page, optional status filter.