API Reference
Contacts

Contacts

Contacts represent the people you call. Each contact is unique within your organization by phone number.

The Contact Object

{
  "id": "clxxx123",
  "name": "Priya Sharma",
  "phoneNumber": "+919876543210",
  "language": "hi-IN",
  "metadata": {
    "city": "Mumbai",
    "tier": "premium"
  },
  "organizationId": "org_1",
  "createdAt": "2026-03-01T10:00:00.000Z",
  "updatedAt": "2026-03-15T08:30:00.000Z"
}

List Contacts

GET /v1/contacts

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
limitintegerItems per page (default: 20, max: 100)
searchstringSearch by name or phone number

Response:

{
  "data": [/* Contact objects */],
  "total": 1500,
  "page": 1,
  "limit": 20,
  "totalPages": 75
}

Get a Contact

GET /v1/contacts/:id

Response: A single Contact object.


Get Contact History

GET /v1/contacts/:id/history

Cross-campaign call & intent history for a contact, unified by phone number and scoped to your organization. History is returned newest-first.

Response:

{
  "contact": {
    "id": "clxxx123",
    "name": "Priya Sharma",
    "phoneNumber": "+919876543210",
    "doNotContact": false,
    "doNotContactReason": null,
    "doNotContactAt": null
  },
  "history": [
    {
      "campaignId": "camp_def456",
      "campaignName": "Mumbai Outreach - March",
      "useCaseType": "COLLECTIONS",
      "callId": "CA...",
      "outcome": "Connected",
      "status": "COMPLETED",
      "attempts": 1,
      "durationSeconds": 87,
      "callAt": "2026-03-10T09:08:27.000Z",
      "scheduledAt": null,
      "intentLabel": { "id": "lbl_abc", "name": "Interested in Paying", "color": "#16a34a", "isPositive": true },
      "intentUndetermined": false,
      "flaggedForReview": false
    }
  ],
  "bestTime": {
    "label": "10 AM–11 AM (Individual, based on 5 calls)",
    "source": "individual",
    "basisCount": 5
  },
  "hasNegativeIntent": false,
  "negativeLabels": []
}
FieldDescription
outcomeConnected, No Answer, Failed, Skipped, In Progress, or Pending
bestTimePreferred call window — source is individual, demographic, or default; label is null when there's not enough data. See best-time.
hasNegativeIntenttrue if any history entry has a suppress/negative intent (warns against re-engagement)
negativeLabelsThe distinct negative labels found, for display
contact.doNotContacttrue if the contact is suppressed org-wide

Create a Contact

POST /v1/contacts

Request Body:

FieldTypeRequiredDescription
namestringYesContact's full name
phoneNumberstringYesE.164 format (e.g., +919876543210)
languagestringNoPreferred language code (e.g., hi-IN)
metadataobjectNoCustom key-value pairs
ageBandstringNoDemographic — e.g. 26-35
genderstringNoDemographic
cityTierstringNoMetro, Tier 1, Tier 2, Rural
occupationstringNoDemographic
incomeBandstringNoDemographic
productTypestringNoe.g. loan, insurance

Demographic fields are optional and used for best-time-to-call clustering. The same fields are accepted by Update a Contact.

Example:

{
  "name": "Priya Sharma",
  "phoneNumber": "+919876543210",
  "language": "hi-IN",
  "metadata": { "city": "Mumbai", "tier": "premium" }
}

Response: 201 Created with the Contact object.

If a contact with the same phone number already exists in your organization, a 409 Conflict is returned.


Update a Contact

PATCH /v1/contacts/:id

Partial update — only include fields you want to change.

Request Body: Any subset of Contact fields (except id, organizationId, createdAt).

Example:

{
  "language": "en-IN",
  "metadata": { "city": "Delhi", "tier": "standard" }
}

Response: The updated Contact object.


Delete a Contact

DELETE /v1/contacts/:id

Response: 200 OK with { "success": true }.

⚠️

Deleting a contact removes them from all audiences. Past call records are preserved.


Bulk Create Contacts

POST /v1/contacts/bulk

Create or update multiple contacts in one request.

Request Body:

FieldTypeRequiredDescription
contactsarrayYesArray of contact objects (max 1,000)

Contact fields: same as Create a Contact.

Example:

{
  "contacts": [
    {
      "name": "Priya Sharma",
      "phoneNumber": "+919876543210",
      "language": "hi-IN",
      "metadata": { "city": "Mumbai" }
    },
    {
      "name": "Ravi Kumar",
      "phoneNumber": "+919123456789",
      "language": "en-IN"
    }
  ]
}

Response:

{
  "created": 2,
  "updated": 0,
  "failed": 0,
  "contacts": [/* created/updated Contact objects */],
  "errors": []
}

If some contacts fail validation, they're reported in errors with the index and reason. The rest are still created.


Bulk Delete Contacts

POST /v1/contacts/bulk-delete

Request Body:

{
  "contactIds": ["clxxx123", "clxxx456", "clxxx789"]
}

Response:

{
  "deleted": 3
}

Add Contact to Audience

POST /v1/contacts/add-to-audience

Request Body:

{
  "contactIds": ["clxxx123", "clxxx456"],
  "audienceId": "aud_abc123"
}

Response: 200 OK with updated audience contact count.