Skip to main content

API reference

Two surfaces, two credentials, two hosts.

SurfaceHostAuthFor
Control planehttps://oberik.comX-API-Key: pk_…administering a project — Project API
Data planehttps://api.oberik.comAuthorization: Bearer <jwt>everything an end-user does

The SDK has a client for each, and they are separate types because their credentials are: createClient takes an end-user token and runs wherever your app runs; createProjectClient holds the project key and runs only on your server.

import { createClient, createProjectClient } from "@oberik/sdk";

// Server-side: administers the project and mints tokens.
const oberik = createProjectClient({ projectId, projectKey });

// Anywhere: one end-user's view of the data plane.
const ai = createClient({ getToken: oberik.tokens.forUser({ subject: user.id }) });

createClient already knows where the data plane is, so baseUrl is only needed for a self-hosted deployment or local development:

import { createClient } from "@oberik/sdk";

const ai = createClient({
// Recommended: called for a token, and again with { expired: true } on a 401.
getToken: async ({ expired }) => fetchTokenFromYourBackend({ force: expired }),
// baseUrl: "http://localhost:8000", // only if you're not on the hosted API
});

The data plane also serves its own generated OpenAPI schema — /openapi.json, with an interactive explorer at /docs on the API host (not on this site). That schema is generated from the running code, so it is the authority on request and response shapes; this page is the map.

Control plane

Authenticated with X-API-Key. The key is project admin, not just a minting credential — see the warning.

MethodPathPurpose
POST/api/projects/:id/tokenmint an end-user JWT
GET/api/projects/:idthe project, with its capability ceiling
PATCH/api/projects/:idrename, or change the ceiling ({ capabilities: {…} })
GET/api/projects/:id/capabilitiesthe ceiling alone, every flag present, plus supported modalities
PUT/api/projects/:id/system-promptthe project's system prompt
PUT/api/projects/:id/originsbrowser origins allowed to call the API
GET POST DELETE/api/projects/:id/keys[/:keyId]project API keys (created ones are shown once)
GET POST DELETE/api/projects/:id/documents[/:documentId]the project-owned corpus
GET POST/api/projects/:id/skillsthis project's skills — including end-users' own private uploads, which visibility and owner_subject tell apart
DELETE/api/projects/:id/skills/:pluginIdremove one
GET POST DELETE/api/projects/:id/mcp[/:mcpId]the project's MCP servers
GET POST DELETE/api/projects/:id/webhook-tools[/:toolId]tools the agent calls by URL (the signing secret is returned once)
POST/api/projects/:id/webhook-tools/:toolId/rotatea new signing secret; the old one keeps verifying for 24 hours
GET/api/projects/:id/webhook-tools/deliveriesrecent calls to your handlers — when, which tool, what came back
GET POST DELETE/api/projects/:id/providers[/:credId]your own LLM keys
POST/api/projects/:id/providers/:credId/refreshre-read a provider's catalog and prices
GET POST/api/projects/:id/default-modelmodel used when a request names none
PUT/api/projects/:id/retrievalembedding and rerank overrides
PUT/api/projects/:id/document-processorhow documents are read
PUT/api/projects/:id/guardrailsoberik.guardrails.setinput and output checks
PUT/api/projects/:id/subagentsoberik.subagents.set — which models delegates may run on
PUT/api/projects/:id/citationsoberik.citations — inline markers or a source list
POST/api/projects/:id/retrieval/probeoberik.retrieval.probe — measure an embedding model's dimension
GET/api/projects/:id/contextcontext-window strategy
GET/api/projects/:id/usage · /observabilityspend, requests, tokens, latency, per-model and per-user
GET/api/projects/:id/limitsusage caps on the project's LLM key
GET/api/projects/:id/sessions[/:sessionId/messages]every session in the project — subagents' own excluded unless include_subagents
GET/api/projects/:id/readinessoberik.readiness — what still has to happen before this project can answer
GET/api/projects/:id/connectoberik.connect — the starting snippet and this project's endpoints
GET POST/api/projects/:id/webhook-secret[/rotate]the key that signs deliveries to you
GET/api/projects/:id/tasksscheduled tasks
GET DELETE/api/projects/:id/wiki[/:itemId]what the agent has written
GET/api/projects/:id/sandboxes · /sandbox-hostlive sandboxes, and what they provide
POST/api/projects/:id/sandboxes/:sessionId/:actionpause · resume · delete
GET PUT/api/projects/:id/computeroberik.computerthis project's own command timeout and how many sandboxes it may hold
GET/api/orgs/:orgId/projects · /costsacross the organization — session only, not a project key

Creating a project (POST /api/orgs/:orgId/projects) and its first key need a signed-in account rather than a key, so those two steps happen in the dashboard.

POST /api/projects/:id/token

FieldTypeMeaning
subjectstringwho the token is (hierarchical identity path)
scopestringvisibility boundary — a prefix of subject
capabilitiesstring[]intersected with the project's ceiling
roles, groupsstring[]added to the project's defaults; used by document ACLs
modelsstring[]model allow-list
maxEffortenumminimal | low | medium | high
maxToolIterationsnumberagent↔tool loop ceiling (default: unlimited)
maxContextTokensnumberhistory ceiling for this token, clamped against the project's
expiresInnumberTTL in seconds (default 3600)

Returns { access_token, token_type, expires_in, tenant_id, capabilities, scope, allowed_models, max_effort, max_context_tokens }. capabilities is what was actually granted — compare it with what you asked for to see what the ceiling trimmed.

