Runtime API overview
alquimia-runtime exposes a single HTTP API for agent inference, registry management, session state, webhooks, and knowledge operations. It is the boundary between your applications and the Alquimia Platform execution engine.
API responsibilities
Section titled “API responsibilities”The runtime API handles:
- Authentication — API tokens, JWT, and Keycloak OIDC.
- Inference — synchronous and streaming agent execution via SSE.
- Registry — storing, versioning, and retrieving agent configurations.
- State — querying and resuming task state.
- Channels — webhook endpoints for WhatsApp, Slack, Email, and custom adapters.
- Webhooks — subscribing to and emitting platform events.
Async inference
Section titled “Async inference”Inference is non-blocking. A client posts a request and receives a task identifier, then opens an SSE stream to receive progress events and the final response.
POST /event/infer/{assistant_id} │ ▼ task_id returned │ ▼GET /event/stream/{task_id} │ ▼SSE events ──► final responseThis design keeps long-running agents from tying up HTTP connections and lets workers scale independently.
Endpoint summary
Section titled “Endpoint summary”All endpoints except /health/* and the channel webhook paths require a Bearer token in the Authorization header when AUTH_PROVIDER=api_token (the default).
| Method | Path | Auth | Summary |
|---|---|---|---|
GET | /health/liveness | No | Liveness probe |
GET | /health/readiness | No | Readiness probe (checks DB + Redis) |
POST | /auth/refresh | No | Refresh a Keycloak access token |
POST | /event/infer/{assistant_id} | Yes | Trigger agent inference |
GET | /event/infer/{assistant_id}/{channel_id} | Channel verifier | Channel webhook challenge |
POST | /event/infer/{assistant_id}/{channel_id} | Channel verifier | Channel inference |
GET | /event/stream/{task_id} | Yes | Stream inference events (SSE) |
WS | /streaming/{assistant_id}/{channel_id} | Channel verifier | Real-time bidirectional audio stream (Twilio Media Streams / WebRTC) |
POST | /event/tool-approval | Yes | Submit human tool approval |
POST | /event/tool-completion | Yes | Submit client-side tool result |
POST | /context/persist | No | Persist conversation context |
GET | /context/retrieve | Yes | Retrieve conversation context |
POST | /context/blob/upload | Yes | Upload a blob to session context |
GET | /context/blob/download/{blob_id} | Yes | Download a session blob |
GET | /registry/ | Yes | Get a registry (agentspace) |
POST | /registry/ | Yes | Create a registry |
PUT | /registry/ | Yes | Update a registry |
DELETE | /registry/ | Yes | Delete a registry |
POST | /registry/query | Yes | Query registries by filter |
POST | /registry/validate | Yes | Validate and migrate agent specs |
POST | /registry/agent | Yes | Create or update an agent |
POST | /registry/agent/query | Yes | Query agents by filter |
DELETE | /registry/agent | Yes | Delete agents by filter |
PUT | /registry/agent/hold/{assistant_id} | Yes | Put an agent on hold |
PUT | /registry/agent/unhold/{assistant_id} | Yes | Remove an agent from hold |
POST | /registry/secret | Yes | Add a secret to a registry |
GET | /registry/secret | Yes | List secrets in a registry |
POST | /registry/secret/query | Yes | Query secrets by filter |
POST | /registry/secret/inspect/{assistant_id} | Yes | Inspect secrets for an agent |
DELETE | /registry/secret | Yes | Delete secrets by filter |
POST | /registry/model | Yes | Add a model registration to a registry |
GET | /registry/model | Yes | List model registrations in a registry |
POST | /registry/model/query | Yes | Query model registrations by filter |
DELETE | /registry/model | Yes | Delete model registrations by filter |
POST | /registry/brain | Yes | Register a Boltzmann brain |
PUT | /registry/brain/{brain_id} | Yes | Update a brain registration |
GET | /registry/brain | Yes | List registered brains |
GET | /registry/brain/{brain_id} | Yes | Get one brain registration |
POST | /registry/brain/query | Yes | Query brains by filter |
DELETE | /registry/brain | Yes | Deregister brains by filter |
POST | /registry/parameters | Yes | Add parameters to a registry |
POST | /registry/parameters/query | Yes | Query parameters by filter |
DELETE | /registry/parameters | Yes | Delete parameters by filter |
GET | /registry/explore/repos | Yes | List OCI registry repositories |
GET | /registry/explore/tags | Yes | List tags for an OCI repository |
PUT | /registry/publish | Yes | Publish a registry to OCI |
PUT | /registry/unpublish | Yes | Remove a registry from OCI |
PUT | /registry/pull | Yes | Pull a registry from OCI and overwrite the local workspace |
PUT | /registry/fetch | Yes | Pull an OCI tag into a cached versioned snapshot |
PUT | /registry/load-version | Yes | Load a cached versioned snapshot for inference |
GET | /registry/versions | Yes | List cached versioned snapshots |
DELETE | /registry/version/{tag} | Yes | Delete a cached versioned snapshot |
GET | /tools | Yes | List tool registrations |
GET | /tools/{registered_tool_id} | Yes | Get a tool registration |
POST | /tools | Yes | Register or update a tool (admin only) |
PUT | /tools/{registered_tool_id}/operations | Yes | Replace a tool’s operations (admin only) |
DELETE | /tools/{registered_tool_id} | Yes | Delete a tool registration (admin only) |
GET | /knowledge/topics | Yes | List knowledge topics |
GET | /knowledge/topics/{topic_id} | Yes | Get a topic by ID |
POST | /knowledge/topics | Yes | Create a topic |
DELETE | /knowledge/topics/{topic_id} | Yes | Delete a topic |
PUT | /knowledge/topics/{topic_id}/update | Yes | Update a topic |
PUT | /knowledge/topics/{topic_id}/tag | Yes | Tag a topic |
PUT | /knowledge/topics/{topic_id}/untag | Yes | Untag a topic |
PUT | /knowledge/topics/{topic_id}/policy | Yes | Update a topic’s access policy |
POST | /knowledge/topics/search/{topic_id} | Yes | Semantic search within a topic |
PUT | /knowledge/topics/{topic_id}/add/{file_id} | Yes | Add a file to a topic |
PUT | /knowledge/topics/{topic_id}/remove/{file_id} | Yes | Remove a file from a topic |
GET | /knowledge/files | Yes | List knowledge files |
POST | /knowledge/files/upload | Yes | Upload a knowledge file |
GET | /knowledge/files/download/{file_id} | Yes | Download a knowledge file |
DELETE | /knowledge/files/delete/{file_id} | Yes | Delete a knowledge file |
PUT | /knowledge/files/{file_id}/tag | Yes | Tag a knowledge file |
PUT | /knowledge/files/{file_id}/untag | Yes | Untag a knowledge file |
PUT | /task/state/{task_id}/{state_id} | Yes | Update controller state (run/stop/restart) |
GET | /worklog/ | Yes | List inference runs (paginated, with filters) |
GET | /worklog/{task_id} | Yes | Full detail for one inference run |
GET | /worklog/{task_id}/events | Yes | All worklog events for a task |
GET | /worklog/{task_id}/verify | Yes | Verify the tamper-evident hash chain for a task |
POST | /webhooks/ | Yes | Register a webhook subscription |
GET | /webhooks/ | Yes | List webhook subscriptions for an agentspace |
GET | /webhooks/{id} | Yes | Get a webhook subscription |
PUT | /webhooks/{id} | Yes | Update a webhook subscription (URL, event types, active, rotate key) |
DELETE | /webhooks/{id} | Yes | Delete a webhook subscription |
The two /event/infer/{assistant_id}/{channel_id} endpoints are public webhook URLs intended to be called by external channel providers (WhatsApp, Slack, email gateways, etc.). Authentication is provider-specific and implemented by the channel itself.
Key endpoints in detail
Section titled “Key endpoints in detail”POST /event/infer/{assistant_id}
Section titled “POST /event/infer/{assistant_id}”Trigger inference for a named agent. Returns a CommonAttributes object containing the task_id you can use to stream results.
Path parameter: assistant_id — the agent identifier in the registry. As of runtime 0.5.1, the identifier may include a version tag: <assistant_id>:<tag>.
Query parameter: agentspace_id (default: "default") — the registry namespace.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
query | string or array | No | Plain text or OpenAI-style content parts for multimodal input. At least one of query or input_audio must be provided |
input_audio | Blob | No | Base64-encoded audio data for audio-only inference (Core 0.5.1+) |
task_id | string | No | Auto-generated if omitted |
session_id | string | No | Auto-generated if omitted |
user_id | string | No | Auto-generated if omitted |
extra_instructions | object | No | Key-value pairs injected as prompt clauses |
evaluation_strategy | object | No | Override the agent’s evaluation strategy |
knowledge_base | array | No | Additional knowledge bases to include |
The resolved version_tag is returned in the response and propagated through inference entry points (event, streaming, live, and channel_notifications).
Responses
| Code | Description |
|---|---|
200 | CommonAttributes with task_id, session_id, assistant_id, agentspace_id, and version_tag |
400 | Agent not found, on hold, or missing secrets |
500 | Connection error (Redis, Kafka, or downstream service) |
Example:
curl -X POST http://localhost:8080/event/infer/support-bot \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "query": "What is your return policy?", "session_id": "session-abc123", "user_id": "user-42" }'GET /event/stream/{task_id}
Section titled “GET /event/stream/{task_id}”Stream inference progress as Server-Sent Events. Poll this after calling /event/infer/.
curl -N http://localhost:8080/event/stream/task-abc123 \ -H "Authorization: Bearer $API_TOKEN"The stream emits WorklogRecord events and closes when an AssistantInferenceResponse event is received.
WS /streaming/{assistant_id}/{channel_id}
Section titled “WS /streaming/{assistant_id}/{channel_id}”Open a real-time bidirectional audio stream for a held phone or WebRTC call. The runtime validates the channel configuration, performs Twilio Account SID verification on the start event, enforces per-source session limits, and segments turns with energy-based VAD. Assistant replies are streamed back as μ-law audio.
The WebSocket path is:
ws://localhost:8080/streaming/{assistant_id}/{channel_id}assistant_idmay include a version tag (support-bot:v1.2.0).channel_idmust match astreaming_channelsentry in the agent spec.- Close code
1008is returned for policy violations (for example, an invalid Account SID or rate limit exceeded). - Close code
1011is returned for internal server errors.
Streaming sessions are governed by the STREAMING_CHANNEL_* runtime settings. See Runtime configuration reference and Connect a messaging or voice channel for details.
GET /worklog/
Section titled “GET /worklog/”Query the persistent inference history stored in PostgreSQL. Supports filtering by session_id, user_id, assistant_id, agentspace_id, final_status, started_after, and started_before. Paginated via limit (1–200) and offset.
curl "http://localhost:8080/worklog/?assistant_id=support-bot&limit=20" \ -H "Authorization: Bearer $API_TOKEN"GET /worklog/{task_id}/verify
Section titled “GET /worklog/{task_id}/verify”Verify the tamper-evident hash chain for a task. The endpoint walks every worklog event in insertion order and checks that previous_hash links and entry_hash values match the canonical payload. If any row has been modified or reordered, the first break is returned.
curl "http://localhost:8080/worklog/task-abc123/verify" \ -H "Authorization: Bearer $API_TOKEN"POST /registry/validate
Section titled “POST /registry/validate”Validates all agent specs in a registry and applies automatic migrations. Use dry_run=true to preview changes without committing them.
curl -X POST "http://localhost:8080/registry/validate?agentspace_id=default&dry_run=true" \ -H "Authorization: Bearer $API_TOKEN"POST /webhooks/
Section titled “POST /webhooks/”Register an external HTTP endpoint to receive CloudEvents when inference events fire. The signing_key is returned only on creation.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
agentspace_id | string | Yes | Agentspace scope |
sink_url | string | Yes | http:// or https:// endpoint |
assistant_id | string | No | Limit delivery to one agent |
event_types | array | No | Event types to forward; empty = all |
signing_key | string | No | 64-character hex HMAC-SHA256 key; auto-generated if omitted |
Every POST to your sink includes:
Content-Type: application/cloudevents+jsonX-Webhook-Signature: sha256=<hex>X-Webhook-EventX-Alquimia-Agentspace
Verify the signature with HMAC-SHA256 of the raw request body using the signing key.
Registry management
Section titled “Registry management”The /registry/* endpoints mutate the local TinyDB agentspace store. In production, registry write endpoints should only be reachable from the master instance; workers mount the registry read-only.
GET /registry/, POST /registry/, PUT /registry/, DELETE /registry/
Section titled “GET /registry/, POST /registry/, PUT /registry/, DELETE /registry/”Create, read, update, and delete agentspaces.
# Create an agentspacecurl -X POST http://localhost:8080/registry/ \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "production", "namespace": "production"}'POST /registry/agent
Section titled “POST /registry/agent”Create or update an agent in the agentspace. The body is a full AssistantConfig JSON document.
curl -X POST http://localhost:8080/registry/agent?agentspace_id=default \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d @support-bot.jsonPUT /registry/publish and PUT /registry/pull
Section titled “PUT /registry/publish and PUT /registry/pull”Publish pushes the agentspace as a signed OCI artifact. Pull fetches an artifact and rehydrates local knowledge bases.
curl -X PUT "http://localhost:8080/registry/publish?agentspace_id=default&tag=v1.0.0" \ -H "Authorization: Bearer $API_TOKEN"
curl -X PUT "http://localhost:8080/registry/pull?agentspace_id=default&source_repo_id=ghcr.io/acme/alquimia/default:v1.0.0" \ -H "Authorization: Bearer $API_TOKEN"Versioned registry endpoints
Section titled “Versioned registry endpoints”Runtime 0.5.1 adds API operations for cached, versioned registry snapshots. These let you pull and run a specific OCI tag without overwriting the workspace dist.json.
| Method | Path | Description |
|---|---|---|
PUT | /registry/fetch | Pull an OCI tag into a cached <tag>.json snapshot |
PUT | /registry/load-version | Load a cached snapshot so subsequent inferences resolve against it |
GET | /registry/versions | List cached snapshots for an agentspace |
DELETE | /registry/version/{tag} | Remove a cached snapshot |
# Fetch a versioned snapshotcurl -X PUT "http://localhost:8080/registry/fetch?agentspace_id=default&tag=v1.2.0" \ -H "Authorization: Bearer $API_TOKEN"
# List cached versionscurl "http://localhost:8080/registry/versions?agentspace_id=default" \ -H "Authorization: Bearer $API_TOKEN"
# Run inference against a tagged assistantcurl -X POST "http://localhost:8080/event/infer/support-bot:v1.2.0?agentspace_id=default" \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"query": "What is the refund policy?"}'The resolved version_tag is returned in CommonAttributes and propagated through inference entry points.
See Publish and pull an agentspace and Registry & OCI.
POST /registry/secret/inspect/{assistant_id}
Section titled “POST /registry/secret/inspect/{assistant_id}”Returns the resolved status of every secret referenced by an agent, which is useful when inference fails with missing-secret errors.
curl -X POST "http://localhost:8080/registry/secret/inspect/support-bot?agentspace_id=default" \ -H "Authorization: Bearer $API_TOKEN"Tool registrations
Section titled “Tool registrations”Tool registration endpoints are admin-only in most deployments because a tool’s connection config and operation classification form the trust boundary.
POST /tools
Section titled “POST /tools”Register or update a ToolRegistration, including per-operation classification.
curl -X POST http://localhost:8080/tools \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "registered_tool_id": "filesystem-tools", "provider_id": "mcp", "connection_config": {"url": {"$secretRef": "MCP_PROVIDER_URL"}}, "operations": [ {"name": "list_files", "match": "exact", "severity": "read-only", "tier_grants": ["reader", "editor", "operator"]}, {"name": "delete_*", "match": "glob", "severity": "destructive", "tier_grants": ["operator"], "approval_required": true} ] }'See Authorization policies for how tier_grants and severity interact with agent role tiers.
Knowledge topics and files
Section titled “Knowledge topics and files”POST /knowledge/topics
Section titled “POST /knowledge/topics”Create a topic.
curl -X POST http://localhost:8080/knowledge/topics \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "topic_id": "product-docs", "description": "Product documentation", "connector": {"provider_id": "qdrant"} }'POST /knowledge/files/upload
Section titled “POST /knowledge/files/upload”Upload a file. The response contains a file_id.
curl -X POST http://localhost:8080/knowledge/files/upload \ -H "Authorization: Bearer $API_TOKEN" \ -F "file=@release-notes.pdf"PUT /knowledge/topics/{topic_id}/add/{file_id}
Section titled “PUT /knowledge/topics/{topic_id}/add/{file_id}”Associate an uploaded file with a topic. Optionally chunk and embed it by passing ?hydrate=true.
curl -X PUT "http://localhost:8080/knowledge/topics/product-docs/add/<file_id>?hydrate=true" \ -H "Authorization: Bearer $API_TOKEN"POST /knowledge/topics/search/{topic_id}
Section titled “POST /knowledge/topics/search/{topic_id}”Run a semantic search within a topic. As of runtime 0.5.1, SearchInTopic supports search_mode, brain_ref, and modules for brain-mode and direct-mode queries.
curl -X POST "http://localhost:8080/knowledge/topics/search/product-docs" \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"query": "return policy", "k": 4}'PUT /knowledge/topics/{topic_id}/policy
Section titled “PUT /knowledge/topics/{topic_id}/policy”Update a topic’s access policy using the TopicPolicyInUpdate schema.
curl -X PUT "http://localhost:8080/knowledge/topics/product-docs/policy" \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "access_policy": { "severity": "read-only", "tier_grants": ["reader", "editor", "operator"] } }'See How to ingest files into a topic for the full workflow.
Task state
Section titled “Task state”PUT /task/state/{task_id}/{state_id}
Section titled “PUT /task/state/{task_id}/{state_id}”Update the controller state of an inference task. Supported states are typically run, stop, and restart.
curl -X PUT http://localhost:8080/task/state/task-abc123/stop \ -H "Authorization: Bearer $API_TOKEN"Channel webhooks
Section titled “Channel webhooks”The two /event/infer/{assistant_id}/{channel_id} endpoints are public webhook URLs:
GEThandles provider challenge handshakes via the channel’sresolve_challengemethod.POSTaccepts inbound messages and calls the channel’sverify_inboundmethod before running inference.
A channel that does not implement provider-specific auth is rejected unless CHANNEL_AUTH_REQUIRED=false.
Authentication modes
Section titled “Authentication modes”Select the auth backend with AUTH_PROVIDER:
| Mode | How it works |
|---|---|
api_token (default) | Pass Authorization: Bearer $API_TOKEN on every request |
jwt | Set JWT_SECRET and pass a signed JWT as the Bearer token |
keycloak | Validate tokens against a Keycloak realm; use /auth/refresh to refresh access tokens |
See Authentication & authorization for deployment guidance.