ModelFusion Docs

ModelFusion API Docs

MVP API reference for early access users

Base URL: https://modelfusion-api.vercel.appVersion: MVP v2 (April 16, 2026)

Quick Start

curl
curl -X POST https://modelfusion-api.vercel.app/api/fusion \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "prompt": "Explain what an API gateway does",
    "preset": "general"
  }'

Authentication

All requests require a Bearer token in the Authorization header:

Authorization: Bearer mf_live_<your_key>

Keys look like mf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (56 chars after prefix). Never share your key publicly or commit it to a repo.

POST /api/fusion

Runs a multi-model fusion on your prompt.

Request Headers

HeaderValueRequired
AuthorizationBearer YOUR_API_KEYYes
Content-Typeapplication/jsonYes
Acceptapplication/json or text/event-streamNo (defaults to SSE)

Request Body

FieldTypeDefaultDescription
promptstring(required)The question or task for the models (max 100,000 chars)
presetstringgeneralDomain preset: general, medfusion, legalfusion, codefusion
modelsstring[]["opus-4.6","o1-pro","deepseek-v3"]Which proposer models to use
judgeModelstringsonnet-4Model used for analysis + synthesis
maxTokensinteger4096Max tokens per proposer response
temperaturenumber0.7Temperature for proposer calls (0.0–1.0)
costBudgetnumber2.00Max USD for this request; rejects with 402 if exceeded
enableVerificationbooleanautoRun Stage 4 verification. Auto-true for medfusion/legalfusion

Valid Models: opus-4.6, o1-pro, deepseek-v3, sonnet-4

Response Modes

ModelFusion™ supports two response modes, chosen by the Accept header.

Mode 1: JSON Response

Set Accept: application/json to receive the complete fusion result as one JSON object.

Response Body (HTTP 200)
{
  "sessionId": "dc26fc42-85a1-4b00-8683-3bb795b40bd1",
  "fusedContent": "The synthesized answer as coherent prose...",
  "analysis": {
    "agreement": [
      {
        "statement": "A claim all models agree on",
        "models": ["opus-4.6", "o1-pro", "deepseek-v3"],
        "confidence": 0.95
      }
    ],
    "conflicts": [...],
    "partialCoverage": [...],
    "uniqueInsights": [...],
    "blindSpots": [...],
    "agreementScore": 87
  },
  "provenance": [
    { "paragraphIndex": 0, "sources": ["opus-4.6", "o1-pro"] },
    { "paragraphIndex": 1, "sources": ["deepseek-v3"] }
  ],
  "verification": {
    "isConsistent": true,
    "issues": [],
    "overallConfidence": 94
  },
  "modelResponses": [...],
  "metadata": {
    "totalCost": 0.0342,
    "totalLatencyMs": 14500,
    "modelsUsed": ["opus-4.6", "o1-pro", "deepseek-v3"],
    "timestamp": "2026-04-16T12:40:38.839Z"
  }
}

Key Response Fields

  • fusedContent — The primary synthesized answer. Use this for display.
  • analysis — Structured cross-model analysis. Expose in UIs that show "why" the answer is trustworthy.
  • provenance — Maps each paragraph to contributing models. Useful for audit trails.
  • verification — Only present when Stage 4 runs. isConsistent: false means the synthesis contains fabrications.

Mode 2: SSE Streaming

Set Accept: text/event-stream to receive Server-Sent Events — better UX for real-time display.

Event Types (in order)
data: {"type":"session","sessionId":"..."}

data: {"type":"analysis","agreementScore":87,"agreementCount":3,"conflictCount":1,...}

data: {"type":"content","text":"The first 80 chars of fused output..."}

data: {"type":"content","text":"The next 80 chars..."}

data: {"type":"provenance","data":[{"paragraphIndex":0,"sources":[...]}]}

data: {"type":"verification","data":{...}}

data: {"type":"done","metadata":{...}}

Domain Presets

Presets prepend a system prompt to every proposer call and can inject judge-specific guidance.

PresetUse CaseSpecial Behavior
generalBalanced analysis, no domain focusDefault behavior
medfusionHealthcare info with evidence gradingVerification stage auto-enabled
legalfusionLegal analysis with hallucination guardsVerification stage auto-enabled
codefusionCode generation and reviewFocuses on syntax, security, error handling
Important: MedFusion and LegalFusion presets are prompt-engineering templates, NOT regulatory compliance certifications. Do not send PHI through MedFusion �� there is no HIPAA/BAA infrastructure in the MVP.

Error Responses

All errors return JSON with an error field.

