API
Sphericon exposes three HTTP surfaces. All are described by OpenAPI documents generated from
TypeSpec, which is the single source of truth; you will find them in the repository under
openapi/. Every operation of the external API is documented in the API reference.
| Surface | Base path | Used by | Auth |
|---|---|---|---|
| External | /api |
Your backend and automation | Authorization: Bearer <token> |
| Collect | /collect |
The browser tracker and your server | x-collect-key header |
| Site | /site |
The Sphericon web app itself | Session, per workspace |
The site API is the web app’s own backend and may change with the UI. Build on the external and collect APIs.
Tokens and scopes
Section titled “Tokens and scopes”Create an API token under Settings → Developers. Each token carries scopes, so you can hand an integration only what it needs, for example:
contacts:read,contacts:write, and the separatecontacts:eraseto delete (erase) a contactevents:writesegments:read,segments:writebroadcasts:write, and the separatebroadcasts:sendto actually sendautomations:write, andautomations:activateto turn one onenrollments:readto read where each Contact is in an automation, and why a failed one failedemails:sendfor transactional mailwebhooks:read,webhooks:write, and the separatewebhooks:regenerate(replace an endpoint’s signing secret) andwebhooks:test(send it a sample event)integrations:read,integrations:writefor sending providers (credentials are write-only: no response ever contains a password or secret key)sending_domains:read,sending_domains:writefor sending domains: create one, publish the returned DKIM record, thenPOST /sending-domains/{id}/verifyand read the domain to see whether it verified (the DKIM private key is never returned)export:read(Enterprise) for the Export streams,GET /export/eventsand the other streams, which read a Workspace’s rows page by page into a warehouse; see the Export streams guide for the cursor, the overlap and a ClickHouse example
Sending, activating and erasing have their own scopes, so a token that can edit drafts cannot send mail and a token that can write contacts cannot erase them.
What the external API covers
Section titled “What the external API covers”| Area | Endpoints |
|---|---|
| Contacts | /contacts, /contacts/batch, /contacts/{id}/tags |
| Custom fields, tags | /custom-fields, /tags |
| Events | /events, /events/batch, /events/actions |
| Segments | /segments, /segments/preview |
| Templates | /templates |
| Broadcasts | /broadcasts, …/segment, …/schedule, …/test-send, …/report |
| Automations | /automations, …/activate, …/deactivate |
| Enrollments | /automations/{id}/enrollments |
| Transactional | /emails |
| Consent | /unsubscribes, /suppressions |
| Sending domains | /sending-domains, /sending-domains/rates |
| Webhooks | /webhooks |
Example: upsert contacts
Section titled “Example: upsert contacts”curl https://sphericon.example.com/api/contacts/batch \ -H "Authorization: Bearer $SPHERICON_TOKEN" \ -H "Content-Type: application/json" \ -d '{"contacts":[{"subjectId":"user_42","email":"ada@example.com","firstName":"Ada"}]}'Pagination
Section titled “Pagination”List endpoints take page (1-based, default 1) and pageSize (default 25) and return:
{ "items": [], "page": 1, "pageSize": 25, "totalItems": 0, "totalPages": 0 }Batches
Section titled “Batches”POST /contacts/batch and POST /events/batch take up to 1000 items. Items are processed
independently: one failure does not roll back the others. The response has one result per item,
in request order, with its zero-based index:
{ "results": [ { "index": 0, "status": "created", "contactId": 101 }, { "index": 1, "status": "failed", "error": "email is invalid" } ]}Contact items have the status created, updated or failed; event items accepted or
failed. Contacts are matched by their alias keys (subjectId, email, phone), so a batch is
safe to repeat.
Errors
Section titled “Errors”Errors are RFC 7807 application/problem+json:
{ "status": 422, "title": "Unprocessable Entity", "detail": "…what went wrong…"}status and title are always present, and detail for client errors. Server errors (5xx)
carry no detail; quote the X-Request-Id response header when you report one.
| Status | Meaning |
|---|---|
400 |
The request could not be parsed. |
401 |
The token is missing, invalid, revoked or expired. |
403 |
The token lacks the required scope. |
404 |
The resource does not exist in this workspace. |
413 |
The body is larger than the configured limit. |
409 |
A request with the same Idempotency-Key is still in flight. |
422 |
Validation failed, or a reference points at another workspace’s row. |
Idempotent sends
Section titled “Idempotent sends”POST /emails accepts an Idempotency-Key header. Repeating a request with the same key replays
the original result without sending a second email, so it is safe to retry after a timeout. A
repeat that arrives while the first is still running gets 409.
Operating Sphericon with an agent
Section titled “Operating Sphericon with an agent”The same binary serves an MCP endpoint at /mcp. Its tools are projected from the external API
contract, so token scopes, workspace scoping and errors behave exactly as they do over /api.
See MCP for agents.
Webhooks
Section titled “Webhooks”Register an endpoint with POST /api/webhooks to be notified when things happen. See
Webhooks for the events, payload, signature check and retries.