> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gigstack.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage API credentials

> Integration guide for Manage API credentials

Use a personal Firebase credential or personal MCP token within the server's current
authority checks. API keys, including legacy keys, cannot manage credentials. Creating
or rotating a key requires private human browser confirmation after a recent real
Firebase sign-in; preparation and metadata readback never disclose its secret.

Legacy key operations below require an explicitly selected team and its current
team administrator/owner or billing-account administrator. Named scoped operations
instead use the explicit billing account and returned server capabilities: its
owner or bounded credential administrator may create, while an existing key's
managers may read, revoke or prepare rotation within their per-key permissions.
Named metadata access does not require selecting a team. Personal Firebase access
must pass real-provider and current MFA checks; a body field or administrator label
cannot substitute for those checks.

## Named keys with explicit scope

Use a separate named key for each integration. A scoped key belongs to one billing
account and one explicit mode, with reviewed `team_ids`, `action_ids`, `expires_at`
(epoch milliseconds), and `manager_user_ids`. Action IDs are exact public operation
IDs from the current server policy catalog; a label such as “all writes” is not a
scope. Named service keys belong to the organization: the issuer UID records
attribution, rather than borrowing that person's current human permissions. Each
request still checks the key's exact scope and current account/team state, API
entitlement and server policy.

Read `GET /users/me/scoped-api-keys/policy?billing_account_id=ACCOUNT_ID` using a
personal Firebase or MCP identity. The policy lists eligible teams, actions and
managers, creation authority, and expiry/overlap bounds. Account owners may omit `expires_at` or set it to null for no expiration. A chosen
expiry cannot exceed 365 days; bounded delegated administrators must supply a
future expiry within their assigned limit. Existing dates are preserved. The server
rechecks eligibility during private execution rather than trusting a saved policy.

Prepare `api_keys.create_scoped` through `POST /users/me/account-approvals` with a
saved UUIDv4 and payload `&#123;name,livemode,billing_account_id,team_ids,action_ids,
expires_at,manager_user_ids&#125;`. Preparing does not issue a credential. The initiating
person reviews the exact scope in the private browser after a recent real sign-in.
Only the first successful private execution response contains the secret. Store it
locally in the integration's secret manager; subsequent reads and retries contain
metadata only. An API key, including a legacy key, cannot manage key lifecycles.

List metadata with `GET /users/me/scoped-api-keys?billing_account_id=ACCOUNT_ID`.
Read one key at `GET /users/me/scoped-api-keys/{keyId}` and its safe lifecycle audit
at `GET /users/me/scoped-api-keys/{keyId}/audit`; include the billing-account query.
Use the returned capabilities and per-key management permissions. Audit entries
contain safe lifecycle evidence, never request bodies, headers or tokens.
`last_used_at` is observed usage only; null means unavailable, not never used.

Prepare `api_keys.rotate_scoped` with `{key_id,overlap_seconds}`. Rotation copies
that key's immutable scope and managers without widening them. Review the explicit
overlap period: the predecessor remains usable only until its scheduled revocation
or earlier expiry. Other keys remain untouched. Revoke a single key using
`DELETE /users/me/scoped-api-keys/{keyId}` with `{operation_id:UUID}` and the exact
billing-account query. Preserve the UUID after an uncertain response and inspect
metadata before repeating the identical request; do not automatically rotate again.

## Use named keys from CLI or MCP

```bash theme={null}
gigstack scoped-api-keys policy --billing-account ACCOUNT_ID --json
gigstack scoped-api-keys list --billing-account ACCOUNT_ID --json
gigstack scoped-api-keys prepare-create --operation-id SAVED_UUIDV4 --file scoped-key-request.json --json
gigstack account-approvals get APPROVAL_ID --json
gigstack scoped-api-keys get KEY_ID --billing-account ACCOUNT_ID --json
gigstack scoped-api-keys audit KEY_ID --billing-account ACCOUNT_ID --json
gigstack scoped-api-keys prepare-rotate --billing-account ACCOUNT_ID --operation-id ANOTHER_UUIDV4 --data '{"key_id":"KEY_ID","overlap_seconds":3600}' --json
gigstack scoped-api-keys revoke KEY_ID --billing-account ACCOUNT_ID --operation-id REVOKE_UUIDV4 --yes --json
```

