Skip to content

Web2 API Reference

Last updated: 2026-06-28

Cortensor supports HTTP integration through two paths: the hosted Portal API Gateway and direct router nodes. Use the hosted gateway when you want customer API keys, managed router pools, usage records, and model aliases. Use direct router APIs when you operate a router or have been issued a router endpoint for a specific deployment.

Hosted Gateway vs Direct Router

flowchart LR
  App["Application"] --> Choice{"Integration path"}
  Choice -->|"hosted"| Gateway["Portal API Gateway<br/>/v1/completions"]
  Choice -->|"direct"| Router["Router Node<br/>/api/v1..v3/*"]
  Gateway --> Keys["API key check"]
  Gateway --> Model["Model alias"]
  Model --> Pool["Managed router pool"]
  Router --> Sessions["Cortensor sessions"]
  Pool --> Sessions
  Gateway --> Usage["Usage and billing records"]
Path Base URL Primary route Auth
Hosted gateway https://api.cortensor.app POST /v1/completions Customer API key issued by Portal.
Direct router Router or reverse-proxy URL /api/v1/*, /api/v2/*, /api/v3/* Router bearer key, trial policy, or x402 where enabled.

Hosted Completion

curl -X POST "$CORTENSOR_GATEWAY_URL/v1/completions" \
  -H "Authorization: Bearer $CORTENSOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "default",
    "prompt": "Explain decentralized AI inference in one paragraph.",
    "max_tokens": 160,
    "temperature": 0.7,
    "top_p": 1,
    "stream": false
  }'

The hosted gateway accepts a completion request, validates the customer API key, resolves the model alias to a router pool and session, forwards the request to /api/v3/completions, and returns a gateway envelope.

{
  "request_id": "req_01HX9CORTENSOR",
  "status": "ok",
  "model": "default",
  "router_pool": "default",
  "data": {},
  "error": null
}

Error responses use the same envelope shape with status: "failed" and error.code, error.message, and optional error.details.

Direct Router Route Families

Family Routes
Liveness and metadata GET /api/v1/ping, GET /api/v1/about, GET /api/v1/info, GET /api/v1/status
Miner visibility GET /api/v1/miners
Completions POST /api/v1/completions, POST /api/v2/completions, POST /api/v3/completions, each with optional /{session_id}
Delegate POST /api/v1/delegate, POST /api/v2/delegate, POST /api/v3/delegate
Validate POST /api/v1/validate, POST /api/v2/validate, POST /api/v3/validate
Factcheck POST /api/v1/factcheck and POST /api/v1/fact-check where aliases are enabled
Trial routes POST /api/v1/trial/completions, v1/v2 delegate and validate trial routes, and v1 factcheck trial routes where enabled
x402 routes POST /api/v1/x402/completions, v1/v2 delegate and validate x402 routes, and v1 factcheck x402 routes where enabled
A2A discovery GET /.well-known/agent.json, GET /api/v1/a2a/agent.json, GET /api/v1/a2a/discovery
Privacy and off-chain Payload encryption-key routes and POST /api/v3/offchain/result where enabled

Direct Router Health

curl -i "$ROUTER_URL/api/v1/ping"
curl -i "$ROUTER_URL/api/v1/about"
curl -i "$ROUTER_URL/api/v1/info" -H "Authorization: Bearer $ROUTER_API_KEY"
curl -i "$ROUTER_URL/api/v1/status" -H "Authorization: Bearer $ROUTER_API_KEY"
curl -i "$ROUTER_URL/api/v1/miners" -H "Authorization: Bearer $ROUTER_API_KEY"

ping and about are designed for liveness and discovery. info, status, miners, and work-submission routes require the router bearer key unless a deployment deliberately exposes a separate trial or payment-gated path.

Direct Completion

Use v3 for the current off-chain completion path. Provide session_id in the URL or request body unless the router has a configured default.

curl -X POST "$ROUTER_URL/api/v3/completions/$SESSION_ID" \
  -H "Authorization: Bearer $ROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "What is Cortensor?",
    "max_tokens": 160,
    "temperature": 0.7,
    "timeout": 180,
    "precommit_timeout": 120,
    "stream": false
  }'

v1 sends the prompt directly through the router. v2 stores the prompt off-chain and submits a URN. v3 stores the prompt with the current v3 off-chain format and disables streaming when encrypted payload handling is active.

Delegate v2

Delegate v2 is the structured delegation route. It requires a session and accepts either task_request_input or the newer objective plus input shape.

curl -X POST "$ROUTER_URL/api/v2/delegate" \
  -H "Authorization: Bearer $ROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": 68,
    "objective": "Summarize the technical purpose of Cortensor routers.",
    "input": {
      "kind": "text",
      "payload": "Routers accept API requests, resolve sessions, and submit tasks to the network."
    },
    "policy": {
      "tier": "balanced",
      "redundancy": 1,
      "timeout": 300,
      "precommit_timeout": 240
    },
    "model_policy": {
      "max_tokens": 180,
      "temperature": 0.4
    }
  }'

Use fetch_web: true or input.kind: "url" only when the router is configured for web fetch support.

Delegate v3

Delegate v3 selects a predefined v2 session pool by replica tier. The router currently accepts replicas directly or consensus.replicas; valid values are 1, 3, and 5.

curl -X POST "$ROUTER_URL/api/v3/delegate" \
  -H "Authorization: Bearer $ROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "delegate-demo-1",
    "objective": "Write a short technical summary of decentralized inference.",
    "input": {"kind": "text", "payload": "Cortensor routes inference work across miner nodes."},
    "consensus": {"replicas": 3},
    "policy": {"tier": "balanced"}
  }'

If the requested replica tier has no configured router session mapping, the route returns missing_v3_session_pool.

Validate v2

Validate v2 checks a claim or candidate output under an explicit policy.

curl -X POST "$ROUTER_URL/api/v2/validate" \
  -H "Authorization: Bearer $ROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": 68,
    "claim": {
      "type": "technical_summary",
      "description": "Validate whether the output describes router behavior accurately.",
      "output": "Routers coordinate API requests, sessions, and task submission."
    },
    "policy": {
      "tier": "safe",
      "redundancy": 3,
      "rules": ["accuracy", "clarity", "no unsupported claims"],
      "timeout_ms": 180000,
      "precommit_timeout_ms": 120000
    }
  }'

The response includes verdict, confidence, reasons, advice, evidence, and per-run data when redundancy is greater than one.

Validate v3

Validate v3 runs validate v2 through a predefined session mapping and aggregates the verdict.

curl -X POST "$ROUTER_URL/api/v3/validate" \
  -H "Authorization: Bearer $ROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "validate-demo-1",
    "claim": {
      "type": "api_result",
      "description": "Check whether the result follows the requested policy.",
      "output": "Candidate output to validate."
    },
    "consensus": {"replicas": 3},
    "policy": {"tier": "safe"}
  }'

Valid verdicts include VALID, INVALID, RETRY, and NEEDS_SPEC.

Factcheck

Factcheck verifies claims with standard or realtime evidence modes. Provide a session directly, or configure the router with FACTCHECK_<MODE>_SESSION_ID or FACTCHECK_SESSION_ID.

curl -X POST "$ROUTER_URL/api/v1/factcheck" \
  -H "Authorization: Bearer $ROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": 68,
    "mode": "standard",
    "claim": {
      "type": "network_roles",
      "statement": "Cortensor supports router, miner, oracle, and validator roles."
    },
    "policy": {
      "tier": "safe",
      "redundancy": 3,
      "task_redundancy": 1,
      "timeout_ms": 120000,
      "precommit_timeout": 90
    }
  }'

Use mode: "realtime" only when realtime evidence support and provider keys are configured on the router.

Trial And x402

Trial routes are intended for limited evaluation and depend on router quota settings. x402 routes return 402 Payment Required until the request includes a valid payment proof.

Route family Trial x402
Completion /api/v1/trial/completions[/<session_id>] /api/v1/x402/completions[/<session_id>]
Delegate /api/v1/trial/delegate, /api/v2/trial/delegate /api/v1/x402/delegate, /api/v2/x402/delegate
Validate /api/v1/trial/validate, /api/v2/trial/validate /api/v1/x402/validate, /api/v2/x402/validate
Factcheck /api/v1/trial/factcheck /api/v1/x402/factcheck

Privacy And Off-Chain Payloads

Off-chain payload routes use URNs instead of placing full prompt or result bytes directly into the contract flow.

urn:blob:v1:s3:akamai:{bucket}:{file_name}
urn:blob:v2:s3:akamai:{bucket}:{file_name}
urn:blob:v3:s3:akamai:{backend_index}:{bucket}:{file_name}

Payload encryption keys are issued through signed requests:

curl -X POST "$ROUTER_URL/api/v1/auth/payload_enc_key/session" \
  -H "Content-Type: application/json" \
  -d @- <<JSON
{
    "address": "$WALLET_ADDRESS",
    "session_id": 68,
    "signature": "$PAYLOAD_KEY_SIGNATURE"
}
JSON

For task-level keys, sign the message sessionId:taskId and call /api/v1/auth/payload_enc_key/task.

Timeouts And Streaming

Decentralized inference can take longer than a single hosted model call. Client integrations set both timeout and precommit_timeout, keep timeout greater than precommit_timeout, and treat retries carefully so duplicate paid work is not submitted.

Streaming is supported by some v1 flows, but v2/v3 private or encrypted flows can force stream: false.

Error Handling

Error class Likely cause
Unauthorized Missing or invalid router bearer key.
Missing session No session ID in the URL/body and no configured default.
Empty v3 pool consensus.replicas requested a v3 pool that the router has not configured.
Timeout Miner, validator, gateway, or reverse-proxy timeout.
Payment required x402 route needs a valid payment proof.
Private payload denied The signing address is not authorized for the session or task scope.