AI Chat
Streaming AI assistants over your catalog. Unlike the product API, these routes
are not under /api/swayzio/v1 — they live at https://app.swayzio.com/api/ai.
Both run on the Node.js runtime with a maxDuration of 120s and stream their
responses (they are not plain JSON endpoints).
Each route requires a Clerk actor (bearer token; the dev header is honored in non‑production only) plus a paid entitlement. Under the hood both forward the caller’s bearer to the Agent Tools routes to execute tools, so every tool call stays owner‑scoped and audited. Telemetry deliberately records no inputs or outputs (no PII).
Endpoints
| Method | Path | Purpose | Auth | Request | Response |
|---|---|---|---|---|---|
POST | /api/ai/assistant | Multi‑turn Inspector chat | Clerk actor + ai.assistant | assistantRequestSchema | UI‑message stream |
POST | /api/ai/catalog | Single‑shot catalog assistant | Clerk actor + ai.catalog | { prompt } (strict) | plain‑text stream |
These are streaming endpoints. /api/ai/assistant emits an AI SDK
UI‑message part stream (consume with useChat or readUIMessageStream);
/api/ai/catalog emits a plain text stream (toTextStreamResponse). Neither
returns a single JSON document. Both set Cache-Control: no-store.
Missing or invalid auth returns 401 { "error": "Unauthorized" }. A denied
paid entitlement returns the standard 403 entitlement payload (see
Authentication). When no agent tools are active or the model
provider errors, the route returns 502.
POST /api/ai/assistant
Multi‑turn chat for the Inspector panel. The request is the AI SDK useChat
shape — a messages array — with an optional trackId for context. It streams
UI message parts, including the approval card for the write tool.
Tools available: searchTracks, getTrackContext, getRightsContext,
findMissingMetadata, suggestProcessingRetries, listPacks (read), plus
addTrackToPack — an approval‑gated write. When the model wants to add a
track to a pack, the stream pauses on an approval‑requested part; the UI renders
an Approve / Cancel card and the tool only executes after the user approves.
Active tools are discovered from /v1/agent-tools/contracts per request.
curl -N -X POST https://app.swayzio.com/api/ai/assistant \
-H "Authorization: Bearer $SWAYZIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"trackId": "trk_456",
"messages": [
{ "role": "user", "parts": [{ "type": "text", "text": "What rights metadata is missing on this track?" }] }
]
}'Consume the stream with the AI SDK rather than parsing it by hand:
import { useChat } from "@ai-sdk/react";
const { messages, sendMessage } = useChat({
api: "/api/ai/assistant",
body: { trackId },
headers: { authorization: `Bearer ${token}` },
});POST /api/ai/catalog
A single‑shot, read‑only catalog assistant. The body is strict:
{ "prompt": string } (trimmed, 1–1000 chars; unknown fields rejected). It
streams plain text and sets an x-swayzio-ai-thread-id response header for
correlation.
Tools available (read‑only): searchTracks, getTrackContext,
getRightsContext, findMissingMetadata, suggestProcessingRetries. There is
no write tool on this route — it can inspect and suggest only.
curl -N -X POST https://app.swayzio.com/api/ai/catalog \
-H "Authorization: Bearer $SWAYZIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "prompt": "Which of my tracks are missing a split sheet?" }'const res = await fetch("https://app.swayzio.com/api/ai/catalog", {
method: "POST",
headers: {
authorization: `Bearer ${token}`,
"content-type": "application/json",
},
body: JSON.stringify({ prompt: "Summarize my catalog by genre." }),
});
const threadId = res.headers.get("x-swayzio-ai-thread-id");
const reader = res.body!.pipeThrough(new TextDecoderStream()).getReader();
for (let chunk; !(chunk = await reader.read()).done; ) {
process.stdout.write(chunk.value); // plain-text chunks
}Both assistants answer only from authenticated tool results and never expose owner ids, tokens, storage URIs, or raw provider payloads. For the underlying tool contracts and the audit trail, see Agent Tools; for the entitlement model see Authentication.