The create file contains the fields listed above; `expires_at` is optional for owners. `manager_user_ids:[]`
adds no delegated managers. Choose `action_ids` from policy, and set `expires_at` to
null for no expiration or an actual future epoch-ms value within its expiry bound.
Rotation preserves the expiry choice, including no expiration. List/audit accept `--limit`
and `--cursor`; continue until `next_cursor:null`, even after an empty page.
Preparation succeeds with safe approval metadata and a `review_url`, not a key.
CLI exits nonzero for refused or unconfirmed requests and retains the operation
reference for readback; it never repeats a consequential request automatically.

The named MCP equivalents are `account_api_keys_policy_get`,
`account_api_keys_list`, `account_api_keys_create_prepare`,
`account_api_keys_rotate_prepare`, `account_api_keys_get`,
`account_api_keys_audit_list`, and `account_api_keys_revoke`. Use existing
`get_account_approval` to inspect preparation. An agent can request review within
current authority, but cannot execute the private secret-disclosure terminal.

## Migrate an existing integration

Existing keys and tokens remain valid according to their existing checks. The
`legacy_unrestricted` label means no reviewed explicit action/team scope was stored;
it does not exempt a legacy credential from current account and permission checks.
No migration deadline, forced rotation, or automatic retirement is implied.

1. Inventory one integration's actual teams, mode and API operations.
2. Read policy and prepare a named key with those exact allowed operation IDs.
3. Review privately and store the one-time secret in that integration.
4. Verify its required requests and expected denial for excluded actions/teams.
5. Switch that integration, then deliberately revoke its old key when ready.

Repeat per integration. Keep the legacy key until its remaining consumers have
migrated; do not use legacy pair rotation as a shortcut for per-key rotation.
Legacy pair creation and rotation below exclude scoped keys. The existing emergency operation
revokes legacy API/MCP credentials only; named scoped keys are untouched.

## Owner emergency for named scoped keys

The current personal billing-account owner can revoke all scoped keys across both
modes using `POST /users/me/scoped-api-keys/emergency-revoke` with the exact billing
account query and `{operation_id:UUID}`. Delegated credential administrators, key
managers and API keys cannot use this operation. Legacy API keys, MCP and OAuth
credentials remain untouched. Pending scoped create/rotate approvals are invalidated.

Save the UUID before requesting revocation. Read
`GET /users/me/scoped-api-keys/emergency-revocations/{operationId}` with the same
billing account after an uncertain response. `processing` reports a partial
`revoked_count` and `completed_at:null`; only `completed` reports the final count.
Repeating POST with the same UUID deliberately resumes the existing operation;
do not retry automatically or substitute a new UUID.

```bash theme={null}
gigstack scoped-api-keys emergency-revoke --billing-account ACCOUNT_ID --operation-id SAVED_UUIDV4 --yes --json
gigstack scoped-api-keys emergency-get SAVED_UUIDV4 --billing-account ACCOUNT_ID --json
```

MCP uses `account_api_keys_emergency_revoke` with the saved operation UUID,
`scope:"billing_account_scoped_keys"` and `confirmed:true`, followed by
`account_api_keys_emergency_get` for readback. The confirmation fields express
intent; the backend independently checks current personal owner authority.

## First-release action catalog

The first scoped-key catalog permits business reads, including client reads, and
service creation, updates and deletion. Client mutations, fiscal issuance or
cancellation, refunds, automation, team/user administration, and credential lifecycle
are not grantable. Client writes can trigger downstream Stripe/fiscal effects whose
scope proof is not yet covered. Read policy for the exact allowed operation IDs;
new routes never inherit a grant. Unknown or unreviewed routes return
`scoped_action_unavailable`. Existing legacy credentials retain their existing
behavior; this release does not claim scoped-key coverage for every account workflow.

## Handle a server denial

