API Keys¶
API keys are credentials used to create and manage organizations and service actors. They are NOT used to access data from services.
Base URL¶
All API endpoints use the following base URL:
Examples in this documentation use the full URL for clarity, but you should use the base URL in your code.
What are API Keys?¶
API keys are credentials used to manage organizations and service actors. They are used to:
- Create organizations
- Create service actors
- Manage service actors (update, delete)
- Exchange for service actor tokens
Important: API keys are NOT used to access data from services like Brain or Analytics. Use service actor tokens for data access.
API Key Format¶
Fermi API keys follow this format:
The fmk_live_ prefix indicates this is a live (production) API key.
Creating API Keys¶
Prerequisites¶
To create an API key, you need:
- A user account with organization access
- User authentication (JWT token from login)
Via Dashboard¶
Note: Dashboard-based API key creation is planned for a future release. Currently, API keys must be created via the API.
Once available, you will be able to:
- Log in to your Fermi dashboard
- Navigate to Settings → API Keys
- Click Create API Key
-
Provide:
- Name: Descriptive name (e.g., "Production API Key", "CI/CD Integration")
- Scopes: Select the permissions you need
- Expiration (optional): Set when the key should expire
- Click Create
- Important: Copy the API key immediately - it won't be shown again!
Via API¶
Create API keys programmatically:
curl -X POST https://api.fermi.dev/public/v1/identity/api-keys \
-H "Authorization: Bearer <your-user-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"name": "My API Key",
"scopes": ["provision:service:create", "provision:token:exchange"],
"expiresAt": "2026-12-31T23:59:59Z"
}'
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the API key |
scopes | string[] | Yes | Array of scope strings |
expiresAt | string | No | ISO 8601 expiration date |
Response:
{
"id": "507f1f77bcf86cd799439011",
"name": "My API Key",
"scopes": ["provision:service:create", "provision:token:exchange"],
"apiKey": "fmk_live_abc123...",
"status": "active",
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-01-01T00:00:00Z",
"expiresAt": "2026-12-31T23:59:59Z",
"lastUsedAt": null
}
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the API key |
name | string | Name of the API key |
scopes | string[] | Array of scopes granted to this API key |
apiKey | string | The actual API key (only returned on creation) |
status | string | Status of the API key: "active" or "revoked" |
createdAt | string | ISO 8601 timestamp when the key was created |
updatedAt | string | ISO 8601 timestamp when the key was last updated |
expiresAt | string | ISO 8601 timestamp when the key expires (optional) |
lastUsedAt | string | ISO 8601 timestamp when the key was last used (optional, null if never used) |
Using API Keys¶
API keys are used to create organizations and service actors. Include your API key in the Authorization header:
curl -X POST https://api.fermi.dev/public/v1/identity/service-actors \
-H "Authorization: Bearer fmk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "My Service Actor",
"organisationId": "your-org-id",
"capabilities": ["analytics:query"]
}'
Note: To access data from services (Brain, Analytics, etc.), you must exchange your API key for a service actor token first.
Managing API Keys¶
List Your API Keys¶
curl -X GET https://api.fermi.dev/public/v1/identity/api-keys \
-H "Authorization: Bearer <your-user-jwt-token>"
Response:
[
{
"id": "507f1f77bcf86cd799439011",
"name": "My API Key",
"scopes": ["provision:service:create"],
"status": "active",
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-01-01T00:00:00Z",
"expiresAt": "2026-12-31T23:59:59Z",
"lastUsedAt": "2025-01-15T10:30:00Z"
}
]
Response Fields (each item in the array):
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the API key |
name | string | Name of the API key |
scopes | string[] | Array of scopes granted to this API key |
status | string | Status of the API key: "active" or "revoked" |
createdAt | string | ISO 8601 timestamp when the key was created |
updatedAt | string | ISO 8601 timestamp when the key was last updated |
expiresAt | string | ISO 8601 timestamp when the key expires (optional) |
lastUsedAt | string | ISO 8601 timestamp when the key was last used (optional, null if never used) |
Rotate an API Key¶
Rotating an API key generates a new key while keeping the same ID and metadata:
curl -X POST https://api.fermi.dev/public/v1/identity/api-keys/{key-id}/rotate \
-H "Authorization: Bearer <your-user-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"scopes": ["provision:service:create", "provision:token:exchange"]
}'
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
scopes | string[] | No | Updated scopes (optional) |
Response:
{
"id": "507f1f77bcf86cd799439011",
"name": "My API Key",
"scopes": ["provision:service:create", "provision:token:exchange"],
"apiKey": "fmk_live_new_key_value...",
"status": "active",
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-01-20T12:00:00Z",
"expiresAt": "2026-12-31T23:59:59Z",
"lastUsedAt": null
}
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the API key (unchanged after rotation) |
name | string | Name of the API key (unchanged after rotation) |
scopes | string[] | Updated array of scopes granted to this API key |
apiKey | string | The new API key value (only returned after rotation) |
status | string | Status of the API key: "active" or "revoked" (set to "active" after rotation) |
createdAt | string | ISO 8601 timestamp when the key was originally created |
updatedAt | string | ISO 8601 timestamp when the key was rotated |
expiresAt | string | ISO 8601 timestamp when the key expires (optional) |
lastUsedAt | string | ISO 8601 timestamp when the key was last used (reset to null after rotation) |
Revoke an API Key¶
Revoking an API key immediately invalidates it:
curl -X POST https://api.fermi.dev/public/v1/identity/api-keys/{key-id}/revoke \
-H "Authorization: Bearer <your-user-jwt-token>"
Response: 204 No Content
Delete an API Key¶
Permanently delete an API key:
curl -X DELETE https://api.fermi.dev/public/v1/identity/api-keys/{key-id} \
-H "Authorization: Bearer <your-user-jwt-token>"
Response: 204 No Content
API Key Scopes¶
Scopes define what your API key can do. When creating an API key, you must specify at least one scope.
Important: API keys use scopes for provisioning and management operations (creating organizations, creating service actors, exchanging tokens). For data access scopes (analytics, brain, connectors), assign those as capabilities to service actors instead.
API Key Scopes (for creating/managing resources):
provision:org:create- Create organizationsprovision:org:read- Read organization informationprovision:service:create- Create service actorsprovision:service:read- Read service actor informationprovision:service:update- Update service actorsprovision:service:delete- Delete service actorsprovision:token:exchange- Exchange API keys for tokensprovision:credentials:rotate- Rotate API keys
Note: Service actor management operations (read, update, delete) do not require specific scopes beyond having a valid API key. The API key's organization determines access.
Note: Analytics, Brain, and other data access scopes are assigned to service actors as capabilities, not API keys. API keys are only used for provisioning and management.
Error Handling¶
Invalid API Key¶
Solution: Verify your API key is correct and hasn't been revoked.
Missing Scope¶
Solution: Create a new API key with the required scope, or rotate your existing key to add the scope.
Expired API Key¶
Solution: Create a new API key or extend the expiration date.
Examples¶
Python Example: Create Service Actor¶
import os
import requests
api_key = os.getenv("FERMI_API_KEY")
org_id = os.getenv("FERMI_ORG_ID")
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
response = requests.post(
"https://api.fermi.dev/public/v1/identity/service-actors",
headers=headers,
json={
"name": "My Service Actor",
"organisationId": org_id,
"capabilities": ["analytics:query"]
}
)
if response.status_code == 201:
result = response.json()
service_actor = result["data"]
print(f"Created service actor: {service_actor['id']}")
else:
print(f"Error: {response.status_code} - {response.text}")
JavaScript/TypeScript Example: Create Service Actor¶
const apiKey = process.env.FERMI_API_KEY;
const orgId = process.env.FERMI_ORG_ID;
const response = await fetch('https://api.fermi.dev/public/v1/identity/service-actors', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'My Service Actor',
organisationId: orgId,
capabilities: ['analytics:query']
})
});
if (response.ok) {
const result = await response.json();
const serviceActor = result.data;
console.log(`Created service actor: ${serviceActor.id}`);
} else {
console.error(`Error: ${response.status} - ${await response.text()}`);
}
Related Documentation¶
- Service Actors - Create service actors for automated systems
- Token Exchange - Convert API keys to short-lived tokens
- Scopes and Permissions - Understand available scopes
- API Reference - Explore available API endpoints