Skip to content

Authentication

Every HTTP API call is authenticated with an API key. There is no separate service account, no OAuth flow, and no token exchange.

For how keys fit the wider identity model — console sign-in, SaaS versus on-prem — see Authentication and Authorization. This page is what an integrator needs.

Sending the key

Two transports, and the difference is deliberate.

EndpointTransport
GET /prompts/active-prompt-version?api_key= query parameter
GET /prompts, GET /skills, GET /skills/*either — header preferred
POST /prompts/active-prompt-versionX-API-Key header
POST /skills/active-versionX-API-Key header
bash
# header — preferred everywhere it is accepted
curl -s "$IM_URL/prompts?project_id=$PID" -H "X-API-Key: $IM_KEY"

# query parameter — the read endpoint's original transport
curl -s "$IM_URL/prompts/active-prompt-version?api_key=$IM_KEY&project_id=$PID&prompt_name=$NAME"

WARNING

A key in a query string ends up in access logs, proxy logs and browser history. That is why the write endpoints accept the header only. Prefer the header wherever both work, and never put a key in a URL you did not generate server-side.

Scopes

INFO

On-prem only. SaaS keys have no scope; they read.

ScopeReadPublish
read❌ — 403
write

Every key created before scopes existed is read. That was deliberate: keys get pasted into CI configs, notebooks and client backends, so a default of write would have silently handed publish rights to every key already in circulation. A key gains publish rights only when someone asks for one explicitly.

Listing is a read, so a read key is enough for discovery. You do not need publish rights to browse.

The key represents a person

This is the part that surprises people, and it is worth understanding before you design around it.

A key carries the identity of the user who created it. Permissions are resolved per request from that person's current access — not from anything stored on the key.

Two consequences:

  1. A key reaches every project its owner belongs to. It is not scoped to one project. Pass whichever project_id you need; the server decides.
  2. Publishing needs more than a write scope. On a project whose flow is Manual review, the key's owner must also hold the approver tag on that project. The scope opens the door; the tag decides who walks through.

DANGER

Design for this failure mode. If the key's owner loses the approver tag, leaves the project, or the key is revoked, every publish starts failing with nothing changed on your side. Treat the key's owner as part of your integration's configuration, and alert an operator on 403 rather than retrying — it will not resolve itself.

Who can do what

Authorisation differs by endpoint, and not in the way you would guess.

EndpointRequires
GET /prompts/active-prompt-versionkey owner is a member of the project's organisation
GET /prompts, GET /skillskey owner is a member of that project
POST publishproject membership, plus the approver tag on Manual review projects

Listing is stricter than reading. Reading one prompt somebody named for you is narrower than enumerating every prompt name across an organisation — and some organisations have thousands of members. So a listing can return 403 where a read of the same project succeeds. If that happens, ask to be added to the project.

Revoked and invalid keys

A revoked key fails everywhere, but not with the same status everywhere:

EndpointRevoked or invalid key
GET /prompts/active-prompt-version404
GET /prompts, GET /skills401
POST publish401

The read endpoint collapses every failure — bad key, unknown project, unknown prompt, no access — into one indistinguishable 404, so it cannot be used to discover what exists. The other endpoints authenticate before they resolve anything, so they can say plainly that the key is the problem.

Worth knowing when you are debugging: a 404 from the read endpoint does not mean the prompt is missing. It may equally be the key.

Key lifecycle

Keys are created in the console (API Keys). The plaintext is shown once — the platform stores only a SHA-256 hash and cannot recover it. Lose it and you revoke and reissue.

Revocation takes effect on the next request; there is no cache to wait for. So does removing the owner from a project or organisation.

Next

Copyright © 2026 elsai foundry.