AI Agents API

Base path /api/ai. Every route needs a signed-in user and an active license. Agent runs also follow the administrator's AI settings: with AI agents switched off they answer 403 AGENTS_DISABLED, and with rate limiting on, too many runs answer 429 RATE_LIMITED. Errors are JSON with error (a sentence you can show) and code.

Routes

MethodEndpointPurpose
GET/api/ai/agentsThe agent ids
POST/api/ai/agents/:idRun an agent; ?async=true queues it when the async mode allows
GET/api/ai/agents/:id/runsRun history of one agent
GET/api/ai/agents/jobsQueued runs
GET/api/ai/agents/jobs/:idOne queued run, with its result
DELETE/api/ai/agents/jobs/:idCancel a queued or running job
GET/api/ai/statusWhether a provider is set up
GET/api/ai/providersThe providers you can choose
GET/api/ai/settingsThe AI settings
PUT/api/ai/settingsChange the AI settings (admin)
POST/api/ai/nl-to-sqlThe IDE's question-to-SQL request
POST/api/ai/chatThe IDE's AI assistant
POST/api/ai/review-scriptThe AI review on approvals

Run an agent

POST /api/ai/agents/script-review
{ "input": { "script": "DELETE FROM orders;", "connectionId": "6f1c…" } }

The ids are script-review, nl-to-sql, schema-explorer, error-diagnosis, query-optimization, auto-rollback, change-impact, release-summary, compliance and anomaly-detection. With a connectionId the agent uses that connection's engine; without one, agents that allow it need dialect, one of the engines the server supports.

AgentInput
script-reviewscript; connectionId or dialect; optional notes
nl-to-sqlprompt, connectionId
schema-explorerconnectionId; history: the turns so far, each { "role": "user" | "assistant", "content": "…" }, ending with the user's question
error-diagnosissql, errorMessage; connectionId or dialect
query-optimizationsql (one statement), connectionId
auto-rollbackforwardScript, dialect; optional preConditions
change-impactscript, connectionId
release-summaryreleaseId; or releaseName, version and scripts: [{ "name", "script", "environment"? }]
compliancescript, dialect; optional environment
anomaly-detectionoptional scriptId and lookbackCount (1 to 1000, default 200)

Text fields are limited to 200,000 characters. A missing or invalid field is refused before anything runs:

400 { "ok": false, "error": "dialect is required when no connection is chosen: one of postgresql, mysql, …", "code": "INVALID_AGENT_INPUT" }

A finished run answers 200:

{ "ok": true,
  "result": { "riskScore": "high", "summary": "…", "findings": [ … ], "suggestedRollback": null },
  "runId": "…", "ms": 2380, "model": "…",
  "usage": { "promptTokens": 1240, "completionTokens": 380, "totalTokens": 1620 },
  "warnings": [ "1 table is left out of the AI context by an administrator's exclusion list." ],
  "cached": false }

model and usage are absent when the agent answered without the AI model. A failed run answers with ok: false, error, code and the status of the cause (see Error codes). Each agent's output is described on its page in the AI Agents guide.

Queued runs

When the administrator's async mode is Always, or it is Opt-in and you add ?async=true, the run is queued:

202 Location: /api/ai/agents/jobs/8c2e…
{ "jobId": "8c2e…", "status": "pending" }

Poll GET /api/ai/agents/jobs/:id until status is success, error or cancelled. The job carries agent, status, input, result, warnings, error_message, run_id, enqueued_at, started_at, finished_at, ms, model and cost_total_tok. GET /api/ai/agents/jobs?limit=50 lists jobs without their input and result. DELETE cancels a job that is pending or running; a job that has finished answers 404 JOB_NOT_FOUND. A job left running for 10 minutes, for example after a restart, is queued again.

Users see and cancel only their own jobs; administrators see all. Someone else's job, or an id that is not a UUID, answers 404 JOB_NOT_FOUND.

Run history

GET /api/ai/agents/script-review/runs?limit=50
{ "runs": [ { "id": "…", "agent": "script-review", "status": "success", "user_email": "dba@example.com",
              "model": "…", "input_summary": "dialect=postgresql, 412c, schema=yes", "output_summary": "risk=high, findings=4",
              "cost_total_tok": 1820, "ms": 2380, "error_message": null, "created_at": "…" } ] }

limit is 1 to 500, default 50. Besides the ten agents, ide-chat, review-script and blast-radius-narrative have run history. Users see their own runs; administrators see everyone's. Prompts and answers are not stored.

Status and providers

GET /api/ai/status
{ "configured": true, "provider": "anthropic", "model": "…" }

