Record a session-replay snapshot batch
Accepts a batch of rrweb events from a browser recorder and hands it to the session-replay pipeline, which stores the recording and derives the session…
POST /v1/event/replay
| Address | https://api.hanzo.ai/v1/event/replay |
| Method | POST |
| Operation | post_event_replay |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Accepts a batch of rrweb events from a browser recorder and hands it to the session-replay pipeline, which stores the recording and derives the session summary a player reads back.
ONE REQUEST IS ONE BATCH, and it is all-or-nothing: the recording is made durable before this answers, so a 200 {"accepted":1} means stored and never "buffered somewhere". There is no partial count, because a half-written recording is not a recording.
sessionId is REQUIRED and bounded — at most 70 characters of ASCII letters, digits or '-'. It is the key every batch of one visit is grouped and ordered by, so an id outside that grammar is refused 400 here rather than accepted and dropped further down. windowId separates two tabs of one session and distinctId attributes the recording to a person; both are optional. events is the rrweb batch, each element a raw eventWithTime object, carried VERBATIM — the summary (click, keypress and mouse-activity counts, size) is derived downstream from exactly these bytes, so nothing is re-encoded or dropped.
THE CALLER'S CREDENTIAL DECIDES THE TENANT, and the body never does: the recording lands in the org the presented credential resolves to. It takes the SAME credentials as /v1/event — a validated bearer, an org API key, or a publishable pk- key on Authorization: Bearer, x-hanzo-ingest-key or ?ingest_key= — so a browser bundle already holding a pk- for events needs nothing new to record. A caller that presents nothing is 401 ingest_key_required; one whose key resolves to no project is 403 ingest_key_unknown; a reduced principal (a Hanzo Team workspace token) is 403 insufficient_capability, because a full-fidelity screen recording has no projected form that is safe for a guest to write into a host org.
BOUNDS: 413 over 512 KiB of body, and that is the only bound on one batch — a recorder is expected to chunk a long session rather than send it whole, and the cap is the size one message can carry rather than an arbitrary number. 503 when the pipeline cannot take the batch: honest unavailability the caller can retry, never a 200 over a discarded recording.
Request
4 fields, body application/json.
| Field | In | Type | Required | Description |
|---|---|---|---|---|
distinctId | body | string | — | |
events | body | any[] | — | |
sessionId | body | string | — | |
windowId | body | string | — |
Response
| Status | Body | Meaning |
|---|---|---|
2XX | CaptureResult | Success |
2XX body — 2 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
accepted | body | integer | — | |
dropped | body | integer | — |
Failure carries the platform error shape — see Errors.
Examples
hanzo has no subcommand for this operation — the CLI serves only what cloud's live route table confirms. Use HTTP or an SDK.
import { Configuration, EventApi } from 'hanzoai';
const api = new EventApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postEventReplay({ distinctId: "<distinctId>", events: ["<events>"] });from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import EventApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = EventApi(client).post_event_replay(distinct_id="<distinctId>", events=["<events>"])cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.EventAPI.PostEventReplay(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, event_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = event_api::post_event_replay(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.EventApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new EventApi(client).postEventReplay();The method above is the one at the current release of the document. [email protected] (npm) and [email protected] (PyPI) were generated from an earlier release, where this operation carried a different id, so it spells the method differently — regenerating the clients is what makes the two agree. SDKs →
curl -X POST https://api.hanzo.ai/v1/event/replay \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"distinctId": "<distinctId>",
"events": [
"<events>"
]
}'The door declares no tool for event — tools/list on https://api.hanzo.ai/v1/mcp names the products it does reach. Use HTTP or an SDK.
How is this guide?