Appearance
Provisioning (management keys)
Mint and manage sub-keys for your own end-users programmatically. These routes are for services that build their own product on top of FluidGhost and hand each of their users a key.
Every route here requires a management key (fg_mgmt_live_…) — see Authentication → Key types. A regular secret key, or a dashboard session, is refused with 403.
- Base:
https://api-ghost.fluidvip.com/api/v1/keys - A management key cannot submit jobs or spend — it only provisions.
- Sub-keys it mints are ordinary secret keys (
fg_sk_live_…) belonging to your account, each tagged with theidentityyou choose (your end-user's id).
For the end-to-end flow, read Provisioning keys for your users.
Mint a sub-key
POST /api/v1/keysAuthenticate with your management key. Mints a secret sub-key for one of your users.
Body
| Field | Type | Required | Notes |
|---|---|---|---|
identity | string | recommended | Your end-user's id — how usage is attributed to that user. |
label | string | no | A human label (e.g. "acme · user 42"). |
scopes | string[] | no | Narrow the sub-key's data-plane scopes. Defaults to the full data plane. keys:manage is never grantable here (no escalation). |
defaultPresetId | string | no | Bind a default preset to the sub-key (settings precedence). |
expiresAt | string (ISO-8601) | no | Optional auto-expiry. |
mode | live | test | no | Defaults to live. |
Response — 201 Created
json
{ "id": "key_…", "key": "fg_sk_live_…", "class": "secret", "identity": "end-user-42",
"scopes": ["variants:write","jobs:read","inspect:read"],
"selfServe": true, "state": "active", "createdAt": "…" }key is the raw secret — shown once. Hand it to your user; store nothing but the id.
Example
bash
curl -X POST https://api-ghost.fluidvip.com/api/v1/keys \
-H "Authorization: Bearer fg_mgmt_live_…" \
-H "Content-Type: application/json" \
-d '{ "identity": "end-user-42", "label": "acme · user 42" }'List your provisioned sub-keys
GET /api/v1/keysReturns only the keys you provisioned (not your own dashboard keys), newest first — no secrets.
json
{ "keys": [ { "id": "key_…", "class": "secret", "identity": "end-user-42", "last4": "a1b2", "state": "active", "lastUsedAt": "…", "createdAt": "…" } ] }Rotate a sub-key
POST /api/v1/keys/{id}/rotateIssues a new secret for the sub-key; the old secret keeps working for a 24-hour grace window so your user can hot-swap. Returns the new key once. 404 if {id} isn't one of your provisioned keys.
Revoke a sub-key
DELETE /api/v1/keys/{id}Revokes the sub-key immediately (the next request with it returns 401). 404 if it isn't one of your provisioned keys.
Errors
| Status | error | When |
|---|---|---|
403 | forbidden | Called without a management key (a secret key or a session). |
404 | not_found | The id isn't a sub-key you provisioned. |
400 | bad_request | Invalid mode/body. |