# Reapption > Reapption records a human's video reaction to a video. For AI agents it is a proof-of-human-attention API: send a payload video, hand the returned single-use link to a human you already reach, and get back their recorded reaction (video + capture metadata) by webhook or polling. Self-serve registration, free during early access. Reapption verifies capture (a fresh reaction was recorded against your task), not sincerity or payment. Plain HTTP + JSON; there is no MCP server. Auth is `X-Agent-Key: agt_…` (or `Authorization: Bearer agt_…`). Every error is JSON `{"code": "…", "error": "…"}` (branch on `code`); a wrong method is `405` with `Allow`; CORS is open; every timestamp is ISO 8601 UTC; every 429 carries `Retry-After`. Base URL: https://reapption.net Any HTTP client works on the agent paths, including Python's default `urllib` User-Agent. ## Docs - [Agent API guide (markdown)](https://reapption.net/docs/agent-api): registration, task flow, webhooks, errors, limits. Also served at /api/agent/docs. - [OpenAPI 3.1 spec](https://reapption.net/openapi.json): every agent endpoint with request/response schemas. - [Landing page](https://reapption.net/agents): what it is for, in human terms. ## Quick start 1. `POST /api/agent/challenge` -> answer the question -> `POST /api/agent/register` -> store `api_key` + `webhook_secret` (shown once). 2. `GET /api/agent/me` with `X-Agent-Key: ` -> confirms the key, shows quota. Billing: everything is free for now. `GET /api/billing/plans` is the price list; `GET /api/agent/billing` shows your plan, credits and limits; `POST /api/agent/billing/checkout` {"plan"|"pack"} returns a Stripe checkout_url for a human to pay. Failed tasks never count, and credits come back for failed or expired tasks. 3. Smoke-test with no human: `POST /api/agent/tasks` JSON `{"sandbox": true, "webhook_url": "https://you.example/hook"}` -> completes itself in ~5 s, fires a signed webhook, never billed. 4. Real task: multipart `POST /api/agent/tasks` with field `payload` (video), **or** JSON `{"payload_url": "https://…/clip.mp4"}` if your tools can't send a file (Reapption downloads it: https only, public host, ≤ 100 MB, must be a video) -> send `react_url` to your human -> webhook or `GET /api/agent/tasks/{id}` until `ready`. ## Key and task management - `GET /api/agent/tasks?status=pending,ready`: list your tasks (recover a lost task_id or react_url). - `POST /api/agent/rotate-key`: new key; old one valid `grace_seconds` (default 60, 0 = immediately). - `POST /api/agent/revoke`: permanently disable the agent and expire its pending links. - `GET /api/agent/tasks/{id}/receipt`: Ed25519-signed receipt (JWS) for a ready task — task, agent, captured_at, duration, video_sha256, the human's answer — verifiable offline with `/.well-known/jwks.json`. - `question` (+ optional `choices`) on task create: the human must answer after watching; the answer returns with the reaction, the webhook and the receipt. - `payout_address: "optional"|"required"` on task create: the capture page asks for an EVM payout address (EIP-55 checked; a typo is a 400 and the link stays usable). It returns checksummed in the task, the webhook and the signed receipt. Reapption never sends funds; pay on the server-measured `duration_ms` vs `payload_duration_ms`, not on client-reported capture fields. - Campaign links (one link, many people): `POST /api/agent/campaigns` with the same payload inputs as a task plus required `max_reactions` (1-1000) -> post the returned `url` (`https://reapption.net/c/`) anywhere. Each reaction becomes its own single-use task as it arrives (one quota unit each; an unused campaign costs nothing), carrying `campaign_id` in the task, webhook and receipt. `dedupe` (default on) allows one reaction per `payout_address`, so `payout_address` defaults to `required`. TTL defaults to 6 h. `GET /api/agent/campaigns/{id}` lists every reaction with its receipt; `PATCH` changes `max_reactions`; `POST …/close` stops it. Anyone with the URL sees the payload, and an address is not an identity. - Webhook tools: `POST /api/agent/webhooks/test {"url"}` sends your receiver a signed test body (use it before a human reacts; 403 = wrong secret on your receiver). `GET /api/agent/webhooks` and `GET /api/agent/tasks/{id}/webhooks` show every delivery attempt (status, error, reply excerpt; 30 days). `POST /api/agent/tasks/{id}/webhook/replay` re-sends one. `GET /api/agent/tasks/{id}` carries a `webhook` summary. - `GET /api/agent/campaigns/{id}/receipt`: one Ed25519-signed settlement receipt over every ready reaction in a campaign. `GET /api/agent/campaigns/{id}?status=failed` filters reactions. `GET /api/agent/address/check?address=` returns the EIP-55 form or the capture page's 400. `react_url` stays on a task after use, with `react_link_state` (pending|used|expired). ## Task lifecycle `pending -> recorded -> ready`, or terminal `expired` (no reaction before the TTL) / `failed` (processing error). Webhooks fire on `ready` and `failed`, signed `X-Reapption-Signature: sha256=HMAC-SHA256(webhook_secret, raw body)`. A ready reaction stays retrievable for 7 days. The reaction object carries `file_size` and `sha256` of the exact file `reaction_url` serves — verify before acting. Media is served from reapption.net (Range supported): the given `reaction_url` is a signed 1 h link needing no header; the same path without the query works with your key. On `GET /api/agent/tasks/{id}` the media sits under a nested `reaction` object (`reaction.reaction_url`, `reaction.sha256`, …); only the webhook body is flat (`reaction_url`, `reaction_sha256`, `reaction_file_size`). A ready task also carries `receipt_url` (its signed receipt) and `capture`: `capture.server` is the server-measured half, and it is `null` on a sandbox task, which no human submitted, so a `null` there is expected. ## Limits Free while in early access. 100 real tasks + 200 sandbox tasks per agent per rolling 24 h (`GET /api/agent/me` shows what's left); 100 MB per video; signed media URLs last 1 h.