Skip to content

Authentication

Every /v1 endpoint except GET /healthz and the signed file URLs requires an API key.

A key looks like this:

glr_sk_8Qd1nR7xKpV2sYbL4mTf9Uae

glr_sk_ followed by 24 random bytes in base64url. The API stores only the SHA-256 of the key plus its first 13 characters (glr_sk_8Qd1nR7) for display. The plaintext exists on the one response that issued it and nowhere else.

The API reads Authorization first and falls back to X-API-Key.

HeaderExampleNotes
AuthorizationAuthorization: Bearer glr_sk_…Preferred. The Bearer prefix is matched case-insensitively.
AuthorizationAuthorization: glr_sk_…Also accepted — a value with no Bearer prefix is used as the key verbatim.
X-API-KeyX-API-Key: glr_sk_…Used only when Authorization is absent or empty.
Both of these work
curl -sS https://api.galleyrender.com/v1/templates \
-H "Authorization: Bearer $GALLEY_API_KEY"
curl -sS https://api.galleyrender.com/v1/templates \
-H "X-API-Key: $GALLEY_API_KEY"

https://mcp.galleyrender.com/mcp accepts Authorization: Bearer glr_sk_…, X-Galley-Api-Key or X-API-Key. It also understands X-Galley-Client-Id.

HeaderPurpose
X-Galley-Api-Key: glr_sk_…The key or trial token to use for this call.
X-Galley-Client-Id: <8–200 chars>An opaque, stable identity for the keyless trial, so the same agent gets the same trial account back across IP changes.

A bearer token that does not begin with glr_sk_ is ignored rather than forwarded — an OAuth token from some other server falls through to the keyless trial instead of producing a 401. With no key and no client id, the trial identity is derived from a salted hash of your IP and User-Agent.

No key at all:

401 Unauthorized
{
"error": {
"type": "authentication_error",
"message": "Missing API key.",
"docs_url": "https://galleyrender.com/docs/errors/authentication_error",
"details": {
"how_to_authenticate": "Send `Authorization: Bearer glr_sk_…` or `X-API-Key: glr_sk_…`.",
"get_a_key": "https://galleyrender.com/docs/quickstart"
}
}
}

A key that is unknown, mistyped or revoked:

401 Unauthorized
{
"error": {
"type": "authentication_error",
"message": "Invalid or revoked API key.",
"docs_url": "https://galleyrender.com/docs/errors/authentication_error",
"details": {
"header": "Authorization: Bearer glr_sk_…",
"get_a_key": "https://galleyrender.com/docs/quickstart"
}
}
}

The API does not distinguish “never existed” from “revoked”, on purpose.

The token in trial.trial_token from a keyless MCP render call is an ordinary API key on an ordinary account. It authenticates against https://api.galleyrender.com exactly like a key you signed up for. The only difference is on the account: a trial carries a lifetime ceiling of 50 billable units rather than a monthly allowance.

A trial token against the REST API
curl -sS https://api.galleyrender.com/v1/usage \
-H "Authorization: Bearer glr_sk_8Qd1nR7xKpV2sYbL4mTf9Uae"

When the ceiling is reached, every render returns quota_exceeded with details.trial: true. Calling create_account with an email clears the ceiling on that same account, so nothing you built during the trial is lost.

Keys are server-side only. The REST API sends no CORS headers at all, so a browser cannot call it from page JavaScript — a fetch from a web page will be blocked by the browser before it sees a response. That is deliberate: there is no configuration that makes a Galley key safe in a browser bundle, a mobile app or anything else a user can read.

Browser-based clients should talk to the MCP endpoint instead, which does send CORS headers (https://mcp.galleyrender.com/mcp), or go through your own backend.

  • Put the key in an environment variable (GALLEY_API_KEY), a secret manager, or your platform’s secret store. Never in source control.
  • Give each deployment its own key, so you can revoke one without taking down the others.
  • The API never logs key values. Neither should you — log the x-request-id response header instead when you need to report something.
  • Signed render URLs carry no key and are safe to hand to a user. They expire in an hour.

Keys are issued once and cannot be read back. To rotate:

  1. Issue a new key for the account.
  2. Deploy it everywhere the old one is used.
  3. Revoke the old key. A revoked key produces the “Invalid or revoked API key.” 401 above on its very next request.

The /v1 REST surface has no key-management endpoints today: creating and revoking keys happens through the account dashboard (https://galleyrender.com/dashboard/keys, linked from the create_account tool’s own response) or by writing to support@galleyrender.com. If you think a key has leaked, revoke it first and ask questions second — see Security.