API keys
Mint, scope, and revoke the itr_ credential that authenticates the Iterant public API.
An Iterant API key is a bearer token that authenticates machine callers such as CI jobs, scripts, or a sync from your CRM, without anyone sharing a dashboard session. Keys are minted per organization and live at Settings → Developers.
Minting, scoping, and revocation work as described, and a key authenticates both the REST API and the MCP server today. Names and payload shapes may still change. See the developer surface overview.
A key is not a read-only credential. Anyone holding one can start an agent task on a brand it can reach, a real Terra turn costing about five minutes of paid model time each. It still cannot publish anything. Scope keys with that in mind, and prefer a brand-pinned key for any caller that only ever works on one brand.
What a key does
A key looks like this:
itr_kK4dQ8vN2pR7wZ1xL6mB3tY9cH5jF0sA8gE2uV4nQ7d- It is a developer-surface credential only. It authenticates
/api/v1/public/and the MCP server. It will not open an internal dashboard route, and anitr_token presented anywhere else is rejected. - It is shown once, in the dialog that creates it. The key list afterwards holds a short, non-secret display prefix (
itr_kK4dQ8v) and nothing more. There is no reveal button and no support path to recover the full key. If you lose it, revoke it and mint another.
Minting a key
Only organization admins create or revoke keys, though any member of the organization can see the list. Create one at Settings → Developers, where the key takes a name of up to 100 characters and a brand, either a specific brand or All brands. Name it after the caller: CI publish pipeline, Clay enrichment sync, costi-laptop-mcp. When you later need to revoke one key out of eight, the name is what you will be reading.
The dialog then shows the full key with a copy button. Copy it into your secret store before you close the dialog, which discards the plaintext for good.
Put it in your CI secret store, your .env (git-ignored), or your password
manager. Do not commit it, do not paste it into a chat thread, and do not put
it in a client-side bundle. A browser-visible key is a public key.
Brand-pinned and org-scoped keys
The Brand choice at creation decides which brands the key is allowed to name on every subsequent call. On the public API the brand is always a path segment, /brands/{brandSlug}/….
Brand-pinned
Pick a specific brand and the key carries that brand. GET /brands/ returns that one brand only, and every brand-scoped route resolves to it.
curl https://api.iterant.ai/api/v1/public/brands/acme/pages/ \
-H "Authorization: Bearer itr_kK4dQ8v…"Asking for a different brand fails, and which error you get depends on how you asked:
- In the URL, as in
/brands/some-other-brand/pages/, you get404 Brand not found., the same answer a brand in a stranger's organization gives. - In an
X-Brand-IDheader, you get403 This API key is restricted to a different brand.That check runs during authentication, before any object is resolved.
X-Brand-ID is otherwise not used on the public surface, and it never selects a brand. Send it with the pinned brand's own id, or omit it. An empty header value counts as omitted. Any other value, malformed ones included, is refused.
Pin a key when the caller only ever works on one brand. It is the narrowest credential available and it fails closed.
Org-scoped
Pick All brands and the key carries no brand. It authenticates the organization, and it can name any brand in that organization in the path:
curl https://api.iterant.ai/api/v1/public/brands/acme/pages/ \
-H "Authorization: Bearer itr_kK4dQ8v…"No header is involved. Get the slugs from GET /api/v1/public/brands/, which lists every brand the key can reach as brandSlug; brand UUIDs are not exposed on this surface.
Org-scoped keys suit an orchestrator working across a portfolio. The trade is blast radius: one leaked key reaches every brand in the organization.
The organization check runs on every request regardless of pin. A brand that is moved into another organization after the key was minted stops resolving, without anyone having to remember to rotate the key.
Revoking
Revocation is immediate and permanent. On the Developers page, an admin clicks Revoke on the row, and the key stops authenticating on the next request. Revoked keys stay in the list, greyed to Revoked, so the audit trail survives.
There is no un-revoke. Rotating means: mint the replacement, deploy it, confirm traffic has moved, then revoke the old one.
Last used is your evidence for that last step. It updates at one-minute resolution, enough to answer "is anything still calling with this key?" and too coarse to serve as a request log.
Errors you will see
Using a key with MCP
The same key is the MCP server's bearer credential. Send it in the Authorization header when adding the server. For Claude Code:
claude mcp add --transport http iterant https://mcp.iterant.ai/mcp \
--header "Authorization: Bearer itr_kK4dQ8v…"A key's reach over MCP matches its reach over REST: a brand-pinned key gives the agent one brand, an org-scoped key gives it the portfolio, and an agent task started over MCP is the same task started over REST. Revoke the key and both surfaces stop working on the next request. Per-client install steps for Claude Desktop, Cursor, and VS Code are in MCP server.
Last updated on