API
OpenAPI specification
The API is described by an OpenAPI 3.1 document. You can read it here, or fetch it as JSON and point your own tooling at it.
The raw document
The document is served as JSON at /api/openapi. The endpoint is public and holds no data about an account: it describes the shape of the endpoints, the error codes and the limits.
You can hand the URL to a client generator, or read it as a reference. The endpoint list on this page and the paths in the document are the same list.
curl https://abackanalytics.com/api/openapi{
"openapi": "3.1.0",
"info": {
"title": "Aback Analytics API",
"version": "1.0.0"
},
"servers": [
{ "url": "https://abackanalytics.com", "description": "Production" }
],
"paths": {
"/api/collect": { "post": { ... } },
"/api/v1/events": { "post": { ... } },
"/api/v1/revenue": { "post": { ... } },
"/api/v1/identify": { "post": { ... }, "delete": { ... } },
"/api/v1/crawls": { "post": { ... } },
"/api/v1/ad-spend": { "post": { ... } },
"/api/v1/reports/overview": { "get": { ... } },
"/api/v1/reports/breakdown": { "get": { ... } },
"/api/sites/{siteId}/export": { "get": { ... } },
"/api/account/sites": { "get": { ... } },
"/api/auth/signup": { "post": { ... } },
"/api/auth/login": { "post": { ... } },
"/api/openapi": { "get": { ... } }
}
}Endpoints
Every endpoint that exists in this version is in the table. There is no endpoint that the document names and the server does not serve.
| Method | Path | What it does | Authentication |
|---|---|---|---|
| POST | /api/collect | Record a batch of browser events for one website. | None. The public tracking id in the body identifies the website. |
| POST | /api/v1/events | Record one event from your own server. | API key with the events:write scope. |
| POST | /api/v1/revenue | Record one confirmed payment and attribute it to a touchpoint. | API key with the revenue:write scope. |
| POST | /api/v1/identify | Link a visitor to one of your users, from your backend. | API key with the events:write scope. |
| DELETE | /api/v1/identify | Forget a user: remove its links and its id on payments. | API key with the events:write scope. |
| POST | /api/v1/crawls | Record the requests of AI crawlers, sent from your server. | API key with the events:write scope. |
| POST | /api/v1/ad-spend | Record ad spend per day, source and campaign. | API key with the revenue:write scope. |
| GET | /api/v1/reports/overview | Read the totals, the daily series, the goals and the revenue of a website. | API key with the reports:read scope. |
| GET | /api/v1/reports/breakdown | Break one dimension down for the same date range. | API key with the reports:read scope. |
| GET | /api/v1/live | Read the activity of the last few minutes. | API key with the reports:read scope. |
| GET | /api/sites/{siteId}/export | Download the stored events of a website as a CSV file. | The session cookie of a signed in user. |
| GET | /api/account/sites | List the websites of the account of the signed in user. | The session cookie of a signed in user. |
| POST | /api/auth/signup | Create an account and receive a session cookie. | None. The request must come from the same origin as the app. |
| POST | /api/auth/login | Sign in and receive a session cookie. | None. The request must come from the same origin as the app. |
| GET | /api/openapi | Read this specification as JSON. | None. |
Authentication
There are two credentials. An API key authenticates the server to server endpoints, and a session cookie authenticates the endpoints that belong to the dashboard of a signed in user.
An API key has the shape abk_xxxxxxxx.secret. The part before the dot is the public prefix, the part after the dot is the secret. The secret is shown exactly once, is stored only as a keyed digest, and belongs on your server only.
A session cookie is named abk_session. The account is always resolved from that session on the server, so no endpoint that uses it accepts an account identifier from the client.
Authorization: Bearer abk_xxxxxxxx.secret
Cookie: abk_session=...A worked example
Sending one event from a server and reading the answer. The same call is in the document with its full request body, its response schema and every status code it can answer with.
curl -X POST https://abackanalytics.com/api/v1/events \
-H "Authorization: Bearer abk_xxxxxxxx.secret" \
-H "content-type: application/json" \
-d '{
"websiteId": "abk_xxxxxxxxxxxxxxxx",
"event": "signup_completed",
"properties": { "plan": "pro" }
}'{
"ok": true,
"data": {
"eventId": "evt_9f2c41b7ac0d4e6f8a1b",
"status": "accepted"
}
}The account scoped endpoint works the same way with the session cookie, and it answers with the public tracking id of every website so a tool can find the right site.
curl https://abackanalytics.com/api/account/sites \
-H "Cookie: abk_session=..."{
"ok": true,
"data": {
"websites": [
{
"id": "site_...",
"name": "Marketing site",
"domain": "example.com",
"timezone": "UTC",
"status": "active",
"trackingId": "abk_xxxxxxxxxxxxxxxx",
"retentionDays": 30
}
]
}
}Limits and error codes
The document carries the machine readable version of the limits: the body size of every endpoint, the number of events in one batch, the length of a range, the row limit of an export, and the rate limit of each bucket. A request that breaks a limit is refused before it is stored.
Every failed request answers with the same envelope, a stable code, a safe message and the request id of the call. The full table of codes is in the API reference, and the human readable contract of each endpoint is on that page too.