Sessions · Reference
API
What your server can ask of Sessions with its server secret: erasing, the journey, key flows and objections. The Laravel SDK makes every one of these calls for you.
Base URL
https://services.my-beast.com/sessionsEvery path below is under it, over HTTPS only. Requests and answers are JSON in UTF-8, and timestamps are Unix milliseconds. A person (subject) and an account are your own ids, as your pages' tokens carry them: 1 to 64 of A-Z a-z 0-9 . _ : -.
Authentication
Send the project's server secret on every request:
Authorization: Bearer sk_…A server secret reaches only its own project. It's shown once, when it's made in Settings → Keys, or kept in Secrets when id made it with the project.
Keep the secret on your server
Recordings
Erasing again is safe: it answers {"erased": 0} the second time. Each erasure is written in the audit log by its count only, never the id it erased.
Erase a person's recordings
DELETE /api/v1/subjects/{subject}/recordings
Every recording of the person: the rows, the encrypted files, and the presses and dialogs read out of them.
The SDK: Sessions::eraseSubject($id).
curl -X DELETE https://services.my-beast.com/sessions/api/v1/subjects/42/recordings \
-H "Authorization: Bearer $MYBEAST_SESSIONS_SECRET"200 {"erased": 3}Erase an account's recordings
DELETE /api/v1/accounts/{account}/recordings
Every recording made in the account (the token's acct), whoever it was of.
The SDK: Sessions::eraseAccount($id).
curl -X DELETE https://services.my-beast.com/sessions/api/v1/accounts/7/recordings \
-H "Authorization: Bearer $MYBEAST_SESSIONS_SECRET"200 {"erased": 12}Read back a test person's recordings
GET /api/v1/subjects/{subject}/recordings/test-export
The person's recordings made under a test token only, newest first, each chunk the events' JSON as the browser sent it. Gzip when asked. At most 200 recordings or 32 MiB of events: past either, truncated is true.
The SDK: Sessions::testRecordings($id).
curl -X GET https://services.my-beast.com/sessions/api/v1/subjects/42/recordings/test-export \
-H "Authorization: Bearer $MYBEAST_SESSIONS_SECRET"200 {"recordings": [{"id": "0b6f…", "started_at": 1793520000000, "masked": true, "chunks": ["[…]"], "unreadable_chunks": 0}], "truncated": false}The journey
Send journey steps
POST /v1/steps
A batch of up to 500 steps, gzip (Content-Encoding: gzip) or plain JSON, at most 2 MiB as sent. Each step stands alone: a bad one is refused by its index, the rest are kept.
The SDK: php artisan mybeast:sessions-flush.
curl -X POST https://services.my-beast.com/sessions/v1/steps \
-H "Authorization: Bearer $MYBEAST_SESSIONS_SECRET" \
-H "Content-Type: application/json" \
-d @body.json{
"steps": [
{
"id": "6f1c2a7e-3b9d-4c1e-9a52-0d7e4b8f1c23",
"subject": "42",
"account": "7",
"subject_since": 1790000000000,
"environment": "production",
"visit": "srv-3f9a1c0b7d2e4a68",
"recording": null,
"at": 1793520000000,
"kind": "save",
"route": "projects.store",
"method": "POST",
"status": 302,
"duration_ms": 84,
"fields": null,
"page": "Projects/Create"
}
]
}Required in each step: id (a UUID: the same step sent twice is kept once), subject, environment, visit, at (Unix milliseconds) and kind: visit, save, refused, error or blocked. route is a route's name, never its URL; fields lists a refused write's field names, at most 20; request is the request's id for Logs. A step with a field Sessions doesn't know is refused.
202 {"accepted": 498, "dropped": 1, "refused": [{"index": 7, "reason": "…"}]}Replace the key flows
PUT /api/v1/flows
Every key flow of the project, replacing the ones there, all or nothing. A flow left out is retired; its runs are kept.
The SDK: php artisan mybeast:sessions-flows.
curl -X PUT https://services.my-beast.com/sessions/api/v1/flows \
-H "Authorization: Bearer $MYBEAST_SESSIONS_SECRET" \
-H "Content-Type: application/json" \
-d @body.json{
"flows": [
{
"slug": "add-project",
"name": "Add a project",
"give_up_after_hours": 24,
"new_account_days": null,
"steps": [
{ "key": "opened", "label": "Opened", "kind": "visit", "routes": ["projects.create"] },
{ "key": "saved", "label": "Saved", "kind": "save", "routes": ["projects.store"] }
]
}
]
}Up to 50 flows of 2 to 20 steps. A step's kind is visit, save or start (a first-run flow's first step, with no routes). Slugs and keys are 1 to 40 of a-z 0-9 -.
200 {"flows": 2}Record an objection
PUT /api/v1/subjects/{subject}/objection
The person objects to the journey: theirs is erased, and none is kept from now on.
The SDK: Sessions::objected($id).
curl -X PUT https://services.my-beast.com/sessions/api/v1/subjects/42/objection \
-H "Authorization: Bearer $MYBEAST_SESSIONS_SECRET"200 {"erased": 140}Lift an objection
DELETE /api/v1/subjects/{subject}/objection
The person's journey is kept again from now on.
The SDK: Sessions::objectionLifted($id).
curl -X DELETE https://services.my-beast.com/sessions/api/v1/subjects/42/objection \
-H "Authorization: Bearer $MYBEAST_SESSIONS_SECRET"204Erase a person's journey
DELETE /api/v1/subjects/{subject}/journey
Their steps, key flow runs and stuck point occurrences.
The SDK: Sessions::eraseJourney($id).
curl -X DELETE https://services.my-beast.com/sessions/api/v1/subjects/42/journey \
-H "Authorization: Bearer $MYBEAST_SESSIONS_SECRET"200 {"erased": 140}Erase an account's journey
DELETE /api/v1/accounts/{account}/journey
The account's steps, key flow runs and stuck point occurrences, whoever they were about. The stuck points stay, recounted.
The SDK: Sessions::eraseAccountJourney($id).
curl -X DELETE https://services.my-beast.com/sessions/api/v1/accounts/7/journey \
-H "Authorization: Bearer $MYBEAST_SESSIONS_SECRET"200 {"erased": 2210}In a batch's answer, dropped counts the steps of a person who objected, and refused names each step that will never be taken by its index, such as monthly-limit past the project's steps this month.
The browser's uploads
The recorder sends each chunk itself, with the public key and the page's token instead of a secret: POST /v1/parts/{recording}?key=pk_…&t=<token>&doc=<n>&seq=<n>. A chunk is at most 2 MiB as sent and 16 MiB unpacked, and a repeated chunk is stored once. The answers, and what the recorder does with each, are in the Browser SDK's reference.
Errors
| Status | Body | When |
|---|---|---|
| 401 | {"message": "unauthenticated"} | No server secret, or not this module's. |
| 402 | {"message": "…", "type": "…", "link": "…"} | The project's subscription has ended. |
| 404 | - | An id other than 1 to 64 of A-Z a-z 0-9 . _ : -. Nothing is kept under it. |
| 413 | {"refused": "too-large"} | /v1/steps: a batch too big, or more than 500 steps. The SDK halves it. |
| 422 | {"refused": "not JSON"} | /v1/steps: not a batch. Sending it again is refused again. |
| 422 | {"message": "flows.0: …"} | /api/v1/flows: a flow that doesn't fit. Nothing changed. |
| 429 | - | Too many requests: 120 a minute per secret on /api/v1, 1,200 a minute on /v1/steps. |
A 5xx or no answer means Sessions didn't confirm: try again later. The SDK's erasing calls throw then, so a queued job retries them.