Skip to main content
POST /api/v1/leads/bulk sends many leads for one campaign in a single request. OnDial creates each lead and starts the calls the same way as POST /api/v1/leads; you get one result per lead, in the same order as your request. Before you send: Lead setup with your campaignId. Optional: send the same body with "dryRun": true first (nothing is created).

Request

Email and WhatsApp leads

The request has the same three forms as Create lead: Call, Email and WhatsApp. Pick the tab you need on the endpoint page. Put the shared values in defaults and only what changes in each lead. Consent is only needed for calls. Get the profile and template ids from Lead setup.

Response

results[i] is the lead at leads[i]. Use contactId with Get contact and your normal webhooks: each accepted lead still sends its own outbound.lead.created / outbound.lead.updated event.

Limits

Example: 1,000 leads = 10 requests of 100 leads, comfortably inside 600 leads per minute if you spread them over about two minutes. Ask us if you need higher limits.

Every case

The whole request is rejected (no lead is created) One lead is rejected, the others continue (status: "rejected", with reasonCode and error) A lead is accepted, with a note

Result statuses

Idempotency and retries

  • Send an Idempotency-Key with every bulk request. If your request times out, send it again with the same key and the same body: you normally get the same response back ("idempotentReplay": true).
  • Replay is best effort: if the saved response is not available (for example it was not stored yet, or it expired after 24 hours), the batch is processed again. It still never creates a lead twice: leads that already exist come back as duplicate_no_requeue instead of created, so read results rather than assuming the first response.
  • To retry only what failed, build a new request from the results with status: "rejected" that you have fixed (use index / clientRef to find them). Do not retry duplicate_in_request or duplicate_no_requeue.
  • A lead that was already created is never created twice: sending it again returns duplicate_no_requeue.

Tips

  • Run with dryRun: true first for a new list. It checks everything, including leads that already exist in the campaign, without creating anything.
  • Use atomic: true when a partly-loaded list would be a problem.
  • Always set clientRef to your CRM id: it makes the response easy to match back to your records.
  • Do not send the same campaign from two requests at the same moment; a second request waits (up to 10 seconds) or returns 409 bulk_in_progress.