Agents and AI
Agents and their keys, AI providers for suggestions and log analysis, and token spend of AI models.
An Agent is a member account for an AI agent, with its own role and keys. You manage Agents here with a Personal key; the Agent itself works only through the MCP endpoint and the AI Gateway, never through this API.
Every request goes to https://cloudgate.octabyte.app/backend on the Hosted instance, or to your console address followed by /backend when you self-host. Send a Personal key in x-api-key and the Organization in x-organization-id; Authentication shows how to make the key, and Errors explains every refusal. The examples setCLOUDGATE_KEY and CLOUDGATE_ORG_ID in the shell first. To do the same in the console, read Agents in the user guide.
Agents
List Agents
GET/agents
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403You may not reach what it touches. The error body.
curl https://cloudgate.octabyte.app/backend/agents \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Create an Agent
POST/agents
Who can call it: Owner or Admin. Needs member: create, which a custom role can also grant.
Request body
| Field | Type | Notes |
|---|---|---|
namerequired | string | 1 to 64 characters. |
role | string | One of agentReader, agentOperator, agentCaller. Default "agentReader". |
grant | object | Default {}. |
grant.accessedProjects | array of string | |
grant.accessedEnvironments | array of string | |
grant.accessedServices | array of string | |
keyExpiresInDays | number | Default 90. |
Responses
201Created- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403Your role does not allow it, or you were not granted what it touches. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/agents \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID" \
-H "content-type: application/json" \
-d '{
"name": "release-bot"
}'Delete an Agent
DELETE/agents/{id}
Who can call it: Owner or Admin. Needs member: delete, which a custom role can also grant.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The Agent's id. |
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403Your role does not allow it, or you were not granted what it touches;404Nothing with that id in this Organization. The error body.
curl -X DELETE https://cloudgate.octabyte.app/backend/agents/RAU6yAYUXFRdXdPLyLoPC \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Suspend an Agent
POST/agents/{id}/suspend
Who can call it: Owner or Admin. Needs member: update, which a custom role can also grant.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The Agent's id. |
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403Your role does not allow it, or you were not granted what it touches;404Nothing with that id in this Organization. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/agents/RAU6yAYUXFRdXdPLyLoPC/suspend \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Resume an Agent
POST/agents/{id}/resume
Who can call it: Owner or Admin. Needs member: update, which a custom role can also grant.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The Agent's id. |
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403Your role does not allow it, or you were not granted what it touches;404Nothing with that id in this Organization. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/agents/RAU6yAYUXFRdXdPLyLoPC/resume \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Add an Agent key
POST/agents/{id}/keys
Who can call it: Owner or Admin. Needs member: update, which a custom role can also grant.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The Agent's id. |
Request body
| Field | Type | Notes |
|---|---|---|
expiresInDays | number | Default 90. |
Responses
201Created- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403Your role does not allow it, or you were not granted what it touches;404Nothing with that id in this Organization. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/agents/RAU6yAYUXFRdXdPLyLoPC/keys \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID" \
-H "content-type: application/json" \
-d '{
"expiresInDays": 90
}'Remove an Agent key
DELETE/agents/{id}/keys/{keyId}
Who can call it: Owner or Admin. Needs member: update, which a custom role can also grant.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The Agent's id. |
keyIdrequired | path | string | The key's id. |
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403Your role does not allow it, or you were not granted what it touches;404Nothing with that id in this Organization. The error body.
curl -X DELETE https://cloudgate.octabyte.app/backend/agents/RAU6yAYUXFRdXdPLyLoPC/keys/SaeR9mLHJGSq35unpTVMV \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"AI providers
List AI providers
GET/ai
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403You may not reach what it touches. The error body.
curl https://cloudgate.octabyte.app/backend/ai \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Create an AI provider
POST/ai
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Request body
| Field | Type | Notes |
|---|---|---|
namerequired | string | Not empty. |
apiUrlrequired | string (uri) | |
apiKeyrequired | string | |
modelrequired | string | Not empty. |
isEnabled | boolean |
Responses
201Created- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/ai \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID" \
-H "content-type: application/json" \
-d '{
"name": "storefront",
"apiUrl": "https://northwind.dev",
"apiKey": "<secret>",
"model": "example"
}'List enabled AI providers
GET/ai/enabled-providers
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403You may not reach what it touches. The error body.
curl https://cloudgate.octabyte.app/backend/ai/enabled-providers \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"List a provider's models
POST/ai/models
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Request body
| Field | Type | Notes |
|---|---|---|
apiUrlrequired | string (uri) | |
apiKeyrequired | string |
Responses
200OK- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/ai/models \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID" \
-H "content-type: application/json" \
-d '{
"apiUrl": "https://northwind.dev",
"apiKey": "<secret>"
}'Suggest a Compose stack with AI
POST/ai/suggest
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Request body
| Field | Type | Notes |
|---|---|---|
aiIdrequired | string | |
inputrequired | string | |
serverId | string or null |
Responses
200OK- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/ai/suggest \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID" \
-H "content-type: application/json" \
-d '{
"aiId": "EuoryVXVYtkcxswEraFUF",
"input": "example"
}'Analyze logs with AI
POST/ai/analyze-logs
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Request body
| Field | Type | Notes |
|---|---|---|
aiIdrequired | string | Not empty. |
logsrequired | string | Not empty. |
contextrequired | string | One of build, runtime. |
Responses
200OK- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/ai/analyze-logs \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID" \
-H "content-type: application/json" \
-d '{
"aiId": "EuoryVXVYtkcxswEraFUF",
"logs": "example",
"context": "build"
}'Test a connection to an AI provider
POST/ai/test-connection
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Request body
| Field | Type | Notes |
|---|---|---|
apiUrlrequired | string (uri) | |
apiKeyrequired | string | |
modelrequired | string | Not empty. |
Responses
200OK- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/ai/test-connection \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID" \
-H "content-type: application/json" \
-d '{
"apiUrl": "https://northwind.dev",
"apiKey": "<secret>",
"model": "example"
}'Test a saved AI provider
POST/ai/{id}/test-connection
The same probe against a config that is already saved. The key comes off the row server-side, because the read path strips it and so the console has nothing to send.
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The AI provider's id. |
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403You may not reach what it touches;404Nothing with that id in this Organization. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/ai/RAU6yAYUXFRdXdPLyLoPC/test-connection \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Deploy an AI-suggested Compose stack
POST/ai/deploy
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Request body
| Field | Type | Notes |
|---|---|---|
environmentIdrequired | string | Not empty. |
idrequired | string | Not empty. |
dockerComposerequired | string | Not empty. |
envVariablesrequired | string | |
serverId | string or null | |
namerequired | string | Not empty. |
descriptionrequired | string | |
domains | array of object | |
domains[].hostrequired | string | Not empty. |
domains[].portrequired | number | At least 1. |
domains[].serviceNamerequired | string | Not empty. |
configFiles | array of object | |
configFiles[].filePathrequired | string | |
configFiles[].contentrequired | string | Not empty. |
Responses
201Created- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches. The error body.
curl -X POST https://cloudgate.octabyte.app/backend/ai/deploy \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID" \
-H "content-type: application/json" \
-d '{
"environmentId": "UVFRqyCfWEtSm6NdDvrZc",
"id": "4HbrppKofUjuRBfrD5AY7",
"dockerCompose": "example",
"envVariables": "example",
"name": "storefront",
"description": "Storefront for Northwind Labs"
}'Get an AI provider
GET/ai/{id}
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The AI provider's id. |
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403You may not reach what it touches;404Nothing with that id in this Organization. The error body.
curl https://cloudgate.octabyte.app/backend/ai/RAU6yAYUXFRdXdPLyLoPC \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Update an AI provider
PATCH/ai/{id}
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The AI provider's id. |
Request body
| Field | Type | Notes |
|---|---|---|
name | string | Not empty. |
apiUrl | string (uri) | |
apiKey | string | |
model | string | Not empty. |
isEnabled | boolean |
Responses
200OK- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches;404Nothing with that id in this Organization. The error body.
curl -X PATCH https://cloudgate.octabyte.app/backend/ai/RAU6yAYUXFRdXdPLyLoPC \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID" \
-H "content-type: application/json" \
-d '{
"name": "storefront",
"apiUrl": "https://northwind.dev",
"apiKey": "<secret>"
}'Delete an AI provider
DELETE/ai/{id}
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The AI provider's id. |
Responses
200OK- The result, as JSON.
- Refusals
401No key, or the key is not valid;403You may not reach what it touches;404Nothing with that id in this Organization. The error body.
curl -X DELETE https://cloudgate.octabyte.app/backend/ai/RAU6yAYUXFRdXdPLyLoPC \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Token spend of an AI model
Read token spend for an AI model
GET/applications/{id}/token-spend
An AI model's spend by UTC day over from..to, split reported and estimated, and by Agent × model served with calls per outcome.
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The id. |
from | query | string | Matches ^\d{4}-\d{2}-\d{2}$. |
to | query | string | Matches ^\d{4}-\d{2}-\d{2}$. |
Responses
200OK- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches;404Nothing with that id in this Organization. The error body.
curl https://cloudgate.octabyte.app/backend/applications/RAU6yAYUXFRdXdPLyLoPC/token-spend \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Token spend of a Project
Read token spend for a Project
GET/projects/{id}/token-spend
The Project's spend by UTC day over from..to (default: the last 30 days), and each Environment's total, summing only the AI models the caller can read.
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The id. |
from | query | string | Matches ^\d{4}-\d{2}-\d{2}$. |
to | query | string | Matches ^\d{4}-\d{2}-\d{2}$. |
Responses
200OK- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches;404Nothing with that id in this Organization. The error body.
curl https://cloudgate.octabyte.app/backend/projects/RAU6yAYUXFRdXdPLyLoPC/token-spend \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Token spend of an Environment
Read token spend for an Environment
GET/environments/{id}/token-spend
The Environment's spend by UTC day over from..to (default: the last 30 days), and each AI model's total, summing only the AI models the caller can read.
Who can call it: Any signed-in member. The route names no permission of its own; Cloudgate checks your role and your access to what it touches as it runs.
Parameters
| Name | In | Type | Notes |
|---|---|---|---|
idrequired | path | string | The id. |
from | query | string | Matches ^\d{4}-\d{2}-\d{2}$. |
to | query | string | Matches ^\d{4}-\d{2}-\d{2}$. |
Responses
200OK- The result, as JSON.
- Refusals
400Validation failed;detailsnames each field;401No key, or the key is not valid;403You may not reach what it touches;404Nothing with that id in this Organization. The error body.
curl https://cloudgate.octabyte.app/backend/environments/RAU6yAYUXFRdXdPLyLoPC/token-spend \
-H "x-api-key: $CLOUDGATE_KEY" \
-H "x-organization-id: $CLOUDGATE_ORG_ID"Something missing or wrong on this page? Email support@octabyte.io, or start a free trial and try it in the console.