Skip to content

API endpoints

Pluma's HTTP API lives under /api/*. All routes go through the middleware chain withTrustedProxies → withLogging → withNoStoreOnUserContent → withAuth → withHostAllowlist → withCORS → mux. Browser sessions auth via WebAuthn passkeys; scripts auth via bearer token (Authorization: Bearer <token> or ?api_token=).

For deep request/response detail, the source is at server/handlers.go and the sibling *_handlers.go files. This page summarises the surface.

Chat & models

Method Path Notes
GET /api/health Upstream reachability + active connection summary.
GET /api/models Models the active LLM connection advertises through /v1/models.
POST /api/chat OpenAI-shaped streaming chat. Streams SSE when stream: true (the default for stateful conversations).

POST /api/chat request body:

{
  "model": "qwen2.5-32b-instruct",
  "messages": [{ "role": "user", "content": "Hi" }],
  "stream": true,
  "conversation_id": "abc123",
  "user_message_id": "u1",
  "assistant_message_id": "a1",
  "temperature": 0.7,
  "top_p": 0.95
}

Stateless mode (no conversation_id) returns a single OpenAI-shape JSON response when stream: false. Used by the auto-titler, prompt-derivation, and AI character creator.

Connections (LLM)

Method Path Notes
GET /api/connections List profiles (API keys redacted).
PUT /api/connections Create or update.
DELETE /api/connections/{id} Remove.
DELETE /api/connections/{id}/key Clear stored API key without removing the profile.
POST /api/connections/{id}/activate Mark active for the next /api/chat.
POST /api/connections/test Ping an unsaved profile to check reachability.
POST /api/connections/discover Probe localhost for running LLM servers.

Conversations

Method Path Notes
GET /api/conversations List with full message arrays. Decrypted on read.
GET /api/conversations/{id} Fetch one.
PUT /api/conversations/{id} Save (overwrite).
DELETE /api/conversations/{id} Remove.
PATCH /api/conversations/{id}/draft Persist the composer draft (encrypted alongside the conversation).
PATCH /api/conversations/{id}/messages/{mid} Edit one message in place.
DELETE /api/conversations/{id}/messages/{mid} Remove one message.

Characters

Method Path Notes
GET /api/characters List (includes external cards from card_dirs).
GET /api/characters/{id} Single card.
GET /api/characters/{id}/avatar Avatar PNG. ?w=<px> resizes server-side.
GET /api/characters/{id}/avatar/status Background portrait job state (none|pending|running|done|failed).
PUT /api/characters/{id} Update. Re-embeds the card JSON into the PNG so the file stays share-ready.
PUT /api/characters/{id}/avatar Replace the avatar; embeds the card JSON.
DELETE /api/characters/{id} Remove.
POST /api/characters/import Multipart PNG / JSON upload.
POST /api/characters/import-url URL import (chub.ai, direct .png/.json links). Uses the SSRF-restricted HTTP client.
GET /api/characters/search chub.ai proxy with query / tag / sort params.
POST /api/characters/restore-pluma Re-install the built-in Pluma character. Bypasses the builtin_pluma_installed flag.

Personas

Method Path Notes
GET /api/personas List.
GET /api/personas/{id} Single persona.
PUT /api/personas/{id} Create or update.
DELETE /api/personas/{id} Remove.
GET /api/personas/{id}/avatar Avatar (when set; stored as a portable Tavern v2 persona card).
PUT /api/personas/{id}/avatar Replace avatar.

HuggingFace model browser

Method Path Notes
GET /api/models/browse?q=&format= Search (format = gguf or mlx).
GET /api/models/browse/files?repo=&format= List candidate files in a repo.
POST /api/models/download Start a background download job.
GET /api/models/downloads Active + recent jobs with byte progress.
POST /api/models/downloads/{id}/cancel Stop a running job.
GET /api/models/local What's on disk under <datadir>/models/.

Image generation

Method Path Notes
GET /api/image/connections SD backend profiles (A1111 / ComfyUI).
PUT /api/image/connections Create or update.
DELETE /api/image/connections/{id} Remove.
POST /api/image/connections/{id}/activate Mark active.
POST /api/image/connections/test Reachability check.
POST /api/image/discover Probe A1111 (7860) + ComfyUI (8188).
GET /api/image/connections/{id}/checkpoints Live model list for the dropdown.
POST /api/image/generate Unified entry point. Body picks A1111 vs ComfyUI semantics by the active profile.
GET /api/image/workflows <datadir>/workflows/ contents.
GET /api/image/workflows/{id} Single workflow JSON.
PUT /api/image/workflows/{id} Save.
DELETE /api/image/workflows/{id} Remove.

Voice library + TTS

Method Path Notes
POST /api/tts/speak Synthesize one chunk. Body: { text, voice, model, format, base_url, ref_audio }.
GET /api/tts/config Current TTS endpoint + model + voice.
PUT /api/tts/config Update TTS endpoint + model + voice.
GET /api/tts/voices?model= Voices the upstream advertises (or that pluma found via filesystem scan / curated catalogue).
GET /api/tts/models Models the TTS upstream advertises.
GET /api/voices List voice-library samples.
POST /api/voices Upload an audio file (multipart: audio + name + description).
POST /api/voices/from-url Import from YouTube / SoundCloud / Vimeo / direct media URL via yt-dlp + SSRF guard.
GET /api/voices/{id} Sample metadata.
DELETE /api/voices/{id} Remove.
GET /api/voices/{id}/audio Serve the raw audio for preview.

Attachments

Method Path Notes
PUT /api/attachments/{name} Store an image blob.
GET /api/attachments/{name} Fetch.
DELETE /api/attachments/{name} Remove.

Auth (WebAuthn passkeys + bearer tokens)

Method Path Notes
GET /api/auth/status Per-origin paired + bypass state for the calling browser.
POST /api/auth/register/begin Start enrollment. First-per-RPID is open (grace window).
POST /api/auth/register/finish Complete enrollment.
POST /api/auth/login/begin Start sign-in challenge.
POST /api/auth/login/finish Complete sign-in; returns session cookie.
POST /api/auth/logout Clear session.
GET /api/auth/credentials List enrolled passkeys.
DELETE /api/auth/credentials/{id} Revoke a passkey.
POST /api/auth/token Mint a bearer token (requires session). Used by the pluma auth login CLI.

First-run wizard

Method Path Notes
GET /api/setup/status { "completed": bool }.
POST /api/setup/complete Mark the wizard dismissed or finished.

Tailscale (embedded tsnet)

Method Path Notes
GET /api/tailscale/status { enabled, mode, state, hostname, fqdn, port, auth_url, error }.
POST /api/tailscale/enable Live-enable; body { "hostname": "..." } optional.
POST /api/tailscale/disable Stop the node + wipe local state under <datadir>/tsnet/.