API Keys API
REST API endpoints for creating and managing tenant API keys.
API Keys API
API keys authenticate server-to-server requests to HelloJohn. Each tenant has two types of keys: publishable keys (safe for frontends) and secret keys (backend only).
Key Types
| Type | Prefix | Use |
|---|---|---|
| Publishable | pk_live_ / pk_test_ | Frontend, SDKs, client-side |
| Secret | sk_live_ / sk_test_ | Server-side API calls |
Secret keys have full API access. Never expose them in client-side code or commit them to version control.
API Key Object
{
"id": "key_01HABCDEF666555",
"name": "Production Backend",
"type": "secret",
"prefix": "sk_live_abc1",
"last_four": "x123",
"scopes": ["users:read", "users:write", "sessions:read"],
"created_at": "2024-01-10T09:00:00Z",
"last_used_at": "2024-01-20T08:15:00Z",
"expires_at": null,
"revoked": false
}The full key value is only returned once at creation time and cannot be retrieved again.
GET /v1/api-keys
List all API keys for the tenant.
Headers: Authorization: Bearer sk_live_... + X-Tenant-ID
Query parameters:
| Parameter | Type | Description |
|---|---|---|
type | string | publishable or secret |
revoked | boolean | Include revoked keys (default: false) |
curl "https://api.hellojohn.dev/v1/api-keys" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321"Response:
{
"data": [
{
"id": "key_01HABCDEF666555",
"name": "Production Backend",
"type": "secret",
"prefix": "sk_live_abc1",
"scopes": ["*"],
"created_at": "2024-01-10T09:00:00Z",
"last_used_at": "2024-01-20T08:15:00Z",
"revoked": false
}
]
}POST /v1/api-keys
Create a new API key.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Human-readable label |
type | string | ✅ | publishable or secret |
scopes | array | — | Restrict to specific scopes. Default: ["*"] (all) |
expires_in | string | — | Expiry duration, e.g. 90d, 1y. Default: no expiry |
Available scopes:
| Scope | Description |
|---|---|
* | Full access (default) |
users:read | Read user data |
users:write | Create/update/delete users |
sessions:read | Read session data |
sessions:write | Revoke sessions |
organizations:read | Read org data |
organizations:write | Manage orgs and members |
webhooks:read | Read webhook configs |
webhooks:write | Create/update webhooks |
audit-logs:read | Read audit logs |
curl -X POST "https://api.hellojohn.dev/v1/api-keys" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{
"name": "Analytics Service",
"type": "secret",
"scopes": ["users:read", "sessions:read"],
"expires_in": "90d"
}'Response: 201 Created
{
"id": "key_01HABCDEF666556",
"name": "Analytics Service",
"type": "secret",
"key": "sk_live_abcdefghijklmnop...",
"scopes": ["users:read", "sessions:read"],
"expires_at": "2024-04-15T10:00:00Z",
"created_at": "2024-01-15T10:00:00Z"
}Important: The
keyfield is only included in the creation response. Copy it now — it cannot be retrieved again.
GET /v1/api-keys/:id
Get details for a specific API key.
curl "https://api.hellojohn.dev/v1/api-keys/key_01HABCDEF666555" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321"Response: 200 OK — Returns API key object (without the full key value).
PATCH /v1/api-keys/:id
Update an API key's name or scopes.
Body (all optional):
| Field | Type | Description |
|---|---|---|
name | string | New label |
scopes | array | New scopes list (replaces existing) |
DELETE /v1/api-keys/:id
Revoke an API key immediately. Revoked keys cannot be restored.
curl -X DELETE "https://api.hellojohn.dev/v1/api-keys/key_01HABCDEF666555" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321"Response: 204 No Content
POST /v1/api-keys/rotate
Rotate an existing API key. Returns a new key value and revokes the old one after a grace period.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | ✅ | Key ID to rotate |
grace_period | string | — | Time before old key is revoked (default: 1h) |
curl -X POST "https://api.hellojohn.dev/v1/api-keys/rotate" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{"id": "key_01HABCDEF666555", "grace_period": "24h"}'Response: 200 OK
{
"id": "key_01HABCDEF666557",
"key": "sk_live_newkeyvalue...",
"old_key_id": "key_01HABCDEF666555",
"old_key_revokes_at": "2024-01-16T10:00:00Z"
}