Select an allowed team and the key's exact mode. If an operation is missing from
`action_ids`, ask a current credential administrator to prepare a separately
reviewed key; the integration cannot grant itself permission. If current module
permissions or account entitlement are missing, correct that authority first.
Per-key managers can inspect/revoke/prepare rotation for managed keys, without
receiving permission to create or widen keys. Policy and safe key responses expose
current capabilities; credentials never override an explicit server denial.

## Legacy pair: inspect before creating

```bash theme={null}
gigstack api-keys list --team TEAM_ID --json
```

The equivalent API request is `GET /api-keys?team=TEAM_ID`. It returns metadata
only: `keyid`, `type`, `team`, `livemode`, `valid`, `timestamp`,
`invalidTimestamp` and `lastUsedAt`. Stored JWTs never appear in list responses.

Pagination uses `limit` (1–100, default 20), `cursor`, `has_more` and
`next_cursor`. `include_revoked=true` includes revoked API keys. A filtered page
can be empty and still have another cursor; stop only when `has_more` is false.
Personal MCP tokens have their own [account endpoints](/guides/users#control-your-own-account).

## Legacy pair: prepare creation or rotation

Credential issuance requires an authenticated browser approval. Save a UUIDv4
before preparing each new request. The CLI commands return safe approval state
and `review_url`, never secrets:

```bash theme={null}
gigstack api-keys create --team TEAM_ID --operation-id UUID_SAVED_BEFORE_CALL --json
gigstack api-keys rotate --team TEAM_ID --operation-id ANOTHER_SAVED_UUID --json
```

These commands call `POST /users/me/account-approvals` with action
`api_keys.generate` or `api_keys.rotate`, the explicit `team_id` and `payload:{}`.
The old `--out` secret-file and issuance confirmation flags are no longer accepted.
The initiating person opens the authenticated review link, verifies the team,
requested live/test modes and exact revocations, and confirms there after a recent
real sign-in. Only that committing browser request receives the newly issued keys.

Legacy pair creation requires no active legacy API keys; rotation revokes only the
reviewed legacy API keys and preserves scoped keys and personal MCP tokens. Relevant account/key changes invalidate the
request rather than silently expanding its scope. The current API entitlement and
administrator authority are rechecked at execution.

After an uncertain preparation response, repeat only the original operation UUID
and exact input. After a lost browser execution response, read the approval receipt;
secrets cannot be retrieved. See [credential approvals](/guides/credential-approvals).

`POST /api-keys` and `POST /api-keys/rotate` are retired and return HTTP 403
`account_approval_required`, including for freshly authenticated Firebase users.
They do not create credentials. Existing list and revocation operations remain.

## Revoke one key or perform emergency revocation

```bash theme={null}
gigstack api-keys revoke API_KEY_ID --team TEAM_ID --yes --json
```

`DELETE /api-keys/{keyId}?team=TEAM_ID` returns metadata with `valid: false`.
Calling it again returns the revoked state. Foreign keys and MCP token IDs return
404; this operation only revokes API credentials.

For an explicitly requested team-wide emergency:

```bash theme={null}
gigstack api-keys emergency-revoke --team TEAM_ID --yes --json
```

`POST /api-keys/emergency-revoke?team=TEAM_ID` revokes active **legacy API and personal MCP** credentials associated with the
team. It can revoke the calling legacy MCP credential. Named scoped keys and records
with malformed scoped markers are untouched. OAuth tokens are not revoked. Its
historical `scope: "team_api_and_mcp_keys"` label describes the legacy operation;
it does not mean all named scoped keys were revoked. `oauth_revoked` remains false.

The server batches large revocations and retains a revocation fence across
interruptions. Continue through another still-authorized Firebase/user session
if the calling MCP token has been revoked; do not assume the whole account has
been disconnected from OAuth integrations.

## Handle an uncertain result

Responses are not cacheable. Never log one-time keys or copy them into source
files. A timeout can happen after a pair was created or revoked: read the current
metadata before another mutation. Listing cannot recover an already-issued
secret. If delivery of a new key was lost, a subsequent deliberate rotation is
a new consequential action, not an automatic retry.

Before release, the signing identity and audience must match the deployed API
gateway. Source and offline checks do not prove that environment configuration.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.