Skip to main content

Imports & Exports API

Bulk data movement in and out of your workspace: import subscribers into a list from a CSV file (with presets for Klaviyo and Braze exports), and export your behavioral event history.

Authentication

The two surfaces use different credentials:

  • Subscriber imports are authenticated with a bearer token, like the dashboard APIs:

    Authorization: Bearer YOUR_ACCESS_TOKEN
  • Event export requires a server API key (hober_srv_…) — see GET /v1/events/export below.


Subscriber imports

Imports run as asynchronous jobs: upload a CSV, get a job ID back immediately, then poll the job until it completes. Rows that fail validation are counted in failed_rows without aborting the rest of the import.

Import job statuses

StatusMeaning
pendingAccepted, waiting to be picked up
processingRows are being processed
completedAll rows attempted (terminal)
failedThe job hit an unrecoverable error (terminal) — see error_message

POST /api/v1/lists/import

Starts a subscriber import into an existing list. The request is multipart/form-data.

Form fields

FieldTypeRequiredDescription
listIdstringYesUUID of the target subscriber list.
filefileYesThe CSV file. Must have a text/csv content type or a .csv extension. Maximum size 50 MB.
sourcestringNoImport preset: csv (default), klaviyo, or braze.

Import presets

The preset controls how the CSV's columns are interpreted:

  • csv — the standard column contract (default when source is omitted).
  • klaviyo — accepts a Klaviyo profile export as-is: Klaviyo's headers are aliased to the standard fields, extra columns are packed into subscriber attributes, and Klaviyo consent statuses are translated conservatively.
  • braze — accepts a Braze user export as-is, with the equivalent header mapping.

Response — 202 Accepted

{
"import_job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending"
}

Error responses

StatusMeaning
400Missing listId or file, or the file is not a CSV
401Missing or invalid bearer token
404The list does not exist in your workspace
413File larger than 50 MB
422Unknown source value

GET /api/v1/lists/import/:jobId

Fetches the status of an import job.

Response — 200 OK

{
"import_job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"processed_rows": 1500,
"total_rows": 5000,
"failed_rows": 10
}
FieldTypeDescription
import_job_idstringThe job UUID.
statusstringpending, processing, completed, or failed.
processed_rowsintRows attempted so far.
total_rowsintTotal rows in the file. Absent until processing starts.
failed_rowsintRows that failed validation and were skipped.
error_messagestringTerminal error reason. Present only on failed jobs.

404 — no import job with that ID in your workspace.


Event exports

GET /v1/events/export

Bulk export of the workspace's behavioral event history, paginated with an opaque cursor. This endpoint requires a server API key — publishable client SDK keys cannot read event history:

Authorization: Bearer hober_srv_YOUR_SERVER_KEY

This is the same endpoint documented on the Events page — see there for the event field semantics and ingestion counterpart.

Query parameters

ParamTypeRequiredDescription
fromRFC 3339NoWindow start on occurred_at. Defaults to all history.
toRFC 3339NoWindow end. Defaults to now.
cursorstringNoOpaque cursor from the previous page's next_cursor.
limitintNoEvents per page, 1–1000. Defaults to 1000.

Response — 200 OK

{
"items": [
{
"id": "6a7b8c9d-0e1f-2a3b-4c5d-6e7f8a9b0c1d",
"subscriber_id": "8a2f6c1e-1234-4abc-9def-567890abcdef",
"anonymous_id": null,
"event_name": "order_placed",
"platform": "web",
"properties": { "total_price": "19.99" },
"occurred_at": "2026-07-01T12:00:00Z",
"received_at": "2026-07-01T12:00:01Z",
"source": "server"
}
],
"next_cursor": ""
}

Rows are ordered by (occurred_at, id), so pages are stable under concurrent ingestion. Keep requesting with the returned next_cursor until it comes back empty — an empty next_cursor means the final page.

Error responses

StatusMeaning
401Missing, malformed, or revoked credential
403The credential is a client SDK key — export requires a server key
422Malformed from / to, limit out of range, or malformed cursor