ModelFusion™ API Docs
MVP API reference for early access users
https://modelfusion-api.vercel.appVersion: MVP v2 (April 16, 2026)Quick Start
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
| Header | Value | Required |
|---|---|---|
Authorization | Bearer YOUR_API_KEY | Yes |
Content-Type | application/json | Yes |
Accept | application/json or text/event-stream | No (defaults to SSE) |
Request Body
| Field | Type | Default | Description |
|---|---|---|---|
prompt | string | (required) | The question or task for the models (max 100,000 chars) |
preset | string | general | Domain preset: general, medfusion, legalfusion, codefusion |
models | string[] | ["opus-4.6","o1-pro","deepseek-v3"] | Which proposer models to use |
judgeModel | string | sonnet-4 | Model used for analysis + synthesis |
maxTokens | integer | 4096 | Max tokens per proposer response |
temperature | number | 0.7 | Temperature for proposer calls (0.0–1.0) |
costBudget | number | 2.00 | Max USD for this request; rejects with 402 if exceeded |
enableVerification | boolean | auto | Run 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.
{
"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: falsemeans the synthesis contains fabrications.
Mode 2: SSE Streaming
Set Accept: text/event-stream to receive Server-Sent Events — better UX for real-time display.
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.
| Preset | Use Case | Special Behavior |
|---|---|---|
general | Balanced analysis, no domain focus | Default behavior |
medfusion | Healthcare info with evidence grading | Verification stage auto-enabled |
legalfusion | Legal analysis with hallucination guards | Verification stage auto-enabled |
codefusion | Code generation and review | Focuses on syntax, security, error handling |
Error Responses
All errors return JSON with an error field.
| Status | Meaning | Example Body |
|---|---|---|
400 | Invalid request body | {"error":"'prompt' is required and must be a string"} |
401 | Missing or invalid API key | {"error":"Invalid API key"} |
402 | Request exceeds cost budget | {"error":"Estimated cost $2.34 exceeds budget $2.00"} |
403 | API key deactivated | {"error":"API key has been deactivated"} |
429 | Rate limit exceeded (coming soon) | {"error":"Rate limit exceeded","retryAfter":45} |
500 | Unexpected server error | {"error":"Internal server error"} |
503 | All models unavailable | {"error":"All models are currently unavailable..."} |
GET /api/fusion
Returns service configuration and capabilities. No authentication required.
{
"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.
{"status":"ok","timestamp":"..."}Returns HTTP 200.
Integration Examples
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
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)
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)
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.