> 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.

# Dashboard

> The web portal for usage, principals, API keys, policy, receipts, revocations, and billing.

The tenant portal at [app.withwrit.com](https://app.withwrit.com) is the web
UI for everything the CLI does, minus the typing. (The older
`https://api.withwrit.com/dashboard` address keeps working.)

**Signing in.** Enter your email and Writ emails you a one-time link (it
works once and expires in 15 minutes). Opening it signs you in for 24
hours and lands you on the portal overview; **Sign out** ends the
session. No password, and no API key pasting. If the session expires, the
portal asks you to sign in again. Teammates who joined with an invite
code can use **Use an API key instead** (the key is kept in that tab
only). The sign-in page never says whether an email already has an
account — that is deliberate, so addresses can't be probed.

**Signing up.** No account yet? Enter your email on the sign-in page and
the email you receive is a **create-your-account** link instead of a
sign-in link. Clicking it is the confirmation: your tenant is created at
that moment (typing the address alone never creates anything), and you
land on a **Welcome to Writ** screen showing your API key and sponsor
token **exactly once** — save them before entering the portal. Writ stores
only hashes, so lost credentials can't be re-shown; you can always mint
new keys on the API keys page. Prefer the API? Create the tenant directly
with `POST /v1/keys` and your email (see [Quickstart](/quickstart));
then sign in with that email.

What's in it:

* **Overview** — the last 24 hours at a glance (receipts, allowed, denied,
  step-up, revoked; from `GET /v1/receipts/stats`), recent activity, and
  receipts used this month against the free tier (10,000/month).
* **API keys** — every key on the tenant (name, prefix, principal, created,
  last used, and how many receipts its checks wrote).
  **Create key** shows the new key exactly once; **Revoke** disables a key
  immediately (agents using it get `401`). Writ only ever stores a hash.
  Team invite codes live here too.
* **Principals** — the tenant's identity directory: create, rename,
  disable/enable, and delete principals; revoke all of a principal's keys
  in one click. Every change is written to the audit log.
* **Policy** — set per-verb modes (`allow`, `deny`, `require_grant`,
  `step_up`). Each change saves immediately and applies to the next check.
  Verbs without an explicit mode always fall back to `require_grant`.
  Tabs switch between the tenant default and the `dev` / `staging` / `prod`
  environment overrides; editing an environment tab changes only that
  environment's override, and verbs it doesn't set inherit the default
  (marked "inherited"). See [Policies](/policies).
* **Audit log** — the tamper-evident receipt log (latest receipts), live by
  default, with decision filters, search, expandable receipt detail
  (target, purpose, reason, grant, chain hash and previous hash), and
  **Verify chain** to check the hash chain end to end.
* **Revoked** — principals under the kill switch. Read-only for a signed-in
  session: revoking and reinstating needs the tenant **sponsor token**
  (paste it per action, or use `writ revoke`), so a browser session alone
  can't flip the kill switch.
* **Billing** — current plan (Free, or Metered once a card is on file),
  free-tier meter, billing status, and whether a payment method is on
  file. **Upgrade to metered** / **Manage payment method** opens Stripe's hosted billing
  portal (card details never touch Writ); Stripe returns you to the portal,
  which confirms the card and lifts the `402 payment_required` gate.

Anything the portal can do, the API and CLI can do — it's a convenience
layer, not a separate system. Grants and revocations still require the
sponsor token.