Authentication
Writ has two credentials, held by two different parties. The API key says which tenant is asking. The sponsor token says a human approved this. Most integrations only ever touch the API key; the sponsor token belongs to the human in the loop.
API keys
An API key looks like writ_... and belongs to a tenant. It authorizes:
POST /v1/check— the commit-time decisionPOST /v1/tokens/verify— auth token validationGET /v1/policy,PUT /v1/policy— the tenant’s verb policyGET /v1/me— tenant and key identityGET /v1/receipts*— reading, streaming, and verifying the audit logPOST /v1/tenant/invites— team invite codes
Issue one with no auth at all:
The first key for an email creates the tenant and returns the
tenant’s sponsorToken — shown exactly once, never recoverable. Save it
immediately; there is no “resend my sponsor token.” Later keys for the
same email (or keys issued via an invite code) join the existing tenant
and do not return a sponsor token.
Then call the API:
Key issuance is rate-limited to 10 keys per hour per client IP.
Sponsor tokens
A sponsor token looks like writ_sp_... and belongs to the tenant’s
human. It authorizes the human-approval half of the product:
POST /v1/grants— approve one write (the STEP_UP flow)POST /v1/revoke— the kill switchPOST /v1/reinstate— undo a revocationGET /v1/revoked— the kill-switch roster
It goes in the same Authorization: Bearer header, on those endpoints
only. API keys are rejected there and sponsor tokens are rejected
everywhere else — the two credentials do not substitute for each other.
Treat the sponsor token like a password: it can approve money movement and revoke agents. Store it in a secret manager, never in code or chat logs.
Tenants and teams
A tenant is the isolation boundary: one audit log, one policy, one set of revocations. A key only ever sees its own tenant’s receipts — there is no cross-tenant read path, and a foreign receipt ID is indistinguishable from a missing one.
To add teammates, create an invite code with your API key:
Teammates pass the code as inviteCode to POST /v1/keys and land in
your tenant. Creating a new code rotates the old one. Joining members
never receive the sponsor token — there is one human credential per
tenant, issued at creation.
The keyless sandbox
No signup, no key: POST /v1/sandbox mints a 90-second grant, but only
for verb: "demo_write" on targets starting with demo-. It’s the
trial loop — prove the intercept works, then issue a real key for real
verbs.