> Call POST /v1/check before a tool that writes. DENY means do not invoke the tool. For clean Markdown of any page, append .md to the page URL. For the complete index, fetch https://docs.withwrit.com/llms.txt.

# Permissions infrastructure for AI agents.

> Put a policy gate in front of your agent's dangerous actions in 15 minutes. Call Writ before a write tool — DENY means do not run the tool.

# Permissions infrastructure for AI agents.

Writ sits between your AI agent and the writes it wants to make — refunds,
provisions, deploys, emails, anything that changes state. Before the write
runs, the agent asks Writ: **may this agent fire this action, for this
purpose, with this sponsor?** The answer is `ALLOW`, `DENY`, or `STEP_UP`
(human approval required). Every answer is written to a tamper-evident audit
log as a receipt.

Three objects make up the whole product: a **principal** (who is acting and
why), a **decision** (allow, deny, or step up, bound to the exact write),
and a **receipt** (the audit record). Read [Concepts](/concepts) for the
full picture.

## For AI agents

You are about to invoke a tool that writes. Call Writ first.

If the decision is **DENY**, do not invoke the tool. Tell the user the write was refused and a receipt exists.

If the decision is **ALLOW**, invoke the tool once. The grant is spent.

If the decision is **STEP_UP**, do not invoke the tool. Tell the user a human sponsor must approve this write. The sponsor mints a grant, then you call `POST /v1/check` again.

---

## Get a key

You need two credentials, and they do different jobs:

* **API key** (`writ_...`) — identifies the tenant. The agent uses it for
  every call: checks, receipts, policy reads.
* **Sponsor token** (`writ_sp_...`) — identifies the human. It approves
  grants and revokes principals. Shown **once** when the tenant is created;
  it is never recoverable and never stored by Writ.

The fastest path is the CLI:

```bash
curl -fsSL https://api.withwrit.com/writ -o writ
chmod +x writ
./writ key --email you@company.com
```

That prints your API key and, for a new tenant, your sponsor token. Store
the sponsor token somewhere safe — a password manager, not a chat log.

Joining a team instead? Get an invite code from a teammate and pass
`--invite-code writ_inv_...`. You get your own API key on their tenant.

## Your first decision

Prove the intercept before wiring anything real:

```bash
# No grant exists, so this is DENY. Stop here and read the receipt.
./writ check --key writ_KEY --sponsor YOU --agent YOU --verb demo_write --target demo-1 --purpose "try the gate"

# Mint a 90-second sandbox grant, then check again: ALLOW.
./writ sandbox --sponsor YOU --agent YOU --target demo-1 --purpose "try the gate"
./writ check --key writ_KEY --sponsor YOU --agent YOU --verb demo_write --target demo-1 --purpose "try the gate"
```

The sandbox grant matches only `demo_write` on a `demo-` target, for 90
seconds, once. Real verbs work the same way: `POST /v1/check` matches a
grant on five fields — sponsor, agent, verb, target, purpose. No match is
**DENY**. Do not run the write.

## Where next

* [Quickstart](/quickstart) — one path: key → DENY → sandbox → ALLOW → receipts → verify-chain, then wrap your first endpoint and scan your codebase.
* [Concepts](/concepts) — principals, decisions, receipts, policy modes,
  grants, the kill switch, tenants. Read this before designing an integration.
* [MCP server](/mcp-server) — give any MCP-compatible agent the 19 Writ tools,
  and have it instrument its own codebase.
* [Audit log](/audit-log) — live streaming, SIEM ingestion, hash-chained
  tamper evidence, verification.
* [GitHub App](/git-hub-app) — one-click scanner install for selected repos:
  every push and pull request scanned, results as a check run and in the portal.
* [CLI reference](/cli-reference) — every `./writ` command.
* [Dashboard](/dashboard) — the web UI at [app.withwrit.com](https://app.withwrit.com):
  usage, policy editor, team invites, live log, kill switch.
* [API reference](/api-reference) — the full endpoint reference. Paste your API key
  into **Authorize**; Fern keeps it in the browser.

## Pricing

**Free: 10,000 receipts a month, no card.** Enough to actually run an agent
against it. Every decision — ALLOW, DENY, STEP_UP — writes a receipt.

**Over that, it's metered: \$1 per 1,000 receipts.** Usage aggregates through the
month and Stripe bills you once. No subscription, no tiers to pick.

When the free tier runs out, `POST /v1/check` returns `402
payment_required` with a `portal_endpoint` (`/v1/billing/portal`). Open the
dashboard (sign in with a one-time link emailed to you), go to **Billing**,
and hit **Add payment method**. That opens Stripe's hosted portal, where the card goes on
file; Stripe sends you back to the dashboard, which confirms the card and
lifts the 402. Writ never touches card data.

Trying it is free two ways: the keyless sandbox demo (`./writ sandbox`)
proves the intercept with no signup, and the free tier needs no card.

**Enterprise is annual commit + volume**, priced on a call — the pilot's
receipt volume sets the commit size. Same meter: the audit log.
[hello@withwrit.com](mailto:hello@withwrit.com) to talk.