API reference

Contacts

Create, read, update, and delete contacts for the authenticated tenant.

Every request needs x-tenant-id and an API key or OAuth token. Channel IDs are copied from Settings → Developer in the app. See Authentication.

List contacts

get/api/public/v1/contacts

Returns a paginated, filterable, sortable list of contacts for the authenticated tenant.

Query parameters

  • pageinteger

    Default 1

  • limitinteger

    Default 25

  • sortstring

    createdAtnamephoneemailcountryupdatedAtlastContactedAtsource

    Default "createdAt"

  • orderstring

    ascdesc

    Default "desc"

  • searchstring

    Matches name, phone, or email.

  • labelstring

    Comma-separated label/tag filter.

  • statusstring

    activedeletedblockedmerged

    Default "active"

  • countrystring
  • sourcestring

    manualimportapiwhatsappweb

  • createdAfterstring (date-time)
  • createdBeforestring (date-time)
  • updatedAfterstring (date-time)
  • updatedBeforestring (date-time)
  • fieldsstring
Response 200Paginated list of contacts
  • successboolean
  • dataobject[]
    16 child fields
    • idstring
    • namestring
    • phonestring
    • emailstring | null
    • countrystring | null
    • tagsstring[]
    • customFieldsobject[]
      4 child fields
      • fieldIdstring | null
      • fieldNamestring | null
      • typestring | null
      • valueany
    • sourcestring

      One ofmanualimportapiwhatsappweb

    • statusstring

      One ofactivedeletedblockedmerged

    • isFavoriteboolean
    • isBlockedboolean
    • marketingOptInboolean
    • marketingOptInAtstring (date-time) | null
    • lastContactedAtstring (date-time) | null
    • createdAtstring (date-time)
    • updatedAtstring (date-time)
  • paginationobject
    8 child fields
    • pageinteger
    • limitinteger
    • totalinteger
    • totalPagesinteger
    • hasNextPageboolean
    • hasPrevPageboolean
    • nextCursorstring | null
    • prevCursorstring | null
  • metaobject
    1 child field
    • apiVersionstring
  • requestIdstring | null
  • timestampstring (date-time)

Errors

  • 400Malformed request or missing tenant context
  • 401Missing or invalid API key
  • 403Forbidden — developer platform disabled, key expired/disabled, or tenant mismatch
  • 422Validation failed
  • 429Too many requests — rate limit exceeded
  • 500Unexpected server error
Error envelope and fixes →
curl -X GET "https://api.inaiy.com/api/public/v1/contacts" \
  -H "x-tenant-id: demo" \
  -H "x-api-key: wp_live_xxxxxxxxxxxxxxxxxxxx"
