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) |
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 rehydrate local knowledge bases |
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 |
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.
Query parameter: agentspace_id (default: "default") — the registry namespace.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
query | string or array | Yes | Plain text or OpenAI-style content parts for multimodal input |
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 |
Responses
| Code | Description |
|---|---|
200 | CommonAttributes with task_id, session_id, assistant_id, agentspace_id |
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.
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"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.
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}'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.