← Back to account

QuReDec Public API

Programmatic access to the QuReDec decision-brief engine. Same engine the web app uses; same per-user credit accounting.

Base URL: https://quredec.com

Quick Start (≈ 5 minutes)

  1. Sign in at https://quredec.com/auth/login.
  2. Generate a key at https://quredec.com/account → API Keys → Generate new key. Copy the qrd_live_… token shown in the modal — it is displayed exactly once.
  3. Submit a question from any terminal:

bash curl -sS -X POST https://quredec.com/api/v1/brief \ -H "Authorization: Bearer qrd_live_YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"question":"Should we adopt parametric release for our terminal sterilization line?"}'

  1. Poll the status_url every 30 s until status is completed or partial (typically 2–5 min):

bash curl -sS -H "Authorization: Bearer qrd_live_YOUR_TOKEN" \ https://quredec.com/api/v1/brief/THE_BRIEF_RUN_ID

The terminal-status response contains the full structured brief — recommendation, confidence, key facts with citation IDs, risks, citations, and a public_share_url you can hand to anyone.

Python (with httpx)

import os, time, httpx

API = "https://quredec.com"
KEY = os.environ["QUREDEC_API_KEY"]
H = {"Authorization": f"Bearer {KEY}"}

# Submit
r = httpx.post(f"{API}/api/v1/brief",
               headers=H,
               json={"question": "Should we ship the new auth flow this sprint?"},
               timeout=30.0)
r.raise_for_status()
run_id = r.json()["brief_run_id"]
print("queued:", run_id)

# Poll
while True:
    s = httpx.get(f"{API}/api/v1/brief/{run_id}", headers=H, timeout=30.0).json()
    if s["status"] in {"completed", "partial", "failed"}:
        break
    print(f"{s['status']}: {s['progress']}%")
    time.sleep(15)

print("recommendation:", s["brief"]["recommendation"])
print("confidence:    ", s["brief"]["confidence"])
print("share URL:     ", s["public_share_url"])

Node / TypeScript

const KEY = process.env.QUREDEC_API_KEY!;
const H = { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" };

const submit = await fetch("https://quredec.com/api/v1/brief", {
  method: "POST",
  headers: H,
  body: JSON.stringify({ question: "Should we migrate our DB to Postgres 16?" }),
});
const { brief_run_id } = await submit.json();

while (true) {
  const r = await fetch(`https://quredec.com/api/v1/brief/${brief_run_id}`, { headers: H });
  const s = await r.json();
  if (["completed", "partial", "failed"].includes(s.status)) {
    console.log(s.brief?.recommendation);
    break;
  }
  await new Promise((res) => setTimeout(res, 15000));
}

Authentication

Every request authenticates with a per-user API key sent in the Authorization header as a Bearer token:

Authorization: Bearer qrd_live_<random-suffix>

Generate keys at https://quredec.com/account. Each key is shown to you exactly once at creation — copy it into a password manager immediately. The server stores only a bcrypt hash and a short prefix; if you lose the token, revoke it from the account page and create a new one.

Token formats:

Prefix Usage
qrd_live_… Production traffic. Charges credits.
qrd_test_… Sandbox tag. Same rules — credits still consumed; format is for your bookkeeping.

Keep your token secret. Anyone who has it can spend your credits.

Credits

Each successful brief submission consumes exactly 1 credit from the authenticated user, identical to a brief generated through the web app. Credit balance and tier are visible on the account page.

If your balance is zero, brief submissions return 402 Payment Required. Top up your account to continue.

Endpoints

POST /api/v1/brief — submit a decision question

Submit a question and queue a brief. The brief is generated asynchronously; poll the status URL until status == "completed".

Request body

Field Type Required Notes
question string yes The decision question. Minimum 10 characters.
links string[] no Up to 10 URLs to use as evidence (papers, articles, transcripts).
mode "A"|"B"|"C" no Pipeline mode. Defaults to B. Most callers should leave unset.
template_key string no Domain template, e.g. pharma_process_change. Defaults to default.

Response 200

{
  "brief_run_id": "f3a1...e7",
  "status": "queued",
  "status_url": "/api/v1/brief/f3a1...e7",
  "public_share_url": "https://quredec.com/shared/brief/f3a1...e7/9b21...",
  "credits_remaining": 29
}

Example

curl -sS -X POST https://quredec.com/api/v1/brief \
  -H "Authorization: Bearer qrd_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"question":"Should we adopt parametric release for our sterilization line?"}'

GET /api/v1/brief/{brief_run_id} — poll status / fetch brief

Returns the current status. Once status is completed (or partial if some evidence layers timed out), the response also includes the structured brief.

Response 200 (in progress)

{
  "brief_run_id": "f3a1...e7",
  "status": "running",
  "progress": 42,
  "status_url": "/api/v1/brief/f3a1...e7",
  "public_share_url": "https://quredec.com/shared/brief/f3a1...e7/9b21...",
  "created_at": "2026-04-27T15:02:18+00:00"
}

Response 200 (completed)

{
  "brief_run_id": "f3a1...e7",
  "status": "completed",
  "progress": 100,
  "status_url": "/api/v1/brief/f3a1...e7",
  "public_share_url": "https://quredec.com/shared/brief/f3a1...e7/9b21...",
  "created_at": "2026-04-27T15:02:18+00:00",
  "brief": {
    "executive_summary": "Parametric release is feasible if process capability ...",
    "recommendation": "Proceed with a 6-month qualification trial",
    "confidence": 0.74,
    "key_facts": [
      {"text": "ISO 14937 permits parametric release...", "citation_ids": ["1", "3"]}
    ],
    "implications": [
      {"text": "Cost reduction of ~$120K/yr...", "citation_ids": ["2"]}
    ],
    "actions": [
      {"text": "Run a 90-day capability study...", "effort": "medium", "impact": "high"}
    ],
    "risks": [
      {"text": "FDA may require additional validation...", "severity": "medium", "citation_ids": ["1"]}
    ],
    "citations": [
      {"citation_id": "1", "title": "FDA guidance ...", "url": "https://fda.gov/...", "source_type": "web_article"}
    ]
  }
}

Example

curl -sS https://quredec.com/api/v1/brief/f3a1...e7 \
  -H "Authorization: Bearer qrd_live_xxxxxxxxxxxx"

Polling cadence: brief generation typically takes 2–5 minutes. Poll every 15–30 seconds, with exponential back-off if you hit the 60 req/min/IP rate limit.

GET /api/v1/brief — list your recent briefs

Query param Type Default Notes
limit int 20 1–100.

Response 200

{
  "items": [
    {
      "brief_run_id": "f3a1...e7",
      "status": "completed",
      "progress": 100,
      "status_url": "/api/v1/brief/f3a1...e7",
      "public_share_url": "https://quredec.com/shared/brief/f3a1...e7/9b21...",
      "created_at": "2026-04-27T15:02:18+00:00"
    }
  ],
  "count": 1
}

Example

curl -sS "https://quredec.com/api/v1/brief?limit=5" \
  -H "Authorization: Bearer qrd_live_xxxxxxxxxxxx"

Use from Claude Desktop / Claude Code / Cursor (MCP)

QuReDec ships a Model Context Protocol server, quredec-mcp, that turns the API above into three tools your AI assistant can call directly:

Tool What it does
decision_brief Submit a question and (by default) wait for the brief
get_brief_status Poll a previously-submitted brief by id
list_recent_briefs List your recent briefs

Install the MCP server and point your AI client at it.

Install

pip install quredec-mcp

(Source: https://github.com/Advanced-Binary-Operations/QuReDec_MCP.)

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "quredec": {
      "command": "quredec-mcp",
      "env": {
        "QUREDEC_API_KEY": "qrd_live_YOUR_TOKEN"
      }
    }
  }
}

