Skip to content

REST API

The public API is served by a Cloudflare Worker at https://api.clawmobile.cloud. All /api/* routes require a bearer token; /auth/* issues them.

Auth

POST /auth/signup

Request a magic link. Body: { "email": string, "invite_code?": string }. While invites are required, a valid invite_code must be supplied. In dev (no email provider configured) the response includes magic_token directly.

GET /auth/verify?token=<magic_token>

Exchange a magic-link token for credentials. Returns { "access_token": string, "refresh_token": string }.

POST /auth/refresh

Body: { "refresh_token": string }{ "access_token": string }.

Sessions

POST /api/sessions

Allocate a device and start a session. Subject to rate limits (1 active session, 5 per hour). Returns a SessionResponse with id, status, and stream_url.

GET /api/sessions/:id

Fetch a session’s current state.

DELETE /api/sessions/:id

End a session. Skills sync to R2, the container is destroyed, the workspace is wiped.

GET /api/sessions/:id/stream

Server-Sent Events for allocation + lifecycle progress (redroid_startingadb_handshakegateway_startingactiveended / error).

Skills

GET /api/skills

List your skills. Returns { "skills": SkillIndex[] }.

GET /api/skills/:name

Skill detail: { "skill": SkillIndex, "versions": SkillVersion[], "runs": EvalRun[] }.

GET /api/skills/:name/share

Generate a presigned, time-limited share URL: { "url": string, "expires_in": number }. Returns 503 if sharing isn’t configured.

Account

GET /api/account/me

Your profile (never includes the API key hash).

PATCH /api/account/me

Update display_name, recording_opt_in, or session_timeout_min.

POST /api/account/me/api-key

Generate (or regenerate) your API key. The plaintext key is shown once in the response — store it immediately.

Errors

Errors are JSON: { "error": string, "code?": string } with a conventional HTTP status (401 unauthenticated, 403 forbidden, 404 not found, 429 rate limited, 503 capacity/feature unavailable).

Next: FAQ