# Zero Regret Messaging — Agent API # http://zeroregretmessaging.com/llm.txt # OpenAPI spec: http://zeroregretmessaging.com/openapi.yaml ZRM creates self-destructing encrypted secrets. You send plaintext; we encrypt it, hand you a one-time URL, and permanently destroy the data the moment it is read (or when a timer expires). No accounts. No logs. No recovery. This file describes the programmatic API intended for use by AI agents and automated tools. --- ## 1. Create a Secret POST http://zeroregretmessaging.com/api/secrets Content-Type: application/json Accept: application/json ### Request body | Field | Type | Required | Default | Constraints | |---------------------|--------------|----------|---------|----------------------| | content | string | yes | — | 1–10 000 characters | | burn_after_reading | boolean | no | true | | | burn_after_seconds | integer|null | no | null | 5–86 400 seconds | | requires_passphrase | boolean | no | false | | | passphrase | string|null | no | null | 4–128 characters | | expires_at | string|null | no | null | ISO 8601 datetime | Fields not listed are ignored. ### Success — 201 Created { "url": "", "token": "<48-character access token>", "burn_after_reading": true, "expires_at": null } ### Error — 422 Unprocessable Content { "message": "The content field is required.", "errors": { "content": ["The content field is required."] } } ### Error — 429 Too Many Requests You may create at most 1 secret per IP address per 30 seconds. The response includes a Retry-After header with the number of seconds to wait. { "message": "Too Many Attempts." } --- ## 2. Retrieve a Secret GET http://zeroregretmessaging.com/api/secrets/{token} Accept: application/json Decrypts and returns the secret content. Reading a secret counts as a view; if burn_after_reading is enabled (the default) the secret is permanently destroyed immediately after this response is sent — it cannot be retrieved again. ### Passphrase-protected secrets Supply the passphrase as either: - Query parameter: ?passphrase=your-phrase - Header: X-Passphrase: your-phrase ### Success — 200 OK { "content": "", "content_type": "text", "burned": true } `burned: true` means the secret was destroyed as part of this response. `burned: false` means it still exists (e.g. burn_after_reading is off and views remain). ### Errors | Status | Meaning | |--------|------------------------------------------------| | 403 | Passphrase required but missing, or incorrect | | 404 | Token not found | | 410 | Secret has already been destroyed or expired | | 500 | Content corrupted (key rotation or corruption) | --- ## Behaviour notes - burn_after_reading (default true): the secret is destroyed on the first successful GET /api/secrets/{token} call. Plan accordingly — you get one shot. - burn_after_seconds starts counting from the moment of first retrieval, not from creation. Useful for a timed read window. - expires_at is a hard deadline. The secret is gone at that instant regardless of whether it has been read. - There is no way to list secrets or check whether a token exists without consuming a view. Treat the token as a one-time voucher. --- ## Examples ### Create and immediately retrieve (agent-to-agent handoff) # Step 1 — create TOKEN=$(curl -s -X POST http://zeroregretmessaging.com/api/secrets \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{"content":"the crow flies at midnight"}' | jq -r .token) # Step 2 — retrieve (destroys the secret) curl -s http://zeroregretmessaging.com/api/secrets/$TOKEN \ -H "Accept: application/json" | jq . ### Create with passphrase, retrieve with passphrase TOKEN=$(curl -s -X POST http://zeroregretmessaging.com/api/secrets \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{"content":"classified","requires_passphrase":true,"passphrase":"swordfish"}' \ | jq -r .token) curl -s "http://zeroregretmessaging.com/api/secrets/$TOKEN?passphrase=swordfish" \ -H "Accept: application/json" | jq .