API keys

Issue, scope, rotate and revoke the keys that let something outside the console drive an agent.

An agent API key is how something outside the console (your backend, a script, an MCP client) acts as an agent. Keys start with plak_, and each one is bound to exactly one agent.

A key is its agent, never more

The binding is the key's entire identity. A key can do exactly what its agent can do: the agent's roles, its org reach and its approval settings all apply, and nothing about the request can widen them. /agent/invoke takes no agent at all, because the key already decided which one runs.

That makes scoping simple. To give a system narrower reach, bind its key to a narrower agent. A key bound to a coordinator also reaches the sub-agents that coordinator hands work to; a key bound to a single agent reaches only that one.

Creating one

In your app, open App access › API keys and create a key. (The agent's own page lists its keys and links there with Manage keys.)

  • Agent. The agent it acts as.
  • Name. What it is for, such as "billing backend" or "support MCP client".
  • Approval. Inherit uses the agent's own approval settings. Force human approval halts every risky step made with this key, even when the agent would otherwise auto-approve. It can only tighten.
  • Expires in days. Optional. Without it, the key does not expire.

Copy the key when it is shown. Only a hash is stored, so it can never be displayed again. The list shows the key's public prefix, its status, when it was last used and when it expires.

Issuing a key needs the Issue API keys permission in your organization.

Keys belong on servers

An agent key can act on your data. It must never reach a browser, a mobile app or a public repository. If client software needs what the agent does, put your own backend in front of it.

Using one

Send it as a bearer token. The x-api-key header works too.

curl "$AUTHORIC_URL/$APP_UID/agent/runs" \
  -H "Authorization: Bearer $AGENT_KEY"

A key works only on its own app. Every failure to authenticate (missing, malformed, unknown, revoked, expired, a key for another app, or a key whose agent is disabled) is the same 401 API_KEY_INVALID, so the answer never reveals which.

Org reach for a key

If your app has organizations of its own, a key has an org reach too, and a call made with it acts within the overlap of the key's reach and its agent's. A new key's reach is none: until you set it, the key reaches only records that belong to you as the app's owner, even if its agent reaches every organization. Set it on the key's row under Org reach. See Where an agent can act.

Rotating

There are two ways, and they differ in whether anything breaks:

  • Without downtime: create a new key for the same agent, deploy it, then revoke the old one. Both work during the overlap.
  • Roll: replaces the key's secret in place, keeping its name, agent, posture and reach. The old secret stops working immediately, so everything holding it fails until it has the new one. Use it when a key may have leaked.

Revoking

Revoke ends a key on its next request; there is no cached grace period. A revoked key cannot be rolled back to life; create a new one instead. Disabling the agent stops all of its keys at once.

What a key cannot do

A key is the least-trusted way into an agent.

  • It cannot approve or continue its own agent's halt. The caller that started a run is never the one that clears it. Deciding over the API takes an approver access token.
  • It cannot turn approval off. An autoApprove sent in a request is ignored.
  • It cannot reach past its agent: another agent's runs, another app, or an organization its reach does not include. Another agent's run is 404 AGENT_RUN_NOT_FOUND, the same answer as a run that does not exist.
  • It can stop and steer its own runs. Both only ever reduce or redirect what the agent does, and a message never approves anything.

Rate limits and retries

Each key is rate limited on its own, on top of your app's and organization's limits; over it you get 429. Separately, your organization may only have so many runs in flight. When retrying an invoke, send an Idempotency-Key header so a network blip joins the run already started instead of starting a second one.

What's next

On this page