Create, list, and revoke team API keys programmatically. Use the scope catalog to build least-privilege keys for CI, engines, and automation.
→ Authentication — how keys are sent on requests
→ Device authorization — CLI sign-in sessions (alternative to long-lived keys)
→ Entitlements — plan limits on API key count
Permission scopes
API keys carry a list of scopes that gate which endpoints they can call. Each REST page documents the scopes it requires (for example agents:read, secrets:write).
Hierarchy
- Resource-level scopes (for example
agents,apps) grant every action on that resource (agents:read,agents:write,agents:execute). - Action-level scopes grant a single capability (for example
flows:execute). *grants full access.- Empty
scopeson a key means full access (backwards compatibility for keys created before scoped permissions).
Keys cannot grant scopes the creator does not hold. If you authenticate with a limited API key, POST /apikeys rejects any scope outside your own grant set.
Common scope strings
| Group | Scopes |
|---|---|
| Agents | agents:read, agents:write, agents:execute |
| Apps / tasks | apps:read, apps:write, apps:execute |
| Flows | flows:read, flows:write, flows:execute |
| Secrets | secrets:read, secrets:write |
| Integrations | integrations:read, integrations:write |
| Teams | teams:read, teams:write |
| API keys | apikeys:read, apikeys:write |
| Engines | engines:read, engines:write (admin catalog only) |
| Billing | billing:read, billing:write |
| Settings | settings:read, settings:write |
Use GET /scopes for the full catalog with labels, descriptions, and preset bundles.
Scope catalog
GET /scopes
Returns every scope definition, UI group, and preset bundle. Requires a valid API key (any scope). Non-admin callers do not see engine scopes or the engine preset.
Example:
1curl https://api.inference.sh/scopes \2 -H "Authorization: Bearer inf_your_key" \3 -H "X-API-Version: 2"Response:
1{2 "scopes": [3 {4 "value": "agents:execute",5 "label": "execute",6 "description": "run agents and send messages",7 "group": "agents"8 }9 ],10 "groups": [11 {12 "id": "agents",13 "label": "agents",14 "description": "manage and run AI agents"15 }16 ],17 "presets": [18 {19 "id": "run",20 "label": "run",21 "description": "execute agents, apps, and flows",22 "scopes": ["agents:read", "apps:read", "agents:execute", "apps:execute"]23 }24 ]25}Preset bundles
| Preset ID | Label | Typical use |
|---|---|---|
read | read-only | Dashboards and monitoring |
run | run | SDK/CLI task execution (no secret write) |
build | build | Developer workflows — create apps, agents, secrets |
engine | engine | Connect private engines (admins only) |
Presets are convenience lists — pass individual scope strings when creating a key.
List API keys
GET /apikeys or POST /apikeys/list
Requires apikeys:read.
Uses cursor pagination (cursor, limit, filters). POST /apikeys/list accepts the same fields in the JSON body.
Listed keys are masked — only the first nine and last three characters of the key string are shown.
Example:
1curl -X POST https://api.inference.sh/apikeys/list \2 -H "Authorization: Bearer inf_your_key" \3 -H "X-API-Version: 2" \4 -H "Content-Type: application/json" \5 -d '{"limit": 50}'Response item fields:
| Field | Type | Description |
|---|---|---|
id | string | Key ID |
name | string | Display name |
key | string | Masked key (1nfsh-abc…xyz) |
scopes | string[] | Granted permissions (empty = full access) |
last_used_at | string | ISO timestamp of last use |
expires_at | string | Expiration (optional) |
source | string | Origin — empty for manual keys, device-auth for legacy CLI keys |
Create API key
POST /apikeys
Requires apikeys:write. Subject to API key entitlement limits for the team.
Request
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name |
scopes | string[] | No | Permission list; omit or [] for full access |
expires_at | string | No | ISO timestamp; must be in the future |
1curl -X POST https://api.inference.sh/apikeys \2 -H "Authorization: Bearer inf_your_key" \3 -H "X-API-Version: 2" \4 -H "Content-Type: application/json" \5 -d '{6 "name": "ci-deploy",7 "scopes": ["apps:read", "apps:execute", "files:write"]8 }'The full key string is returned only in the create response. Store it immediately — list responses never include the plaintext value.
JavaScript SDK:
1const key = await client.apiKeys.create({2 name: 'ci-deploy',3 scopes: ['apps:read', 'apps:execute'],4});5console.log(key.key); // only time the full value is availableRevoke API key
DELETE /apikeys/{id}
Requires apikeys:write. Returns the deleted key DTO.
1curl -X DELETE https://api.inference.sh/apikeys/key_abc123 \2 -H "Authorization: Bearer inf_your_key" \3 -H "X-API-Version: 2"Revocation is immediate — in-flight requests may still succeed briefly while caches expire.
Team pinning
Keys created in Settings → API Keys or via POST /apikeys are pinned to the team active when they were created. They ignore X-Team-ID — a leaked automation key cannot be retargeted at another team via a header.
Device-auth and magic-link session tokens support team switching. See Authentication — Team context.
Next
- Authentication — header format and team context
- Device authorization — CLI sessions and
auth/sessionsmanagement - Secrets API — runtime credentials (distinct from API keys)