AI API
Chat completions and embeddings with the project's own key or plan credits, metered per app and per user.
Base URL: your app's origin ($APP_ORIGIN): the published host, a custom domain, or the platform origin for the builder preview. Errors answer { ok: false, error: { code, message } } unless noted. Add x-appbricx-env: dev or prod to pick the database explicitly; otherwise the host decides (preview means dev, a published host means prod).
Authentication
- App key
- A project key or preview token identifies the app. No user session is needed.
Authorization: Bearer $APP_KEY
Endpoints
Chat completion
POST/__appbricx/ai/chat
One chat completion with the project's resolved model. Streams server-sent events by default; send stream: false for one JSON answer. The project's system prompt is prepended.
- Auth
- App key:
Authorization: Bearer $APP_KEY
Body
| Name | Type | Description |
|---|---|---|
messagesrequired | Array<{ role, content }> | 1 to 64 messages; role is system, user or assistant. |
streamoptional | boolean | Default true (SSE). false answers JSON. |
max_tokensoptional | number | Upper bound on the answer (the project cap applies). |
Response
Streaming: data: {"type":"text_delta","data":"…"} events, then {"type":"done","data":{ usage }} and [DONE].
{
"ok": true,
"content": "The floor 3 printer jams when printing on A3.",
"usage": {
"prompt_tokens": 21,
"completion_tokens": 11
},
"elapsed_ms": 840
}Errors
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key"). |
| 429 | RATE_LIMITED | The project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default). |
| 403 | TOOL_NOT_ALLOWED | The key may not call ai.chat. |
| 400 | PARAMS_INVALID | messages missing, too many, or malformed. |
| 413 | PAYLOAD_TOO_LARGE | Body over 1 MB. |
| 400 | INPUT_TOO_LARGE | Prompt over the project's input cap. |
| 402 | BUDGET_EXCEEDED | Per-user or project token budget spent. |
| 402 | INSUFFICIENT_CREDITS | Plan credits used up (platform-funded key). |
| 403 | MODEL_NOT_ALLOWED | The model isn't on the project's allow-list. |
| 503 | AI_DISABLED_FOR_PROJECT | AI is off for this project. |
| 503 | PROVIDER_ERROR | The provider failed. |
curl -X POST "$APP_ORIGIN/__appbricx/ai/chat" \
-H "Authorization: Bearer $APP_KEY" \
-H "content-type: application/json" \
-d '{"messages":[{"role":"user","content":"Summarize: the printer on floor 3 jams on A3 paper."}],"stream":false,"max_tokens":120}'const res = await fetch(`${APP_ORIGIN}/__appbricx/ai/chat`, {
method: "POST",
headers: {
Authorization: `Bearer ${APP_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({
"messages": [
{
"role": "user",
"content": "Summarize: the printer on floor 3 jams on A3 paper."
}
],
"stream": false,
"max_tokens": 120
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);Source: services/api/src/routes/ai-proxy.ts:833
Embeddings
POST/__appbricx/ai/embed
Embedding vectors for a batch of texts with the configured embedding provider.
- Auth
- App key:
Authorization: Bearer $APP_KEY
Body
| Name | Type | Description |
|---|---|---|
textsrequired | string[] | 1 to 100 texts, each up to 8192 characters. |
Response
{
"ok": true,
"vectors": [
[
0.012,
-0.034,
"…"
],
[
0.021,
0.004,
"…"
]
],
"model": "text-embedding-3-small",
"dimensions": 1536,
"elapsed_ms": 210
}Errors
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key"). |
| 429 | RATE_LIMITED | The project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default). |
| 403 | TOOL_NOT_ALLOWED | The key may not call ai.embed. |
| 400 | PARAMS_INVALID | texts missing, too many or too long. |
| 402 | BUDGET_EXCEEDED | Budget spent. |
| 503 | AI_DISABLED_FOR_PROJECT | AI is off. |
| 503 | EMBEDDING_NOT_CONFIGURED | No embedding provider. |
| 503 | PROVIDER_ERROR | The provider failed. |
curl -X POST "$APP_ORIGIN/__appbricx/ai/embed" \
-H "Authorization: Bearer $APP_KEY" \
-H "content-type: application/json" \
-d '{"texts":["printer jams on A3","projector won't turn on"]}'const res = await fetch(`${APP_ORIGIN}/__appbricx/ai/embed`, {
method: "POST",
headers: {
Authorization: `Bearer ${APP_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({
"texts": [
"printer jams on A3",
"projector won't turn on"
]
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);Source: services/api/src/routes/ai-proxy.ts:1091