Skip to main content

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 (25 or 50 — see that endpoint's OpenAPI spec). There is currently no enforced maximum: passing a very large limit returns that many rows.
  • offset — Number of results to skip (default 0).
  • There is no cursor, page, or sort/order query 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:

ModuleDescription
UsersUser accounts, authentication, and bootstrap
ProjectsProjects, membership, and access control
API KeysAPI keys scoped to projects
SecretsEncrypted project secrets
FilesFile storage and retrieval
DocumentsDocument management and processing
ConversationsConversation sessions and state
ChatsReal-time messaging and AI interactions
AgentsAutonomous agents and tool execution
WebhooksEvent subscriptions and deliveries
AI ProvidersLLM 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.