Skip to main content
IMP exposes two complementary API surfaces. GraphQL is the right choice when you are creating, reading, updating, or deleting platform entities (agents, sessions, users, prompts, knowledge, evals). REST is the right choice for operations that involve streaming responses, file upload/download, media generation, or binary output — the things that do not map naturally to GraphQL’s request/response model.

Agent runs

Stream or synchronously invoke any agent instance via POST /agents/litellm/run/{instance}.

Session files

List, upload, sync, and delete files attached to an agent session.

Media

Transcribe audio, synthesize speech, and generate or edit images.

System

Ping for auth status, fetch theme and platform config.

Base URL

The IMP backend listens on port 9001 by default:
All paths in this reference are relative to that base URL.

Authentication

Three credential types are accepted across REST endpoints.

API key

Pass an organisation API key in the x-api-key header (or the alias exulu-api-key):
Key format: sk_<secret>/<keyname> — the secret portion, a literal /, and the human-readable key name. A Bearer prefix on the header value is tolerated and stripped. Keys can be scoped to a specific agent; a scoped key is rejected if used against a different agent. Manage keys under API keys in the admin area.

Session JWT

Pass a NextAuth session JWT as a bearer token in the Authorization header:
The token is HS256, signed with the deployment’s NEXTAUTH_SECRET. This is what the IMP frontend sends automatically. You can copy your personal token from the API keys page.
The agent-run endpoint (/agents/litellm/run/{instance}) does not require authentication when the agent’s rights_mode is set to public. All other REST endpoints require either an API key or a session JWT.The internal-key header (set to the deployment’s INTERNAL_SECRET) is accepted only on the Uppy S3 proxy routes (/s3/*), which are part of the file-upload infrastructure and documented with the upload endpoints. The session-file routes (/sessions/{sessionId}/files/...) use the standard API key or Bearer JWT authentication.

When to use REST vs GraphQL

Streaming semantics

When you call POST /agents/litellm/run/{instance} with the stream: true header, the response is an AI SDK UIMessage stream delivered over HTTP with Content-Type: text/event-stream. Each line is a server-sent event carrying a serialised UIMessage part. The stream follows the AI SDK protocol:
  • Lines prefixed 0: carry the initial message envelope.
  • Lines prefixed 2: carry incremental part deltas (text deltas, tool-call initiation, tool-result).
  • Lines prefixed 9: carry finish-step events with per-step token usage.
  • Lines prefixed e: carry the final finish event with aggregate token usage in messageMetadata.
On the client side, use the AI SDK’s useChat hook or streamText utilities to consume the stream. The backend also pipes the stream to completion in the background so that onFinish fires even if the client disconnects mid-stream — session persistence is not lost on abort. A 413 response (rather than a stream error) is returned when the session’s context window is full. Call POST /agents/litellm/compact/{instance} to compact the session history before retrying.

Agent-run worked example

Request

Response (streaming, stream: true)

The response body is a series of text/event-stream lines:

Response (synchronous, stream: false)

The sync response body is the assistant’s text as a JSON-encoded string — the entire body is a quoted string, not an object. Use streaming mode if you need structured events or token usage.

Session files

Session files are stored in S3 under the session’s prefix. The typical flow is:
  1. Call POST /sessions/{sessionId}/files/upload-sign to get a presigned PUT URL and key.
  2. PUT the file bytes directly to the presigned URL.
  3. Call POST /sessions/{sessionId}/files/sync-to-sandbox with the returned key so the agent can read the file on its next tool call.
Use GET /sessions/{sessionId}/files to list files and DELETE /sessions/{sessionId}/files?key=<key> to remove one. The GET /sessions/{sessionId}/file/preview-pdf endpoint converts Office files (.docx, .xlsx, .pptx, etc.) to PDF via LibreOffice for in-browser preview. The JWT may be passed as an ?auth= query parameter so <iframe> elements can load the PDF without a custom request header.

Media endpoints

Transcription (POST /transcribe) accepts multipart audio up to 25 MB and returns the transcribed text. Requires EXULU_USE_LITELLM=true and TRANSCRIPTION_MODEL to be set. An optional language field (ISO 639-1) prevents Whisper from mis-detecting the language on short clips. Speech synthesis (POST /speech) converts up to 4,000 characters of text to an MP3 audio file. Requires EXULU_USE_LITELLM=true, TTS_MODEL, and TTS_VOICE. Image generation (POST /images/generate, POST /images/edit, POST /images/select, GET /images/history) backs the in-chat image widget. Models are declared in config.litellm.yaml with model_info.type: image_generation. Generated images are stored in S3 and returned as presigned URLs.

System endpoints

  • GET /ping — returns { "authenticated": true/false }. Useful for checking credentials without triggering a full agent run. No authentication required.
  • GET /theme — returns the platform theme (light/dark colour maps). No authentication required.
  • GET /config — returns the platform’s active feature flags and service states (LiteLLM, workers, file uploads, MCP, telemetry). No authentication required.

Gateway endpoints

IMP provides two integration surfaces for external clients:
  • LiteLLM gateway — direct OpenAI-compatible pass-through at /litellm/{project}/v1/.... Call any model in your config.litellm.yaml by name using any OpenAI-compatible SDK or tool. Use this for raw model calls, embeddings, and batch jobs.
  • MCP endpoint — Streamable HTTP MCP server at /mcp/:agent for Claude Desktop, Cursor, and any MCP-compatible client. Use this to expose a specific IMP agent with its instructions and knowledge.

GDPR / DSGVO

Operator endpoints for fulfilling data-subject access and erasure requests are documented on the GDPR endpoints page. Both require super_admin and are intentionally API-only.