Live · api.dragonfireai.org

One key.
All the AIs.

Chat. Vision. Embeddings. Images. Video. Voice. Search. Structured extraction. One API surface, one key, one model naming convention.

Base URL:https://api.dragonfireai.org
Browse Endpoints Request an API Key

Closed alpha — access by invite

API keys aren't self-serve yet. We're finalising sovereign account primitives (mnemonic + wallet) before opening registrations. Join the Signal group to request a test key and get updates when self-serve opens.

Join Signal

API Reference

Three request-shape families. Every endpoint accepts Authorization: Bearer drg_... and JSON. Model names are shared across all three.

Authorization: Bearer drg_xxxxxxxxxxxxxxxx
Chat Completions family — the widely-used /v1/chat/completions request shape
POST/v1/chat/completionschat + reasoning + vision · streaming supported
POST/v1/embeddingsvector embeddings for RAG / search
POST/v1/images/generationstext → image (t2i)
POST/v1/images/editimage + prompt → edit (i2i)
POST/v1/images/variationsimage → variations
POST/v1/audio/speechTTS · 12 emotions on Pro tier
POST/v1/audio/transcriptionsSTT (multipart/form-data)
GET/v1/modelslive raw-LLM catalog (public, no auth)
GET/v1/agentslive LoRA agent roster (public, no auth) — creator + base + provider state
Messages family — the /v1/messages request shape
POST/v1/messagesMessages-API shape · same routing as chat/completions
DragonFire Extended — sovereign extensions beyond the standard shapes
POST/v1/chat/emotionalchat returns {message, emotion} for face + voice drive
POST/v1/videos/generationsimage-to-video (still + prompt → short reel)
POST/v1/extractcontent + JSON Schema → structured JSON
POST/v1/html/extractHTML + schema → JSON (auto-strip script/style)
POST/v1/web/extractURL + schema → JSON (fetch + extract in one call)
POST/v1/web/searchdistributed web search (5-tier cascade)
POST/v1/fixschema-constrained repair of broken LLM output
POST/v1/html/cleanHTML → plain / markdown / semantic text
POST/v1/formatinput → markdown / plain / code
POST/v1/transcription/summarizeSTT text → chat summary in one hop
POST/v1/artifactsschema-guided artifact generation
Agents — sovereign LoRA personas

DragonFire agents are .ai personas: a LoRA tuned on a small dense base, owned by a creator, addressable by a memorable name. Fires the same POST /v1/chat/completions shape — just set "model": "<agent-id>". Router picks a hot provider when one is serving, otherwise falls back to the base-family cloud (and always settles the earnings under the agent name so creator attribution holds).

Loading live agents from GET /v1/agents
Live source: curl https://api.dragonfireai.org/v1/agents (public, no auth). More agents publish as creators register.
Models — raw chat LLMs

Wire-compat tier for OpenAI/Anthropic SDKs. Every entry maps to a base chat model. Set "model": "<id>" in the request body. The list is grouped by modality (chat, embeddings, image, video, speech, transcription, vision, search) and refreshed on every page load.

Loading live catalog from GET /v1/models
If a call returns model_not_found during closed alpha, the name may have drifted — always cross-check against the live grid above (or curl GET /v1/models).

Quick examples

Copy-paste ready. All three families share the same drg_ Bearer — only the wire shape changes.

Chat · /v1/chat/completions
curl https://api.dragonfireai.org/v1/chat/completions \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dragon-gpt",
    "messages": [{"role": "user", "content": "Hello, forge master."}]
  }'
Streaming chat (SSE)
curl https://api.dragonfireai.org/v1/chat/completions \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  --no-buffer \
  -d '{
    "model": "dragon-gpt",
    "stream": true,
    "messages": [{"role": "user", "content": "Tell me a short story."}]
  }'
# Response: text/event-stream, one JSON chunk per line, terminated by "data: [DONE]"
Messages shape · /v1/messages
curl https://api.dragonfireai.org/v1/messages \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dragon-gpt",
    "max_tokens": 512,
    "messages": [{"role": "user", "content": "Hello, forge master."}]
  }'
Embeddings · /v1/embeddings
curl https://api.dragonfireai.org/v1/embeddings \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dragon-embed",
    "input": ["forge master", "the anvil sings", "iron will bends"]
  }'
