Authentication

One credential opens everything here. There are no scopes, no client ids and no OAuth flow: an API key is a string, it goes in a header, and it grants the read described in Overview.

Minting a key

Keys are minted inside the product by a workspace admin, in Workspace settings → API or from the Export dialog's API row. Both are the same form and the same list — a key minted in one appears in the other, because there is one credential path in this product rather than two that could disagree about what Revoke means.

A key is a system's: it belongs to the workspace and keeps working after whoever minted it has left. It opens this API, and the MCP server until 14 January 2027; a person connecting an assistant signs in instead.

You give a key a name, which is required. The name is all the key has once the plaintext is gone, and a workspace full of unnamed keys is a workspace nobody can safely revoke in. You may also give it a sentence saying what it is for, for the admin who meets it nine months later.

The plaintext is shown once

The mint response is the only place the key exists as a readable string. No screen shows it again and no endpoint hands it back. If you lose it, mint another and revoke the one you lost.

Copy it out of the panel before you close it. This is not a warning about a screen that is inconvenient to get back to — there is nothing to get back to.

Sending it

curl -H "Authorization: Bearer imp_key_…" \
  https://app.improbable.work/api/v1/cycles

Authorization: Bearer and nothing else. There is no ?key= parameter, on purpose: a credential in a query string is a credential in every proxy log and every Referer header between you and the server.

Until 14 January 2027, the same header with the same key also opens the MCP door at /api/mcp, and revoking a key closes both. From that day the MCP server answers only to a person signing in from their assistant; see MCP server.

Expiry

A key can be given a life when it is minted, chosen from a fixed set of durations rather than a date:

How long a key may be given to live
Choice
Never
1 day
7 days
30 days
60 days
90 days
180 days
1 year

Never is first and it is the default. That is deliberate rather than careless: a key that lapses on a schedule nobody chose fails at three in the morning in the one way this API is deliberately undiagnosable — the door answers the same 401 for an expired key as for one that never existed. A credential should stop working because somebody decided it should, and Revoke is the control for that.

An expired key is still listed in the product, and the row says so in as many words, because that row is what somebody opens the page to find after a pipeline starts failing overnight.

Revocation

Revoking takes effect on the next request. There is no grace period, no cached token and no undo: a replacement is a different string that somebody has to paste into whatever was using the old one.

Nothing here can un-say a secret that has already been pasted into another system, which is why the confirmation asks you to type the key's name rather than the word "revoke" — the question worth answering before you act is not "are you sure" but "which one is this".

When it does not work

Every failure to authorize answers 401 with exactly this body:

{ "ok": false, "error": "Invalid or missing API key" }

Missing header, malformed header, unknown key, revoked key, expired key: one message for all five. Probing this API cannot tell a retired key from one that was never real. Do not build a client that branches on the reason — it will never get one. Rate limits and errors has the rest of the status codes.