Beta — endpoints, schemas, limits and examples may change before general availability.
Hellomateo API Documentation
Recipes

Contact and entity batch imports

Submit contact, deal, and appointment imports and poll their status.

Use the entity-specific batch import endpoints when you need to submit multiple contacts, deals, or appointments for asynchronous processing.

EntityCreate a batchPoll one batchList batches
ContactsPOST /v1/contacts/imports/batchGET /v1/contacts/imports/{id}GET /v1/contacts/imports
DealsPOST /v1/deals/imports/batchGET /v1/deals/imports/{id}GET /v1/deals/imports
AppointmentsPOST /v1/appointments/imports/batchGET /v1/appointments/imports/{id}GET /v1/appointments/imports

Every batch request creates a new import job. The API does not deduplicate requests by payload or external_id, so retrying a successful request creates another job.

Submit an inline payload

Batch requests use JSON and include a non-empty payload array. Each item is an entity import record. The request body limit is 5 MB. Multipart uploads and file IDs are not supported by these endpoints.

curl https://api.getmateo.com/v1/contacts/imports/batch \
  --request POST \
  --header "Authorization: Bearer $MATEO_API_TOKEN" \
  --header "hellomateo-version: 2026-07-01" \
  --header "Content-Type: application/json" \
  --data '{
    "external_id": "erp-contact-import-2026-07-14",
    "contact_list_external_id": "newsletter",
    "payload": [
      {
        "external_id": "customer-1001",
        "full_name": "Ada Lovelace",
        "email": "ada@example.com"
      },
      {
        "external_id": "customer-1002",
        "full_name": "Grace Hopper",
        "email": "grace@example.com"
      }
    ]
  }'

For contact batches, use at most one of contact_list_id and contact_list_external_id.

Deal and appointment batches use the same envelope and accept their respective record fields:

{
  "external_id": "erp-deal-import-2026-07-14",
  "allow_deal_reassignment": false,
  "payload": [
    {
      "external_id": "deal-1001",
      "name": "Annual renewal",
      "contact_external_id": "customer-1001"
    }
  ]
}

Send that body to POST /v1/deals/imports/batch. For appointments, send the appointment records to POST /v1/appointments/imports/batch and use allow_appointment_reassignment when needed.

Batch routes return 415 Unsupported Media Type when Content-Type is missing or is not a JSON media type. They return 413 Payload Too Large when the JSON body exceeds 5 MB. Malformed JSON and payload validation failures return 400 Bad Request.

A successful submission returns 201 Created and the new import job. This abbreviated example highlights the fields used for polling:

{
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "type": "contact_details",
  "external_id": "erp-contact-import-2026-07-14",
  "status": "pending",
  "started_at": null,
  "completed_at": null,
  "total_count": null,
  "success_count": null,
  "failed_count": null,
  "failure": null
}

Poll the import

Build the detail URL from the returned id and the same entity collection used to create the job:

curl https://api.getmateo.com/v1/contacts/imports/3c90c3cc-0d44-4b50-8888-8dd25736052a \
  --header "Authorization: Bearer $MATEO_API_TOKEN" \
  --header "hellomateo-version: 2026-07-01"

Batch 1 exposes coarse status semantics:

  • pending means at least one result count is not available yet.
  • completed means total_count, success_count, and failed_count are all available.

A completed job may still contain failed records. Check success_count and failed_count rather than treating completed as “every record succeeded.” The status schema also reserves processing, failed, and unknown for the persisted lifecycle rollout. The following response is abbreviated:

{
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "type": "contact_details",
  "status": "completed",
  "total_count": 2,
  "success_count": 1,
  "failed_count": 1,
  "failure": null
}

Poll with backoff until the job reaches a terminal status. Do not repeatedly submit the batch to check whether it finished.

List and filter imports

Entity import history is separate for contacts, deals, and appointments. Lists are ordered by creation time and use cursor pagination.

curl --globoff 'https://api.getmateo.com/v1/contacts/imports?status[in]=pending,completed&limit=20' \
  --header "Authorization: Bearer $MATEO_API_TOKEN" \
  --header "hellomateo-version: 2026-07-01"

Follow next_page_url when it is present. You can also filter by one external_id or use external_id[in] for multiple values.

On this page