Agentic API

File a question, poll for a verdict, answer clarifications, read the outcome — the full machine loop for autonomous agents and headless callers.

VectorCourt is a bounded adversarial council: independent models argue a decision under pressure and a compressor collapses the result into a single structured verdict. This page documents the HTTP API an agent calls directly. There is no SDK to install — it is plain HTTP with a JSON body and one header.

The loop in one breath: POST /v1/submit a question → poll GET /v1/submissions/{id} until status: completed → read decision.outcome.kind to decide what to do. If the council needs input first, it asks; you answer with POST /v1/cases/{id}/clarify and keep polling.

Authentication

Send your key in the X-VC-Key header. Keys are issued per account (Pro and above). Submitting and answering clarifications require a key; polling a submission does not — the submission UUID is itself an unguessable capability, so an agent can hand the poll URL to another worker without sharing the key.

X-VC-Key: vc_your_key_here

If you exceed your plan's daily budget you get 429 with {"error":"daily_spend_limit","resets_at":"..."} — back off until resets_at or upgrade. See pricing.

1 — File a question

POST /v1/submit

Request body

FieldTypeNotes
questionstringrequiredThe decision to adjudicate. State the options and constraints; vague questions get vague verdicts.
extended_deliberationbooloptionalOpt into a larger reasoning budget (Pro/Enterprise). Slower, deeper.
callback_urlstringoptionalHTTPS URL notified on clarification_pending and finalized (see Webhooks). Requires a key.
initial_leaningstringoptionalYour expected answer; the verdict reports how it diverged.
include_patent_searchbooloptionalSearch the patent / prior-art corpus for evidence. Runs automatically when the question is about patents, IP, prior art, freedom-to-operate, novelty, or infringement; set this to force it on for other questions. Premium — may add cost and latency.

Optionally send an Idempotency-Key header (≤200 bytes) so a retried submit returns the same submission instead of filing twice.

Response — 202 Accepted

{
  "submission_id": "3fc1c266-…",
  "case_id":       "9545b6b9-…",
  "status":        "queued",
  "poll_url":      "/v1/submissions/3fc1c266-…",
  "verdict_url":   "/v/9545b6b9-…",
  "created_at":    "2026-06-16T12:34:56Z"
}

curl

curl -sS -X POST https://vectorcourt.com/v1/submit \
  -H "Content-Type: application/json" \
  -H "X-VC-Key: $VC_KEY" \
  -d '{"question":"Should a 15-person startup build its own auth or use Auth0/Clerk? Argue both sides.","extended_deliberation":true}'

2 — Poll for the verdict

GET /v1/submissions/{id}

Poll every few seconds. A verdict takes minutes — the council is really deliberating, not template-filling. Status moves through:

statusmeaning
queuedaccepted, waiting for a worker
processingthe council is deliberating
completedverdict is ready in result.body
failedterminal error; error explains

When completed, the verdict lives at result.body. The two fields an agent acts on:

{
  "status": "completed",
  "result": {
    "body": {
      "verdict_status": "full",
      "one_liner": "Use Auth0 now; revisit only if SSO/compliance forces a build.",
      "decision": {
        "outcome": {
          "kind": "answer",
          "conditions": [],
          "escalation": null,
          "source": "proposed"
        }
      },
      "cost": 0.79,
      "duration_seconds": 327.9
    }
  }
}

3 — The outcome contract (read this)

Every finalized verdict carries a sealed tri-state outcome at decision.outcome.kind. This is the single field an agent branches on — it tells you whether you may act, act with caveats, or must wake a human.

answer
Act on the verdict. No conditions, no escalation.
answer_with_conditions
Act, but under named assumptions in outcome.conditions[] (each an assumption plus optional metric/threshold/window). Re-escalate if a condition breaks.
escalate_to_human
Do not act autonomously. outcome.escalation.trigger is one of authority_boundary, irreversibility, insufficient_evidence, scope_violation; detail explains why.

The contract is guaranteed consistent: answer never carries conditions, answer_with_conditions always carries at least one, and escalate_to_human always carries an escalation reason. Branch on kind and you never have to parse prose.

3a — The North Star: are you asking the right question?

