v1 · API reference

Contacts

Manage the people you email. Create and update contacts one at a time or import thousands in the background, with standard and custom field values that templates can reference as variables.

Base URL: https://www.unitpost.com/api/v1/api/v1

Contacts

List contacts

GET/api/v1/api/v1/contacts

GET /contacts
curl -X GET 'https://www.unitpost.com/api/v1/api/v1/contacts' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Response · 200
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "contact",
      "id": "id_123",
      "email": "customer@example.com",
      "first_name": "string",
      "last_name": "string",
      "unsubscribed": false,
      "unsubscribed_at": "2026-01-01T00:00:00.000Z",
      "unsubscribe_reason": "USER",
      "custom_fields": {},
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z"
    }
  ]
}

Retrieve a list of the contacts in your workspace, newest-first and cursor-paginated. Each row includes the contact's core fields and any custom field values. Use a contact's id (or email) with Retrieve a contact for the full record, add contacts with Create a contact, or bring a list in bulk with Start an async contact import. Requires the contacts:read capability.

Parameters3 fields
FieldTypeDescription
limitinteger · queryMax rows to return (default 20, max 100).
afterstring · queryReturn rows after this id (forward paging).
beforestring · queryReturn rows before this id (backward paging).
Response · 200 fields11 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
emailrequiredstring
first_namerequiredobject
last_namerequiredobject
unsubscribedrequiredboolean
unsubscribed_atrequiredobject
unsubscribe_reasonrequiredobject
custom_fieldsrequiredobject
created_atrequiredstring
updated_atrequiredstring
200401422

Create a contact

POST/api/v1/api/v1/contacts

POST /contacts
curl -X POST 'https://www.unitpost.com/api/v1/api/v1/contacts' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "customer@example.com",
    "first_name": "Ada",
    "last_name": "Lovelace"
  }'
Response · 201
{
  "object": "contact",
  "id": "id_123",
  "email": "customer@example.com",
  "first_name": "string",
  "last_name": "string",
  "unsubscribed": false,
  "unsubscribed_at": "2026-01-01T00:00:00.000Z",
  "unsubscribe_reason": "USER",
  "custom_fields": {},
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Add a single contact to your workspace. Set an email plus any standard or custom field values; custom fields must already exist (define them with Create a custom contact field). Emails are unique per workspace, so creating one that already exists returns 409 — use Update a contact to change an existing contact, or Start an async contact import to add many at once. Requires the contacts:write capability.

Request body5 fields
FieldTypeDescription
emailrequiredstring
first_namestring
last_namestring
unsubscribedboolean
custom_fieldsobject
Response · 201 fields11 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
emailrequiredstring
first_namerequiredobject
last_namerequiredobject
unsubscribedrequiredboolean
unsubscribed_atrequiredobject
unsubscribe_reasonrequiredobject
custom_fieldsrequiredobject
created_atrequiredstring
updated_atrequiredstring
201401409422

Retrieve a contact

GET/api/v1/api/v1/contacts/{id}

GET /contacts/{id}
curl -X GET 'https://www.unitpost.com/api/v1/api/v1/contacts/con_123' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Response · 200
{
  "object": "contact",
  "id": "id_123",
  "email": "customer@example.com",
  "first_name": "string",
  "last_name": "string",
  "unsubscribed": false,
  "unsubscribed_at": "2026-01-01T00:00:00.000Z",
  "unsubscribe_reason": "USER",
  "custom_fields": {},
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Retrieve a single contact and all of its field values. The {id} path segment accepts either the contact's id or its email address, so you can look a contact up without storing our id. Change it with Update a contact, or see which subscription topics it's opted into with List a contact's topic subscriptions. Requires the contacts:read capability.

Parameters1 field
FieldTypeDescription
idrequiredstring · path
Response · 200 fields11 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
emailrequiredstring
first_namerequiredobject
last_namerequiredobject
unsubscribedrequiredboolean
unsubscribed_atrequiredobject
unsubscribe_reasonrequiredobject
custom_fieldsrequiredobject
created_atrequiredstring
updated_atrequiredstring
200401404

Update a contact

PATCH/api/v1/api/v1/contacts/{id}

PATCH /contacts/{id}
curl -X PATCH 'https://www.unitpost.com/api/v1/api/v1/contacts/con_123' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "unsubscribed": true
  }'
Response · 200
{
  "object": "contact",
  "id": "id_123",
  "email": "customer@example.com",
  "first_name": "string",
  "last_name": "string",
  "unsubscribed": false,
  "unsubscribed_at": "2026-01-01T00:00:00.000Z",
  "unsubscribe_reason": "USER",
  "custom_fields": {},
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Update a contact's standard or custom field values. Only the fields you send are changed; omitted fields are left as-is. The {id} accepts a contact id or email. To manage a contact's subscription preferences instead, use Set a contact's topic preference. Requires the contacts:write capability.

Parameters1 field
FieldTypeDescription
idrequiredstring · path
Request body4 fields
FieldTypeDescription
first_nameobject
last_nameobject
unsubscribedboolean
custom_fieldsobject
Response · 200 fields11 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
emailrequiredstring
first_namerequiredobject
last_namerequiredobject
unsubscribedrequiredboolean
unsubscribed_atrequiredobject
unsubscribe_reasonrequiredobject
custom_fieldsrequiredobject
created_atrequiredstring
updated_atrequiredstring
200401404422

Delete a contact

DELETE/api/v1/api/v1/contacts/{id}

DELETE /contacts/{id}
curl -X DELETE 'https://www.unitpost.com/api/v1/api/v1/contacts/con_123' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Permanently delete a contact and its field values. This also removes the contact from every segment it belonged to. To stop mailing someone without deleting them, unsubscribe them from a topic with Set a contact's topic preference or add them to your suppression list instead. Requires the contacts:write capability.

Parameters1 field
FieldTypeDescription
idrequiredstring · path
204401404

List contact imports

GET/api/v1/api/v1/contacts/imports

GET /contacts/imports
curl -X GET 'https://www.unitpost.com/api/v1/api/v1/contacts/imports' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Response · 200
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "contact_import",
      "id": "id_123",
      "status": "pending",
      "total": 1,
      "imported": 0,
      "skipped": 0,
      "failed": 0,
      "invalid": [
        {
          "row": 0,
          "reason": "string"
        }
      ],
      "error": "string",
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z"
    }
  ]
}

