Docs
Open the console →
API reference

API reference: AI assistant

Cushy assistant API: POST a conversation (optionally with image attachments) to a real OpenAI-compatible model, grounded on an org-scoped infrastructure summary and RAG retrieval.

POST/api/assistant/chatSession

Send the conversation ({ messages: [{ role, content, images? }] }; roles user/assistant, last must be user). The server grounds the model on a live, read-only data digest of YOUR org (real spend figures and trends, inventory, the network topology graph, alerts and Terraform state) plus your org's most-similar prior Q&A and indexed cost/topology insight documents (RAG), calls the configured OpenAI-compatible backend, and returns the answer. A user turn may carry up to 4 image attachments (png/jpeg/webp/gif, ≤5MB each, base64 + mediaType) forwarded as multimodal content — transient, never stored. Audited assistant.query.

Example request
json
{ "messages": [ { "role": "user", "content": "Which VPCs have no NAT gateway?" } ] }
Example response
json
{ "text": "…", "model": "gemini-…", "usage": { "…": "…" } }
Errors
StatusWhen
400Malformed conversation, an assistant turn with images, or an over-limit attachment.
401Not signed in.
429Per-user rate limit.
502The model backend errored or is unreachable (never a fabricated answer).
503No AI backend configured — { configured: false }.
POST/api/assistant/deploySession · mutate_infra

The DEPLOYER assistant. Send the conversation ({ messages: [{ role, content }] }) describing what to deploy; the server grounds the model on YOUR org's real blueprint catalog, connected cloud accounts and Terraform folders, then RESOLVES the model's answer against that same real data and returns a validated draft proposal ({ blueprintId, accountId, workspaceId|null, workspaceName, vars, missing[] }) plus the prose reply. THIS ROUTE MUTATES NOTHING — no workspace, no plan, no apply: the draft is handed to the deploy wizard, which runs the unchanged plan → policy → cost → approve → apply pipeline. A blueprint, account or folder the model names that does not exist comes back as { proposal: null, unresolved: { kind, detail } } — never a substitute. Audited assistant.deploy_proposed.

Example request
json
{ "messages": [ { "role": "user", "content": "a t3.small web server in eu-west-1" } ] }
Example response
json
{ "reply": "…", "proposal": { "blueprintId": "aws/compute-instance", "accountId": 12, "workspaceId": null, "workspaceName": "web-staging", "vars": {}, "missing": [] }, "unresolved": null }
Errors
StatusWhen
400Malformed conversation.
401Not signed in.
403Your role lacks mutate_infra (a Viewer cannot draft a deployment).
429Per-user rate limit.
502The model backend errored or is unreachable.
503No AI backend configured — { configured: false }.