Response 200
{
  "success": true,
  "data": [
    {
      "id": "6650a1b2c3d4e5f6a7b8c9d0",
      "name": "Jane Doe",
      "phone": "+14155552671",
      "email": "jane@example.com",
      "country": "US",
      "tags": [
        "vip",
        "newsletter"
      ],
      "customFields": [
        {
          "fieldId": "664f...",
          "fieldName": "Company",
          "type": "text",
          "value": "Acme Inc"
        }
      ],
      "source": "api",
      "status": "active",
      "isFavorite": false,
      "isBlocked": false,
      "marketingOptIn": true,
      "marketingOptInAt": "2026-07-12T09:30:00.000Z",
      "lastContactedAt": null,
      "createdAt": "2026-07-12T09:30:00.000Z",
      "updatedAt": "2026-07-12T09:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 25,
    "total": 137,
    "totalPages": 6,
    "hasNextPage": true,
    "hasPrevPage": false,
    "nextCursor": null,
    "prevCursor": null
  },
  "meta": {
    "apiVersion": "v1",
    "sort": {
      "field": "createdAt",
      "direction": "desc"
    }
  },
  "requestId": "a1f4c2e0-9b6d-4a1e-8c3f-2d7e5b9a0c11",
  "timestamp": "2026-07-12T09:30:00.000Z"
}

Create a contact

post/api/public/v1/contacts

Create a new contact. Fails with 409 if a contact with the same phone already exists, and 404 if primaryTeamId or assignedAgentId is not in this workspace.

Request bodyrequired

  • namestringrequired
  • phonestringrequired

    E.164 format

  • emailstring (email) | null
  • countrystring | null
  • tagsstring[]
  • customFieldsobject[]
  • sourcestring

    One ofmanualimportapiwhatsappweb

  • marketingOptInboolean
  • primaryTeamIdstring | null

    Owning team id (24-char ObjectId). Must be a team in this workspace; null clears it.

  • assignedAgentIdstring | null

    Owning agent (user) id. Must be a member of this workspace; null clears it.

Response 201Contact created
  • successboolean
  • dataobject
    16 child fields
    • idstring
    • namestring
    • phonestring
    • emailstring | null
    • countrystring | null
    • tagsstring[]
    • customFieldsobject[]
      4 child fields
      • fieldIdstring | null
      • fieldNamestring | null
      • typestring | null
      • valueany
    • sourcestring

      One ofmanualimportapiwhatsappweb

    • statusstring

      One ofactivedeletedblockedmerged

    • isFavoriteboolean
    • isBlockedboolean
    • marketingOptInboolean
    • marketingOptInAtstring (date-time) | null
    • lastContactedAtstring (date-time) | null
    • createdAtstring (date-time)
    • updatedAtstring (date-time)
  • metaobject
    1 child field
    • apiVersionstring
  • requestIdstring | null
  • timestampstring (date-time)

Errors

  • 400Malformed request or missing tenant context
  • 401Missing or invalid API key
  • 403Forbidden — developer platform disabled, key expired/disabled, or tenant mismatch
  • 404Contact not found
  • 409Duplicate contact (phone already exists)
  • 422Validation failed
  • 429Too many requests — rate limit exceeded
  • 500Unexpected server error
Error envelope and fixes →
curl -X POST "https://api.inaiy.com/api/public/v1/contacts" \
  -H "x-tenant-id: demo" \
  -H "x-api-key: wp_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"name":"Jane Doe","phone":"+14155552671","email":"jane@example.com","country":"US","tags":["vip"],"marketingOptIn":true}'
Request body
{
  "name": "Jane Doe",
  "phone": "+14155552671",
  "email": "jane@example.com",
  "country": "US",
  "tags": [
    "vip"
  ],
  "marketingOptIn": true
}
Response 201
{
  "success": true,
  "data": {
    "id": "6650a1b2c3d4e5f6a7b8c9d0",
    "name": "Jane Doe",
    "phone": "+14155552671",
    "email": "jane@example.com",
    "country": "US",
    "tags": [
      "vip",
      "newsletter"
    ],
    "customFields": [
      {
        "fieldId": "664f...",
        "fieldName": "Company",
        "type": "text",
        "value": "Acme Inc"
      }
    ],
    "source": "api",
    "status": "active",
    "isFavorite": false,
    "isBlocked": false,
    "marketingOptIn": true,
    "marketingOptInAt": "2026-07-12T09:30:00.000Z",
    "lastContactedAt": null,
    "createdAt": "2026-07-12T09:30:00.000Z",
    "updatedAt": "2026-07-12T09:30:00.000Z"
  },
  "meta": {
    "apiVersion": "v1"
  },
  "requestId": "a1f4c2e0-9b6d-4a1e-8c3f-2d7e5b9a0c11",
  "timestamp": "2026-07-12T09:30:00.000Z"
}

Look up a contact

get/api/public/v1/contacts/lookup

Find one contact by exactly one of `phone` (matched with or without the leading +), `igsid` (Instagram), or `psid` (Messenger). Returns 404 when no active contact matches.

Query parameters

  • phonestring

    E.164 phone. URL-encode the + as %2B.

  • igsidstring

    Instagram scoped id.

  • psidstring

    Messenger Page-scoped id.

  • fieldsstring

    Comma-separated list of fields to return (sparse fieldset).

Response 200The contact
  • successboolean
  • dataobject
    16 child fields
    • idstring
    • namestring
    • phonestring
    • emailstring | null
    • countrystring | null
    • tagsstring[]
    • customFieldsobject[]
      4 child fields
      • fieldIdstring | null
      • fieldNamestring | null
      • typestring | null
      • valueany
    • sourcestring

      One ofmanualimportapiwhatsappweb

    • statusstring

      One ofactivedeletedblockedmerged

    • isFavoriteboolean
    • isBlockedboolean
    • marketingOptInboolean
    • marketingOptInAtstring (date-time) | null
    • lastContactedAtstring (date-time) | null
    • createdAtstring (date-time)
    • updatedAtstring (date-time)
  • metaobject
    1 child field
    • apiVersionstring
  • requestIdstring | null
  • timestampstring (date-time)

Errors

  • 400Malformed request or missing tenant context
  • 401Missing or invalid API key
  • 403Forbidden — developer platform disabled, key expired/disabled, or tenant mismatch
  • 404Contact not found
  • 422Validation failed
  • 429Too many requests — rate limit exceeded
  • 500Unexpected server error
Error envelope and fixes →
curl -X GET "https://api.inaiy.com/api/public/v1/contacts/lookup" \
  -H "x-tenant-id: demo" \
  -H "x-api-key: wp_live_xxxxxxxxxxxxxxxxxxxx"
Response 200
{
  "success": true,
  "data": {
    "id": "6650a1b2c3d4e5f6a7b8c9d0",
    "name": "Jane Doe",
    "phone": "+14155552671",
    "email": "jane@example.com",
    "country": "US",
    "tags": [
      "vip",
      "newsletter"
    ],
    "customFields": [
      {
        "fieldId": "664f...",
        "fieldName": "Company",
        "type": "text",
        "value": "Acme Inc"
      }
    ],
    "source": "api",
    "status": "active",
    "isFavorite": false,
    "isBlocked": false,
    "marketingOptIn": true,
    "marketingOptInAt": "2026-07-12T09:30:00.000Z",
    "lastContactedAt": null,
    "createdAt": "2026-07-12T09:30:00.000Z",
    "updatedAt": "2026-07-12T09:30:00.000Z"
  },
  "meta": {
    "apiVersion": "v1"
  },
  "requestId": "a1f4c2e0-9b6d-4a1e-8c3f-2d7e5b9a0c11",
  "timestamp": "2026-07-12T09:30:00.000Z"
}

Get a contact by id

get/api/public/v1/contacts/{id}

Fetch a single contact by its public id.

Path parameters

  • idstringrequired

    24-char contact ObjectId

Query parameters

  • fieldsstring

    Comma-separated list of fields to return (sparse fieldset).

Response 200The contact
  • successboolean
  • dataobject
    16 child fields
    • idstring
    • namestring
    • phonestring
    • emailstring | null
    • countrystring | null
    • tagsstring[]
    • customFieldsobject[]
      4 child fields
      • fieldIdstring | null
      • fieldNamestring | null
      • typestring | null
      • valueany
    • sourcestring

      One ofmanualimportapiwhatsappweb

    • statusstring

      One ofactivedeletedblockedmerged

    • isFavoriteboolean
    • isBlockedboolean
    • marketingOptInboolean
    • marketingOptInAtstring (date-time) | null
    • lastContactedAtstring (date-time) | null
    • createdAtstring (date-time)
    • updatedAtstring (date-time)
  • metaobject
    1 child field
    • apiVersionstring
  • requestIdstring | null
  • timestampstring (date-time)

Errors

  • 400Malformed request or missing tenant context
  • 401Missing or invalid API key
  • 403Forbidden — developer platform disabled, key expired/disabled, or tenant mismatch
  • 404Contact not found
  • 429Too many requests — rate limit exceeded
  • 500Unexpected server error
Error envelope and fixes →
curl -X GET "https://api.inaiy.com/api/public/v1/contacts/6650a1b2c3d4e5f6a7b8c9d0" \
  -H "x-tenant-id: demo" \
  -H "x-api-key: wp_live_xxxxxxxxxxxxxxxxxxxx"
Response 200
{
  "success": true,
  "data": {
    "id": "6650a1b2c3d4e5f6a7b8c9d0",
    "name": "Jane Doe",
    "phone": "+14155552671",
    "email": "jane@example.com",
    "country": "US",
    "tags": [
      "vip",
      "newsletter"
    ],
    "customFields": [
      {
        "fieldId": "664f...",
        "fieldName": "Company",
        "type": "text",
        "value": "Acme Inc"
      }
    ],
    "source": "api",
    "status": "active",
    "isFavorite": false,
    "isBlocked": false,
    "marketingOptIn": true,
    "marketingOptInAt": "2026-07-12T09:30:00.000Z",
    "lastContactedAt": null,
    "createdAt": "2026-07-12T09:30:00.000Z",
    "updatedAt": "2026-07-12T09:30:00.000Z"
  },
  "meta": {
    "apiVersion": "v1"
  },
  "requestId": "a1f4c2e0-9b6d-4a1e-8c3f-2d7e5b9a0c11",
  "timestamp": "2026-07-12T09:30:00.000Z"
}

Update a contact

patch/api/public/v1/contacts/{id}

Partially update a contact. Provide at least one field.

Path parameters

  • idstringrequired

    24-char contact ObjectId

Request body

  • namestring
  • phonestring

    E.164 format

  • emailstring (email) | null
  • countrystring | null
  • tagsstring[]
  • customFieldsobject[]
  • sourcestring

    One ofmanualimportapiwhatsappweb

  • marketingOptInboolean
  • primaryTeamIdstring | null

    Owning team id (24-char ObjectId). Must be a team in this workspace; null clears it.

  • assignedAgentIdstring | null

    Owning agent (user) id. Must be a member of this workspace; null clears it.

Response 200Contact updated
  • successboolean
  • dataobject
    16 child fields
    • idstring
    • namestring
    • phonestring
    • emailstring | null
    • countrystring | null
    • tagsstring[]
    • customFieldsobject[]
      4 child fields
      • fieldIdstring | null
      • fieldNamestring | null
      • typestring | null
      • valueany
    • sourcestring

      One ofmanualimportapiwhatsappweb

    • statusstring

      One ofactivedeletedblockedmerged

    • isFavoriteboolean
    • isBlockedboolean
    • marketingOptInboolean
    • marketingOptInAtstring (date-time) | null
    • lastContactedAtstring (date-time) | null
    • createdAtstring (date-time)
    • updatedAtstring (date-time)
  • metaobject
    1 child field
    • apiVersionstring
  • requestIdstring | null
  • timestampstring (date-time)

Errors

  • 400Malformed request or missing tenant context
  • 401Missing or invalid API key
  • 403Forbidden — developer platform disabled, key expired/disabled, or tenant mismatch
  • 404Contact not found
  • 409Duplicate contact (phone already exists)
  • 422Validation failed
  • 429Too many requests — rate limit exceeded
  • 500Unexpected server error
Error envelope and fixes →
curl -X PATCH "https://api.inaiy.com/api/public/v1/contacts/6650a1b2c3d4e5f6a7b8c9d0" \
  -H "x-tenant-id: demo" \
  -H "x-api-key: wp_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"name":"Jane A. Doe","tags":["vip","priority"]}'
Request body
{
  "name": "Jane A. Doe",
  "tags": [
    "vip",
    "priority"
  ]
}
Response 200
{
  "success": true,
  "data": {
    "id": "6650a1b2c3d4e5f6a7b8c9d0",
    "name": "Jane Doe",
    "phone": "+14155552671",
    "email": "jane@example.com",
    "country": "US",
    "tags": [
      "vip",
      "newsletter"
    ],
    "customFields": [
      {
        "fieldId": "664f...",
        "fieldName": "Company",
        "type": "text",
        "value": "Acme Inc"
      }
    ],
    "source": "api",
    "status": "active",
    "isFavorite": false,
    "isBlocked": false,
    "marketingOptIn": true,
    "marketingOptInAt": "2026-07-12T09:30:00.000Z",
    "lastContactedAt": null,
    "createdAt": "2026-07-12T09:30:00.000Z",
    "updatedAt": "2026-07-12T09:30:00.000Z"
  },
  "meta": {
    "apiVersion": "v1"
  },
  "requestId": "a1f4c2e0-9b6d-4a1e-8c3f-2d7e5b9a0c11",
  "timestamp": "2026-07-12T09:30:00.000Z"
}

Delete a contact

delete/api/public/v1/contacts/{id}

Soft-delete a contact. Returns 204 No Content on success.

Path parameters

  • idstringrequired

    24-char contact ObjectId

Errors

  • 400Malformed request or missing tenant context
  • 401Missing or invalid API key
  • 403Forbidden — developer platform disabled, key expired/disabled, or tenant mismatch
  • 404Contact not found
  • 429Too many requests — rate limit exceeded
  • 500Unexpected server error
Error envelope and fixes →
curl -X DELETE "https://api.inaiy.com/api/public/v1/contacts/6650a1b2c3d4e5f6a7b8c9d0" \
  -H "x-tenant-id: demo" \
  -H "x-api-key: wp_live_xxxxxxxxxxxxxxxxxxxx"

Create or update a contact by phone

post/api/public/v1/contacts/upsert

Matches an existing contact by `phone` (with or without the leading +). If found, only the fields you send are updated (tags and customFields replace the stored lists) and the response is 200. If not found, the contact is created (name defaults to the phone, source to `api`) and the response is 201. `meta.created` tells you which happened. Returns 404 if primaryTeamId or assignedAgentId is not in this workspace.

Request bodyrequired

  • namestring
  • phonestringrequired

    E.164 format

  • emailstring (email) | null
  • countrystring | null
  • tagsstring[]
  • customFieldsobject[]
  • sourcestring

    One ofmanualimportapiwhatsappweb

  • marketingOptInboolean
  • primaryTeamIdstring | null

    Owning team id (24-char ObjectId). Must be a team in this workspace; null clears it.

  • assignedAgentIdstring | null

    Owning agent (user) id. Must be a member of this workspace; null clears it.

Response 200Existing contact updated (meta.created = false)
  • successboolean
  • dataobject
    16 child fields
    • idstring
    • namestring
    • phonestring
    • emailstring | null
    • countrystring | null
    • tagsstring[]
    • customFieldsobject[]
      4 child fields
      • fieldIdstring | null
      • fieldNamestring | null
      • typestring | null
      • valueany
    • sourcestring

      One ofmanualimportapiwhatsappweb

    • statusstring

      One ofactivedeletedblockedmerged

    • isFavoriteboolean
    • isBlockedboolean
    • marketingOptInboolean
    • marketingOptInAtstring (date-time) | null
    • lastContactedAtstring (date-time) | null
    • createdAtstring (date-time)
    • updatedAtstring (date-time)
  • metaobject
    1 child field
    • apiVersionstring
  • requestIdstring | null
  • timestampstring (date-time)

Errors

  • 400Malformed request or missing tenant context
  • 401Missing or invalid API key
  • 403Forbidden — developer platform disabled, key expired/disabled, or tenant mismatch
  • 404Contact not found
  • 422Validation failed
  • 429Too many requests — rate limit exceeded
  • 500Unexpected server error
Error envelope and fixes →
curl -X POST "https://api.inaiy.com/api/public/v1/contacts/upsert" \
  -H "x-tenant-id: demo" \
  -H "x-api-key: wp_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"phone":"+14155552671","name":"Jane Doe","tags":["vip"]}'
Request body
{
  "phone": "+14155552671",
  "name": "Jane Doe",
  "tags": [
    "vip"
  ]
}
Response 200
{
  "success": true,
  "data": {
    "id": "6650a1b2c3d4e5f6a7b8c9d0",
    "name": "Jane Doe",
    "phone": "+14155552671",
    "email": "jane@example.com",
    "country": "US",
    "tags": [
      "vip",
      "newsletter"
    ],
    "customFields": [
      {
        "fieldId": "664f...",
        "fieldName": "Company",
        "type": "text",
        "value": "Acme Inc"
      }
    ],
    "source": "api",
    "status": "active",
    "isFavorite": false,
    "isBlocked": false,
    "marketingOptIn": true,
    "marketingOptInAt": "2026-07-12T09:30:00.000Z",
    "lastContactedAt": null,
    "createdAt": "2026-07-12T09:30:00.000Z",
    "updatedAt": "2026-07-12T09:30:00.000Z"
  },
  "meta": {
    "apiVersion": "v1"
  },
  "requestId": "a1f4c2e0-9b6d-4a1e-8c3f-2d7e5b9a0c11",
  "timestamp": "2026-07-12T09:30:00.000Z"
}