Laver docs
Open Laver
Workspaces and access

API keys#

An API key is a bearer token that lets a script, an integration or an agent work in one of your workspaces. You create keys for yourself — there is no way to mint a key that acts as somebody else.

You need an active membership of the workspace and a signed-in session. Any role can create a key, viewers included.

For what to do with a key once you have one, see the agent and API quickstart.

What a key is, and is not#

A key acts as its creating user, with exactly their access — no more and no less. Every request made with it re-runs the same membership, role and board-access checks your own session would. There is no separate permission model to keep in step.

That means:

  • A key made by a viewer is read-only. It gets the same 403 Your role in this workspace is read-only. you would.
  • A key made by a member reaches the boards that member reaches, and 404s on the rest.
  • If your role changes, your existing keys change with it, immediately. A key carries your current access, never the access you had when you made it.
  • A key is confined to the one workspace you name when you create it. It carries your access within that workspace only — a request against a board, ticket or workspace it was not made for gets a 403, even for a workspace you are an active member of with your own session. GET /workspaces through a key lists only that one workspace, not every workspace you belong to.
  • A key cannot create a new workspace or see invitations addressed to you — neither names a single workspace to check the key against, so both are refused outright rather than scoped.

Keys work on the board and ticket API — /workspaces, /boards and /tasks. They are not accepted on /profile, /admin, /billing, /wikis, /wiki-pages, /notifications or /auth, all of which take a session token only. In particular:

  • A key cannot mint further keys. Key creation lives under /profile, which refuses keys, so a leaked key can never be used to manufacture more.
  • A key cannot administer the workspace. No inviting, no role changes, no revoking other people's keys, no billing.

Create a key#

The secret is shown once, in the response to the call that creates it. Only a hash is stored, so it cannot be shown again. If you lose it, revoke it and make a new one.

bash
curl -X POST https://api.laver.app/profile/api-keys \
  -H "Authorization: Bearer <your-session-token>" \
  -H "Content-Type: application/json" \
  -d '{
        "workspace_uuid": "11111111-2222-4333-8444-555555555555",
        "name": "nightly triage bot"
      }'
json
{
    "api_key": {
        "uuid": "66666666-7777-4888-8999-000000000000",
        "workspace_uuid": "11111111-2222-4333-8444-555555555555",
        "name": "nightly triage bot",
        "token_hint": "laver_Ab3xQ9",
        "last_used_at": null,
        "created_at": "2026-01-01T09:00:00.000Z"
    },
    "token": "laver_..."
}

Copy token straight into your secret store. token_hint is the first few characters, kept so you can tell your keys apart in a list — it is far too little to use.

Give the key a name that says what it is for. When something goes wrong, the name is what tells you which key to revoke.

List your keys#

bash
curl https://api.laver.app/profile/api-keys \
  -H "Authorization: Bearer <your-session-token>"

Returns your live keys across every workspace you are still an active member of, newest first, each with its workspace, name, hint and last_used_at. Secrets are never returned. last_used_at is what makes a key safe to revoke: a key that has never been used, or has not been used in months, is one you can retire without guessing.

Delete a key#

bash
curl -X DELETE https://api.laver.app/profile/api-keys/66666666-7777-4888-8999-000000000000 \
  -H "Authorization: Bearer <your-session-token>"

Revocation is immediate — the very next request made with that key answers 401 {"error": "That API key is not valid or has been revoked."}. It cannot be undone, and it cannot be reversed by recreating a key with the same name.

You can only delete your own keys this way. An owner or admin can revoke any key in their workspace from Admin → API keys, which also lists every key with the person it belongs to.

Ten keys per workspace#

You may hold ten live keys in a single workspace. The eleventh is refused:

json
{
    "error": "You already have 10 keys in this workspace. Revoke one first."
}

The status is 409. Revoked keys do not count, so retiring one frees the slot immediately. The cap is per workspace, so belonging to three workspaces means up to ten keys in each.

What stops a key working#

Event Effect on the key
You delete the key Dead immediately
An owner or admin revokes it Dead immediately
The person it belongs to is deactivated All of their keys in that workspace stop working
The person it belongs to is removed from the workspace Same — all of their keys there stop working
The workspace is deleted Memberships are deactivated, so the keys stop
That person's role is changed Key keeps working, with the new role's access
That person changes their password or signs out everywhere Key keeps working

The deactivation rule is the important one: switching someone off in Admin → People stops their agents with them, in one action, without hunting for keys. It is the offboarding step that matters most.

The last row is the counterpart, and it surprises people: "log out everywhere" ends sessions. A key is not a session, so it survives. Revoke keys explicitly.

Keep the secret secret#

A key is a password that does not expire and belongs to a person. Treat it like one.

Never put a key into:

  • a support ticket, a bug report or an issue description
  • a comment on a ticket, or a wiki page
  • a log line, a stack trace, an error report or an analytics event
  • a screenshot, a screen recording or a shared terminal session
  • a commit, a config file in version control, or a CI job's plain-text variables
  • a chat message, "just for a second"

Instead: put it in a secret manager or an environment variable, pass it only in the Authorization header, and redact anything beginning laver_ before you paste output anywhere. Support will never ask you for a key — if anyone does, that is the whole of the reason not to send it.

Note that requests made with a key share a rate-limit budget by source address rather than getting their own per-user budget, so several noisy agents behind one address can throttle each other.

If a key leaks#

Assume it is being used. Do this in order:

  1. Revoke it nowDELETE /profile/api-keys/<api-key-uuid>, or Admin → API keys if it belongs to someone else or they are unavailable. Revoking is instant and cheap; there is nothing to weigh up.
  2. Issue a replacement and deploy it to whatever was using the old key. Do this after revoking, not before — a leaked key that is still live while you tidy up is the risk.
  3. Check what it could reach. A key holds its owner's whole access: their role and their boards in every workspace they are a member of, not only the one the key names. That is the blast radius — work it out from the owner's memberships, not from the key.
  4. Check the audit log (Admin → Audit log) around the time of the leak. Key creation and revocation are both recorded, so an unfamiliar api_key.created entry is worth investigating.
  5. If you cannot reach the key's owner, deactivate them in Admin → People. That stops every key they hold in the workspace at once.
  6. Scrub the place it leaked — edit the comment, rotate the log, delete the screenshot. Do this last: it never substitutes for revoking, because you cannot know who already read it.