InboxTender API

Contacts

Create-or-merge contacts by phone or email, and read them back.

A contact is identified by its addresses — a phone number, an email, or both. That's what makes pushing idempotent: send the same person twice and you update one record instead of minting a twin.

The contact object

{
  "id": "k97c2fq0v6bz8kj3n1xw5d4rhm",
  "name": "Tyler West",
  "phone": "+13232500210",
  "email": "tyler@example.com",
  "notes": "Wants the XLT",
  "tags": ["hot lead", "f-150"],
  "createdAt": 1756640000000
}

Phones are normalized to E.164 (+1…); emails are lowercased; tags are lowercased and capped at 16 per contact.

Create or merge a contact

POST /api/v1/contacts
curl https://api.inboxtender.com/api/v1/contacts \
  -H "Authorization: Bearer it_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Tyler West",
    "phone": "(323) 250-0210",
    "email": "tyler@example.com",
    "tags": ["hot lead"],
    "notes": "Wants the XLT"
  }'
FieldTypeNotes
phonestring10 US digits or full E.164. At least one of phone / email is required.
emailstringLowercased on save.
namestringUp to 120 characters.
notesstringUp to 500 characters.
tagsstring[]Up to 16, each up to 30 characters.

Answers 201 when a contact was created, 200 when it merged into an existing one; both return { "contact": …, "created": true|false }.

Merge rules

  • A matching phone or email updates the existing contact and adds the other address when it is unclaimed. Email-only contacts are supported.
  • If the phone and email belong to different contacts, the request returns 409 with error code identifier_conflict. Neither contact is changed.
  • Each normalized email and phone belongs to one contact per workspace.
  • Merges fill blanks only: a name or notes your team already wrote is never overwritten. Tags are added, never removed.
  • Re-running the same request is always safe.

List contacts

GET /api/v1/contacts?limit=50&cursor=…&tag=hot%20lead

Newest first. limit is 1–100 (default 50). Page with the returned nextCursor until it comes back null. tag filters within each page, so a filtered page can come back short while nextCursor still advances.

{ "contacts": [ … ], "nextCursor": "…" }

Get one contact

GET /api/v1/contacts/:id

Answers { "contact": … }, or 404 if the id is unknown — including ids that belong to a different workspace.

On this page