5-step quickstart
Sign up, register a stream, watch the first probe land

Five steps,
to a watched stream.

Walk a copyable curl through sign up, key mint, stream registration, and live confirmation — and land on the protected /app/streams.

You need a working HLS or DASH manifest URL for step three.
Every step after sign in reuses the same session cookie.
The raw API key in step two is shown once — copy it then.
Quickstart steps
Step 01Auth

Create an account & sign in

Sign up through the UI at /sign-up or POST to /api/auth/sign-up/email. Better-auth sets a better-auth.session_token cookie on the response. Every call in steps 2–4 includes it via -b.
POST /api/auth/sign-up/email — run from your terminal
curl -X POST https://streamwake.polsia.io/api/auth/sign-up/email \
  -H "content-type: application/json" \
  -d '{
    "name": "Your Name",
    "email": "you@example.com",
    "password": "choose-a-strong-password"
  }'
200 Response — sets better-auth.session_token cookie
{
  "user": {
    "id": "ckq3xuserabc123",
    "name": "Your Name",
    "email": "you@example.com",
    "emailVerified": false,
    "createdAt": "2026-08-04T18:21:02.000Z",
    "updatedAt": "2026-08-04T18:21:02.000Z"
  },
  "token": "set-as-better-auth.session_token-cookie",
  "note": "Set-Cookie: better-auth.session_token=<opaque>; HttpOnly; SameSite=Lax"
}

Already have an account? The same cookie comes from POST /api/auth/sign-in/email — re-issue the session any time it expires.

Step 02Authorize

Mint an API key

After sign in, POST to /api/v1/keys with the cookie from step one. The handler returns the raw swk_… key once in the 201 response. What we persist is the sha256 hash — copy the raw key now or start over.
POST /api/v1/keys — requires session cookie from step 1
curl -X POST https://streamwake.polsia.io/api/v1/keys \
  -H "content-type: application/json" \
  -b "better-auth.session_token=<your-session-cookie>" \
  -d '{ "label": "Production web player" }'
201 Response — rawKey is shown once
{
  "id": "ckq3xkeyabc123",
  "label": "Production web player",
  "rawKey": "swk_<your-raw-key>",
  "createdAt": "2026-08-04T18:21:02.000Z"
}
Step 03Write

Register a stream

POST the manifest URL you want monitored. The handler validates it against the SSRF guard, then idempotently upserts by sourceUrl — re-posting the same URL returns the existing record instead of 409. Same session cookie as steps 1–2.
POST /api/v1/streams — idempotent on sourceUrl
curl -X POST https://streamwake.polsia.io/api/v1/streams \
  -H "content-type: application/json" \
  -b "better-auth.session_token=<your-session-cookie>" \
  -d '{
      "sourceUrl": "https://example.com/manifest.m3u8"
    }'
201 Response — StreamItem (note the id, used in step 4)
{
  "id": "ckq3xstreamabc123",
  "sourceUrl": "https://example.com/manifest.m3u8",
  "name": "Primary CDN — eu-west",
  "targetRegion": "eu-west",
  "createdAt": "2026-08-03T18:24:11.000Z",
  "agentState": "healthy",
  "status": "watching",
  "lastAction": "registered",
  "lastCheckedAt": null,
  "uptimePct": 100
}
Step 04Read

Confirm the stream is being watched

GET the id from step three with the same cookie. The uptimePct field is computed server-side from the last 24 hours of probes — right after registration it reads 100 (no failures observed yet).
GET /api/v1/streams/<id> — with the id from step 3
curl https://streamwake.polsia.io/api/v1/streams/ckq3xstreamabc123 \
  -b "better-auth.session_token=<your-session-cookie>"
200 Response — StreamStatus
{
  "id": "ckq3xstreamabc123",
  "sourceUrl": "https://example.com/manifest.m3u8",
  "agentState": "healthy",
  "uptimePct": 100,
  "lastAction": "registered",
  "lastCheckedAt": "2026-08-03T18:25:00.000Z"
}
Programmatic confirmation — or check the agents feed
GET /api/v1/agents
curl https://streamwake.polsia.io/api/v1/agents \
  -b "better-auth.session_token=<your-session-cookie>"
200 Response — AgentEventList
{
  "items": [
    {
      "id": "ckq3xprobe123",
      "streamId": "ckq3xstreamabc123",
      "sourceUrl": "https://example.com/manifest.m3u8",
      "streamName": "Primary CDN — eu-west",
      "severity": "info",
      "anomalyClass": "no anomaly",
      "fix": "registered",
      "action": "no action needed — stream healthy",
      "createdAt": "2026-08-03T18:25:00.000Z",
      "latencyMs": 142
    },
    {
      "id": "ckq3xprobe124",
      "streamId": "ckq3xstreamdef456",
      "sourceUrl": "https://backup.example.com/manifest.m3u8",
      "streamName": "Backup CDN — eu-west",
      "severity": "warn",
      "anomalyClass": "slow response",
      "fix": "raised the latency budget and re-probed to confirm the trend",
      "action": "raised the latency budget and re-probed to confirm the trend",
      "createdAt": "2026-08-03T18:25:00.000Z",
      "latencyMs": 1840
    }
  ]
}
or check the agents feed →
Step 05Operate

Continue in the dashboard

The streams dashboard at /app/streams polls /api/v1/streams every 5 seconds with the same session. If the route bounces you to /sign-in, repeat step one — the session cookie is missing or expired.
Continue in dashboard → /app/streams

Auth-gated — sign in completes the loop.

Next steps

You have the loop.
Now operate it.

The page you land on in step five

Streams dashboard

Every registered stream, its current state, and the last action the agent took. Polls every 5 seconds.

Open /app/streams
Live observations

Agents feed

The latest probes, severity, latency, and the action the agent took — the same surface exposed at GET /api/v1/agents.

Open /app/agents

Want the API in one place?

The reference is on its own page — three endpoints, exact shapes, copy-paste curls.

Open the API reference