StatusMeaningExample Body
400Invalid request body{"error":"'prompt' is required and must be a string"}
401Missing or invalid API key{"error":"Invalid API key"}
402Request exceeds cost budget{"error":"Estimated cost $2.34 exceeds budget $2.00"}
403API key deactivated{"error":"API key has been deactivated"}
429Rate limit exceeded (coming soon){"error":"Rate limit exceeded","retryAfter":45}
500Unexpected server error{"error":"Internal server error"}
503All models unavailable{"error":"All models are currently unavailable..."}

GET /api/fusion

Returns service configuration and capabilities. No authentication required.

Response
{
  "models": ["opus-4.6", "o1-pro", "deepseek-v3", "sonnet-4"],
  "defaultModels": ["opus-4.6", "o1-pro", "deepseek-v3"],
  "presets": [
    { "id": "general", "name": "General", "description": "..." },
    { "id": "medfusion", "name": "MedFusion", "description": "..." }
  ],
  "defaultJudge": "sonnet-4",
  "features": {
    "verification": {
      "description": "Optional synthesis verification pass",
      "autoEnabled": ["medfusion", "legalfusion"],
      "canOverride": true
    },
    "provenance": { "description": "Paragraph-level source attribution" },
    "partialCoverage": { "description": "Points covered by some but not all models" }
  }
}

GET /api/health

Simple health check endpoint.

Response
{"status":"ok","timestamp":"..."}

Returns HTTP 200.

Integration Examples

Python

python
import requests

response = requests.post(
    "https://modelfusion-api.vercel.app/api/fusion",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json",
        "Accept": "application/json",
    },
    json={
        "prompt": "Explain quantum entanglement",
        "preset": "general",
    },
)

result = response.json()
print(result["fusedContent"])
print(f"Agreement: {result['analysis']['agreementScore']}/100")

Node.js / TypeScript

typescript
const response = await fetch("https://modelfusion-api.vercel.app/api/fusion", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.MODELFUSION_API_KEY}`,
    "Content-Type": "application/json",
    "Accept": "application/json",
  },
  body: JSON.stringify({
    prompt: "Explain quantum entanglement",
    preset: "general",
  }),
});

const result = await response.json();
console.log(result.fusedContent);

SSE Streaming (JavaScript)

javascript
const response = await fetch("https://modelfusion-api.vercel.app/api/fusion", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    "Accept": "text/event-stream",
  },
  body: JSON.stringify({ prompt: "...", preset: "general" }),
});

const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  buffer += decoder.decode(value, { stream: true });
  const lines = buffer.split("\n\n");
  buffer = lines.pop() || "";

  for (const line of lines) {
    if (!line.startsWith("data: ")) continue;
    const event = JSON.parse(line.slice(6));

    switch (event.type) {
      case "analysis":
        console.log("Agreement:", event.agreementScore);
        break;
      case "content":
        process.stdout.write(event.text);
        break;
      case "done":
        console.log("\nTotal cost:", event.metadata.totalCost);
        break;
    }
  }
}

Telegram Bot (Python)

python
from telegram import Update
from telegram.ext import ContextTypes
import requests

MF_API_KEY = "mf_live_..."
MF_URL = "https://modelfusion-api.vercel.app/api/fusion"

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_prompt = update.message.text

    response = requests.post(
        MF_URL,
        headers={
            "Authorization": f"Bearer {MF_API_KEY}",
            "Content-Type": "application/json",
            "Accept": "application/json",
        },
        json={"prompt": user_prompt, "preset": "general"},
        timeout=60,
    )

    result = response.json()
    reply = result["fusedContent"]
    score = result["analysis"]["agreementScore"]
    footer = f"\n\n_Agreement: {score}/100 across {len(result['metadata']['modelsUsed'])} models_"

    await update.message.reply_text(reply + footer, parse_mode="Markdown")

Current MVP Limitations

  • Frontier model access: Opus 4.6 and o1-pro are temporarily unavailable pending OpenRouter credit top-up. Requests involving those models will return solo fallback on DeepSeek-V3 alone.
  • Rate limiting: Not yet enforced in the MVP. Please be a good citizen during testing.
  • SSE streaming: Code path exists but hasn't been extensively tested in production.
  • No async/webhook mode yet: All requests are synchronous.

Support

  • Status page: Check Vercel status for infrastructure issues
  • Bug reports: Send directly to the engineering team
  • Feature requests: Welcome during the early access period

Last updated: April 16, 2026. API is versioned implicitly — breaking changes will trigger a /v2 URL path.