Structured JSON · /v1/extract
curl https://api.dragonfireai.org/v1/extract \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "The Ember 300 sedan launches at £24,990 and ships in Q3.",
    "schema": {
      "type": "object",
      "properties": {
        "product_name":    {"type": "string"},
        "price_gbp":       {"type": "number"},
        "release_quarter": {"type": "string"}
      },
      "required": ["product_name", "price_gbp", "release_quarter"]
    }
  }'
Web search · /v1/web/search
curl https://api.dragonfireai.org/v1/web/search \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "q": "distributed systems consensus overview",
    "num_results": 5
  }'
Text-to-image · /v1/images/generations
curl https://api.dragonfireai.org/v1/images/generations \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dragon-image",
    "prompt": "a bronze dragon curled around a lit forge, dusk light",
    "size": "1024x1024"
  }'
Image-to-video · /v1/videos/generations
curl https://api.dragonfireai.org/v1/videos/generations \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dragon-reel",
    "image_url": "https://example.com/still.jpg",
    "prompt": "gentle camera pan, sparks bloom",
    "duration_s": 4
  }'
Text-to-speech (standard) · /v1/audio/speech
curl https://api.dragonfireai.org/v1/audio/speech \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  -o speech.mp3 \
  -d '{
    "model": "dragon-tts",
    "voice": "george",
    "input": "The dragon rises at dawn."
  }'
Text-to-speech (premium, emotion) · /v1/audio/speech
curl https://api.dragonfireai.org/v1/audio/speech \
  -H "Authorization: Bearer drg_xxxxx" \
  -H "Content-Type: application/json" \
  -o speech.mp3 \
  -d '{
    "model": "dragon-voice",
    "voice": "george",
    "emotion": "warm",
    "input": "The dragon rises at dawn."
  }'
Speech-to-text · /v1/audio/transcriptions
curl https://api.dragonfireai.org/v1/audio/transcriptions \
  -H "Authorization: Bearer drg_xxxxx" \
  -F "[email protected]" \
  -F "model=dragon-stt"
Python · requests
import requests

resp = requests.post(
    "https://api.dragonfireai.org/v1/chat/completions",
    headers={"Authorization": "Bearer drg_xxxxx"},
    json={
        "model": "dragon-gpt",
        "messages": [{"role": "user", "content": "Hello, forge master."}],
    },
    timeout=60,
)
print(resp.json()["choices"][0]["message"]["content"])
Node · fetch
const resp = await fetch("https://api.dragonfireai.org/v1/chat/completions", {
  method: "POST",
  headers: {
    "Authorization": "Bearer drg_xxxxx",
    "Content-Type":  "application/json",
  },
  body: JSON.stringify({
    model: "dragon-gpt",
    messages: [{ role: "user", content: "Hello, forge master." }],
  }),
});
const data = await resp.json();
console.log(data.choices[0].message.content);
Go · net/http
package main

import (
    "bytes"
    "fmt"
    "io"
    "net/http"
)

func main() {
    body := []byte(`{"model":"dragon-gpt","messages":[{"role":"user","content":"Hello, forge master."}]}`)
    req, _ := http.NewRequest("POST", "https://api.dragonfireai.org/v1/chat/completions", bytes.NewReader(body))
    req.Header.Set("Authorization", "Bearer drg_xxxxx")
    req.Header.Set("Content-Type",  "application/json")
    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    out, _ := io.ReadAll(resp.Body)
    fmt.Println(string(out))
}

Errors & response codes

Every non-2xx response is JSON with the shape {"error": {"code": "...", "message": "..."}}. Log the x-request-id header if you need to report one.

StatusError codeWhat it means
400bad_requestMalformed JSON body or missing required field
400model_not_foundThe model value isn't in /v1/models and has no alias — never billed upstream
401invalid_api_keyBearer missing, wrong format, or unknown to the registry
402insufficient_balanceWallet balance won't cover the estimated call cost
402quota_exceeded_monthlyKey hit its monthly DC cap; response body includes the reset unix timestamp
403scope_deniedKey isn't scoped for this endpoint or model
429rate_limitedToo many requests inside the sliding window — back off and retry
502upstream_unreachableRoute to the model provider failed — retry safely, no billing
504upstream_timeoutProvider held the connection too long — retry safely, no billing
Safe retries

4xx should not be retried without a code change. 5xx (502 / 504) is safe to retry — no wallet debit lands until the upstream returns a usable response, so a timeout costs nothing.

Want an API key?

Self-serve isn't open yet — we're finalising sovereign account primitives (mnemonic + wallet) before we accept registrations. Join the Signal group to request a test key, share feedback, and get pinged when the front door opens.

Join the Signal Group