API Keys
Manage per-project API keys. Standard keys are created by the tenant; scoped and admin keys require elevated privileges. Plaintext is returned exactly once on creation.
Endpoint
| Method | Path | Auth | Idempotent |
|---|---|---|---|
| GET | | tenant Bearer | yes |
| POST | | tenant Bearer | no (plaintext returned once) |
| POST | | admin Bearer | no |
| POST | | admin Bearer | no |
| DELETE | | admin Bearer | yes (204) |
Parameters
| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| string | yes | — | path parameter; project ID |
| string | yes* | — | human label; visible in dashboard |
| object | no | — | permission manifest for the key |
| string | yes** | — | path parameter for rotate/delete |
| string[] | yes*** | — | permission scopes; body of scoped endpoint |
| number | no | — | time-to-live in seconds; scoped endpoint only |
*Required for POST
/keys (standard create).
**Required for rotate and delete endpoints.
***Required for POST /keys/scoped.
Response
// GET /keys — List (metadata only)
{
keys: Array<{
id: string
name: string
key_prefix: string // e.g. "bf_pk_..."
permissions: Record<string, unknown> | null
created_at: string
expires_at: string | null
revoked_at: string | null
}>
}
// POST /keys — Create (plaintext returned ONCE)
{
key: string // full plaintext key, e.g. "bf_pk_..."
apiKey: {
id: string
name: string
key_prefix: string
permissions: Record<string, unknown> | null
created_at: string
}
warning: string // "Store this key securely — it will not be shown again"
}
// POST /keys/scoped — Create scoped key (admin Bearer)
{
id: string
token: string // full plaintext token
permissions: string[]
expiresAt: string // ISO 8601 or null if no TTL
}
// POST /keys/:keyId/rotate — Rotate key (admin Bearer)
{
id: string
token: string // new plaintext token
permissions: string[]
expiresAt: string | null
}
// DELETE /keys/:keyId — Delete key (admin Bearer)
// HTTP 204 No Content (no body)
Examples
# List keys (metadata only)
curl https://api.blueforge.studio/api/platform/projects/prj_xxx/keys \
-H "Authorization: Bearer $BF_TENANT_KEY"
# Create a standard key
curl -X POST https://api.blueforge.studio/api/platform/projects/prj_xxx/keys \
-H "Authorization: Bearer $BF_TENANT_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "ci-deploy"}'
# Create a scoped key (admin)
curl -X POST https://api.blueforge.studio/api/platform/projects/prj_xxx/keys/scoped \
-H "Authorization: Bearer $BF_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"scopes": ["read", "write"], "ttlSeconds": 3600}'
# Rotate a key (admin)
curl -X POST https://api.blueforge.studio/api/platform/projects/prj_xxx/keys/key_abc/rotate \
-H "Authorization: Bearer $BF_ADMIN_KEY"
# Delete a key (admin) — returns 204
curl -X DELETE https://api.blueforge.studio/api/platform/projects/prj_xxx/keys/key_abc \
-H "Authorization: Bearer $BF_ADMIN_KEY"
import { Client } from "@blueforge/client"
// List keys
const { keys } = await client.projects.keys.list("prj_xxx")
// Create key
const { key, warning } = await client.projects.keys.create("prj_xxx", { name: "ci-deploy" })
console.log("Save immediately:", key)
console.log(warning)
// Create scoped key (admin token required)
const scoped = await client.projects.keys.createScoped("prj_xxx", {
scopes: ["read", "write"],
ttlSeconds: 3600
})
// Rotate (admin token required)
const rotated = await client.projects.keys.rotate("prj_xxx", "key_abc")
// Delete (admin token required)
await client.projects.keys.delete("prj_xxx", "key_abc")
Pitfalls
- Plaintext key is returned once on create. Store it in your secret manager immediately — it cannot be retrieved again.
- There is no separate rotate endpoint for standard keys. The recommended rotation workflow is: create a new key, switch all consumers to it, then DELETE the old key.
- The scoped key and rotate endpoints require admin Bearer authentication, not tenant Bearer.
- DELETE returns HTTP 204 with no response body. This is idempotent — subsequent DELETE calls on the same keyId also return 204.
See also
- projects.create — Create a new platform project (keys are provisioned on creation)
- Key permissions framework is managed via the API Keys package; see
for advanced permission manifests@blueforge/api-keys
Tested against
- @blueforge/platform-api: 2.4.1
- Last verified: 2026-07-15