The AI Engine API lets you submit natural-language queries, structured execution plans, and supported presets to Havilo. Every successful run starts asynchronously: create a run, poll or stream progress, then fetch the generated artifacts.
POST /runs returns a run envelope immediately after the request is accepted. It does not wait for the AI work to finish and does not include full artifact bodies. Poll GET /runs/{id} or stream events until the run reaches a terminal state, then fetch each artifact body from GET /artifacts/{id}.
Base URL
https://havilo.ai/api/v1All paths in this section are relative to that base URL.
Core Flow
- Create a run with
POST /runs. - Poll
GET /runs/{id}or stream events from/runs/{id}/events/stream. - Read artifact metadata from the run envelope.
- Fetch artifact bodies with
GET /artifacts/{id}.
Available Guides
- Quickstart - Create a run and fetch a table artifact.
- Authentication - Bearer keys, scopes, and key safety.
- Runs - Request bodies, run envelopes, cancel, and idempotency.
- Step Kinds - Parameters for every plan step kind.
- Artifacts - Table, text, and entity-card artifact bodies.
- Events - Polling, event tokens, and SSE streams.
- Webhooks - Lifecycle callbacks and signature verification.
- Entity References - Resolve entity IDs before entity-scoped runs.
- Dossier Preset - Generate a dossier for a known entity.
- Errors - Error shape, status codes, and retry guidance.
- Reliability - Idempotency, retries, and practical limits.
Supported Run Inputs
| Input type | Use when |
|---|---|
query | You want Havilo to understand the question and create the plan. |
plan | You already know the exact steps to run. |
preset | You want a supported packaged workflow such as dossier. |
Timestamp and ID Format
Run IDs, artifact IDs, and entity IDs are UUID strings. Timestamps such as created_at, completed_at, and event occurred_at are Unix epoch milliseconds. completed_at appears only after a run reaches a terminal state.
api_version is echoed on run and event responses so clients can log which contract handled a request. Treat it as an opaque version string; you do not need to send it on normal requests.