Subscribers API
POST /api/v1/subscribers/upsert
Creates or updates a subscriber record, keyed by external_id. Authenticated
with the publishable SDK key (X-SDK-Key header). Idempotent: re-sending the
same body converges on the same record, which is what makes retrying
pipelines (Zapier, reverse-ETL) safe.
Request Body
{
"external_id": "user-123",
"email": "user@example.com",
"attributes": {
"plan": "pro",
"country": "US"
}
}
external_id is the only required field. An optional consent assertion
records an express email opt-in alongside the upsert.
Response
200 with the stored subscriber:
{
"id": "8a2f6c1e-…",
"external_id": "user-123",
"email": "user@example.com",
"attributes": "{\"plan\":\"pro\",\"country\":\"US\"}",
"created_at": "2026-07-26T12:00:00Z",
"updated_at": "2026-07-26T12:00:00Z"
}
attributes travels as a JSONB-encoded string (schemaless by design).
401 — missing or invalid SDK key. 422 — validation failure naming the field.
DELETE /api/v1/subscribers/{id}
Authenticated with a dashboard bearer token (see Authentication). Permanently deletes a single subscriber and all associated devices and list memberships. Delivery log rows are anonymised (foreign keys set to NULL) rather than deleted.
For GDPR compliance details, cascade behaviour, and the operator runbook, see the GDPR Data Retention Policy guide.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string (UUID) | Hober subscriber UUID |
Response
204 No Content on success. No response body.
Error responses
| Status | Meaning |
|---|---|
401 | Missing or invalid bearer token |
404 | Subscriber not found |