Administrators also get endpoint. GET /api/ai/providers lists each provider's id, label, defaultModel, requiresApiKey and requiresEndpoint.

Settings

GET /api/ai/settings gives other users provider, model, apiKeySet and scriptReviewMode. Administrators also get endpoint, apiVersion, deployment, region, projectId, awsRoleArn, awsAccessKeyIdSet, awsSecretAccessKeySet, awsSessionTokenSet, extraHeaders (names with the value [stored]), maxTokens, temperature, timeoutMs and agents. Keys are never returned.

PUT /api/ai/settings
{ "provider": "anthropic", "apiKey": "…", "model": "…", "temperature": 0.2,
  "extraHeaders": { "X-Team": "[stored]", "X-Gateway": "eu-1" },
  "agents": { "globalEnabled": true, "schemaDetailLevel": "types", "excludedTables": "hr.salaries, payroll",
              "sendRowData": false, "schemaTableCap": 0, "rateLimitEnabled": true, "rateLimitPerMinute": 30,
              "cacheEnabled": false, "cacheTtlSeconds": 300, "asyncMode": "opt-in" } }

Send only the fields you change. An empty or missing apiKey, awsAccessKeyId, awsSecretAccessKey or awsSessionToken keeps the stored value; a header sent as [stored] keeps its value and a header left out is removed. Secrets are encrypted before they are stored. This is the only way to change AI settings: the general settings API refuses ai_ and agents_ keys with 400 USE_AI_SETTINGS. Invalid values are refused, naming every problem:

400 { "error": "temperature must be a number from 0 to 2; agents.asyncMode must be off, opt-in, always", "code": "INVALID_AI_SETTINGS" }
FieldAllowed
providerAn id from /api/ai/providers, or empty
endpointAn http:// or https:// URL, up to 500 characters
awsRoleArnAn IAM role ARN
maxTokens / temperature / timeoutMs1 to 200,000 / 0 to 2 / 1,000 to 600,000
extraHeadersUp to 20 headers with valid names and values of up to 2,000 characters
scriptReviewModeauto or manual
agents.schemaTableCap / rateLimitPerMinute / cacheTtlSeconds0 to 100,000 / 1 to 10,000 / 1 to 86,400
agents.schemaDetailLevel / asyncModenames, types, full / off, opt-in, always
agents.globalEnabled, rateLimitEnabled, cacheEnabled, sendRowDatatrue or false

IDE and approval requests

RequestBodyAnswer
POST /api/ai/nl-to-sqlprompt, connectionId{ "success": true, "content": "SELECT …;", "model", "usage" }
POST /api/ai/chatmessages: the conversation, last 20 turns used; optional connectionId{ "success": true, "content": "…", "model", "usage" }
POST /api/ai/review-scriptscript; optional databaseType (no engine is assumed without it){ "success": true, "riskScore", "findings", "summary" }; riskScore is low, medium, high or critical. An answer from the model without a usable risk score, or not in the review format, is 502 with success: false and the reason; no risk is guessed

They follow the same settings as the agents, are recorded in the run history, and answer failures with success: false, error, code and the status below.

Error codes

StatusCodeMeaning
400INVALID_AGENT_INPUTA field is missing or invalid; the message names it
400INVALID_AI_SETTINGSA setting is out of range; the message names each one
400USE_AI_SETTINGSAn AI setting was sent to /api/db-devops/settings; use PUT /api/ai/settings
403AGENTS_DISABLEDAn administrator switched AI agents off
404CONNECTION_NOT_FOUNDThe connection does not exist
404RELEASE_NOT_FOUNDThe release does not exist
404JOB_NOT_FOUNDNo such job for you, or it has already finished (on cancel)
404AGENT_NOT_FOUNDNo agent, or no run history, with that id
429RATE_LIMITEDToo many runs of this agent this minute; the message says how long to wait
503AI_NOT_CONFIGUREDNo AI provider is set up
502CONNECTION_FAILEDThe connection could not be opened
502SCHEMA_UNREADABLEThe schema or foreign keys could not be read
502HISTORY_UNREADABLEThe script run history could not be read
502MODEL_ANSWER_UNUSABLEThe AI model's answer was missing something or could not be read; run again
502MODEL_ANSWER_CUT_OFFThe AI model's answer stopped at the Max Tokens limit; raise Max Tokens, then run again
502AI_REQUEST_FAILEDThe AI provider returned an error or did not answer
502AGENT_RUN_FAILEDThe run failed for another reason; the message says why
500JOB_ENQUEUE_FAILEDThe run could not be queued
500AI_SETTINGS_UNREADABLE / AI_SETTINGS_SAVE_FAILEDThe settings store could not be read or written