Skip to documentation

API & MCP

Getting started with the API

Everything eli.ai does in the browser — reading the knowledge base, editing the graph, running queries and agents, producing reports — is available over HTTP at https://your-host/api/v1. This guide takes you from zero to your first authenticated response, and pins down the two rules that trip up most first integrations: which kind of key to mint, and when you need an X-Workspace-Id header.

Prerequisites

  • A running eli.ai instance and its host — this guide uses https://your-host.
  • Membership in at least one workspace (owner or admin, to create keys).
  • curl and a shell. Every example reads the key from $ELI_KEY.

Two kinds of key

eli.ai has two API-key prefixes. Pick by whether the integration lives inside one workspace or spans several:

  • Workspace keyeli_sk_…. Bound to exactly one workspace at creation. No header needed; the workspace is implicit. This is the default for a service, a CI job, or a per-client integration.
  • User keyeli_uk_…. Bound to you, and valid across every workspace you belong to. Each request must name the target workspace with an X-Workspace-Id header. Use it for a personal script that hops between workspaces, or a dashboard aggregating several.

The X-Workspace-Id rule, once and for all

A eli_sk_ key ignores X-Workspace-Id — the workspace is baked in. A eli_uk_ key requires it, and the header must name a workspace you are a member of; otherwise the request is rejected before it touches any data. Scope always comes from the key and header — you never put a workspace id in a URL or body.

Scopes

Every key carries a subset of scopes; each endpoint requires one. Grant the least a key needs:

  • kb:read — list/read documents, search, entities, and relations.
  • kb:write — create/update/delete documents, entities, and relations.
  • data:read — list connectors and named data queries.
  • data:run — execute a named data query against a live connector.
  • reports:read — list and fetch report snapshots.
  • reports:write — generate new report snapshots.
  • agents:run — the grounded query endpoint (it invokes the chat model) plus starting, cancelling, approving, and giving feedback on agent runs.
  • runs:read — read run status and step traces.

A valid key that lacks the scope an endpoint requires gets 403 insufficient_scope — it never silently succeeds with a narrower result.

Mint a key

  1. Open Settings → API keys

    In your workspace, go to Settings → API keys. A cross-workspace user key is created from your account settings instead; both flows land in the same dialog.
  2. Name it and choose scopes

    Give it a descriptive label (e.g. ingest-worker) and check only the scopes it needs. For this guide, kb:read is enough.
  3. Copy the secret now

    The raw key is shown exactly once — only its SHA-256 hash is stored. Put it in your secret manager immediately; if you lose it, revoke and re-create.
  4. Export it

    Everything below reads it from the environment.
    Codebash
    export ELI_KEY="eli_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Your first call

The cheapest way to prove a key works is to list entities — a read that needs only kb:read:

GET/api/v1/entitiesBearer · kb:read

List canonical entities, most graph-central first. Paginate with limit (1–200, default 50) and offset; filter with type.

Query parameters

limitintegerPage size, 1–200. Default 50.
offsetintegerRows to skip. Default 0.
typestringFilter to one entity type, e.g. organization.
Example requestbash
curl -s https://your-host/api/v1/entities?limit=3 \
  -H "Authorization: Bearer $ELI_KEY"
Responsejson
{
  "entities": [
    { "id": "01KY0ZW3B8AVDR67NXSE96P81N", "name": "Order Platform", "type": "system", "pagerank": 0.0421 },
    { "id": "01KY0ZX8M2QF4T9BQH3V7C5RD0", "name": "Northwind Trading Co", "type": "organization", "pagerank": 0.0388 },
    { "id": "01KY0ZYQ4W1E6K2NR9TB8AZP7M", "name": "Dana Whitfield", "type": "person", "pagerank": 0.0312 }
  ],
  "total": 214,
  "limit": 3,
  "offset": 0
}

With a cross-workspace eli_uk_ key the only difference is the header naming which workspace to read:

user key → name the workspacebash
curl -s https://your-host/api/v1/entities?limit=3 \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "X-Workspace-Id: 01KY0V000WORKSPACE0000001"

Error envelopes

Errors are data, not surprises. Every failure returns a small JSON object with a machine-readable error string; validation failures add a zod issues array. Branch on the status code:

error shapesjson
{ "error": "unauthorized" }                       // 401 — missing/invalid/revoked key
{ "error": "insufficient_scope" }                 // 403 — key lacks the required scope
{ "error": "not_found" }                          // 404 — unknown id, or another workspace's row under RLS
{ "error": "no-model-configured" }                // 409 — an LLM step has no enabled provider
{ "error": "Invalid request body",
  "issues": [ { "path": ["name"], "message": "Required" } ] }  // 400 — body failed validation

Cross-workspace reads are 404, never 403

A resource in another workspace does not return "forbidden" — under row-level security it simply does not exist for your key, so the handler returns 404 not_found. This never confirms another tenant's data. Full status table in Errors & rate limits.

Where to next

One key is the on-ramp to the whole platform. The leverage: the same token that just listed entities also ingests documents that grow the graph, asks grounded questions, runs governed live-data queries, drives agents, and produces client-ready reports — under one identity, one audit trail, and one set of scopes you control.