Retrieve a list of your bulk contact-import jobs, newest-first and cursor-paginated. Each row is a reference to one import and its current progress. Start a new one with Start an async contact import, or drill into a single job with Retrieve a contact import. Requires the contacts:read capability.

Parameters3 fields
FieldTypeDescription
limitinteger · queryMax rows to return (default 20, max 100).
afterstring · queryReturn rows after this id (forward paging).
beforestring · queryReturn rows before this id (backward paging).
Response · 200 fields11 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
statusrequiredenumpending | processing | completed | failed
totalrequirednumber
importedrequirednumber
skippedrequirednumber
failedrequirednumber
invalidrequiredobject[]
errorrequiredobject
created_atrequiredstring
updated_atrequiredstring
200401422

Start an async contact import

POST/api/v1/api/v1/contacts/imports

POST /contacts/imports
curl -X POST 'https://www.unitpost.com/api/v1/api/v1/contacts/imports' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{ }'
Response · 202
{
  "object": "contact_import",
  "id": "id_123",
  "status": "pending",
  "total": 1,
  "imported": 0,
  "skipped": 0,
  "failed": 0,
  "invalid": [
    {
      "row": 0,
      "reason": "string"
    }
  ],
  "error": "string",
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Import a batch of contacts (up to 5,000 per request) in the background. The call returns immediately with an import job you poll for progress and per-row results — new contacts are created and existing ones (matched by email) are updated. Track it with Retrieve a contact import, or see all your imports via List contact imports. To add a single contact synchronously, use Create a contact. Requires the contacts:write capability.

Request body1 field
FieldTypeDescription
contactsrequiredobject[]
Response · 202 fields11 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
statusrequiredenumpending | processing | completed | failed
totalrequirednumber
importedrequirednumber
skippedrequirednumber
failedrequirednumber
invalidrequiredobject[]
errorrequiredobject
created_atrequiredstring
updated_atrequiredstring
202401422

Retrieve a contact import

GET/api/v1/api/v1/contacts/imports/{id}

GET /contacts/imports/{id}
curl -X GET 'https://www.unitpost.com/api/v1/api/v1/contacts/imports/con_123' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Response · 200
{
  "object": "contact_import",
  "id": "id_123",
  "status": "pending",
  "total": 1,
  "imported": 0,
  "skipped": 0,
  "failed": 0,
  "invalid": [
    {
      "row": 0,
      "reason": "string"
    }
  ],
  "error": "string",
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Retrieve a bulk import job by id to check its status and per-row results — how many contacts were created, updated, or skipped, and why any rows failed. Poll this while an import runs. Start one with Start an async contact import. Requires the contacts:read capability.

Parameters1 field
FieldTypeDescription
idrequiredstring · path
Response · 200 fields11 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
statusrequiredenumpending | processing | completed | failed
totalrequirednumber
importedrequirednumber
skippedrequirednumber
failedrequirednumber
invalidrequiredobject[]
errorrequiredobject
created_atrequiredstring
updated_atrequiredstring
200401404