Skip to content

Send a contact / queue a call​

POST
/contacts/

Upserts a Contact by (workspace, phone) and enqueues a ScheduledCall against a campaign. Powers Make's "Send Contact" module.

Evaluated in this order — which step fails determines the status code:

  1. phone missing or unnormalizable → 400
  2. Campaign resolution: neither campaign_id nor campaign given → 400; not found → 404; campaign (name) matches more than one campaign → 409 (use campaign_id instead)
  3. Campaign status isn't draft/active/paused → 409 (not accepting new contacts)
  4. external_id already seen for this campaign → 200 (not 201) with the existing row, untouched — idempotent replay
  5. Contact upserted by (workspace, phone)
  6. Compliance gate (blacklist/DNC/consent) fails → 422, no call scheduled
  7. ScheduledCall created → 201

campaign_id wins if both campaign_id and campaign are given. An invalid consent_status silently falls back to implied rather than being rejected.

Authorizations​

ApiKeyAuth

Personal API key. Code samples use Authorization: Bearer <token> — replace <token> with your key from Settings → API Keys (include the word Bearer).

Type
HTTP (bearer)
or
oauth2

OAuth2 access token from the consent flow third-party apps go through (see /oauth/authorize/). Interchangeable with a personal API key on every operation below — both are sent as a Bearer token in the same header.

authorizationCode Flow
Authorization URL"/oauth/authorize/"
Token URL"/oauth/token/"
Scopes:
  • "campaigns:read"List your call campaigns
  • "campaigns:write"Create new call campaigns
  • "contacts:write"Create contacts and queue calls into your campaigns

Request Body​

application/json

Destination number in any format the platform can normalize (US-friendly forms or E.164). Missing/invalid → 400.

Campaign to queue against. Wins over campaign if both are given. Prefer this when you already know the id from List campaigns.

Campaign name, exact match. Ambiguous names return 409 — use campaign_id instead. One of campaign_id or campaign is required.

Contact display name (CRM / agent context).

Optional email. Not used for dialing.

Optional company name.

Optional department / team label.

Free-form notes for your records or agent tools.

Compliance consent marker (e.g. implied, express, unknown). Invalid values silently fall back to implied.

Idempotency key, scoped to the campaign. Replaying the same external_id returns the original call with 200 instead of a duplicate.

Responses​

Idempotent replay: this campaign already has a call for the given external_id. The same four fields as 201 — existing row, not mutated.

application/json
JSON
{
  
"contact_id": 44,
  
"scheduled_call_id": 901,
  
"campaign_id": 12,
  
"status": "pending"
}

Playground​

Server
Authorization
Body

Samples​

Powered by VitePress OpenAPI