QUICKSTART

Four steps: get a key, send your agent’s first decision, read the signed record it left, and verify that record yourself. About ten minutes with curl; no SDK needed.

1 · GET A KEY

During the design-partner phase we issue keys by hand. Email autopsy@queryfanout.dev with your team and what your agent does. You get:

Keys are tenant-scoped: you only ever see your own records. Keep the key in an environment variable or secret store, never in code or a prompt. Check it:

export QF_URL=https://queryfanout.dev
export QF_KEY=...   # your writer key

curl -s "$QF_URL/auth/whoami" -H "X-API-Key: $QF_KEY"
# {"tenant_id": "your-tenant", "role": "writer", "permissions": ["audit:read", "decision:write", ...]}

2 · SEND A DECISION

Your agent already found some sources. Send the question and those sources to POST /policy/evaluate. Query Fanout runs no search; it scores what you sent, decides answer or escalate, and records the decision.

curl -s -X POST "$QF_URL/policy/evaluate" \
  -H "X-API-Key: $QF_KEY" -H "Content-Type: application/json" \
  -d '{
  "query": "What is Yuma Consensus in Bittensor?",
  "policy": "support",
  "agent_id": "subnet-agent",
  "run_id": "quickstart-1",
  "sources": [
    {"title": "Yuma Consensus | Bittensor docs",
     "url": "https://docs.learnbittensor.org/learn/yuma-consensus",
     "snippet": "Yuma Consensus is the algorithm that turns the weights that validators set into emissions for miners and validators on each subnet."},
    {"title": "opentensor/subtensor",
     "url": "https://github.com/opentensor/subtensor",
     "snippet": "Subtensor implements Yuma Consensus, which computes miner and validator emissions on each subnet from the weights validators set."}
  ]
}'

Response (trimmed):

{
  "allow_answer": true,
  "audit_id": "28c80253-596b-4692-...",
  "overall_confidence": 0.7433,
  "policy": {"profile": "support", "action": "allow", "reasons": ["All policy checks passed."],
             "metrics": {"source_count": 2, "top_authority": 0.92, "scorer": "qf-score-v2"}},
  "evidence": [
    {"title": "Yuma Consensus | Bittensor docs", "confidence": 0.885,  "authority": 0.92, "source_type": "web"},
    {"title": "opentensor/subtensor",            "confidence": 0.8035, "authority": 0.92, "source_type": "web"}
  ]
}

3 · READ THE AUDIT RECORD

curl -s "$QF_URL/audit/AUDIT_ID/replay" -H "X-API-Key: $QF_KEY"

The replay shows the question, every source the agent sent with its score breakdown (scoring: relevance, authority and the rule that set it, agreement, and for agent sources their citations and trust weight), the exact policy definition used, the outcome, and:

Find decisions without an id: GET /audit?run_id=quickstart-1, or filter by agent_id, allow_answer, policy_action, time range or text. Reviewers can do the same in the browser in the auditor workspace with a read-only key.

4 · VERIFY IT YOURSELF

Don’t take our word for it. Download a signed evidence pack and check it offline against public keys you saved earlier:

curl -s "$QF_URL/audit/evidence-pack?run_id=quickstart-1" -H "X-API-Key: $QF_KEY" -o pack.zip
curl -s "$QF_URL/audit/keys" -o keys.json      # pin once, store out of band
pip install "qf-verify[tsa]"
qf-verify pack.zip --trusted-keys-file keys.json
# VERIFIED: 1 record(s) checked, 0 failure(s)

Change one byte of a record in the pack and qf-verify fails. Try it on the live demo without a key.

IN YOUR AGENT LOOP

import os, requests

def gate(question, sources, run_id):
    r = requests.post(
        os.environ["QF_URL"] + "/policy/evaluate",
        headers={"X-API-Key": os.environ["QF_KEY"]},
        json={"query": question, "policy": "support", "agent_id": "subnet-agent",
              "run_id": run_id, "sources": sources},
        timeout=30,
    )
    r.raise_for_status()
    return r.json()

d = gate(question, sources, run_id)
if d["allow_answer"]:
    answer(question)
else:
    escalate(d["audit_id"], d["policy"]["reasons"])

Every call is recorded by default; send "audit": false to skip recording. Email, phone, card and SSN-shaped values are redacted before anything is written, but don’t send personal data you don’t need. The ledger is tamper-evident, not tamper-proof, and this is engineering evidence, not a compliance certification.

Full API docs · OpenAPI explorer · How it works · Contact