API Keys Reference
Endpoints for managing tenant API keys. For the conceptual overview, see Authentication.
Base path: /v3/api_keys/
Required permission: admin.api_keys (for all endpoints except /v3/scopes).
GET /v3/api_keys
List API keys for the current tenant.
Query parameters:
| Parameter |
Type |
Default |
Notes |
include_revoked |
boolean |
false |
If true, include revoked keys |
Response (200):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | {
"api_keys": [
{
"id": "key_01HXYZ",
"name": "production-sender",
"prefix": "sg_live_a1b2c3d4",
"environment": "live",
"scopes": ["mail.send", "mail.schedule"],
"created_at": "2026-04-23T10:00:00Z",
"last_used_at": "2026-04-23T10:15:30Z",
"expires_at": null,
"revoked_at": null
}
]
}
|
The prefix is the first 12 characters of the key — enough to identify it, not enough to authenticate with. The full secret is only available at creation.
POST /v3/api_keys
Create a new API key.
Request body:
| Field |
Type |
Required |
Notes |
name |
string |
Yes |
1–255 chars |
environment |
string |
No |
live (default) or test |
scopes |
array of string |
No |
Permission scopes; defaults to empty (no access) |
expires_at |
datetime (ISO-8601) |
No |
Optional expiry |
Response (201):
| {
"id": "key_01HXYZ",
"name": "production-sender",
"api_key": "sg_live_a1b2c3d4e5f6g7h8i9j0...",
"prefix": "sg_live_a1b2c3d4",
"environment": "live",
"scopes": ["mail.send"],
"created_at": "2026-04-23T10:00:00Z",
"expires_at": null
}
|
The api_key field is returned exactly once. Store it immediately.
Errors:
| Status |
Cause |
| 400 |
scopes contains an unknown permission name |
| 403 |
scopes requests a permission the caller doesn't have |
GET /v3/api_keys/{key_id}
Get a single API key's metadata (never the secret).
Response (200):
| {
"id": "key_01HXYZ",
"name": "production-sender",
"prefix": "sg_live_a1b2c3d4",
"environment": "live",
"scopes": ["mail.send"],
"created_at": "2026-04-23T10:00:00Z",
"last_used_at": "2026-04-23T10:15:30Z",
"expires_at": null,
"revoked_at": null
}
|
PATCH /v3/api_keys/{key_id}
Update name or scopes on an existing key.
Request body:
| Field |
Type |
Notes |
name |
string |
New name |
scopes |
array |
New scope set (replaces existing) |
Response (200): updated key metadata.
DELETE /v3/api_keys/{key_id}
Revoke a key. Takes effect immediately.
Response (204): no body.
Revoked keys remain in the database (as an audit record) but cannot authenticate.
POST /v3/api_keys/{key_id}/regenerate
Rotate a key — issue a new secret, invalidate the old one.
Response (200):
| {
"id": "key_01HXYZ",
"name": "production-sender",
"api_key": "sg_live_newSecret...",
"prefix": "sg_live_newSecre",
"environment": "live",
"scopes": ["mail.send"],
"created_at": "2026-04-23T10:00:00Z",
"rotated_at": "2026-04-24T10:00:00Z"
}
|
The api_key field is the new secret, returned once. The old secret stops working immediately.
GET /v3/scopes
List available permission scopes. Does not require admin.api_keys — any authenticated caller can query.
Query parameters:
| Parameter |
Notes |
category |
Filter by category (mail, templates, admin, etc.) |
Response (200):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | {
"permissions": [
{"name": "mail.send", "category": "mail", "description": "Send emails"},
{"name": "mail.schedule", "category": "mail", "description": "Schedule emails for later delivery"},
{"name": "mail.cancel", "category": "mail", "description": "Cancel scheduled emails"},
{"name": "templates.read", "category": "templates", "description": "View templates"},
{"name": "templates.write", "category": "templates", "description": "Create and update templates"},
{"name": "templates.delete", "category": "templates", "description": "Delete templates"},
{"name": "suppressions.read", "category": "suppressions", "description": "View suppression lists"},
{"name": "suppressions.write", "category": "suppressions", "description": "Manage suppression lists"},
{"name": "stats.read", "category": "stats", "description": "View email statistics"},
{"name": "stats.export", "category": "stats", "description": "Export statistics data"},
{"name": "webhooks.read", "category": "webhooks", "description": "View webhook configurations"},
{"name": "webhooks.write", "category": "webhooks", "description": "Manage webhook configurations"},
{"name": "domains.read", "category": "domains", "description": "View sender domains"},
{"name": "domains.write", "category": "domains", "description": "Manage sender domains"},
{"name": "admin.api_keys", "category": "admin", "description": "Manage API keys"},
{"name": "admin.users", "category": "admin", "description": "Manage user roles"},
{"name": "admin.settings", "category": "admin", "description": "Manage tenant settings"}
]
}
|
| Prefix |
Environment |
Behavior |
sg_live_ |
Live |
Delivers real mail |
sg_test_ |
Test |
Forces sandbox mode on every send |
Both formats are followed by a 64-character hex string. Total key length: 72 characters.