JavaScript & React SDK
eli.ai's package family separates wire contracts, a headless HTTP client, and React UI. You can use only JSON types, drive every public API operation from a server, or embed complete capabilities in a React application without importing Next.js.
Implemented in the repository
@eli-ai/contracts, @eli-ai/client, and @eli-ai/react are implemented as version 0.1.0 workspace packages. A public package-registry release is a separate distribution step, so confirm your registry before using the install commands below. The OpenAPI reference remains the wire source of truth.Three layers, one wire contract
@eli-ai/contractsFramework-free request, response, error, and SSE event types through capability subpaths.
@eli-ai/clientA standards-based Fetch client covering all 56 current operations, including authenticated SSE.
@eli-ai/reactAn injected provider, generic async hooks, complete capability components, and an optional CSS export.
Headless client
The client accepts a deployment origin, a credential resolver, a workspace resolver, and an injectable Fetch implementation. Dates stay ISO strings, currency stays a decimal string, and route-specific response envelopes stay intact.
Capability subpaths
Contracts are imported by grouped capability, so a document integration does not need React or agent stream types. The contracts root deliberately re-exports only shared metadata (common, auth, capabilities, and operations); payload contracts use explicit subpaths. Stable paths are /common, /auth, /query, /documents, /graph, /governance, /data, /agents, /quality, /reports, /connectors, /capabilities, and /operations.
Authentication and workspace selection
The client adds protocol headers; it does not make an authorization decision. The server still resolves the key, checks the operation's scope, narrows user keys against the owner's live workspace role, and runs tenant reads and writes beneath FORCE row-level security.
Workspace selection is deterministic: a headless method's per-call workspaceIdoverrides the client transport default. React hooks and components pass the provider's workspace as that per-call override when supplied; otherwise the injected transport's default applies. An explicit x-workspace-id custom header takes final precedence, so do not pass untrusted arbitrary headers through an integration wrapper.
| Key | Workspace rule |
|---|---|
| eli_sk_… | Fixed to one workspace. A different X-Workspace-Id is rejected. |
| eli_uk_… · one workspace | The single allowed workspace is selected automatically. |
| eli_uk_… · multiple/all | Every request must include X-Workspace-Id inside the key grant and live membership. |
Do not put a workspace key in browser code
eli_sk_ key in a bundle, HTML, local storage, or public runtime configuration. The current API also installs no cross-origin CORS policy. Browser React consumers should use a same-origin server-side BFF or reverse proxy that injects a Bearer key. A shared origin alone does not reuse the application session: /api/v1 still returns 401 without a Bearer credential. Direct browser use is only appropriate for a narrowly scoped user credential under an operator-controlled setup. The injected transport/custom Fetch is the trust boundary.Durable runs over Fetch-based SSE
Starting an agent returns HTTP 202 with a durable run id and stream path. The worker executes independently; agents.streamRun() attaches to a database-backed replay/tail. Fetch is required instead of native EventSource because the stream needs Authorization and, for some user keys, X-Workspace-Id.
Reconnects replay progress
agents.cancelRun(id) for cooperative cancellation. Streams close on suspended, final, error, or the current ten-minute safety timeout.React composition
React receives an already-constructed transport, or the transport retained from an aggregate client. That keeps key retrieval, tenant selection, same-origin proxying, and tracing outside the render tree. Each capability component constructs only its matching client module from that transport. Complete components use scoped eli-* classes and the optional CSS export; hooks remain usable with application-owned markup. EliProvider deliberately has no API-key prop.
No Next.js dependency
Current capability coverage
The headless client covers every operation in the current OpenAPI document. React adds complete components by product capability; MCP remains a separate protocol at /api/mcp.
| Capability | Canonical scopes | Current routes | React surface |
|---|---|---|---|
| Query & search | agents:run · kb:read | /query · /search | EliQuery · EliSearch |
| Documents | kb:read · kb:write | /documents · verify · lineage | EliDocuments · EliDocumentLineage |
| Entities & governance | kb:read · kb:write | /entities · /relations · /manifest · change requests · SKOS | EliKnowledgeGraph · EliGovernance |
| Live data | data:read · data:run | /data/connectors · /data/queries | EliLiveData |
| Reports | reports:read · reports:write | /reports | EliReports |
| Agents & runs | agents:run · runs:read | /agents/{slug}/runs · /runs/{id}/* | EliAgentRunner · EliRunDetail |
| Policy, evals & cache | kb:read · kb:write | /policy · /evals · /qrels · /cache/stats | EliQuality · EliPolicyDecisions · EliEvalMetrics · EliCacheStats |
| Content connectors | data:read · kb:write | /connectors · /connectors/{id}/sync | EliConnectors |
Canonical versus accepted read scopes
scope and acceptedScopes, matching OpenAPI's x-required-scope and x-accepted-scopes. OpenAPI recommends kb:read for graph, lineage, policy, eval, and cache reads; selected compatibility guards also accept older runs:read keys. New integrations should request the canonical scope.Error behavior
Non-2xx responses become EliApiError, retaining status, machine code, validation issues, parsed details, and the x-request-id when present. Fetch failures become EliTransportError; invalid successful JSON or response content types become EliProtocolError; malformed JSON in an SSE frame becomes EliSseParseError. Abort keeps its native identity. A terminal SSE error payload remains a yielded RunEvent.
- 400: fix request or workspace selection; do not retry unchanged input.
- 401: missing, invalid, or revoked credential.
- 402: monthly agent-spend admission blocked.
- 403: insufficient scope, live capability, or workspace grant.
- 404: unknown or cross-workspace resource; the distinction is intentionally hidden.
- 409: required model is not configured.
- 429: active-run capacity is full, not a general API throttle.
The current API has no universal pagination envelope, standard idempotency key, general rate limiter, or cross-origin CORS policy. Document enrichment is asynchronous after durable save, and run SSE is the only unified public push channel today.
Repository, registry, and HTTP use
Inside this repository, consume the version 0.1.0 workspace packages directly. Outside it, confirm the package-registry release before running the install commands. The HTTP/OpenAPI contract remains the interoperable fallback and source of truth: