Skip to content

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:

BASE_URL = "https://api.fermi.dev/public/v1/identity"

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:

fmk_live_<unique-key-string>

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:

  1. Log in to your Fermi dashboard
  2. Navigate to SettingsAPI Keys
  3. Click Create API Key
  4. 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 organizations
  • provision:org:read - Read organization information
  • provision:service:create - Create service actors
  • provision:service:read - Read service actor information
  • provision:service:update - Update service actors
  • provision:service:delete - Delete service actors
  • provision:token:exchange - Exchange API keys for tokens
  • provision: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.

Scopes Reference

Error Handling

Invalid API Key

{
  "error": "Unauthorized",
  "message": "Invalid API key"
}

Solution: Verify your API key is correct and hasn't been revoked.

Missing Scope

{
  "error": "Forbidden",
  "message": "Missing required scope: provision:service:create"
}

Solution: Create a new API key with the required scope, or rotate your existing key to add the scope.

Expired API Key

{
  "error": "Unauthorized",
  "message": "API key has expired"
}

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()}`);
}