AI
Invoke a registered AI prompt from the client. JSON-mode output, streaming, and per-call usage metering — your provider key stays server-side.
The client AI surface proxies a registered prompt to its configured provider and returns the upstream response. Your provider key never reaches the device — the prompt's system text, model, token ceiling, rate limit, and key all live in Amba's backend.
Only prompts marked client_invokable can be reached from the device. Register and configure prompts via the Admin AI API or the amba_ai_prompts_* MCP tools.
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /client/ai/anthropic/messages | Invoke a prompt registered against an Anthropic model. |
| POST | /client/ai/openai/chat/completions | Invoke a prompt registered against an OpenAI model. |
| POST | /client/ai/mistral/chat/completions | Invoke a prompt registered against a Mistral model. |
| POST | /client/ai/prompts/:name/invoke | Invoke by slug in the URL (returns the raw upstream body, no envelope). |
The three vendor-shaped paths are a stable wire surface for the SDK — the actual provider is resolved from the registered prompt, so pick the path that matches how you registered the prompt. All three carry the same body shape. A prompt registered against Gemini works through any of these (or the slug path) too — the backend builds Gemini's distinct contents[] / system-instruction body for you.
Request
| Field | Type | Required | Notes |
|---|---|---|---|
prompt_slug | string | yes | Registered prompt name. (prompt_key is accepted as a legacy alias; prompt_slug wins.) |
variables | object | no | Template variables substituted into the prompt's {{placeholders}}. |
messages | array | no | Conversation history ({ role, content }). When present, supersedes variables. A message's content may be a string or an array of content blocks ({ type: 'text', text } / { type: 'image', url | data, mime? }) for vision input — see Vision. |
images | array | no | SDK convenience for vision input — each { url } or { data, mime } attaches to the last user message as an image content block. See Vision. |
max_tokens | integer | no | Output cap. Clamped to the prompt's configured ceiling — you can ask for less, never more. |
temperature | number | no | Sampling temperature; falls back to the prompt's default. |
enable_prompt_cache | boolean | no | Opt into Anthropic prompt caching for this call. |
stream | boolean | no | When true, the response is a Server-Sent Events stream (see Streaming). |
Response 200
Returns the upstream provider body verbatim, wrapped in the standard { data: … } envelope:
The OpenAI / Mistral paths return their own native chat.completion shape under data.
Every successful call records a usage event server-side, so cost is attributed per user without you instrumenting a counter.
Structured JSON output
Provider-native structured-output controls (response_format, tool_choice, …) are passed through on the registered-prompt body. To force a model to return parseable JSON, configure response_format on the prompt, or pass it through the admin invoke extra_body (allowlisted to provider-native tuning keys):
{"type": "json_object"}— the model returns a syntactically valid JSON object.{"type": "json_schema", "json_schema": { "name": "…", "schema": { … } }}— the model returns JSON conforming to your schema (OpenAI / Mistral).
The response is still the provider's native shape; the JSON your model produced is the text inside the first content block, which you then JSON.parse.
Vision (image input)
A prompt registered against a vision-capable model can receive images. Send them as a message's content array of blocks — { type: 'text', text } and { type: 'image', url } (or { type: 'image', data, mime } for base64) — and the backend maps each block to the provider's native image format:
The web/node SDKs also accept an images convenience array ([{ url }] or [{ data, mime }]) that attaches to the last user message for you.
If the prompt's model is not vision-capable, the request returns 422 ai_model_not_multimodal rather than silently dropping the image — switch the prompt to a vision model (e.g. claude-sonnet-4-5, gpt-4o, gemini-2.5-pro) and retry. Image tokens are metered into the usual usage event.
Streaming
Pass stream: true to receive a Server-Sent Events stream instead of a buffered JSON body. The backend forwards the provider's SSE frames as they arrive (content-type: text/event-stream) and still records the final usage server-side, so cost accounting is preserved on the streamed path.
The buffered SDK methods (Amba.ai.anthropic.messages.create(...)) decode a single JSON envelope
and therefore reject stream: true — consume the SSE stream over the REST endpoint directly (or
from a server function) until a streaming SDK method lands.
Errors
400 INVALID_BODY—prompt_slugmissing.400 INVALID_NAME— prompt name empty or too long.403 NOT_CLIENT_INVOKABLE— the prompt exists but isn't markedclient_invokable.404 PROMPT_NOT_FOUND— no prompt registered under that slug.422 ai_model_not_multimodal— the request included an image but the prompt's model can't accept images; switch the prompt to a vision-capable model.502 AI_GATEWAY_ERROR/502 AI_GATEWAY_UNREACHABLE— upstream provider failure.503 GATEWAY_UNCONFIGURED— the project has no provider key registered yet.
Try it:
/client/ai/anthropic/messagescurl -X POST 'https://api.amba.dev/v1/client/ai/anthropic/messages' \
-H 'Content-Type: application/json' \
-d '{
"prompt_slug": "support_assistant",
"variables": {
"user_query": "How do I cancel?"
},
"max_tokens": 512
}'Curl:
Reference
- AI proxy (SDK feature) — the typed
Amba.ai.*surface. - Admin AI prompts — register + configure prompts.