# QR Agent > QR Agent management API. A QR code encodes an opaque URL on our own domain; the content behind it is encrypted at rest with per-tenant envelope encryption and is never public. A viewer must be signed in and authorized, or pass a private access gate (magic link, PIN, or email OTP). The one exception is the deliberate `public` access mode, which drops the gate for that code only -- encryption at rest and tenant isolation still apply. When a request is ambiguous the API fails closed and reveals nothing. Authentication: API key only on `/api/v1`, sent as `Authorization: Bearer sk_...`. Scopes are `qr:metadata:read`, `qr:content:read`, `qr:create`, `qr:update`, `qr:archive`, `analytics:read`, `audit:read`, `access:request`. A key minted before the action scopes existed carries the legacy pair `read` and `write` instead, which expands into them at request time; `qr:content:read` is deliberately outside that expansion, so an older key never gained plaintext access. The session cookie used by the dashboard is not accepted on `/api/v1`, and an API key is not accepted anywhere else -- the two never overlap. Errors: every `/api/v1` failure is a flat JSON object with a stable `code` from a closed set of 83. Branch on `code`, never on `message`. Retry only when `retryable` is true. Lists are paginated: pass `cursor` from a previous response's `next_cursor` until `has_more` is false. Do not parse a cursor; it is signed and bound to the tenant and filters it was issued under. API v1 endpoints, by resource: - **QRs** -- QR code lifecycle: create, read, update, archive, and download the QR image. - `GET /api/v1/qrs`: List QR codes - `POST /api/v1/qrs`: Create a QR code - `DELETE /api/v1/qrs/{id}`: Delete (archive) a QR code - `GET /api/v1/qrs/{id}`: Get a QR code - `PATCH /api/v1/qrs/{id}`: Update a QR code - `GET /api/v1/qrs/{id}/content`: Read the content behind a QR code - `GET /api/v1/qrs/{id}/image`: Get QR image - `POST /api/v1/qrs/search`: Search QR codes - **Access Links** -- Magic-link tokens that grant time-limited gate access to a QR without requiring the viewer to log in. - `POST /api/v1/qrs/{qr_id}/access-links`: Create an access link (magic link) - `DELETE /api/v1/qrs/{qr_id}/access-links/{id}`: Revoke an access link - **Bulk** -- Queued actions across up to 1000 QR codes at once. Every job returns 202 with an id; poll it for per-item results. A partial failure never rolls back the items that succeeded. - `GET /api/v1/bulk`: List bulk jobs - `POST /api/v1/bulk`: Queue a bulk action - `GET /api/v1/bulk/{id}`: Get a bulk job - `POST /api/v1/bulk/{id}/cancel`: Ask a bulk job to stop - `GET /api/v1/bulk/{id}/download`: Get an export download URL - **Meta** -- Unauthenticated contract endpoints: the specification and the error catalogue. - `GET /api/v1/errors`: The machine-readable error catalogue - **Delegations** -- Short-lived on-behalf-of tokens. Mint one from your API key before handing work to an agent: it carries a subset of the key's scopes, optionally a single QR code, and an expiry of at most one hour. Policy is re-checked on every request, so revoking or narrowing the parent key takes effect immediately on every token minted from it. - `GET /api/v1/delegations`: List delegations - `POST /api/v1/delegations`: Mint a short-lived on-behalf-of token - `DELETE /api/v1/delegations/{id}`: Revoke a delegation - **Deliveries** -- Give a verified recipient access to a QR without ever holding an access secret yourself. You name a recipient reference the workspace has already verified; the server mints the link, binds it to that mailbox, and emails it. You receive a status and a revocation handle. This is the endpoint a delegated token must use -- POST /qrs/{qr_id}/access-links is refused for one, because a magic-link URL in a response body IS a bearer credential. - `GET /api/v1/deliveries`: List deliveries - `DELETE /api/v1/deliveries/{id}`: Revoke a delivery - `POST /api/v1/qrs/{qr_id}/deliveries`: Deliver access to verified recipients - **Reports** -- Read-only, aggregate reports (kt1m7). Every response is metadata-only by shape: no field on these types can carry a viewer identity, an IP, a user-agent, a referer or a request URL. - `GET /api/v1/folders`: List folders - `GET /api/v1/jobs`: List recent bulk jobs - `GET /api/v1/qrs/{id}/analytics`: Read scan analytics for one code - `GET /api/v1/reports/capabilities`: Read what the reporting surface will and will not answer - `GET /api/v1/usage`: Read usage against plan limits ## Contract - [OpenAPI specification](https://getqragent.com/api/v1/openapi.json): the authoritative machine-readable contract. Start here; it supersedes anything on this page. - [Error catalogue](https://getqragent.com/api/v1/errors): the closed set of 83 error codes, served as JSON. - [API catalog](https://getqragent.com/.well-known/api-catalog): RFC 9727 discovery document pointing at the above. ## Docs - [Rules of engagement for an agent](https://getqragent.com/agents.md): READ FIRST. Preconditions, what is refused, how to read a failure, and when to stop. - [Features](https://getqragent.com/features.md): what the product does, in prose. - [For AI agents](https://getqragent.com/ai-agents.md): the human-facing page -- each claim mapped to the control that enforces it, and what it deliberately does NOT protect. - [Security model](https://getqragent.com/security.md): the encryption and access model in detail. - [Pricing](https://getqragent.com/pricing.md): plans, quotas and what each tier includes. - [Changelog](https://getqragent.com/changelog.md): what shipped and when. ## Optional - [FAQ](https://getqragent.com/faq.md): common questions, none of them contractual. - [Terms](https://getqragent.com/terms.md) and [Privacy](https://getqragent.com/privacy.md): the legal pages. - [Contact](https://getqragent.com/contact.md): support, for anything this file does not answer. Canonical location: https://getqragent.com/llms.txt