Data plane

Chat

MethodPathSDK
POST/chatai.chat.send · ai.chat.run
POST/chat/streamai.chat.stream
GET/chat/stream/{run_id}resume (automatic)
POST/chat/stream/{run_id}/cancelhandle.cancel()
POST/chat/stream/{run_id}/steerhandle.steer · ai.chat.steer
GET/chat/sessionsai.chat.sessions.listsubagents' own conversations excluded unless include_subagents
GET/chat/sessions/{id}/messagesai.chat.sessions.messages
GET/chat/sessions/{id}/todosai.chat.sessions.todos
GET/chat/sessions/{id}/eventsai.chat.sessions.watch
POST/chat/sessions/{id}/followupsai.chat.sessions.followups
POST/chat/sessions/{id}/recapai.chat.sessions.recap
POST/chat/sessions/{id}/forkai.chat.sessions.fork
DELETE/chat/sessions/{id}ai.chat.sessions.delete

Answering a paused question is ai.chat.answer — a POST /chat carrying question_answers, not its own endpoint. Approving a paused action is the same shape with approval_decisions, and returning client-tool results is tool_results.

Browser hand-off

MethodPathSDK
POST/chat/sessions/{id}/browser/frameai.chat.sessions.browserFrame
GET/chat/sessions/{id}/browser/streamai.chat.sessions.browserStream (SSE screencast)
POST/chat/sessions/{id}/browser/inputai.chat.sessions.browserInput
POST/chat/sessions/{id}/browser/checkai.chat.sessions.handoffCheck

ai.chat.sessions.handoff() wraps all four into one controller — Handing the page to the user.

Documents

MethodPathSDK
POST/documentsai.documents.uploadSimple
GET/documentsai.documents.list
GET/documents/{id}ai.documents.get
PATCH/documents/{id}ai.documents.update
POST/documents/{id}/reingestai.documents.reingest
GET/documents/{id}/chunksai.documents.chunks
GET/documents/{id}/download-urlai.documents.downloadUrl
DELETE/documents/{id}ai.documents.delete
POST/documents/retrieveai.documents.retrieve
POST/documents/presign-uploadai.documents.upload
POST/documents/{id}/presign-parts
POST/documents/{id}/complete-upload
POST/documents/{id}/abort-upload

Tools, tasks, triggers

MethodPathSDK
GET/toolsai.tools.list
GET/capabilitiesai.capabilities — what this token holds, and which enable_* switches are worth setting on it
POST/tasksai.tasks.create
GET/tasks · /tasks/{id}ai.tasks.list · ai.tasks.get
POST/tasks/{id}/cancelai.tasks.cancel
POST GET/triggersai.triggers.create · ai.triggers.list
POST/triggers/{trigger_id}/rotateai.triggers.rotate — new URL, old one alive 24h
DELETE/triggers/{trigger_id}ai.triggers.delete
POST/triggers/{slug}fire one — no bearer token; the URL is the credential

Skills and memory

MethodPathSDK
POST/pluginsai.plugins.upload · ai.plugins.uploadFolder
GET/pluginsai.plugins.list
DELETE/plugins/{id}ai.plugins.delete
GET/memoryai.memory.list — what the agent remembers, and its wiki pages
DELETE/memory/{item_id}ai.memory.delete

Sandboxes

MethodPathSDK
GET/computers/hostai.computers.host
POST GET/computers/sessionsai.computers.create · list
GET DELETE/computers/sessions/{id}ai.computers.get · destroy
POST/computers/sessions/{id}/pause · /resumeai.computers.pause · resume
POST/computers/sessions/{id}/execai.computers.exec
POST GET/computers/sessions/{id}/filesai.computers.upload · download

Governance

MethodPathSDK
GET/auditai.audit.list
POST/audit/forgetai.audit.forget
POST/auth/tokenai.auth.token — narrow an existing credential
GET/health · /readyai.health.live · ai.health.ready

/tenants exists too, for a service key provisioning tenants directly — including DELETE /tenants/{id}, which erases a tenant whole: every row carrying its id, its vectors, its raw bytes in object storage, its sandboxes and its schedules. An integration using projects never touches it; deleting a project calls it for you.

Capabilities

The complete set, grouped as the dashboard groups them, with the per-request flag that can decline each one. Fuller descriptions, and what a token can and can't do with them, are in Authentication.

GroupCapabilitiesPer-request flags
Conversationchat, system_prompt, steer, voiceenable_voice_control
Knowledgedocuments:read, documents:write, memoryenable_rag, enable_memory
Internetweb_search, browser, browser_handoffenable_web_search, enable_browser
Agentictodo, computer, subagents, tasks:read, tasks:write, triggersenable_todo, enable_computer, enable_subagents, enable_scheduling
Human in the loopask_user, approvals, ui_tools, followups, recap, auto_title, voice:transferenable_ask_user, enable_approvals, enable_auto_title
Extensionswebhook_tools, mcp:manage, plugins:write, action_spaceenable_webhook_tools, enable_plugins, enable_action_space
In and outinput:file (accept any upload) · input:image|audio|video (model perceives it directly) · output:file (send any produced file) · output:image|audio|video (model generates it)output_modalities

The effective answer for any tool family is always project ceiling ∩ token capability ∩ per-request flag, plus allowed_tools if you set one. A client can always decline; it can never exceed.

For agents

This documentation is published in machine-readable form: