API overview
Exolvra has two API surfaces, and which one you use depends on what you're building. This page explains the difference, how auth works for each, and which pages in this section cover which.
Two APIs, one platform
Exolvra exposes its functionality through two distinct HTTP APIs. They live side-by-side on the same gateway but serve very different audiences and have different security models.
1. The public Bot API — /api/v1/*
Scoped, narrow, external-facing. Designed for the drop-in chat widget and any third-party integration that talks to a specific chatbot. Authenticated with bot-scoped API keys (exo_...) that users mint from the dashboard.
- Who uses it: external websites, third-party apps, automation tools, the chat widget
- What it does: OpenAI-compatible chat completions, bot metadata, session lifecycle
- Auth:
Authorization: Bearer exo_...— keys are bound to a single chatbot - Security posture: cloud mode is always enforced; no filesystem, shell, or browser access; specialists are unreachable
Covered on:
- Authentication — how keys work, errors, CORS, security model
- Chat completions — the OpenAI-compatible endpoint and session management
2. The internal platform API — /api/*
Full platform access. Used by the dashboard itself to manage projects, issues, agents, data, documents, MCP servers, and everything else. Authenticated with user sessions (when called from the dashboard) or personal API keys (exou_..., minted from your profile page).
- Who uses it: your own scripts, internal backends, personal automation, the dashboard
- What it does: CRUD on every platform resource — projects, issues, goals, agents, data store, documents, MCP, budgets, skills, approvals
- Auth: dashboard session cookies, or
Authorization: Bearer exou_...for headless calls - Security posture: role-based — every endpoint has a minimum role requirement (ViewerOrAbove, EditorOrAbove, AdminOnly) and checks it on every request
Covered on:
- Projects — create and manage projects and goals
- Issues — create and manage issues, comments, attachments, links
- Data store — read structured data agents have produced
- Agents — create, configure, and inspect agents
- Approvals — read the approval inbox and submit decisions
- Documents — manage document collections for RAG-backed chatbots
- MCP — browse the catalogue and manage installed MCP servers
Picking a surface
| You’re building… | Use |
|---|---|
| A chat widget on your website | Public Bot API (/api/v1/*) with a bot-scoped key |
| A Slack / Discord / Telegram bot backed by a chatbot | Public Bot API with a bot-scoped key |
| A personal script that creates issues from an email trigger | Internal API (/api/*) with a personal API key |
| A backend that tracks your team’s Exolvra projects | Internal API with a personal API key |
| An internal dashboard that summarises your instance’s activity | Internal API |
| Anything that uses OpenAI SDKs out of the box | Public Bot API |
| Anything that touches specialists, projects, or the data store | Internal API |
The two surfaces never overlap. A bot-scoped exo_ key cannot read or write any internal resource, and a personal exou_ key cannot use the public /api/v1/chat/completions endpoint.
Base URL and versioning
Both surfaces live at the same host — wherever your Exolvra gateway runs.
- Public Bot API:
https://your-exolvra.example/api/v1/...— explicitly versioned, breaking changes get a v2 - Internal API:
https://your-exolvra.example/api/...— unversioned; follows the dashboard’s release cadence
The internal API is technically a public HTTP surface (anyone with a valid key can hit it), but it’s not designed as a published contract the way the Bot API is. If you’re building something durable against it, pin to a specific Exolvra version and test before upgrading.
Response formats
Every endpoint returns JSON. Successful responses use standard HTTP codes:
- 200 OK — successful read or update
- 201 Created — successful create (with a
Locationheader pointing at the new resource) - 204 No Content — successful delete or action with no body
- 4xx — client errors (missing auth, bad input, forbidden, not found)
- 5xx — server errors
Error responses use a simple shape:
{
"error": {
"message": "Human-readable description",
"type": "invalid_request_error"
}
}
The Bot API error shape is compatible with OpenAI SDKs. The internal API uses the same shape for consistency.
Rate limits
The public Bot API has per-key rate limits that you can configure on the key detail page. Default is conservative — 60 requests per minute per key. Exceeded requests get a 429 response.
The internal API is not rate-limited by default. Personal API keys can have an optional rate limit set when generating the key.
OpenAPI / Swagger
The gateway exposes a Swagger UI at /swagger when running in development mode. It’s the most complete reference for the exact request and response shapes of every endpoint — including field names, types, nullability, and examples. Use it when you need fields this documentation doesn’t mention explicitly.
In production, Swagger UI is disabled by default — enable it from Config if you want it accessible.
Where to go next
- Authentication — bot-scoped key model for
/api/v1/* - Chat completions — the main public endpoint
- Projects — the internal API entry point
- Profile — generating personal API keys for internal calls