Service Actors¶
Service actors are non-human entities used for automated systems. They are created using API keys and used with token exchange to access data.
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 Service Actors?¶
Service actors are:
- Non-human actors for automated systems
- Scoped by capabilities (permissions)
- Organization-scoped - belong to a specific organization
Creating Service Actors¶
Prerequisites¶
To create a service actor, you need:
- An API key with
provision:service:createscope - The organization ID where the service actor will be created
Creating via API¶
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": "CI/CD Pipeline Actor",
"organisationId": "507f1f77bcf86cd799439011",
"capabilities": ["analytics:query", "analytics:write"],
"status": "active"
}'
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Descriptive name for the service actor |
organisationId | string | Yes | ID of the organization this actor belongs to |
capabilities | string[] | No | Array of scopes/capabilities (default: empty) |
status | enum | No | active or suspended (default: active) |
Response:
{
"success": true,
"message": "Service actor created successfully",
"data": {
"id": "6960f3d6a4d1ed0d90654714",
"name": "CI/CD Pipeline Actor",
"organisation": {
"id": "6960f37ba4d1ed0d90654702",
"capabilities": [],
"status": "active"
},
"parentOrganisation": {
"id": "68ffc9de7c7e746b83120aa7",
"capabilities": [],
"status": "active"
},
"creatorUserId": "68ffc7a57c7e746b83120a9a",
"capabilities": ["provision:service:create", "provision:token:exchange"],
"status": "active",
"createdAt": "2026-01-09T12:25:58.694Z",
"updatedAt": "2026-01-09T12:25:58.694Z"
}
}
Response Fields:
| Field | Type | Description |
|---|---|---|
success | boolean | Indicates if the operation was successful |
message | string | Human-readable message about the operation |
data | object | The created service actor object |
data.id | string | Unique identifier for the service actor |
data.name | string | Name of the service actor |
data.organisation | object | Organisation object (child org) that this service actor belongs to |
data.organisation.id | string | Unique identifier for the child organisation |
data.organisation.capabilities | string[] | Capabilities available to the child organisation |
data.organisation.status | string | Status of the child organisation: "active" or "suspended" |
data.parentOrganisation | object | Organisation object (parent org) that created this service actor |
data.parentOrganisation.id | string | Unique identifier for the parent organisation |
data.parentOrganisation.capabilities | string[] | Capabilities available to the parent organisation |
data.parentOrganisation.status | string | Status of the parent organisation: "active" or "suspended" |
data.capabilities | string[] | Array of scopes/capabilities granted to this service actor |
data.status | string | Status of the service actor: "active" or "suspended" |
data.creatorUserId | string | ID of the user who created this service actor |
data.createdAt | string | ISO 8601 timestamp when the service actor was created |
data.updatedAt | string | ISO 8601 timestamp when the service actor was last updated |
Managing Service Actors¶
List Service Actors¶
List all service actors for your organization:
curl -X GET "https://api.fermi.dev/public/v1/identity/service-actors?page=1&limit=10" \
-H "Authorization: Bearer fmk_live_your_api_key_here"
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number (default: 1) |
limit | number | No | Items per page, max 50 (default: 10) |
Response:
{
"data": [
{
"id": "507f1f77bcf86cd799439011",
"name": "CI/CD Pipeline Actor",
"organisation": {
"id": "507f1f77bcf86cd799439011",
"capabilities": [],
"status": "active"
},
"parentOrganisation": {
"id": "507f1f77bcf86cd799439012",
"capabilities": [],
"status": "active"
},
"capabilities": ["analytics:query", "analytics:write"],
"status": "active",
"creatorUserId": "507f1f77bcf86cd799439013",
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-01-01T00:00:00Z"
}
],
"hasNextPage": false,
"hasPreviousPage": false
}
Response Fields:
| Field | Type | Description |
|---|---|---|
data | array | Array of service actor objects |
hasNextPage | boolean | Indicates if there are more pages available |
hasPreviousPage | boolean | Indicates if there are previous pages available |
Each item in the data array contains:
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the service actor |
name | string | Name of the service actor |
organisation | object | Organisation object (child org) that this service actor belongs to |
organisation.id | string | Unique identifier for the child organisation |
organisation.capabilities | string[] | Capabilities available to the child organisation |
organisation.status | string | Status of the child organisation: "active" or "suspended" |
parentOrganisation | object | Organisation object (parent org) that created this service actor |
parentOrganisation.id | string | Unique identifier for the parent organisation |
parentOrganisation.capabilities | string[] | Capabilities available to the parent organisation |
parentOrganisation.status | string | Status of the parent organisation: "active" or "suspended" |
capabilities | string[] | Array of scopes/capabilities granted to this service actor |
status | string | Status of the service actor: "active" or "suspended" |
creatorUserId | string | ID of the user who created this service actor |
createdAt | string | ISO 8601 timestamp when the service actor was created |
updatedAt | string | ISO 8601 timestamp when the service actor was last updated |
Get Service Actor by ID¶
curl -X GET https://api.fermi.dev/public/v1/identity/service-actors/{service-actor-id} \
-H "Authorization: Bearer fmk_live_your_api_key_here"
Response:
{
"id": "6960f3d6a4d1ed0d90654714",
"name": "CI/CD Pipeline Actor",
"organisation": {
"id": "6960f37ba4d1ed0d90654702",
"capabilities": [],
"status": "active"
},
"parentOrganisation": {
"id": "68ffc9de7c7e746b83120aa7",
"capabilities": [],
"status": "active"
},
"creatorUserId": "68ffc7a57c7e746b83120a9a",
"capabilities": ["analytics:query", "analytics:write"],
"status": "active",
"createdAt": "2026-01-09T12:25:58.694Z",
"updatedAt": "2026-01-09T12:25:58.694Z"
}
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the service actor |
name | string | Name of the service actor |
organisation | object | Organisation object (child org) that this service actor belongs to |
organisation.id | string | Unique identifier for the child organisation |
organisation.capabilities | string[] | Capabilities available to the child organisation |
organisation.status | string | Status of the child organisation: "active" or "suspended" |
parentOrganisation | object | Organisation object (parent org) that created this service actor |
parentOrganisation.id | string | Unique identifier for the parent organisation |
parentOrganisation.capabilities | string[] | Capabilities available to the parent organisation |
parentOrganisation.status | string | Status of the parent organisation: "active" or "suspended" |
capabilities | string[] | Array of scopes/capabilities granted to this service actor |
status | string | Status of the service actor: "active" or "suspended" |
creatorUserId | string | ID of the user who created this service actor |
createdAt | string | ISO 8601 timestamp when the service actor was created |
updatedAt | string | ISO 8601 timestamp when the service actor was last updated |
Note: Returns null if the service actor is not found.
Update Service Actor¶
Update a service actor's name, capabilities, or status:
curl -X PATCH https://api.fermi.dev/public/v1/identity/service-actors/{service-actor-id} \
-H "Authorization: Bearer fmk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Actor Name",
"capabilities": ["analytics:query", "analytics:read", "analytics:write"],
"status": "active"
}'
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No | Updated name for the service actor |
capabilities | string[] | No | Updated array of scopes/capabilities |
status | enum | No | active or suspended |
Response:
{
"success": true,
"message": "Service actor updated successfully",
"data": {
"id": "6960f3d6a4d1ed0d90654714",
"name": "Updated Actor Name",
"organisation": {
"id": "6960f37ba4d1ed0d90654702",
"capabilities": [],
"status": "active"
},
"parentOrganisation": {
"id": "68ffc9de7c7e746b83120aa7",
"capabilities": [],
"status": "active"
},
"creatorUserId": "68ffc7a57c7e746b83120a9a",
"capabilities": ["analytics:query", "analytics:read", "analytics:write"],
"status": "active",
"createdAt": "2026-01-09T12:25:58.694Z",
"updatedAt": "2026-01-20T12:00:00.000Z"
}
}
Response Fields:
| Field | Type | Description |
|---|---|---|
success | boolean | Indicates if the operation was successful |
message | string | Human-readable message about the operation |
data | object | The updated service actor object |
data.id | string | Unique identifier for the service actor |
data.name | string | Updated name of the service actor |
data.organisation | object | Organisation object (child org) that this service actor belongs to |
data.organisation.id | string | Unique identifier for the child organisation |
data.organisation.capabilities | string[] | Capabilities available to the child organisation |
data.organisation.status | string | Status of the child organisation: "active" or "suspended" |
data.parentOrganisation | object | Organisation object (parent org) that created this service actor |
data.parentOrganisation.id | string | Unique identifier for the parent organisation |
data.parentOrganisation.capabilities | string[] | Capabilities available to the parent organisation |
data.parentOrganisation.status | string | Status of the parent organisation: "active" or "suspended" |
data.capabilities | string[] | Updated array of scopes/capabilities granted to this service actor |
data.status | string | Updated status of the service actor: "active" or "suspended" |
data.creatorUserId | string | ID of the user who created this service actor |
data.createdAt | string | ISO 8601 timestamp when the service actor was originally created |
data.updatedAt | string | ISO 8601 timestamp when the service actor was last updated |
Delete Service Actor¶
Service actors are soft-deleted:
curl -X DELETE https://api.fermi.dev/public/v1/identity/service-actors/{service-actor-id} \
-H "Authorization: Bearer fmk_live_your_api_key_here"
Response: 204 No Content
Service Actor Capabilities¶
Capabilities are scopes/permissions that define what a service actor can do. These are used for data access and service operations, not for provisioning.
Common capabilities:
analytics:query- Query analytics dataanalytics:read- Read analytics dataanalytics:write- Write analytics databrain:read- Read brain databrain:write- Write brain dataconnectors:read- Read connector dataconnectors:write- Write connector dataconnectors:sync- Sync connector data
Note: Service actor capabilities determine what data and services the actor can access. These are different from API key scopes, which are used for provisioning operations.
Using Service Actors with Token Exchange¶
Service actors are used with token exchange to get short-lived JWT tokens:
- Create a service actor with appropriate capabilities
- Use your API key (with
provision:token:exchangescope) to exchange for a service actor token - Use the token for authenticated requests
Service Actor Status¶
Service actors can have two statuses:
active: Service actor is active and can be usedsuspended: Service actor is suspended and cannot be used
Suspended service actors cannot exchange tokens or make API calls.
Error Handling¶
Missing Scope¶
Solution: Create an API key with provision:service:create scope.
Invalid Organization¶
{
"status": 403,
"errors": {
"auth": "Service actor's parent organisation must match API key's organization"
}
}
Solution: Ensure the organisationId matches your API key's organization.
Service Actor Not Found¶
Solution: Verify the service actor ID is correct and belongs to your organization.
Examples¶
Python Example¶
import os
import requests
api_key = os.getenv("FERMI_API_KEY")
org_id = os.getenv("FERMI_ORG_ID")
response = requests.post(
"https://api.fermi.dev/public/v1/identity/service-actors",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
},
json={
"name": "Python Integration",
"organisationId": org_id,
"capabilities": ["analytics:query", "analytics:read"]
}
)
if response.status_code == 201:
result = response.json()
service_actor = result["data"]
print(f"Created service actor: {service_actor['id']}")
print(f"Organisation ID: {service_actor['organisation']['id']}")
print(f"Parent Organisation ID: {service_actor['parentOrganisation']['id']}")
else:
print(f"Error: {response.status_code} - {response.text}")
JavaScript/TypeScript Example¶
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: 'JavaScript Integration',
organisationId: orgId,
capabilities: ['analytics:query', 'analytics:read']
})
});
if (response.ok) {
const result = await response.json();
const serviceActor = result.data;
console.log(`Created service actor: ${serviceActor.id}`);
console.log(`Organisation ID: ${serviceActor.organisation.id}`);
console.log(`Parent Organisation ID: ${serviceActor.parentOrganisation.id}`);
} else {
console.error(`Error: ${response.status} - ${await response.text()}`);
}
Next Steps¶
- Token Exchange - Learn how to exchange service actors for tokens
- Scopes and Permissions - Understand available capabilities
- API Reference - Explore API endpoints