# Elektric — complete agent reference CODING AGENTS: Start here: https://elektric.ai/elektric-agent-setup.md # Elektric > One API for models, Memory, context, and Knowledge. Canonical identifiers (do not infer alternate spellings): TypeScript package `elektric-ai`; Python distribution `elektric-ai`; Python import `elektric`; API key `ELEKTRIC_API_KEY`; API base `https://elektric.ai/v1`; compatibility model `elektric-auto` only when required. Complete machine reference: https://elektric.ai/llms-full.txt ## Start here - [Quickstart](https://elektric.ai/docs/get-started) - [Integration decision](https://elektric.ai/docs/integration) - [TypeScript SDK](https://elektric.ai/elektric-typescript-sdk.md) - [Python SDK](https://elektric.ai/elektric-python-sdk.md) - [OpenAI compatibility](https://elektric.ai/docs/build/openai-compatibility) ## Core AI - [Chat / inference](https://elektric.ai/docs/get-started) - [Routing](https://elektric.ai/docs/concepts/routing) - [Streaming](https://elektric.ai/docs/build/streaming) ## Context and state - [Conversations](https://elektric.ai/docs/concepts/conversations) - [Memory](https://elektric.ai/docs/concepts/memory) - [Knowledge](https://elektric.ai/docs/concepts/knowledge) ## Tools and retrieval - [Web search / browsing](https://elektric.ai/docs/concepts/tools) - [Tools / tool calling](https://elektric.ai/docs/concepts/tools) - [Files and document understanding](https://elektric.ai/docs/primitives/documents) ## Media and modalities - [Images](https://elektric.ai/docs/primitives/images) - [Audio](https://elektric.ai/docs/primitives/audio) - [Video](https://elektric.ai/docs/primitives/video) ## Platform primitives - [Embeddings](https://elektric.ai/docs/primitives/embeddings) - [Realtime](https://elektric.ai/docs/primitives/realtime) - [Jobs / asynchronous operations](https://elektric.ai/docs/primitives/jobs) - [Assets](https://elektric.ai/docs/primitives/assets) ## Operations - [Requests / observability](https://elektric.ai/docs/operate/observability) - [Authentication](https://elektric.ai/docs/build/authentication) - [Errors / retries](https://elektric.ai/docs/operate/errors-retries) - [Usage](https://elektric.ai/docs/api/usage) - [Billing](https://elektric.ai/docs/operate/pricing-billing) --- Source: docs/overview.md Canonical URL: https://elektric.ai/docs # What is Elektric? Elektric is infrastructure for building AI applications. **One API for models, Memory, context, and Knowledge.** Send the User, Conversation, and message. Elektric handles automatic model selection, Conversation continuity, selective Memory, relevant History, Project Knowledge, fallback, Usage, and cost tracking. ```text Developer app → Elektric chat → Conversation + Memory + History + Knowledge → automatic model selection → Response ``` Elektric is currently in beta. Public interfaces are versioned under `/v1` and may evolve before general availability. ## Next steps - [Make your first request](https://elektric.ai/docs/get-started) - [Understand how Elektric works](https://elektric.ai/docs/concepts/how-elektric-works) - [Read the API reference](https://elektric.ai/docs/api/chat-completions) --- Source: docs/getting-started.md Canonical URL: https://elektric.ai/docs/get-started # Quickstart Send your first Elektric request in under five minutes. ## Prerequisites - An Elektric account and Project - A Project API Key - Node.js 18+, Python 3.10+, or curl ## 1. Create an API Key Open the Project's **API Keys** tab, create a key, and copy it when shown. ## 2. Set the secret Set `ELEKTRIC_API_KEY` in your trusted server environment. Never put it in browser code or source control. ## 3. Install an SDK ```sh npm install elektric-ai ``` or: ```sh python -m pip install elektric-ai ``` ## 4. Send a request ```ts import { Elektric } from "elektric-ai"; const elektric = new Elektric({ apiKey: process.env.ELEKTRIC_API_KEY! }); const response = await elektric.chat({userId:"user_123",conversationId:"conversation_123",message:"Hello"}); console.log(response.message); ``` ## Expected result The assistant message is printed. The response also exposes a Request ID. ## What happens automatically? The same Conversation ID continues a thread. The same User ID may carry selective Memory across Conversations. Relevant History and ready Project Knowledge may be used. Elektric automatically selects a model and handles fallback. ## Next steps - [Conversations](https://elektric.ai/docs/concepts/conversations) - [Memory](https://elektric.ai/docs/concepts/memory) - [Knowledge](https://elektric.ai/docs/concepts/knowledge) - [Streaming](https://elektric.ai/docs/guides/streaming) - [Request Logs](https://elektric.ai/docs/concepts/requests) --- Source: docs/integration.md Canonical URL: https://elektric.ai/docs/integration # Integration Use Elektric as the application's AI backend and preserve the application's existing architecture. Make the smallest reasonable change that replaces direct provider inference with Elektric. ## Choose the integration path For new Elektric integrations, prefer the native Elektric SDK. It exposes Elektric's provider-neutral chat and platform capabilities directly. If an existing application already depends heavily on the OpenAI SDK or an OpenAI-compatible interface and replacing that integration would create unnecessary changes, use Elektric's OpenAI-compatible API instead. Do not choose compatibility for a new application merely because it is familiar. Compatibility clients use base URL `https://elektric.ai/v1`, API key environment variable `ELEKTRIC_API_KEY`, and model `elektric-auto`. Do not expose or select an underlying provider model. ## Security Read `ELEKTRIC_API_KEY` only on trusted server-side or edge infrastructure. Never hard-code, print, commit, expose in browser code, or paste the key into chat. If the repository needs an environment example, add `ELEKTRIC_API_KEY=` without a value and preserve its existing `.gitignore` behavior. ## Verify A basic integration is working when the request succeeds, an assistant message is returned, and the safe Request ID is available for tracing. Run the relevant tests, affected typecheck, and affected build before declaring the integration complete. --- Source: docs/concepts.md Canonical URL: https://elektric.ai/docs/concepts/how-elektric-works # Elektric concepts ## How Elektric works Your server sends an authenticated request. Elektric assembles enabled context, automatically selects a suitable model, handles fallback, returns a normalized response, and records safe operational and Usage data. Provider identity and internal routing details stay private. ## Projects A Project is the application boundary for API Keys, Knowledge, Requests, Usage, billing attribution, and Limits. Every Project API Key scopes operations to that Project. ## Users `userId` is your customer-defined, stable end-user identifier. You do not create Users through a separate Elektric endpoint. Reuse the same ID for continuity, use different IDs for isolation, and prefer an opaque internal ID over personal information. ## Conversations `conversationId` identifies one thread. Reuse the same User and Conversation IDs for follow-ups. A different Conversation ID starts a new thread while selective Memory may remain for the same User. Conversation deletion does not delete Memory, Knowledge, or other Conversations. ## Memory Memory is small, selective, durable User information across Conversations. Categories are `identity`, `preference`, `project`, `goal`, `constraint`, and `routine`. Memory is automatic, inspectable, editable, and deletable. Elektric does not promise to remember everything. ## Memory versus History - Memory: “User is building Orion.” - History: “Last Tuesday they rejected semantic retrieval.” History supplies relevant specific details from previous Conversations. Elektric does not load every old message on every request. ## Knowledge Knowledge is Project-level reference material: documentation, policies, manuals, and company information. Sources move through `processing`, `ready`, `failed`, and `deleting`. Supported types are PDF, text, Markdown, HTML, XML, CSV, DOCX, XLSX, XLS, ODT, and ODS. The maximum upload is 16 MiB. Knowledge improves grounding but does not guarantee perfect answers from every file. ## Requests Each inference has a Request ID. Request Logs expose status, latency, tokens, context-layer booleans, streaming, fallback, and safe errors. They exclude provider/model internals and content. ## Usage and Billing Usage reports operational totals and estimated provider inference cost, the 5% Elektric fee, and estimated charge. The append-only prepaid Billing ledger is authoritative. --- Source: docs/guides/current-product.md Canonical URL: https://elektric.ai/docs/guides/chat-app # Current-product guides These task-oriented guides use the public v1 API and SDK 0.1.0. ## Build a chat app Prerequisites: a Project, Project API Key, Node.js 18+, and `npm install elektric-ai`. ```ts import { Elektric } from "elektric-ai"; const elektric = new Elektric({ apiKey: process.env.ELEKTRIC_API_KEY! }); const response = await elektric.chat({ userId: "user_123", conversationId: "thread_123", message: "Hello", }); console.log(response.message, response.requestId); ``` ## Add Conversation persistence Reuse the same `userId` and `conversationId`, then retrieve the thread with `conversations.get({conversationId})`. ## Memory across Conversations Send a durable fact in Conversation A, then ask about it in Conversation B with the same User ID. Memory formation is selective and may be asynchronous. Inspect it with `memory.list`, correct it with `memory.update`, and deactivate it with `memory.delete`. ## Add Project Knowledge Use `knowledge.add`, poll `knowledge.get` until `ready`, ask a relevant question through chat, and call `knowledge.delete` when finished. A failed source must be deleted and re-uploaded. ## Stream responses ```ts for await (const event of elektric.chat.stream({ userId: "user_123", conversationId: "thread_123", message: "Explain DNS.", })) if (event.type === "text_delta") process.stdout.write(event.text); ``` ## Debug Requests Read `response.requestId`, then call `requests.get({requestId})`. Inspect status, latency, token Usage, context flags, and fallback without exposing content. ## Control spend Prepaid balance is the account hard ceiling. An optional monthly Project spend cap limits one Project. Requests blocked before inference are not charged. ## Handle errors Branch on the safe error type/code, retain the Request ID, and retry only transient failures. For HTTP 429, honor `Retry-After`. --- Source: docs/migrate-from-openai.md Canonical URL: https://elektric.ai/docs/build/openai-compatibility # Migrate from OpenAI For new Elektric integrations, prefer the native Elektric SDK. Use this compatibility path when an existing application already depends heavily on the OpenAI SDK or an OpenAI-compatible interface and replacing it would create unnecessary changes. Do not choose compatibility for a new application merely because it is familiar. Migrating from OpenAI to Elektric takes three changes: 1. Use your Elektric project API key. 2. Change the base URL to `https://elektric.ai/v1`. 3. Change the model to `elektric-auto`. You do not need to replace the OpenAI SDK. ```diff import OpenAI from "openai"; const client = new OpenAI({ - apiKey: process.env.OPENAI_API_KEY, + apiKey: process.env.ELEKTRIC_API_KEY, + baseURL: "https://elektric.ai/v1", }); const response = await client.chat.completions.create({ - model: "your-current-model", + model: "elektric-auto", messages: [{ role: "user", content: "Reply with: Elektric works." }], }); ``` `elektric-auto` is Elektric's logical model. Elektric selects and manages the underlying provider and model for each request. Do not configure an OpenAI, Anthropic, Google, or other upstream provider credential. `ELEKTRIC_API_KEY` is the only AI-provider secret this Elektric connection needs. ## Supported compatibility | Field | Status | Behavior | | --- | --- | --- | | `model` | Supported | `elektric-auto` or omission; other values are rejected. | | `messages` | Supported | Ordered text `system`, `user`, and `assistant` messages. | | `stream` | Supported | Genuine incremental OpenAI SSE across eligible Elektric providers. | | `temperature` | Supported | Passed through to eligible providers. | | `max_tokens` | Supported | Normalized to Elektric's output-token limit. | | `max_completion_tokens` | Supported | Alias for `max_tokens`; supplying both is rejected. | | `n` | Limited | Omission or `1` only. | | `top_p`, `stop`, penalties, `response_format` | Not yet supported | Rejected with `unsupported_parameter`. | | `tools`, `tool_choice` | Not yet supported | Rejected with `unsupported_parameter`. | | `user`, `seed`, `logprobs` | Not yet supported | Rejected with `unsupported_parameter`. | | Unknown fields | Not supported | Rejected explicitly rather than silently ignored. | Multimodal content arrays and tool calls are not yet supported. Elektric returns normalized JSON errors that the OpenAI SDK exposes as normal API errors. Streaming works through Elektric regardless of whether `elektric-auto` selects OpenAI or Anthropic internally. Every public chunk uses one Elektric-owned response ID, timestamp, and `model: "elektric-auto"`. `stream_options` is not currently accepted; provider usage is still captured internally for billing and telemetry when the provider reports it. OpenAI JavaScript SDK 7.4.0 retries connection failures, 408, 409, 429, and 5xx responses twice by default. A retry can repeat inference and billing when the outcome of the first network request is unknown. Set `maxRetries: 0` if your application requires no automatic generation retries. Its default request timeout is 10 minutes and can be changed with `timeout`. For new TypeScript projects, Elektric also provides a native SDK. Applications already using another OpenAI-compatible gateway can generally migrate by changing the API key, base URL, and model in the same way. ## REST ```sh curl https://elektric.ai/v1/chat/completions \ -H "Authorization: Bearer $ELEKTRIC_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"elektric-auto","messages":[{"role":"user","content":"Hello"}]}' ``` --- Source: packages/sdk/README.md Canonical URL: https://elektric.ai/docs/sdks/typescript # Elektric TypeScript SDK Canonical documentation: [Quickstart](../../docs/getting-started.md) · [AI coding agents](../../docs/guides/ai-coding-agents.md) · [llms.txt](../../public/llms.txt) One provider-neutral TypeScript interface for chat, media, tools, Web, jobs, and realtime. ## Install ```bash npm install elektric-ai ``` This is the official [`elektric-ai` package on npm](https://www.npmjs.com/package/elektric-ai). Do not substitute a similarly named package. ## Configure and make a request ```ts import { Elektric } from "elektric-ai"; const elektric = new Elektric({ apiKey: process.env.ELEKTRIC_API_KEY! }); const result = await elektric.chat({ userId: "customer-456", conversationId: "support-123", message: "What is our refund policy?", }); console.log(result.message, result.requestId); ``` The production URL, `https://elektric.ai`, is built in. `baseUrl` is available for development and testing. `elektric-auto` is implicit in this simple method. It does not send provider, retrieval, or Context controls, and the SDK never automatically retries an AI execution. ## Persistent conversations ```ts const result = await elektric.chat({ conversationId: "support-123", userId: "customer-456", message: "What about enterprise?", }); ``` Both IDs are required by the native beta chat method. The same `userId` and `conversationId` continues a thread; a new `conversationId` starts a new thread while retaining that user's durable Memory. Knowledge configured for the API-key project is used automatically when relevant. ```ts const conversation = await elektric.conversations.get({ conversationId: "support-123" }); const recent = await elektric.conversations.list({ userId: "customer-456", limit: 20 }); await elektric.conversations.delete({ conversationId: "support-123" }); ``` Conversation lists are newest-updated-first and cursor-paginated. GET returns up to 100 chronological messages; pass `messageCursor` to continue. Deleting a Conversation does not delete Memory, Knowledge, or other Conversations. A later chat may deterministically create a new thread with the same external ID. Memory is durable user-specific information across Conversations. It remains automatic during chat. Inspect or correct it with `elektric.memory.list/get/update/delete`; these methods are scoped to the API-key project and require `userId`. Manual create is intentionally deferred because stable conceptual keys remain owned by the certified updater. ```ts const memories = await elektric.memory.list({ userId: "customer-456" }); const card = await elektric.memory.get({ userId: "customer-456", memoryId: memories.data[0].id }); await elektric.memory.update({ userId: "customer-456", memoryId: card.id, summary: "User prefers concise prose." }); await elektric.memory.delete({ userId: "customer-456", memoryId: card.id }); ``` Deleting Memory deactivates that card immediately but does not erase its source Conversation or prevent History from recalling legitimate past events. Conversation is the current thread, History finds details from older threads, and Knowledge contains project/company reference material. ## OpenAI-compatible requests ```ts const raw = await elektric.chat.completions.create({ model: "elektric-auto", conversation_id: "support-123", messages: [{ role: "user", content: "What about enterprise?" }], }); ``` The convenience result exposes normalized `text`, `id`, `usage`, and `requestId`, plus the original completion at `result.raw`. Direct HTTP and OpenAI-compatible clients use the same `/v1/chat/completions` backend. ## Streaming ```ts for await (const event of elektric.chat.stream({ userId: "customer-456", conversationId: "support-123", message: "Explain our policy." })) { if (event.type === "text_delta") process.stdout.write(event.text); } ``` Pass `signal` to cancel locally. Streaming accepts conversation and user IDs, but the current backend intentionally does not persist or inject conversation Context for streaming requests. Cancellation does not imply that upstream work or billing was stopped. The deprecated `chatStream()` alias remains for compatibility. ## Files and multimodal input ```ts const file = await elektric.files.upload({ file: pdfBytes, mediaType: "application/pdf" }); const answer = await elektric.chat({ messages: [{ role: "user", content: [ { type: "text", text: "Summarize this." }, { type: "file", fileId: file.id }, ] }] }); ``` Use `files` for uploads and `assets` for normalized generated media metadata/downloads. Assets expose opaque Elektric IDs, never storage or upstream IDs. ## Tools and Web ```ts const weather = elektric.tool<{ city: string }>({ name: "weather", description: "Read the current weather.", inputSchema: { type: "object", properties: { city: { type: "string" } }, required: ["city"] }, }); const response = await elektric.chat({ messages, tools: [weather], web: true }); console.log(response.text, response.sources, response.toolCalls); ``` Your application authorizes and executes tool calls, then returns an `ElektricToolResult` in the next request. Elektric does not execute customer tools. ## Images, audio, video, and jobs ```ts const image = (await elektric.images.generate({ prompt: "A lighthouse at sunrise" })).images[0]; const job = await elektric.video.generate({ image: image.fileId, prompt: "Slow camera push." }); const completed = await elektric.jobs.wait(job.id, { signal: abortController.signal }); ``` Use `audio.transcribe`, `audio.speech`, `images.generate`, `images.edit`, `video.analyze`, and `video.generate`. Async operations return an `ElektricJob`; `job.wait()` is sugar for `elektric.jobs.wait(job.id)`. ## Embeddings and realtime Default embedding usage is `elektric.embeddings.create({ input })`. Profiles are discoverable at `elektric.embeddingProfiles` and remain available at `elektric.embeddings.profiles` for compatibility. `elektric.realtime.connect()` returns a normalized session with `sendText`, `sendAudio`, `commitAudio`, `interrupt`, `on`, and `close`. ## Errors and runtimes ```ts import { ElektricError } from "elektric-ai"; try { await elektric.chat({ messages }); } catch (error) { if (error instanceof ElektricError) console.error(error.code, error.requestId); } ``` Errors expose safe Elektric `code`, `status`, `requestId`, and optional `details`; upstream errors are never returned. Supported environments are ESM, fetch-compatible Node.js 18+, Cloudflare Workers, and other server/edge runtimes with standard Web APIs. Realtime additionally requires WebSocket support. Use `ELEKTRIC_API_KEY` in server-side code. Never ship an Elektric secret key in a public browser bundle; a browser app should call your backend, which calls Elektric. The native SDK is recommended for the complete Elektric platform. OpenAI compatibility is available for rapidly migrating existing OpenAI-compatible code. See [Elektric documentation](https://elektric.ai/docs). ## Knowledge management Knowledge is project-level reference material used automatically when relevant. Use `knowledge.add`, `list`, `get`, and `delete`; poll until `status === "ready"`. Upload accepts Web bytes and Node Buffer with a filename/MIME type. Retry is deferred: delete and re-upload failed sources. ## Streaming Web sources Pass `web: true` to `elektric.chat.stream()` or `chatStream()`. Streams emit normalized `source` events in addition to existing text/content and finish events. Sources may arrive before, during, or after text and are de-duplicated by URL; the underlying SSE ends after the finish chunk with `[DONE]`. --- Source: packages/python-sdk/README.md Canonical URL: https://elektric.ai/docs/sdks/python # Elektric Python SDK Canonical documentation: [Quickstart](../../docs/getting-started.md) · [AI coding agents](../../docs/guides/ai-coding-agents.md) · [llms.txt](../../public/llms.txt) One provider-neutral Python interface for chat, media, Web, tools, state, jobs, and realtime. The distribution is `elektric-ai`; the Python import remains `elektric`. This is the official [`elektric-ai` distribution on PyPI](https://pypi.org/project/elektric-ai/). Do not substitute a similarly named distribution. ## Install and configure ```bash python -m pip install elektric-ai ``` ```python from elektric import Elektric with Elektric() as client: response = client.chat( message="Explain quantum computing simply.", user_id="user-123", conversation_id="thread-123", ) print(response.message, response.request_id) ``` The production URL is built in; `base_url` is only needed for local or staged deployments. Native chat requires customer-defined `user_id` and `conversation_id`; the `elektric-auto` model is implicit. No provider key, provider name, or model is accepted. AI executions are never automatically retried. ## Conversations ```python conversation = client.conversations.get(conversation_id="thread-123") recent = client.conversations.list(user_id="user-123", limit=20) client.conversations.delete(conversation_id="thread-123") ``` GET messages are chronological and cursor-paginated with `message_cursor` (default/max 100). LIST is newest-updated-first with opaque cursors (default 20, max 100). Deleting a Conversation does not delete Memory, Knowledge, or other Conversations; a later chat may recreate a fresh thread with the same external ID. ## Memory management Memory is durable user-specific information across Conversations and remains automatic during chat. ```python memories = client.memory.list(user_id="user-123") card = client.memory.get(user_id="user-123", memory_id=memories.data[0].id) client.memory.update(user_id="user-123", memory_id=card.id, summary="User prefers concise prose.") client.memory.delete(user_id="user-123", memory_id=card.id) ``` Manual create is deferred; the certified updater owns stable conceptual keys and the 30-card/1,000-token profile limits. Delete deactivates active Memory immediately but does not erase source Conversations or History. ## Async and streaming ```python from elektric import AsyncElektric async with AsyncElektric() as client: response = await client.chat(message="Hello", user_id="user-123", conversation_id="async-123") async for event in client.chat_stream( message="Count to three", user_id="user-123", conversation_id="async-stream" ): if event.type == "content_delta": print(event.text, end="") ``` Sync streaming is the same iterator pattern without `async`. Closing a local stream or wait does not imply remote cancellation. ## Web and tools Set `web=True` and read `response.sources`. Tools use Elektric dictionaries with `name`, `description`, and `input_schema`; calls expose `id`, `name`, and parsed `arguments`. Execute them locally, then send the original user message followed by `{"role": "tool", "tool_call_id": call["id"], "content": result}`. ## Files, embeddings, and media Use `files.upload/get/delete`, `assets.get/download/delete`, `embeddings.create`, and the discoverable `embedding_profiles` alias. Media methods are `audio.transcribe/speech`, `images.generate/edit`, `video.analyze/generate`, and `jobs.get/wait/cancel`. Video generation returns an `ElektricJob`; stopping a local wait never cancels it. ## Realtime Realtime is intentionally async-only in Python: ```python async with await client.realtime.connect(input=["text"], output=["text"]) as session: await session.send_text("Hello") async for event in session: print(event.type, event.data) ``` Sessions also provide `send_audio`, `commit_audio`, `interrupt`, and `close`. ## Errors and support Catch `ElektricError` and inspect `type`, `code`, `status_code`, `request_id`, and safe `details`. Canonical subclasses include authentication, invalid-request, rate-limit, timeout, and service errors. Legacy billing, bad-request, and server subclasses remain compatible. Provider errors and secrets are never exposed or logged. Python 3.10–3.12 metadata is supported. Both clients are context managers and should be closed. See [Elektric documentation](https://elektric.ai/docs). The native SDK is recommended for the full platform; OpenAI compatibility is for quick migration of existing code. ## Streaming Web sources Pass `web=True` to synchronous or asynchronous `chat_stream`. A `StreamEvent(type="source")` carries an `ElektricSource`; source events may arrive before, during, or after content deltas and are de-duplicated by URL. The server sends finish before `[DONE]`. ## Knowledge management Knowledge is project-level reference material used automatically when relevant. `client.knowledge.add(file)` accepts a path, bytes, or open binary file. Use `list`, `get`, and `delete`, and poll until `status == "ready"`. Retry is deferred: delete and re-upload failed sources. --- Source: docs/api-reference.md Canonical URL: https://elektric.ai/docs/build/authentication # API Reference Base URL: `https://elektric.ai/v1` Authentication: `Authorization: Bearer $ELEKTRIC_API_KEY` Every route is scoped to the authenticated Project. Successful management responses include `x-elektric-request-id`; failures use the safe error envelope. ## Chat Completions - `POST /v1/chat/completions` - JSON request: `model` (compatibility clients), `messages`, `user_id`, `conversation_id`, optional `stream`, `max_tokens`, and supported generation fields. - Native context continuity requires customer-defined User and Conversation IDs. - With `stream:true`, the response is SSE and ends with `[DONE]`. ## Conversations - `GET /v1/conversations?user_id=&limit=&cursor=` - `GET /v1/conversations/:conversationId?message_limit=&message_cursor=` - `DELETE /v1/conversations/:conversationId` → 204 List limit defaults to 20 and maxes at 100. Message pages max at 100. Cursors are opaque. ## Memory - `GET /v1/memory?user_id=&status=&limit=&cursor=` - `GET /v1/memory/:memoryId?user_id=&include_inactive=` - `PATCH /v1/memory/:memoryId?user_id=` with `{"summary":"1–500 characters"}` - `DELETE /v1/memory/:memoryId?user_id=` → 204 Manual Memory creation is not public. Delete deactivates one card. ## Knowledge - `POST /v1/knowledge` as multipart form data with exactly one `file` → 201 - `GET /v1/knowledge?status=&limit=&cursor=` - `GET /v1/knowledge/:sourceId` - `DELETE /v1/knowledge/:sourceId` → 204 after cleanup Upload maximum: 16 MiB. Status: `processing`, `ready`, `failed`, or `deleting`. ## Requests - `GET /v1/requests?status=&user_id=&conversation_id=&from=&to=&limit=&cursor=` - `GET /v1/requests/:requestId` The safe DTO includes timestamps, status, latency, streaming, token Usage, context booleans, fallback, and a generic error on detailed failed records. ## Usage - `GET /v1/usage?from=&to=` - `GET /v1/usage/timeseries?from=&to=` Default: current UTC month. Explicit ranges are half-open `[from,to)` and at most 366 days. Money is an exact USD string with nine fractional digits. Usage cost is estimated. ## Billing - `GET /v1/billing` - `GET /v1/billing/transactions?type=&from=&to=&limit=&cursor=` The prepaid append-only ledger is authoritative. Project API Keys have read-only access. ## Limits - `GET /v1/limits` Returns `beta-limits-v1`, payload ceilings, current monthly Project spend, and an optional monthly cap. --- Source: docs/errors.md Canonical URL: https://elektric.ai/docs/operate/errors-retries # Errors Errors use `{error:{type,code,message,request_id}}`. Branch on type/code, not message text. | HTTP | Type | What to do | | --- | --- | --- | | 401 | `authentication_error` | Check the Project API Key and Bearer header. | | 400 | `invalid_request_error` | Correct the request schema or value. | | 402 | `billing_error` / `insufficient_balance_error` | Fund the balance or review the Project cap. | | 429 | `rate_limit_error` | Honor `Retry-After`, then retry with backoff. | | 408/504 | `timeout_error` | Retry safely with bounded backoff. | | 503 | `service_unavailable_error` | Retry with bounded exponential backoff. | | 500 | `internal_error` | Record the Request ID; contact support if persistent. | --- Source: docs/platform.md Canonical URL: https://elektric.ai/docs/platform/routing-reliability # Platform ## Routing and reliability Elektric automatically selects suitable models and handles provider fallback. Public APIs intentionally hide provider identity, internal model names, scores, and routing matrices. ## Request lifecycle 1. Elektric authenticates the Project API Key. 2. Project-shared Limits and billing admission run before inference. 3. Elektric assembles enabled Conversation, Memory, History, and Knowledge context. 4. Automatic routing selects a suitable model and handles fallback when necessary. 5. Elektric returns or streams the normalized response. 6. Request telemetry is recorded and billing is settled. Pre-inference rejection does not invoke a provider and is not charged. --- Source: docs/streaming.md Canonical URL: https://elektric.ai/docs/platform/streaming # Streaming Set `stream:true` on `POST /v1/chat/completions`, or use the SDK stream method. ```ts for await (const event of elektric.chat.stream({userId:"user_123",conversationId:"thread_123",message:"Explain DNS."})) { if (event.type === "text_delta") process.stdout.write(event.text); } ``` SSE text arrives incrementally and the raw stream ends with `[DONE]`. Completed streams settle measured Usage. --- Source: docs/billing.md Canonical URL: https://elektric.ai/docs/billing # Pricing and Credits Elektric beta is prepaid. Each finalized billable request costs: **provider inference cost + 5% Elektric fee** Platform, routing, Memory updater, context orchestration, and Knowledge-ingestion costs are absorbed by Elektric during beta. Usage API amounts are estimates. The append-only Billing ledger is authoritative. Public money values are exact USD decimal strings. --- Source: docs/limits.md Canonical URL: https://elektric.ai/docs/limits # Rate and Spend Limits All API Keys for a Project share: - 60 requests per minute - 20 requests per 10-second burst - 10 concurrent inference requests Payload ceilings: - Chat request: 8 MiB - Messages: 256 - Serialized message: 256 KiB - Requested output: 32,768 tokens - Knowledge upload: 16 MiB HTTP 429 returns a stable code, `Retry-After`, `x-elektric-ratelimit-limit`, and `x-elektric-ratelimit-reset`. Multiple Project keys do not multiply Limits. Prepaid balance is the account hard ceiling. An optional monthly Project spend cap limits one Project. Pre-inference rejection is not charged. --- Source: docs/security.md Canonical URL: https://elektric.ai/docs/security/api-keys # API Keys, Isolation, and Secrets ## API Keys Project API Keys authorize one Project. Create and revoke them in the dashboard. Keys are shown once; rotate a key if it may have been exposed. ## Data isolation Keys scope data to a Project. Knowledge and operational data are Project-scoped. Conversations and Memory are additionally associated with customer-defined User IDs; different Users are isolated. ## Local secrets Use an ignored `.env` file or a shell environment variable: ```dotenv ELEKTRIC_API_KEY= ``` Use your deployment host's encrypted secret manager in production. Never expose a key in browser code, mobile binaries, URLs, source control, logs, screenshots, analytics, or AI prompts. --- Source: docs/privacy-retention.md Canonical URL: https://elektric.ai/docs/security/deletion # Data Deletion - Conversation delete removes one thread but not Memory, Knowledge, or other Conversations. - Memory delete deactivates one card but does not erase its source Conversation. - Knowledge delete removes provider items before metadata and returns 204 after cleanup. These endpoint operations are not a complete User or account deletion workflow. Contact support for a broader deletion request. --- Source: docs/troubleshooting.md Canonical URL: https://elektric.ai/docs/troubleshooting # Troubleshooting Start with the safe error code and Request ID. - **Invalid API Key:** check the Bearer header, Project, and key status. - **Wrong model:** compatibility uses `elektric-auto`; native SDK chat is implicit. - **Conversation not found:** confirm the ID and Project scope. - **Memory not appearing:** Memory is selective; confirm the User ID and Project tool setting. - **Knowledge processing:** continue polling with a reasonable delay. - **Knowledge failed:** inspect the safe error, verify file type and 16 MiB limit, then delete and re-upload. - **Rate limit:** honor `Retry-After`. - **Insufficient balance:** add prepaid credit or review the Project cap. - **Timeout or unavailable:** retry with bounded exponential backoff. When contacting support, include the Request ID, UTC time, endpoint, HTTP status, and safe error code. Never send an API Key, full prompt, private Knowledge, or provider credentials.