The AI dashboard is currently in beta and may be unavailable or have limited functionality in certain regions.

Tutorial

Using the API

Authenticate and make programmatic requests to the Elis AI backend.

1

Create an API key

Go to Settings → API Keys and create a new key (see the Settings tutorial for details). Copy the key value.

2

Make your first request

Send a request to the chat endpoint with your API key in theX-API-Key header:

curl -X POST https://your-domain/api/chat \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"message": "Hello", "conversation_id": null}'
3

Handle the streaming response

The response is a Server-Sent Events (SSE) stream. Each event contains a token chunk. Accumulate chunks to build the full response.

data: {"token": "Hello"}
data: {"token": " there"}
data: {"token": "!"}
data: [DONE]
4

Continue the conversation

Pass the conversation_id from the response in subsequent requests to continue the same conversation with full context.

5

OpenAI-compatible endpoint (/api/v1)

For drop-in OpenAI compatibility, use POST /api/v1/chat/completions. It's stateless — send the full messages array each call. The model is a tier, not a fixed model (elis/auto, elis/agent, elis/nano, elis/small, elis/frontier); the pool binds the best available underlying model at dispatch. The response model is the resolved catalog key (e.g. gpt-4o-mini), not the alias you sent.

curl -X POST https://your-domain/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer elis_YOUR_API_KEY" \
  -d '{"model": "elis/small", "messages": [{"role": "user", "content": "Hello"}]}'

Speed-mode tags (developer): append a speed mode to elis/agent or elis/auto to steer depth without pinning a model — elis/agent-instant, -balanced, -deep (the same names the chat uses). On elis/auto-… the per-prompt tier pick is biased into that band. The legacy tier-name suffixes -nano/-small/-frontier still work as aliases; unknown suffixes fall back to the untagged base.

Streaming: every tier streams when you pass stream: true. Note elis/agent is non-streaming by default — it returns one chat.completion unless you opt into SSE. The final SSE chunk carries the same usage object as a non-streaming response (no stream_options opt-in needed).

Latency expectations. The direct tiers answer in seconds because they skip orchestration; the elis/agent modes run the full engine (memory recall, agent matching, tool steps, grading), which buys answer quality at the cost of wall-clock time. Typical warm-path timings for a short prompt (measured Jul 2026):

ModelTypical responseWhat runs
elis/nano< 1 sDirect dispatch, lightweight model
elis/small~1 sDirect dispatch, balanced model
elis/frontier~1.5–2 sDirect dispatch, top-tier model
elis/auto~2 sPer-prompt tier router, then direct dispatch
elis/agent-instant~6–8 sOrchestrated, instant depth budget
elis/agent~8–15 sOrchestrated, auto depth
elis/agent-balanced~10–14 sOrchestrated, balanced depth budget
elis/agent-deep~30–45 sOrchestrated, deep multi-step budget

Two caveats: the first elis/agent call in a fresh session pays a one-time warm-up (30 s+ is normal; later calls are much faster), and actual latency depends on which miners are serving your pool. Use stream: true on agent modes so users see progress instead of a silent wait.

6

Pin an expert, store for recall, read real usage

These three elis/agent-only features shape an orchestrated call:

  • Pinning — pass agent (alias agent_id) and/or template (alias template_id) to force a specific expert/recipe instead of dynamic matching. Scope-enforced: you can pin a global agent or one in your own org only, and the template must belong to the agent — otherwise 400. The pin is honored even for simple prompts (not dropped by the fast path).
  • store — set store: true to index the exchange (embedding + fact extraction + memory compaction) so a later elis/agent call can recall it. Default is false (stateless, OpenAI-matching).
  • Measured usage — the response usage is the token amount actually metered and billed for the request (summed across every engine step on elis/agent), not an estimate. total_tokens equals what was charged to your balance.
  • The elis object — every elis/agent response includes a non-standard elis block so you can see what the engine selected: agent_id and template_id (the ones you pinned, or the ones auto-matched), resolved_model (the concrete model that ran), and run_id (to find the Decision Trace in Observability). OpenAI-compatible clients ignore it; on a stream it rides the final usage chunk.
curl -X POST https://your-domain/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer elis_YOUR_API_KEY" \
  -d '{
    "model": "elis/agent",
    "agent": "return_a_json_array_1",
    "template": "return_a_json_array_1:v2",
    "store": true,
    "messages": [{"role": "user", "content": "Give three prime numbers."}]
  }'
Tip:store, agent, and template are rejected with 400 invalid_request_error on the direct tiers (elis/auto|nano|small|frontier) — those paths don't run the orchestration engine, so the flags have nothing to act on.
7

Stateful sessions with /api/v1/responses

POST /api/v1/responses is the stateful alternative to chat/completions: instead of replaying the full message history each call, pass the last response's id as previous_response_id and the platform remembers the session. Same tier models and tags as Step 5, plus reasoning.effort (low|medium|high) to steer depth.

curl -X POST https://your-domain/api/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer elis_YOUR_API_KEY" \
  -d '{
    "model": "elis/agent",
    "input": "And what is its population?",
    "previous_response_id": "resp_abc123",
    "store": true
  }'

store, agent/template pinning, non-streaming default with stream: true SSE opt-in, and measured billed usage all work exactly as on chat/completions (Step 6) — the Responses API reports usage as input_tokens/output_tokens, delivered on the final response.done event when streaming.

Tip:You can also authenticate with a JWT token in the Authorization: Bearer header instead of an API key.
Tip:Need to manage recurring research widgets programmatically? See the Automations API tutorial for creating widgets, triggering runs, streaming events, and downloading PDF/Excel exports via REST.
Tip:Organization policy note: internet controls apply to web-sourced tools only. Linked REST API data source calls are managed separately through organization data source configuration.