curl --request POST \
--url https://apix.spotzee.com/api/client/users/batch \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
[
{
"anonymous_id": "anon-2c8a3e",
"external_id": "cust-9f4b21",
"email": "jane@example.com",
"phone": "+61400123456",
"timezone": "Australia/Sydney",
"locale": "en-AU",
"data": {
"first_name": "Jane",
"plan": "pro"
}
}
]
'{
"results": [
{
"index": 0,
"external_id": "cust-9f4b21",
"anonymous_id": "<string>",
"contact": {
"id": 1024,
"project_id": 42,
"external_id": "cust-9f4b21",
"created_at": "2026-04-28T05:14:00.000Z",
"updated_at": "2026-04-28T05:14:00.000Z",
"anonymous_id": "anon-2c8a3e",
"email": "jane@example.com",
"phone": "+61400123456",
"timezone": "Australia/Sydney",
"locale": "en-AU",
"data": {
"first_name": "Jane",
"last_name": "Doe",
"plan": "pro"
},
"has_push_device": true,
"devices": [
{}
]
},
"error": {
"code": "resource_missing",
"message": "Contact identity could not be resolved."
}
}
],
"succeeded": 2,
"failed": 0
}Creates or updates up to 100 contacts in a single call and reports per-item success or failure before returning. Each input must include either anonymous_id or external_id; supplying both links the two identifiers. Use this when the calling system needs to react to partial failures inline; use PATCH /users instead for fire-and-forget queued processing.
Idempotent — pass an Idempotency-Key header to make safely retryable. On a replay the original response is returned with Idempotent-Replayed: true. See the API conventions guide for the full state machine, TTL, and mismatch behaviour.
curl --request POST \
--url https://apix.spotzee.com/api/client/users/batch \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
[
{
"anonymous_id": "anon-2c8a3e",
"external_id": "cust-9f4b21",
"email": "jane@example.com",
"phone": "+61400123456",
"timezone": "Australia/Sydney",
"locale": "en-AU",
"data": {
"first_name": "Jane",
"plan": "pro"
}
}
]
'{
"results": [
{
"index": 0,
"external_id": "cust-9f4b21",
"anonymous_id": "<string>",
"contact": {
"id": 1024,
"project_id": 42,
"external_id": "cust-9f4b21",
"created_at": "2026-04-28T05:14:00.000Z",
"updated_at": "2026-04-28T05:14:00.000Z",
"anonymous_id": "anon-2c8a3e",
"email": "jane@example.com",
"phone": "+61400123456",
"timezone": "Australia/Sydney",
"locale": "en-AU",
"data": {
"first_name": "Jane",
"last_name": "Doe",
"plan": "pro"
},
"has_push_device": true,
"devices": [
{}
]
},
"error": {
"code": "resource_missing",
"message": "Contact identity could not be resolved."
}
}
],
"succeeded": 2,
"failed": 0
}Documentation Index
Fetch the complete documentation index at: https://docs.spotzee.com/llms.txt
Use this file to discover all available pages before exploring further.
Project-scoped secret API key (sk_…). Pass in the Authorization: Bearer <key> header. Grants access to the project the key was issued for.
1 - 100 elementsA single contact upsert. At least one of anonymous_id or external_id must be present. When both are present they are linked.
Anonymous tracking identifier captured before the contact was identified.
"anon-2c8a3e"
Optional system-of-record identifier to attach to this anonymous contact.
"cust-9f4b21"
Contact’s email address. Validated against RFC 5322 on write.
"jane@example.com"
Contact’s phone number. E.164 preferred; other formats are normalised when possible.
"+61400123456"
IANA timezone (for example Australia/Sydney).
50"Australia/Sydney"
BCP-47 locale tag (for example en-AU).
255"en-AU"
Per-item upsert outcomes. Partial success is allowed.
Synchronous result of a bulk contact upsert. Partial success is allowed.
Per-item outcomes in the same order as the request body.
Hide child attributes
Position of this item in the request body, zero-indexed.
0
External identifier supplied by the caller for this contact, when available.
"cust-9f4b21"
Anonymous identifier supplied by the caller for this contact, when available.
The persisted contact, present when the item upserted successfully.
Hide child attributes
Numeric identifier. Use external_id as the stable cross-system reference.
1024
Identifier of the project this contact belongs to.
42
Stable identifier supplied by the calling system. Treated as the contact’s primary key for upserts.
"cust-9f4b21"
Time the contact was first created. ISO 8601.
"2026-04-28T05:14:00.000Z"
Time the contact was last modified. ISO 8601.
"2026-04-28T05:14:00.000Z"
Anonymous tracking identifier captured before the contact was identified, when available.
"anon-2c8a3e"
Contact’s email address. Format-validated on write.
"jane@example.com"
Contact’s phone number in E.164 format on read.
"+61400123456"
IANA timezone used for time-of-day delivery scheduling.
"Australia/Sydney"
BCP-47 locale used for content rendering.
"en-AU"
True when the contact has at least one registered push device.
Failure detail, present when the item could not be persisted.
Hide child attributes
Per-item error code drawn from the canonical 16-code catalogue.
resource_missing, resource_already_exists, parameter_missing, parameter_invalid_empty, parameter_invalid_format, parameter_unknown, validation_failed, authentication_required, permission_denied, idempotency_key_mismatch, rate_limited, version_unsupported, version_required, webhook_signature_invalid, quota_exceeded, internal_error "resource_missing"
Human-readable, en-AU explanation of why this item failed.
"Contact identity could not be resolved."
Count of items that upserted successfully.
2
Count of items that failed.
0
Was this page helpful?