REST API Reference
The SOAT REST API provides standard HTTP endpoints for all platform operations. Every endpoint is versioned, authenticated, and returns JSON responses.
Base URL
https://your-soat-server.com
Replace your-soat-server.com with your SOAT instance URL. For development, use http://localhost:3000.
Authentication
The API supports two authentication methods:
User Authentication (JWT Bearer Token)
For user accounts, authenticate using JWT bearer tokens obtained after login:
# 1. Bootstrap the first admin user
curl -X POST https://your-soat-server.com/api/v1/users/bootstrap \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "supersecret"}'
# 2. Login to get a token
curl -X POST https://your-soat-server.com/api/v1/users/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "supersecret"}'
# Response: {"token": "eyJhbGc..."}
# 3. Use the token in requests
curl https://your-soat-server.com/api/v1/users \
-H "Authorization: Bearer eyJhbGc..."
JWT tokens expire after 7 days.
Project Key Authentication
For programmatic access to a specific project, use API keys (project keys). Create a project key through the API, then authenticate requests with it:
# Create a project key (requires user authentication first)
curl -X POST https://your-soat-server.com/api/v1/project-keys \
-H "Authorization: Bearer <user-token>" \
-H "Content-Type: application/json" \
-d '{"projectPublicId": "proj_xyz", "policyIds": [1]}'
# Response: {"id": "sk_...", "secret": "sk_..."}
# Use the key in requests (set the full "ID" string as bearer token)
curl https://your-soat-server.com/api/v1/projects/proj_xyz/files \
-H "Authorization: Bearer sk_..."
Project keys are scoped to a single project and inherit permissions from the associated policy.
Common Patterns
Error Responses
All errors return a 4xx or 5xx status code. Most business-logic errors use a structured shape with a stable code:
{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Project 'proj_abc123' not found.",
"meta": { "id": "proj_abc123" }
}
}
meta is optional and present only for some error codes. A handful of legacy authentication/authorization checks instead return a plain string in error with no code or meta, e.g. { "error": "Unauthorized" } or { "error": "Forbidden" }. Unhandled server errors always return 500 with { "error": "Internal Server Error" } — the underlying exception message is never forwarded to the client.
Common status codes:
- 200 — Success
- 201 — Created
- 400 — Bad Request (invalid parameters)
- 401 — Unauthorized (missing or invalid token)
- 403 — Forbidden (insufficient permissions)
- 404 — Not Found
- 409 — Conflict (e.g., duplicate resource)
- 500 — Internal Server Error
Pagination
Only endpoints that return a history/log of records — for example
GET /api/v1/trigger-firings, GET /api/v1/webhook-deliveries,
GET /api/v1/traces, GET /api/v1/generations, GET /api/v1/sessions,
GET /api/v1/files, GET /api/v1/secrets, GET /api/v1/actors, and
GET /api/v1/ai-providers — accept limit/offset query parameters:
curl 'https://your-soat-server.com/api/v1/trigger-firings?trigger_id=trg_abc&limit=25&offset=0' \
-H "Authorization: Bearer <token>"
limit— Number of results per page. The default varies by endpoint (25or50— see that endpoint's OpenAPI spec). There is currently no enforced maximum: passing a very largelimitreturns that many rows.offset— Number of results to skip (default0).- There is no
cursor,page, orsort/orderquery parameter on any endpoint. Sort order (when defined) is fixed per endpoint — check that resource's module doc — and is not client-configurable.
Primary resource-list endpoints that are not paginated (GET /api/v1/projects, GET /api/v1/triggers, GET /api/v1/orchestrations, GET /api/v1/orchestration-runs, GET /api/v1/webhooks, GET /api/v1/agents, and others) return the full array of matching resources in one response — do not send limit/offset to these.
There are currently no per-project or per-API-key request-rate limits, quotas, or throttling enforced by the server — every authenticated request is processed immediately, bounded only by the resource limits described above and the 1 MiB inbound webhook body cap.
Path and Query Parameters
Path parameters are replaced in the URL; query parameters are appended:
# Path parameter: file ID in the URL
GET /api/v1/files/{id}
curl https://your-soat-server.com/api/v1/files/file_abc123
# Query parameters: appended to the URL
GET /api/v1/files?projectPublicId=proj_123&limit=10
curl 'https://your-soat-server.com/api/v1/files?projectPublicId=proj_123&limit=10'
Request Body
POST and PUT requests accept JSON request bodies with Content-Type: application/json:
curl -X POST https://your-soat-server.com/api/v1/files \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "report.pdf",
"projectPublicId": "proj_123"
}'
File uploads use multipart/form-data instead:
curl -X POST https://your-soat-server.com/api/v1/files/upload \
-H "Authorization: Bearer <token>" \
-F "file=@report.pdf" \
-F "projectPublicId=proj_123"
Modules
The REST API is organized into modules, each covering a specific resource:
| Module | Description |
|---|---|
| Users | User accounts, authentication, and bootstrap |
| Projects | Projects, membership, and access control |
| API Keys | API keys scoped to projects |
| Secrets | Encrypted project secrets |
| Files | File storage and retrieval |
| Documents | Document management and processing |
| Conversations | Conversation sessions and state |
| Chats | Real-time messaging and AI interactions |
| Agents | Autonomous agents and tool execution |
| Webhooks | Event subscriptions and deliveries |
| AI Providers | LLM provider configuration |
TypeScript SDK
For TypeScript projects, use the @soat/sdk package to interact with the REST API with full type safety and autocompletion:
import { createSoatClient } from '@soat/sdk';
const soat = createSoatClient({
baseUrl: 'https://your-soat-server.com',
token: 'your-bearer-token',
});
const { data: files } = await soat.GET('/api/v1/files', {
params: { query: { projectPublicId: 'proj_123' } },
});
Every endpoint, parameter, and response schema is fully typed.
OpenAPI Specification
The REST API is defined in OpenAPI 3.1 format. Download the spec:
GET https://your-soat-server.com/openapi.yaml
Use this spec to generate clients in any language or integrate with API documentation tools.