The outcome above answers what you asked. But a verdict can also tell you the question itself was the wrong one — and correctly answering the wrong question is the catastrophe. A single-model assistant answers inside the frame you hand it. The council, when the deliberation produces a strong counter-signal, answers and names the direction worth choosing next, with proof. In the verdict markdown this appears as a prominent ## North Star — block right after the decision; it fires on a wrong-target disambiguation, an inverted minority (a dissenter who outscored the winner), a surviving challenge to the question's premise, or a high-severity risk in a domain you never asked about. Most clean verdicts show none — its presence is the signal.

The machine-readable form is next_action in the agent view (GET /v1/submissions/{id}?view=agent), the server's conclusion folding quorum, quality, and run-time system pressure into one recommendation:

next_actionWhat it meansWhat to do
proceedQuality gate passed; verdict binding.Use it.
proceed_with_conditionsHolds under stated conditions.Use it, honor the conditions.
escalate_to_humanThe court escalated.Surface to a person.
rerun_degradedLow quality because a seat dropped — an infrastructure failure, not the question's fault.Re-file the same question.
resendLow quality under full quorum but high system pressure — plausibly transient.Wait, then re-file the same question.
reframe_questionLow quality under a full, unstressed court — an epistemic failure. The question is mis-posed; resending reproduces it.Do not resend as-is. Reframe, or step back and ask what decision this actually serves.

The load-bearing distinction is epistemic vs infrastructure failure: same symptom (low quality), opposite cause, opposite fix. The worst case is reframe_question with no directional counter-signal — a healthy, unstressed court (full quorum, low pressure) that produced low quality and could not even point at a better target. The verdict body still carries a North Star block here, but instead of naming a better direction it says step back before you re-ask: you are in the wrong place — reframe, do not retry. (So the North Star section is present, not absent; what is missing is a better target, not the block itself.)

4 — Answer a clarification

The council often needs a missing constraint before it can rule. When it does, the verdict's escalation.questions[] are populated (and a callback_url, if set, fires a clarification_pending event). The agent — not a human — is usually the right one to answer: it can ground the answer in the system the question is about.

POST /v1/cases/{case_id}/clarify (requires X-VC-Key; only the filing key or an admin may answer)

{
  "answers": [
    { "question_id": "esc-q-1a2b…", "answer": "~50K QPS, multi-region, p99 budget 40ms", "confidence": "firm" }
  ]
}

Answer all pending questions in one call. confidence is firm, preferred, or uncertain. The case returns to deliberating and re-runs; keep polling the submission (or the case wait_url) until it finalizes. Answers are PII-scrubbed before they reach the council.

5 — Webhooks (optional)

Pass callback_url on submit to be pushed to instead of polling. VectorCourt POSTs a JSON body on clarification_pending and finalized:

{
  "event": "finalized",
  "case_id": "9545b6b9-…",
  "status": "finalized",
  "verdict_url": "/v/9545b6b9-…",
  "verdict_status": "full",
  "outcome": { "kind": "answer", "conditions": [], "source": "proposed" },
  "sent_at": "2026-06-16T12:45:30Z"
}

Each callback is signed. Verify it before trusting it:

headervalue
X-VectorCourt-Callback-Signaturev1=<hex> — HMAC-SHA256 over timestamp + "." + body, keyed by your API key
X-VectorCourt-Callback-TimestampRFC3339 send time
X-VectorCourt-Callback-Eventclarification_pending | finalized

Callback URLs must be HTTPS and public (private/loopback IPs are rejected at dial time to prevent SSRF). Delivery retries on transient failure; respond 2xx to acknowledge.

A minimal agent loop

sid=$(curl -sS -X POST https://vectorcourt.com/v1/submit \
        -H "X-VC-Key: $VC_KEY" -H "Content-Type: application/json" \
        -d '{"question":"...","extended_deliberation":true}' | jq -r .submission_id)

while :; do
  body=$(curl -sS https://vectorcourt.com/v1/submissions/$sid)
  case "$(echo "$body" | jq -r .status)" in
    completed) echo "$body" | jq '.result.body.decision.outcome'; break ;;
    failed)    echo "$body" | jq -r .error; break ;;
    *)         sleep 5 ;;
  esac
done

Once you have outcome.kind: answer → proceed; answer_with_conditions → proceed and watch the conditions; escalate_to_human → hand off. That is the whole contract.