workspace onlinestreaming availableaccount access protecteddeveloper tools readysupport availableworkspace onlinestreaming availableaccount access protecteddeveloper tools readysupport available
// Documentation

WormGPT API.

A small, streaming HTTP API for chat completions. Requests are authenticated with a personal API key and metered against your existing account balance — there is no separate API billing.

Base URL

base url
https://worm-gpt.com/api/public/v1

All requests must be sent over HTTPS.

Authentication

Every request must include an Authorization header with a personal API key. Create one on the API keys page. Never expose keys in client-side code, browser extensions, or repositories.

header
Authorization: Bearer wgpt_YOUR_KEY

Chat completions

POST /chat — send a list of messages and receive a streaming or buffered response. The active model chain is chosen server-side. If the primary model fails, the request automatically falls back to the next configured model. A single request is never billed twice.

curl · streaming
curl -N https://worm-gpt.com/api/public/v1/chat \
  -H "Authorization: Bearer wgpt_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      { "role": "user", "content": "Explain OAuth 2.1 in one paragraph." }
    ]
  }'
node · streaming
const res = await fetch("https://worm-gpt.com/api/public/v1/chat", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WORMGPT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    messages: [{ role: "user", content: "Hello!" }],
  }),
});

// Stream Server-Sent Events (default). Set { stream: false } to get JSON.
const reader = res.body!.getReader();
const decoder = new TextDecoder();
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  for (const line of decoder.decode(value).split("\n")) {
    if (!line.startsWith("data: ")) continue;
    const payload = line.slice(6);
    if (payload === "[DONE]") return;
    const { delta } = JSON.parse(payload);
    process.stdout.write(delta ?? "");
  }
}

Set { "stream": false } in the request body to receive a single JSON response:

response · buffered
{
  "model": "google/gemini-2.5-flash-lite",
  "message": { "role": "assistant", "content": "..." }
}

Errors

Errors use standard HTTP status codes. The body is JSON with an error.type and error.message.

error · 402
{
  "error": {
    "type": "insufficient_tokens",
    "message": "No tokens remaining. Add a plan or top up to continue."
  }
}
  • 401 unauthorized — missing or revoked key.
  • 402 insufficient_tokens — top up or subscribe.
  • 429 rate_limited — 60 requests per minute per key.
  • 502 upstream_error — all configured models failed.
  • 503 unavailable — no model is currently configured.

Metering & safety

One account, one balance

Chat, API, and MCP requests all draw from the same token balance and usage_ledger.

No duplicate charges

A hold is placed before generation and settled exactly once, even if the request falls back to another model.