Restart Claude Desktop. In a new conversation, ask:

Use the decision_brief tool to evaluate "Should I migrate from Stripe to LemonSqueezy?"

Claude will call the tool, wait 2–5 min, and reply with the structured brief inline.

Claude Code (CLI)

Add to ~/.claude/mcp_servers.json:

{
  "mcpServers": {
    "quredec": {
      "command": "quredec-mcp",
      "env": {
        "QUREDEC_API_KEY": "qrd_live_YOUR_TOKEN"
      }
    }
  }
}

Then run claude and use the /mcp command to confirm quredec is connected; decision_brief is now callable in any session.

Cursor

In Settings → Features → MCP Servers, add:

Field Value
Name quredec
Command quredec-mcp
Env: QUREDEC_API_KEY qrd_live_YOUR_TOKEN

Cursor's agent can now request a decision brief mid-conversation.

Direct from Python (no MCP)

If you don't want a long-running MCP server, the Python snippet in Quick Start above is the same path — it calls the same endpoints.

Sharing a brief

Every brief response includes a public_share_url — a read-only HTML view anyone with the link can open. The URL is bound to the brief id by an HMAC, so it cannot be guessed from the brief id alone.

To revoke all share URLs at once, rotate the server-side share secret (operator-side action — contact support).

Errors

All errors return JSON with an error code and a human-readable message.

Status Code Meaning
400 invalid_json Body could not be parsed as JSON.
400 invalid_body Body parsed but is not a JSON object.
400 invalid_question question missing or shorter than 10 characters.
400 invalid_links links is not an array of strings.
401 unauthorized Missing, malformed, or revoked Authorization header.
402 no_credits Authenticated user has no credits remaining this cycle.
404 not_found brief_run_id does not belong to the caller (or doesn't exist).
429 (rate-limit JSON) More than 60 requests per minute from your IP.
500 credit_check_failed Internal error checking credits — retry.
503 feature_disabled Brief generation is currently disabled by the operator.

401 responses include WWW-Authenticate: Bearer realm="QuReDec API".

Limits

Versioning

This document describes API v1. Breaking changes will ship under a new prefix (/api/v2/...). Additive changes — new fields on existing responses, new optional request fields — may land without notice; client code MUST tolerate unknown fields.