{"openapi":"3.1.0","info":{"title":"Headless Oracle","version":"5.0.0","description":"Cryptographically signed market-state receipts for AI agents and automated trading systems. All signed receipts use Ed25519. Consumers MUST treat UNKNOWN status as CLOSED and halt execution. Receipts expire at expires_at — do not act on stale receipts.","contact":{"name":"Headless Oracle","email":"api@headlessoracle.com","url":"https://headlessoracle.com"},"license":{"name":"MIT","url":"https://github.com/LembaGang/headless-oracle-v5/blob/main/LICENSE"},"x-model-agnostic":true,"x-regulatory-alignment":["CFTC_SL_25_39","SEC_project_blueprint_tokenized_collateral","ISO_10383"],"x-regulatory-references":[{"body":"CFTC","id":"Staff Letter 25-39","title":"Tokenized Collateral Guidance","date":"2025-12-08","url":"https://www.cftc.gov/csl/25-39/download"},{"body":"SEC Crypto Task Force","id":"Project Blueprint","title":"Tokenized Collateral","date":"2025-11-27","url":"https://www.sec.gov/files/project-blueprint-tokenized-collateral-112725.pdf"}]},"externalDocs":{"description":"Full documentation for LLMs and agents","url":"https://headlessoracle.com/llms-full.txt"},"servers":[{"url":"https://headlessoracle.com","description":"Production"},{"url":"https://api.headlessoracle.com","description":"API alias (same worker)"}],"tags":[{"name":"Market State","description":"Signed market-state receipts and schedule data"},{"name":"Key Management","description":"API key provisioning and account management"},{"name":"Verification","description":"Receipt signature verification"},{"name":"Audit","description":"Attestation digests, Merkle chains, and receipt logs"},{"name":"Discovery","description":"Health, exchanges, public keys, and machine-readable metadata"},{"name":"Operations","description":"Metrics, analytics, and SLO tracking"},{"name":"MCP","description":"Model Context Protocol (JSON-RPC 2.0)"},{"name":"Payment","description":"x402 micropayments, Paddle billing, credit packs"},{"name":"Webhooks","description":"State-change webhook subscriptions"},{"name":"OAuth","description":"OAuth 2.0 token endpoints (RFC 6749/7662)"},{"name":"Documentation","description":"Agent guides, specs, and blog content"}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-Oracle-Key"},"BearerAuth":{"type":"http","scheme":"bearer","description":"OAuth 2.0 Bearer token from POST /oauth/token"}},"schemas":{"Status":{"type":"string","enum":["OPEN","CLOSED","HALTED","UNKNOWN"],"description":"UNKNOWN MUST be treated as CLOSED. Halt all execution."},"Source":{"type":"string","enum":["SCHEDULE","OVERRIDE","SYSTEM","REALTIME"]},"SignedReceipt":{"type":"object","required":["receipt_id","issued_at","expires_at","issuer","mic","status","source","halt_detection","receipt_mode","schema_version","public_key_id","signature"],"properties":{"receipt_id":{"type":"string","format":"uuid"},"issued_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time","description":"Do not act on this receipt after this time."},"issuer":{"type":"string","example":"headlessoracle.com","description":"Domain of the oracle that issued this receipt. Resolve {issuer}/v5/keys to retrieve the public key."},"mic":{"type":"string","example":"XNYS"},"status":{"$ref":"#/components/schemas/Status"},"source":{"$ref":"#/components/schemas/Source"},"reason":{"type":"string","description":"Present when source is OVERRIDE."},"halt_detection":{"type":"string","enum":["active","schedule_only"],"description":"\"active\" = real-time intraday halt detection via external API (XNYS, XNAS only). \"schedule_only\" = calendar hours + holidays only; unscheduled intraday circuit breaker halts are not detected. Agents must adjust confidence accordingly."},"receipt_mode":{"type":"string","enum":["demo","live"],"description":"'demo' for unauthenticated /v5/demo; 'live' for /v5/status, /v5/batch, and MCP tool receipts."},"schema_version":{"type":"string","example":"v5.0","description":"Receipt schema version. Consumers should verify this matches the version they were built against."},"public_key_id":{"type":"string","example":"key_2026_v1"},"signature":{"type":"string","description":"Ed25519 signature of canonical payload as 128-char hex string."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"status":{"type":"string","description":"Present on CRITICAL_FAILURE — always UNKNOWN."},"supported":{"type":"array","items":{"type":"string"},"description":"Present on UNKNOWN_MIC errors."}}}}},"paths":{"/v5/demo":{"get":{"tags":["Market State"],"summary":"Public signed receipt","description":"Returns a signed market-state receipt. No authentication required. Suitable for integration testing and public dashboards. For production use, prefer /v5/status.","parameters":[{"name":"mic","in":"query","schema":{"type":"string","default":"XNYS"},"description":"Market Identifier Code (MIC). See /v5/exchanges for supported values."}],"responses":{"200":{"description":"Signed receipt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedReceipt"}}}},"400":{"description":"Unknown MIC","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/status":{"get":{"tags":["Market State"],"summary":"Authenticated signed receipt","description":"Returns a signed market-state receipt. Requires X-Oracle-Key header OR x402 payment via Payment-Signature/X-Payment header. Primary production endpoint.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"mic","in":"query","schema":{"type":"string","default":"XNYS"},"description":"Market Identifier Code (MIC)."},{"name":"Payment-Signature","in":"header","schema":{"type":"string"},"description":"x402 v2 payment header — base64-encoded JSON PaymentPayload with EIP-712 TransferWithAuthorization signature. Alternative to X-Oracle-Key for keyless per-request payment ($0.001 USDC on Base mainnet)."},{"name":"X-Payment","in":"header","schema":{"type":"string"},"description":"x402 v1 payment header — base64-encoded JSON OR raw JSON { txHash, network, amount, paymentAddress, memo }. Alternative to Payment-Signature."}],"responses":{"200":{"description":"Signed receipt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedReceipt"}}}},"400":{"description":"Unknown MIC","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing API key"},"402":{"description":"Payment required — free tier exhausted or no API key. Body includes x402 payment requirements (accepts[], payTo, amount). Send Payment-Signature or X-Payment header to pay $0.001 USDC per request."},"403":{"description":"Invalid API key"}}}},"/v5/schedule":{"get":{"tags":["Market State"],"summary":"Next open/close times","description":"Schedule-based next session open and close times in UTC. Not signed. Does not reflect real-time halts or KV overrides. For authoritative status use /v5/demo or /v5/status.","parameters":[{"name":"mic","in":"query","schema":{"type":"string","default":"XNYS"}}],"responses":{"200":{"description":"Schedule data","content":{"application/json":{"schema":{"type":"object","properties":{"mic":{"type":"string"},"name":{"type":"string"},"timezone":{"type":"string","description":"IANA timezone name."},"queried_at":{"type":"string","format":"date-time"},"current_status":{"$ref":"#/components/schemas/Status"},"next_open":{"type":"string","format":"date-time","nullable":true},"next_close":{"type":"string","format":"date-time","nullable":true},"lunch_break":{"nullable":true,"description":"Null if no lunch break. start/end are local exchange time (HH:MM). See timezone field.","type":"object","properties":{"start":{"type":"string","example":"11:30"},"end":{"type":"string","example":"12:30"}}},"note":{"type":"string"}}}}}},"400":{"description":"Unknown MIC"}}}},"/v5/exchanges":{"get":{"tags":["Discovery"],"summary":"Directory of supported exchanges","description":"Returns all exchanges for which Oracle provides signed receipts.","responses":{"200":{"description":"Exchange list","content":{"application/json":{"schema":{"type":"object","properties":{"exchanges":{"type":"array","items":{"type":"object","properties":{"mic":{"type":"string"},"name":{"type":"string"},"timezone":{"type":"string"}}}}}}}}}}}},"/v5/keys":{"get":{"tags":["Discovery"],"summary":"Public key registry","description":"Returns active signing public keys and the canonical payload specification required for independent receipt verification. Each key includes valid_from and valid_until (null if no scheduled rotation) for lifecycle tracking.","responses":{"200":{"description":"Key registry with canonical signing spec","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v5/health":{"get":{"tags":["Discovery"],"summary":"Signed liveness probe","description":"Returns a signed receipt confirming the Oracle signing infrastructure is alive. Use this to distinguish Oracle-is-down from market-is-UNKNOWN. A 200 with valid signature means signing works. A 500 means signing is offline.","responses":{"200":{"description":"Signed health receipt","content":{"application/json":{"schema":{"type":"object","required":["receipt_id","issued_at","expires_at","status","source","public_key_id","signature","exchange_count","supported_mics"],"properties":{"receipt_id":{"type":"string","format":"uuid"},"issued_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["OK"]},"source":{"type":"string","enum":["SYSTEM"]},"public_key_id":{"type":"string"},"signature":{"type":"string"},"exchange_count":{"type":"integer","example":28,"description":"Number of exchanges currently configured (unsigned)."},"supported_mics":{"type":"array","items":{"type":"string"},"example":["XNYS","XNAS","XLON","XJPX","XPAR","XHKG","XSES","XASX","XBOM","XNSE","XSHG","XSHE","XKRX","XJSE","XBSP","XSWX","XMIL","XIST","XSAU","XDFM","XNZE","XHEL","XSTO","XCBT","XNYM","XCBO","XCOI","XBIN"],"description":"List of supported MIC codes (unsigned)."}}}}}},"500":{"description":"Signing system offline — CRITICAL_FAILURE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/openapi.json":{"get":{"tags":["Discovery"],"summary":"OpenAPI 3.1 specification","responses":{"200":{"description":"This document"}}}},"/mics.json":{"get":{"summary":"Exchange registry — full ISO metadata","description":"Static JSON array of all 28 supported exchanges. Each entry carries: mic (ISO 10383), name, country (ISO 3166-1 alpha-2), timezone (IANA), currency (ISO 4217), and sameAs (ISO 20022 MIC registry URL). No authentication required. Response is a top-level array, not an object wrapper. Cache-Control: public, max-age=86400.","responses":{"200":{"description":"Array of exchange metadata objects","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["mic","name","country","timezone","currency","sameAs"],"properties":{"mic":{"type":"string","example":"XNYS","description":"ISO 10383 Market Identifier Code."},"name":{"type":"string","example":"New York Stock Exchange"},"country":{"type":"string","example":"US","description":"ISO 3166-1 alpha-2 country code."},"timezone":{"type":"string","example":"America/New_York","description":"IANA timezone identifier."},"currency":{"type":"string","example":"USD","description":"ISO 4217 currency code."},"sameAs":{"type":"string","format":"uri","example":"https://www.iso20022.org/market-identifier-codes","description":"ISO 20022 MIC registry URL."}}}}}}}}}},"/v5/batch":{"get":{"tags":["Market State"],"summary":"Authenticated batch receipt query","description":"Returns independently signed receipts for multiple exchanges in one request. Each receipt goes through the same 4-tier fail-closed architecture as /v5/status. Receipts are built in parallel. Requires X-Oracle-Key header or x402 payment ($0.005 USDC for batch).","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"mics","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated MIC codes. Duplicates are deduplicated. Example: XNYS,XNAS,XLON."},{"name":"Payment-Signature","in":"header","schema":{"type":"string"},"description":"x402 v2 payment header — base64-encoded JSON PaymentPayload ($0.005 USDC on Base mainnet for batch)."},{"name":"X-Payment","in":"header","schema":{"type":"string"},"description":"x402 v1 payment header — base64-encoded JSON or raw JSON."}],"responses":{"200":{"description":"Batch of signed receipts","content":{"application/json":{"schema":{"type":"object","required":["batch_id","queried_at","receipts"],"properties":{"batch_id":{"type":"string","format":"uuid"},"queried_at":{"type":"string","format":"date-time"},"receipts":{"type":"array","items":{"$ref":"#/components/schemas/SignedReceipt"}}}}}}},"400":{"description":"Missing mics parameter or unknown MIC","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing API key"},"403":{"description":"Invalid API key"},"500":{"description":"Signing system offline — CRITICAL_FAILURE"}}}},"/.well-known/oracle-keys.json":{"get":{"summary":"RFC 8615 key discovery","description":"Standard well-known URI for Ed25519 public key discovery (RFC 8615). Returns active signing key(s) with lifecycle metadata. The hex `public_key` field is the source of truth for deployed SDKs (@headlessoracle/verify, headless-oracle). `jwks_uri` points at the RFC 7517 JWKS form for JOSE-aware verifiers. No authentication required. Use /v5/keys for the full canonical payload specification.","responses":{"200":{"description":"Active signing key(s)","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/.well-known/jwks.json":{"get":{"summary":"RFC 7517 JWKSet (discovery-only)","description":"JSON Web Key Set (RFC 7517) form of the active Ed25519 signing key for JOSE-aware verifiers. Single-key set; each key carries an RFC 7638 thumbprint as `kid`. Discovery-only in this release — receipts do not yet carry `kid`, so deployed SDKs continue to verify against /.well-known/oracle-keys.json (hex `public_key`). kid-aware receipt verification is planned for a future major release. Content-Type: application/jwk-set+json. Cache-Control: public, max-age=300.","responses":{"200":{"description":"JWKSet with the active signing key","content":{"application/jwk-set+json":{"schema":{"type":"object"}}}},"500":{"description":"Public key not configured — CONFIGURATION_ERROR"}}}},"/mcp":{"post":{"tags":["MCP"],"summary":"MCP (Model Context Protocol) endpoint","description":"JSON-RPC 2.0 / MCP Streamable HTTP (protocol version 2024-11-05). Tools: get_market_status, get_market_schedule, list_exchanges. No authentication required.","responses":{"200":{"description":"JSON-RPC 2.0 response"},"202":{"description":"Notification accepted (no body)"},"405":{"description":"GET not allowed — use POST"}}}},"/v5/checkout":{"post":{"tags":["Payment"],"summary":"Create Paddle Checkout Transaction","description":"Creates a Paddle transaction for the Pro plan and returns the hosted payment URL. No authentication required. Redirect the user to the returned url.","responses":{"200":{"description":"Checkout transaction created","content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"405":{"description":"Method not allowed — use POST","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Paddle API error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Billing not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/paddle":{"post":{"tags":["Payment"],"summary":"Paddle webhook receiver","description":"Receives and processes Paddle events. Requires a valid Paddle-Signature header. Handles: transaction.completed (key generation + email), subscription.updated, subscription.past_due, subscription.canceled.","responses":{"200":{"description":"Event received and processed"},"400":{"description":"Missing Paddle-Signature header"},"401":{"description":"Invalid signature"}}}},"/v5/account":{"get":{"tags":["Key Management"],"summary":"Account info for the calling API key","description":"Returns plan, status, and key_prefix for the authenticated key. Use to verify subscription status.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Account info","content":{"application/json":{"schema":{"type":"object","required":["plan","status","key_prefix"],"properties":{"plan":{"type":"string","example":"pro"},"status":{"type":"string","enum":["active","suspended","cancelled"]},"key_prefix":{"type":"string","nullable":true,"example":"ok_live_a1b2c3"}}}}}},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required — subscription suspended or cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Account not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/robots.txt":{"get":{"summary":"robots.txt","description":"Standard robots exclusion file. Explicitly permits AI crawlers to all public documentation endpoints.","responses":{"200":{"description":"robots.txt content","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/llms.txt":{"get":{"summary":"llms.txt — spec-compliant index for LLM crawlers","description":"Concise index following llmstxt.org convention. Links to /llms-full.txt for complete documentation. Returned as text/markdown.","responses":{"200":{"description":"llms.txt index","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/llms-full.txt":{"get":{"summary":"llms-full.txt — complete API documentation for LLMs","description":"Full documentation in one file: all endpoints, receipt schema, exchange hours, MCP config, code examples, x402 payment flow, compliance mapping. Linked from /llms.txt.","responses":{"200":{"description":"Complete documentation","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/SKILL.md":{"get":{"summary":"Agent integration guide (Markdown)","description":"Step-by-step integration guide optimised for AI agents. Covers MCP setup, HTTP patterns, code examples, safety rules, verification SDK usage, and common mistakes. Returns Last-Modified and ETag headers for cache invalidation.","responses":{"200":{"description":"Markdown integration guide","content":{"text/markdown":{"schema":{"type":"string"}}},"headers":{"ETag":{"schema":{"type":"string"},"description":"FNV-1a hash of content, quoted (RFC 7232)."},"Last-Modified":{"schema":{"type":"string"},"description":"RFC 7231 HTTP-date of last content change."}}}}}},"/v5/metrics":{"get":{"summary":"Public usage stats","description":"Returns today's MCP request totals and unique client count from ORACLE_TELEMETRY KV. No authentication required. Metrics are best-effort — KV unavailability returns zeros rather than 500.","responses":{"200":{"description":"Usage statistics","content":{"application/json":{"schema":{"type":"object","required":["total_mcp_requests_today","unique_mcp_clients_today","exchanges_covered","edge_cases_per_year","uptime_status"],"properties":{"total_mcp_requests_today":{"type":"integer","description":"Sum of all MCP request_count values for today."},"unique_mcp_clients_today":{"type":"integer","description":"Distinct MCP client IPs seen today (hashed)."},"exchanges_covered":{"type":"integer","example":28},"edge_cases_per_year":{"type":"integer","example":1319},"uptime_status":{"type":"string","enum":["operational"]}}}}}}}}},"/v5/metrics/public":{"get":{"summary":"Social-proof metrics","description":"Public, no auth. Stable facts about the service suitable for embedding in READMEs, dashboards, or evaluations. x402 payment stats are best-effort from ORACLE_TELEMETRY KV.","responses":{"200":{"description":"Service metrics","content":{"application/json":{"schema":{"type":"object","required":["exchanges","mcp_tools","uptime_days","tests_passing","signing_algorithm","receipt_ttl_seconds","mcp_protocol_version","mcpscoreboard_preflight","fail_closed"],"properties":{"exchanges":{"type":"integer","example":28},"mcp_tools":{"type":"integer","example":5},"uptime_days":{"type":"integer","description":"Days since 2026-02-28 origin date."},"tests_passing":{"type":"integer","example":650},"signing_algorithm":{"type":"string","example":"Ed25519"},"receipt_ttl_seconds":{"type":"integer","example":60},"x402_enabled":{"type":"boolean"},"x402_network":{"type":"string","example":"base"},"x402_payment_count":{"type":"integer","description":"Total x402 payments processed."},"last_payment_at":{"type":["string","null"],"format":"date-time"},"mcp_protocol_version":{"type":"string","example":"2024-11-05"},"mcpscoreboard_preflight":{"type":"integer","example":100,"description":"MCPScoreboard preflight score out of 100."},"fail_closed":{"type":"boolean","example":true}}}}}}}}},"/v5/keys/instant":{"post":{"summary":"Get a free API key instantly — zero friction","description":"Returns a free-tier API key immediately. No email, no signup. One key per agent_id (idempotent). Rate-limited to 10 keys per IP per day. Designed for autonomous agents to self-provision.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_id"],"properties":{"agent_id":{"type":"string","description":"Unique identifier for the agent (any string, max 256 chars)","example":"my-trading-agent-v1"}}}}}},"responses":{"200":{"description":"API key issued or existing key returned","content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string","example":"ho_free_a1b2c3..."},"daily_limit":{"type":"integer","example":500},"plan":{"type":"string","example":"free"},"usage":{"type":"string"},"example":{"type":"string"},"upgrade_url":{"type":"string"}}}}}},"400":{"description":"Invalid or missing agent_id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited — max 10 instant keys per day per IP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/keys/request":{"post":{"summary":"Provision a free-tier API key via email","description":"Generates a ho_free_ prefixed API key and emails it to the provided address. Rate-limited to 3 requests per IP per 24 hours. No authentication required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Key sent to email","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","example":"free"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid or missing email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Method not allowed — use POST","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited — max 3 free keys per day per IP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/funnel":{"get":{"summary":"Conversion funnel snapshot","description":"Returns today's conversion funnel: 402 counts, upgrade path usage, conversion rate. Requires MASTER_API_KEY.","parameters":[{"name":"date","in":"query","schema":{"type":"string","format":"date"},"description":"Date to query (YYYY-MM-DD, defaults to today)"}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Funnel data","content":{"application/json":{"schema":{"type":"object","properties":{"date":{"type":"string"},"top_of_funnel":{"type":"integer"},"conversion_rate":{"type":"string"}}}}}},"401":{"description":"Admin access required"}}}},"/v5/compliance":{"get":{"summary":"Compliance declaration (environment.market_state family)","description":"Machine-readable compliance self-report. Documents the 6 pre-trade safety checks (APTS v1.0 check vocabulary, preserved for citation continuity) that Headless Oracle satisfies as the proposed reference implementation of environment.market_state (open PR on the Verifiable Intent repo). No authentication required. Suitable for CI pipelines and MCP evaluation tools.","responses":{"200":{"description":"Compliance document","content":{"application/json":{"schema":{"type":"object","properties":{"standard":{"type":"string","example":"environment.market_state (Verifiable Intent environment.* constraint family); APTS v1.0 check vocabulary preserved for citation continuity"},"oracle":{"type":"string"},"version":{"type":"string"},"last_verified":{"type":"string","format":"date-time"},"checks":{"type":"array","items":{"type":"object","properties":{"check":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["pass","fail"]},"evidence":{"type":"string"}}}}}}}}}}}},"/v5/stack":{"get":{"summary":"Deprecated — alias for /v5/pre-trade-stack","description":"Deprecated. Returns the Composable Pre-Trade Verification Pattern v2.0 payload (same as /v5/pre-trade-stack) wrapped in a deprecation envelope. New integrations SHOULD use /v5/pre-trade-stack directly. This endpoint will continue to respond during the deprecation window but may be removed in a future major version.","tags":["Discovery"],"deprecated":true,"x-successor":"/v5/pre-trade-stack","responses":{"200":{"description":"Deprecation envelope + Pattern v2.0 payload. See /v5/pre-trade-stack for the canonical schema.","content":{"application/json":{"schema":{"type":"object","properties":{"_deprecated":{"type":"object","properties":{"note":{"type":"string"},"replacement":{"type":"string","format":"uri"},"replacement_path":{"type":"string"}}}},"additionalProperties":true}}}}}}},"/v5/usage":{"get":{"summary":"Per-key usage statistics","description":"Returns today/month request counts, free tier limits, credit balance, and upgrade info for the authenticated key. Requires X-Oracle-Key header. Paid keys return null limits and 0 usage counts.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Usage statistics for the calling key","content":{"application/json":{"schema":{"type":"object","properties":{"key_prefix":{"type":"string"},"plan":{"type":"string"},"requests_today":{"type":"integer"},"requests_this_month":{"type":"integer"},"daily_limit":{"type":["integer","null"]},"monthly_limit":{"type":["integer","null"]},"percent_used_today":{"type":"number"},"percent_used_month":{"type":"number"},"rate_limit_resets_at":{"type":"string","format":"date-time"},"upgrade_url":{"type":"string","format":"uri"},"x402_available":{"type":"boolean"},"x402_amount":{"type":"string"},"credit_balance":{"type":"integer"}}}}}},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/dst-risk":{"get":{"summary":"DST transition risk","description":"Returns a structured breakdown of DST transition risk for European exchanges. No authentication required. Includes affected exchanges, error windows for naive agents using hardcoded UTC offsets, and a live verified schedule for XLON. Note: SMA in this response denotes Signed Market Attestation, not Simple Moving Average.","responses":{"200":{"description":"DST risk data","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"string","example":"EU_DST_SPRING_2026"},"transition_utc":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"description":{"type":"string"},"affected_exchanges":{"type":"array","items":{"type":"object","properties":{"mic":{"type":"string"},"name":{"type":"string"},"timezone":{"type":"string"},"shift":{"type":"string"},"naive_agent_open_utc":{"type":"string"},"actual_open_utc_after_dst":{"type":"string"},"error_minutes":{"type":"integer"},"risk":{"type":"string"}}}},"risk_window_minutes":{"type":"integer","example":60},"us_europe_dst_gap_note":{"type":"string"},"verified_schedule":{"type":"object","nullable":true},"sma_protocol_note":{"type":"string"},"note":{"type":"string"}}}}}}}}},"/v5/traction":{"get":{"summary":"Live traction metrics","description":"Public endpoint returning exchanges covered, uptime, today's MCP usage, and stack positioning. No authentication required. Suitable for investor and partner check-ins.","responses":{"200":{"description":"Traction metrics","content":{"application/json":{"schema":{"type":"object","properties":{"exchanges_covered":{"type":"integer","example":28},"edge_cases_per_year":{"type":"integer","example":1319},"uptime_since":{"type":"string","format":"date-time"},"days_live":{"type":"integer"},"mcp_requests_today":{"type":"integer"},"unique_mcp_clients_today":{"type":"integer"},"sma_spec_version":{"type":"string","example":"1.0"},"verifiable_intent_rfc":{"type":"string","example":"submitted"},"x402_enabled":{"type":"boolean"},"halt_monitor":{"type":"string","example":"active"}}}}}}}}},"/v5/implementations":{"get":{"summary":"Standards implementations registry","description":"Returns known implementations of environment.market_state (Verifiable Intent environment.* family) and its predecessor working-spec protocols (SMA, MPAS, APTS — brand-retired, concepts preserved). No authentication required. Submit your own via the submit_url field.","responses":{"200":{"description":"Implementations registry","content":{"application/json":{"schema":{"type":"object","properties":{"standards":{"type":"object"},"total_implementations":{"type":"integer","example":5},"last_updated":{"type":"string","example":"2026-03-31"}}}}}}}}},"/v5/showcase":{"get":{"summary":"Reference projects using Headless Oracle","description":"Returns a curated list of projects using Headless Oracle in production or for research. Submit yours via the submit_url field.","responses":{"200":{"description":"Showcase entries","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object"}},"submit_url":{"type":"string"},"note":{"type":"string"}}}}}}}}},"/v5/sandbox":{"post":{"tags":["Authentication"],"summary":"Provision a sandbox or credit key for testing","description":"Two paths: (1) Email path — POST with { \"email\": \"...\" } to get a sb_ sandbox key (7 days, 200 calls). One key per email/IP per 7-day window. (2) x402 agent path — POST with X-Payment header containing a valid Base mainnet USDC payment ($0.001). Skips email entirely; returns a ho_crd_ credit key with 10 credits. Agent-native: no human in the loop. Sandbox keys are rejected by /v5/receipts and /v5/webhooks/subscribe (paid features).","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","example":"developer@example.com","description":"Required for email path. Omit when using X-Payment header."},"use_case":{"type":"string","maxLength":500,"description":"Brief description of what you're building (helps us prioritise)."}}}}}},"parameters":[{"name":"X-Payment","in":"header","required":false,"description":"x402 payment proof (JSON). When present, skips email verification and issues a credit key. Format: { \"txHash\": \"0x...\", \"network\": \"base\", \"amount\": \"1000\", \"paymentAddress\": \"0x...\", \"memo\": \"\" }","schema":{"type":"string"}}],"responses":{"200":{"description":"Key issued (sandbox or credit)","content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string","example":"sb_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"},"tier":{"type":"string","enum":["sandbox","credits"]},"email_captured":{"type":"boolean"},"expires_at":{"type":"string","format":"date-time"},"calls_remaining":{"type":"integer"},"credits":{"type":"integer","description":"Credit balance (x402 path only)."},"upgrade_url":{"type":"string"},"quickstart":{"type":"object"}}}}}},"400":{"description":"Email missing or invalid (email path)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"X-Payment header invalid or payment verification failed (x402 path)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Sandbox allocation already used for this IP or email","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"SANDBOX_LIMIT_REACHED"},"message":{"type":"string"},"upgrade_url":{"type":"string"},"plans":{"type":"object"}}}}}},"503":{"description":"x402 payments not configured on this instance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/archive":{"get":{"summary":"Historical receipt archive","description":"Returns historical signed receipts for a MIC. Builder+ keys: 30-day window. Sandbox/free keys: today only. Use the date query param (YYYY-MM-DD) to request a specific day.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"mic","in":"query","required":false,"schema":{"type":"string"},"description":"MIC code. Defaults to XNYS."},{"name":"date","in":"query","required":false,"schema":{"type":"string"},"description":"Date in YYYY-MM-DD format. Defaults to today."}],"responses":{"200":{"description":"Receipt archive for the requested MIC and date","content":{"application/json":{"schema":{"type":"object","properties":{"mic":{"type":"string","example":"XNYS"},"date":{"type":"string","example":"2026-03-25"},"count":{"type":"integer"},"receipts":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key or tier restriction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/audit/digest":{"get":{"tags":["Audit"],"summary":"Daily attestation digest with Merkle root","description":"Returns a tamper-proof summary of all attestations issued on a given date. Merkle root is SHA-256 of ordered receipt IDs. Each day chains to the previous via previous_day_merkle_root. Public, no auth. If date is today, returns partial (in-progress) digest.","parameters":[{"name":"date","in":"query","required":false,"schema":{"type":"string","example":"2026-04-07"},"description":"Date in YYYY-MM-DD. Defaults to today."}],"responses":{"200":{"description":"Daily attestation digest","content":{"application/json":{"schema":{"type":"object","properties":{"date":{"type":"string","example":"2026-04-07"},"total_receipts_issued":{"type":"integer","example":47},"exchanges_attested":{"type":"array","items":{"type":"string"},"example":["XLON","XNYS"]},"receipt_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"merkle_root":{"type":"string","description":"SHA-256 Merkle tree root of ordered receipt_ids"},"previous_day_merkle_root":{"type":"string","nullable":true},"chain_length":{"type":"integer"},"computed_at":{"type":"string","format":"date-time"},"partial":{"type":"boolean","description":"true if date is today (in-progress)"}}}}}},"400":{"description":"Invalid date","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/audit/chain":{"get":{"tags":["Audit"],"summary":"Hash chain of daily attestation digests","description":"Returns the last N daily digests showing the Merkle chain. Each day references the previous day's merkle_root. Tampering with any day breaks the chain forward. chain_intact indicates verification result.","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":7,"maximum":30},"description":"Number of days to include (default 7, max 30)."}],"responses":{"200":{"description":"Chain of daily digests","content":{"application/json":{"schema":{"type":"object","properties":{"chain_length":{"type":"integer"},"chain_intact":{"type":"boolean","description":"true if all previous_day_merkle_root values match"},"latest_date":{"type":"string"},"oldest_date":{"type":"string"},"digests":{"type":"array","items":{"type":"object"}}}}}}}}}},"/v5/stream":{"get":{"summary":"SSE stream of signed market_status events","description":"Server-Sent Events stream delivering a signed market_status receipt every 30 seconds via a StreamCoordinator Durable Object. One Durable Object instance per MIC. Emits event:halted as a terminal event when a circuit breaker override is active. Auth required (X-Oracle-Key header or ?key= query param).","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"mic","in":"query","required":false,"schema":{"type":"string"},"description":"MIC code. Defaults to XNYS."},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"API key (alternative to X-Oracle-Key header)."}],"responses":{"200":{"description":"SSE stream (text/event-stream). Events: market_status (recurring), halted (terminal)."},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/conformance-vectors":{"get":{"summary":"Canonical test vectors for SDK authors","description":"Returns 5 live-signed canonical test vectors covering the full receipt space: XNYS OPEN, XNYS CLOSED, XJPX lunch break, UNKNOWN (system), and HEALTH OK. Each vector includes the receipt, the canonical_payload (base64-encoded canonical JSON string before signing), and the public_key (hex) used to sign it. SDK authors can use these to verify their Ed25519 implementation. No authentication required.","responses":{"200":{"description":"Conformance test vectors","content":{"application/json":{"schema":{"type":"object","properties":{"generated_at":{"type":"string","format":"date-time"},"public_key":{"type":"string","description":"Hex-encoded Ed25519 public key used for all vectors."},"vectors":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","example":"XNYS_OPEN"},"receipt":{"type":"object"},"canonical_payload":{"type":"string","description":"Base64-encoded canonical JSON payload that was signed."},"public_key":{"type":"string","description":"Hex-encoded public key for this vector."}}}}}}}}}}}},"/.well-known/agent.json":{"get":{"summary":"Structured agent metadata","description":"Machine-readable JSON describing Oracle capabilities, MCP tools, REST endpoints, auth requirements, and trust anchors. Includes spec_version (YYYY-MM-DD) for staleness detection.","responses":{"200":{"description":"Agent metadata","content":{"application/json":{"schema":{"type":"object","properties":{"schema_version":{"type":"string","example":"1.0"},"spec_version":{"type":"string","example":"2026-02-26","description":"YYYY-MM-DD — compare against cached value to detect stale metadata."},"name":{"type":"string"},"capabilities":{"type":"array","items":{"type":"string"}},"mcp":{"type":"object"},"rest_api":{"type":"object"},"trust":{"type":"object"},"safety":{"type":"object"}}}}}}}}},"/.well-known/security.txt":{"get":{"summary":"Security contact (RFC 9116)","description":"RFC 9116 security.txt — machine-readable security contact information. Lists responsible disclosure contact, expiry date, and preferred language.","responses":{"200":{"description":"security.txt content","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/v5/webhooks/subscribe":{"post":{"tags":["Webhooks"],"summary":"Subscribe to market state-change webhooks","description":"Register a webhook URL to receive signed receipts when a market transitions between states (OPEN↔CLOSED, HALT). Builder+ plans only. Sandbox keys are rejected. Returns webhook_id and subscription_id.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","mics"],"properties":{"url":{"type":"string","format":"uri","description":"HTTPS endpoint to receive webhook deliveries."},"mics":{"type":"array","items":{"type":"string"},"description":"MIC codes to subscribe to (e.g. [\"XNYS\",\"XNAS\"])."},"events":{"type":"array","items":{"type":"string"},"description":"Event types to subscribe to. Default: [\"status_change\"]."}}}}}},"responses":{"200":{"description":"Subscription created","content":{"application/json":{"schema":{"type":"object","properties":{"webhook_id":{"type":"string","description":"Unique ID for this webhook. Use for DELETE /v5/webhooks/{webhook_id}."},"subscription_id":{"type":"string","description":"Legacy alias for webhook_id (backward compat)."},"url":{"type":"string"},"mics":{"type":"array","items":{"type":"string"}}}}}}},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Sandbox keys cannot use webhooks — upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key or plan limit reached (builder=5, pro=25)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/webhooks":{"get":{"tags":["Webhooks"],"summary":"List all webhooks for this API key","description":"Returns all active webhook subscriptions for the authenticated key. Each entry includes webhook_id, url, mics, events, created_at, status.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Webhook list","content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"type":"object","properties":{"webhook_id":{"type":"string"},"url":{"type":"string"},"mics":{"type":"array","items":{"type":"string"}},"events":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["active","paused"]}}}},"count":{"type":"integer"}}}}}},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/webhooks/{webhook_id}":{"delete":{"tags":["Webhooks"],"summary":"Delete a webhook subscription","description":"Permanently removes the webhook subscription. Returns 204 No Content on success. Also decrements the plan webhook count.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook ID returned from POST /v5/webhooks/subscribe."}],"responses":{"204":{"description":"Webhook deleted"},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key or webhook does not belong to this key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/webhooks/test/{webhook_id}":{"post":{"tags":["Webhooks"],"summary":"Send a synthetic test delivery to a webhook","description":"Fires a single test delivery to the webhook URL. Uses the current market state for the first subscribed MIC. One delivery attempt (no retry). Returns the payload sent.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook ID to test."}],"responses":{"200":{"description":"Test delivery result","content":{"application/json":{"schema":{"type":"object","properties":{"delivered":{"type":"boolean"},"payload_sent":{"type":"object","description":"The exact webhook payload delivered."},"status_code":{"type":"integer","description":"HTTP status from the webhook endpoint."}}}}}},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Webhook does not belong to this key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/webhooks/health":{"get":{"tags":["Webhooks"],"summary":"WebhookDispatcher Durable Object health status","description":"Returns the last known health status of the WebhookDispatcher Durable Object — written by the DO alarm() after each 60s dispatch cycle. No authentication required. Does not wake the DO.","responses":{"200":{"description":"Dispatcher health status","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","unknown"],"description":"\"ok\" = DO alarm ran recently. \"unknown\" = no health record in KV yet."},"next_alarm":{"type":"string","format":"date-time","description":"When the next dispatch cycle is scheduled."},"checked_at":{"type":"string","format":"date-time"}}}}}}}}},"/v5/receipts":{"get":{"tags":["Audit"],"summary":"Receipt audit log (builder+ only)","description":"Returns a filtered audit log of signed receipts issued to this API key. Each row contains mic, status, source, issued_at, schema_version. Requires Builder or Pro plan. Supports limit, mic, and from query params.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50},"description":"Max rows to return (max 200)."},{"name":"mic","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by MIC code."},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"Return receipts after this ISO8601 timestamp."}],"responses":{"200":{"description":"Audit log","content":{"application/json":{"schema":{"type":"object","properties":{"receipts":{"type":"array","items":{"type":"object","properties":{"mic":{"type":"string"},"status":{"$ref":"#/components/schemas/Status"},"source":{"$ref":"#/components/schemas/Source"},"issued_at":{"type":"string","format":"date-time"},"schema_version":{"type":"string","example":"v5.0"}}}},"count":{"type":"integer"}}}}}},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Plan upgrade required (sandbox/free keys cannot access receipt audit)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/x402/mint":{"post":{"tags":["Billing"],"summary":"Mint a persistent API key via x402 USDC payment","description":"Agents submit a verified Base mainnet USDC transaction hash and receive a persistent ho_live_ API key. Builder tier: 99 USDC = 50K calls/day. Pro tier: 299 USDC = 200K calls/day. Replay protection: each tx_hash can only be used once (365-day TTL).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tx_hash","tier"],"properties":{"tx_hash":{"type":"string","description":"Base mainnet USDC transaction hash (0x-prefixed)."},"tier":{"type":"string","enum":["builder","pro"],"description":"Desired key tier."},"email":{"type":"string","format":"email","description":"Optional: receive the key by email."}}}}}},"responses":{"200":{"description":"Key minted","content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string","description":"Your new persistent API key (ho_live_ prefix). Store securely — shown once."},"tier":{"type":"string","enum":["builder","pro"]},"daily_limit":{"type":"integer"}}}}}},"400":{"description":"Invalid tx_hash or payment amount insufficient","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Transaction already used to mint a key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Base mainnet RPC unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/credits/purchase":{"post":{"tags":["Billing"],"summary":"Purchase prepaid credits via x402 USDC payment","description":"Submit a verified Base mainnet USDC payment to add prepaid credits to your key. Credit tiers: 0.001 USDC = 1 credit, 0.09 USDC = 100 credits, 0.80 USDC = 1000 credits. Requires X-Payment header with verified tx.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Credits added","content":{"application/json":{"schema":{"type":"object","properties":{"credits_added":{"type":"integer"},"new_balance":{"type":"integer"},"tier":{"type":"string"}}}}}},"402":{"description":"Payment required or insufficient amount","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Payment verification service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/credits/balance":{"get":{"tags":["Billing"],"summary":"Check prepaid credit balance","description":"Returns the current credit balance for the authenticated key. Credits are consumed 1-per-request on /v5/status and /v5/batch when the free tier limit is reached.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Credit balance","content":{"application/json":{"schema":{"type":"object","properties":{"balance":{"type":"integer","description":"Remaining prepaid credits."},"estimated_requests_remaining":{"type":"integer"},"last_purchased":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/card/{mic}":{"get":{"tags":["Discoverability"],"summary":"SVG status card for a market exchange","description":"Returns a terminal-style SVG status card showing the current market state for a MIC. Dark chrome, syntax-highlighted JSON, status-coloured text, pulsing LIVE dot. Cache-Control: no-cache. Suitable for README badges and dashboards.","parameters":[{"name":"mic","in":"path","required":true,"schema":{"type":"string"},"description":"MIC code (e.g. XNYS, XNAS, XLON)."}],"responses":{"200":{"description":"SVG status card","content":{"image/svg+xml":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Unknown MIC code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/x402":{"get":{"tags":["Discoverability"],"summary":"x402 Foundation compatibility declaration","description":"Declares x402 protocol compatibility for the x402 Foundation ecosystem. Returns network, facilitator, first payment timestamp, and links to discovery and payment proof endpoints.","responses":{"200":{"description":"x402 compatibility info","content":{"application/json":{"schema":{"type":"object","properties":{"x402_compatible":{"type":"boolean"},"network":{"type":"string","example":"base"},"facilitator":{"type":"string","example":"cdp"},"first_payment_at":{"type":"string","format":"date-time","nullable":true},"payment_proof":{"type":"string"},"discovery":{"type":"string"},"awesome_x402":{"type":"string"},"foundation":{"type":"string"}}}}}}}}},"/v5/verify":{"post":{"tags":["Verification"],"summary":"Verify Ed25519 receipt signature (REST)","description":"Public endpoint. Accepts a signed market receipt and verifies the Ed25519 signature in-worker. Returns validity, expiry status, and reason. Offline verification via @headlessoracle/verify is also supported and MAY be preferred by agents that don't need a REST round-trip.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["receipt"],"properties":{"receipt":{"type":"object","description":"Complete signed receipt as returned by /v5/status or /v5/demo.","additionalProperties":true}}}}}},"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"expired":{"type":"boolean"},"reason":{"type":"string","enum":["SIGNATURE_VALID","INVALID_SIGNATURE","MALFORMED_RECEIPT","ORACLE_NOT_CONFIGURED","RECEIPT_EXPIRED — re-fetch required"]},"mic":{"type":"string","nullable":true},"status":{"type":"string","nullable":true},"expires_at":{"type":"string","format":"date-time","nullable":true}}}}}},"400":{"description":"Missing or malformed body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Verification"],"summary":"Verify Ed25519 receipt signature (query params)","description":"GET variant — accepts receipt fields as query parameters. Same verification logic as POST.","parameters":[{"name":"receipt","in":"query","required":true,"schema":{"type":"string"},"description":"JSON-encoded signed receipt string."}],"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v5/historical":{"get":{"tags":["Market State"],"summary":"Historical market-state reconstruction","description":"Reconstructs market status at a past timestamp from schedule data. Public, unsigned. Includes DST proximity notes. Not a signed attestation.","parameters":[{"name":"mic","in":"query","required":true,"schema":{"type":"string"},"description":"MIC code."},{"name":"at","in":"query","required":true,"schema":{"type":"string","format":"date-time"},"description":"ISO 8601 timestamp to reconstruct."}],"responses":{"200":{"description":"Reconstructed status","content":{"application/json":{"schema":{"type":"object","properties":{"mic":{"type":"string"},"queried_at":{"type":"string"},"computed_status":{"$ref":"#/components/schemas/Status"},"source":{"type":"string","example":"SCHEDULE_RECONSTRUCTION"},"reasoning":{"type":"object"},"dst_note":{"type":"string","nullable":true},"disclaimer":{"type":"string"}}}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v5/status/realtime":{"get":{"tags":["Market State"],"summary":"Real-time halt detection status","description":"Returns the signed receipt plus halt monitor metadata (active REALTIME overrides). Requires X-Oracle-Key.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"mic","in":"query","schema":{"type":"string","default":"XNYS"}}],"responses":{"200":{"description":"Receipt with halt monitor metadata","content":{"application/json":{"schema":{"type":"object","properties":{"mic":{"type":"string"},"signed_receipt":{"$ref":"#/components/schemas/SignedReceipt"},"halt_monitor":{"type":"object"}}}}}},"400":{"description":"Unknown MIC"},"401":{"description":"Missing API key"}}}},"/oauth/token":{"post":{"tags":["OAuth"],"summary":"OAuth 2.0 token endpoint (RFC 6749)","description":"Client Credentials grant. client_id = existing Oracle API key. Returns a short-lived opaque bearer token (3600s TTL) for MCP authentication.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["grant_type","client_id"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"]},"client_id":{"type":"string","description":"Your Oracle API key"}}}}}},"responses":{"200":{"description":"Token issued","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","example":"bearer"},"expires_in":{"type":"integer","example":3600},"scope":{"type":"string","example":"oracle:read"}}}}}},"400":{"description":"Invalid request (missing client_id or unsupported grant type)"},"401":{"description":"Invalid client (API key not recognised)"},"405":{"description":"Method not allowed — use POST"}}}},"/oauth/introspect":{"post":{"tags":["OAuth"],"summary":"OAuth 2.0 token introspection (RFC 7662)","description":"Returns { active: true/false } for a given token. Always HTTP 200 per RFC 7662.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"}}}}}},"responses":{"200":{"description":"Introspection result","content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean"},"scope":{"type":"string"},"exp":{"type":"integer","nullable":true},"token_type":{"type":"string"}}}}}}}}},"/v5/briefing":{"get":{"tags":["Discovery"],"summary":"Daily market intelligence snapshot","description":"All 28 exchanges at a glance: open/closed/lunch break, upcoming opens/closes with minutes-until, holidays today. Public, no auth. Cached 60s.","responses":{"200":{"description":"Market briefing","content":{"application/json":{"schema":{"type":"object","properties":{"briefing_date":{"type":"string"},"markets_open_now":{"type":"array","items":{"type":"string"}},"markets_closed_now":{"type":"array","items":{"type":"string"}},"markets_in_lunch_break":{"type":"array","items":{"type":"string"}},"upcoming_opens":{"type":"array","items":{"type":"object"}},"upcoming_closes":{"type":"array","items":{"type":"object"}},"holidays_today":{"type":"array","items":{"type":"string"}},"coverage":{"type":"integer"}}}}}}}}},"/v5/referrers":{"get":{"tags":["Operations"],"summary":"Daily referrer traffic breakdown","description":"Lists domains that linked to headlessoracle.com today (or a given date). Best-effort from KV counters.","parameters":[{"name":"date","in":"query","schema":{"type":"string","format":"date"},"description":"YYYY-MM-DD (defaults to today)"}],"responses":{"200":{"description":"Referrer counts","content":{"application/json":{"schema":{"type":"object","properties":{"date":{"type":"string"},"referrers":{"type":"object","additionalProperties":{"type":"integer"}}}}}}}}}},"/v5/payment-proof":{"get":{"tags":["Payment"],"summary":"On-chain USDC payment ledger","description":"Public. Returns lifetime x402 payment stats from KV: count, first/last payment timestamps, Base mainnet USDC contract and verify link.","responses":{"200":{"description":"Payment proof","content":{"application/json":{"schema":{"type":"object","properties":{"payment_count":{"type":"integer"},"first_payment_at":{"type":"string","nullable":true},"first_payment_tx":{"type":"string","nullable":true},"last_payment_at":{"type":"string","nullable":true},"network":{"type":"string"},"asset":{"type":"string"},"contract":{"type":"string"},"verify_at":{"type":"string"}}}}}}}}},"/v5/revenue-pulse":{"get":{"tags":["Operations"],"summary":"Admin revenue feed (Paddle + x402)","description":"Admin only — requires MASTER_API_KEY in X-Oracle-Key header. Returns Paddle lifetime counts (by tier), x402 lifetime stats, and the most recent 50 Paddle revenue events from KV (30-day TTL). Consumed by .github/workflows/health-check.yml to surface new revenue as GitHub issues.","parameters":[{"name":"X-Oracle-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Master API key"}],"responses":{"200":{"description":"Revenue pulse","content":{"application/json":{"schema":{"type":"object","properties":{"paddle":{"type":"object"},"x402":{"type":"object"}}}}}},"401":{"description":"Missing or invalid master key"}}}},"/v5/why-not-free":{"get":{"tags":["Payment"],"summary":"Machine-readable upgrade ladder","description":"Structured payment options for agents that receive a 402. Linked from every 402 via Link header.","responses":{"200":{"description":"Payment options","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v5/pricing":{"get":{"tags":["Payment"],"summary":"Machine-readable pricing tiers","description":"All tiers in one JSON response: sandbox, free, x402, credits, builder, pro, protocol. Canonical pricing source.","responses":{"200":{"description":"Pricing tiers","content":{"application/json":{"schema":{"type":"object","properties":{"tiers":{"type":"array","items":{"type":"object"}},"x402":{"type":"object"},"checkout_url":{"type":"string"},"sandbox_url":{"type":"string"}}}}}}}}},"/v5/slo":{"get":{"tags":["Operations"],"summary":"SLO and error budget report","description":"Returns uptime tracking, error budget computation, and burn rate. Public, no auth.","responses":{"200":{"description":"SLO report","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v5/errors/{code}":{"get":{"tags":["Discovery"],"summary":"Machine-readable error documentation","description":"Returns description, HTTP status, and resolution steps for a specific error code (e.g. RATE_LIMITED, API_KEY_REQUIRED).","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"},"description":"Error code in SCREAMING_SNAKE_CASE."}],"responses":{"200":{"description":"Error documentation","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"resolution":{"type":"string"},"http_status":{"type":"integer"}}}}}},"404":{"description":"Unknown error code"}}}},"/.well-known/x402.json":{"get":{"tags":["Discovery"],"summary":"x402 payment resource discovery","description":"Lists endpoints that accept x402 micropayments: /v5/status ($0.001 USDC), /v5/batch ($0.005), /v5/x402/mint (99/299 USDC). x402scan-compatible.","responses":{"200":{"description":"x402 resources","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"integer"},"resources":{"type":"array","items":{"type":"object"}}}}}}}}}},"/.well-known/mcp-servers.json":{"get":{"tags":["Discovery"],"summary":"Self-describing MCP registry feed","description":"Machine-readable listing metadata for MCP registries. Proposed convention — registries can poll to sync tool/exchange counts automatically.","responses":{"200":{"description":"Server registry","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/.well-known/mcp/server-card.json":{"get":{"tags":["Discovery"],"summary":"MCP server card metadata","description":"Full MCP server metadata: tools, coverage, authentication, x402 payment details, standards compliance. Also served at /.well-known/mcp.json.","responses":{"200":{"description":"Server card","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/.well-known/oauth-protected-resource":{"get":{"tags":["OAuth"],"summary":"OAuth 2.0 Protected Resource Metadata (RFC 8705)","description":"Tells MCP clients where to find the authorization server for optional OAuth.","responses":{"200":{"description":"Protected resource metadata","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"tags":["OAuth"],"summary":"OAuth 2.0 Authorization Server Metadata (RFC 8414)","description":"Describes token endpoint, supported grant types, and scopes.","responses":{"200":{"description":"AS metadata","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/.well-known/ai-plugin.json":{"get":{"tags":["Discovery"],"summary":"ChatGPT / OpenAI plugin manifest","description":"Plugin manifest for ChatGPT Custom GPT Actions. Also served at /ai-plugin.json.","responses":{"200":{"description":"Plugin manifest","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v5/pre-trade-stack":{"get":{"tags":["Discovery"],"summary":"Composable pre-trade verification stack (JSON)","description":"Machine-readable description of the Composable Pre-Trade Verification Pattern v2.0 — a deployment pattern in which environment.market_state and adjacent verification steps (spend authorization, signal verification, payment) compose into a gating sequence for autonomous trading agents. References environment.market_state and environment.wallet_state as normative specifications in the Verifiable Intent environment.* family.","responses":{"200":{"description":"Pre-trade stack definition","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/docs/specifications/pre-trade-stack":{"get":{"tags":["Documentation"],"summary":"Pre-trade verification stack specification","description":"Composable Pre-Trade Verification Pattern v2.0. Deployment pattern: execution-environment verification (environment.market_state) → spend authorization → signal verification → payment → trade execution. text/markdown.","responses":{"200":{"description":"Specification document","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/docs/specifications/cpvr-1":{"get":{"tags":["Documentation"],"summary":"CPVR-1: Composable Pre-Trade Verification Receipt (PROPOSAL)","description":"Proposed JSON envelope format wrapping all pre-trade verification proofs (market state, spend authorization, signal verification, payment) into a single verifiable artifact. text/markdown.","responses":{"200":{"description":"Specification document","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/docs/specifications/multi-oracle-consensus-v1":{"get":{"tags":["Documentation"],"summary":"Multi-Oracle Consensus Protocol v1.0.1 (Published Standard)","description":"First published standard for market-state verification across independent oracle feeds. Defines minimum oracle count (3), consensus algorithm (majority_with_fail_closed), attestation format, verification flow, and cryptographic requirements. Architecturally consistent with emerging regulatory direction on tokenized collateral (CFTC Staff Letter 25-39, December 2025; SEC Crypto Task Force Project Blueprint on Tokenized Collateral, November 2025). License: MIT. text/markdown.","responses":{"200":{"description":"Specification document","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/v1/verification/multi-oracle-guide":{"get":{"tags":["Discovery"],"summary":"Multi-Oracle Consensus Protocol — machine-readable guide","description":"JSON description of the Multi-Oracle Consensus Protocol v1.0.0. Includes consensus algorithm, attestation format, verification flow, error handling, cryptographic requirements, and reference oracle implementations. Unauthenticated — public good.","responses":{"200":{"description":"Multi-oracle consensus guide","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/docs/integrations/ampersend":{"get":{"tags":["Documentation"],"summary":"Ampersend integration guide","description":"Integration recipe: Headless Oracle (proposed environment.market_state reference implementation) + Ampersend (spend authorization service). Code examples, batch verification, MCP integration.","responses":{"200":{"description":"Integration guide","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/.well-known/agent-card.json":{"get":{"tags":["Discovery"],"summary":"A2A v1 Agent Card (alias)","description":"A2A Protocol v1 agent card. Same content as /.well-known/agent.json. Some A2A crawlers check agent-card.json per the latest spec.","responses":{"200":{"description":"Agent card","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/AGENTS.md":{"get":{"tags":["Documentation"],"summary":"Agent integration guide (AAIF/Linux Foundation format)","description":"Markdown briefing for autonomous agents: critical rules, MCP tools, x402 payment, all 28 exchanges. text/markdown.","responses":{"200":{"description":"Agent guide","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/skill.md":{"get":{"tags":["Documentation"],"summary":"Ampersend skill format","description":"YAML frontmatter skill file for Ampersend registry. x402 payment details, ERC-8004, 28 exchanges.","responses":{"200":{"description":"Skill file","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/sitemap.xml":{"get":{"tags":["Discovery"],"summary":"XML sitemap","responses":{"200":{"description":"Sitemap","content":{"application/xml":{"schema":{"type":"string"}}}}}}},"/badge/{mic}":{"get":{"tags":["Discovery"],"summary":"shields.io-style market status badge","description":"SVG badge: green=OPEN, grey=CLOSED, red=HALTED, orange=UNKNOWN. Cache-Control: max-age=60.","parameters":[{"name":"mic","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"SVG badge","content":{"image/svg+xml":{"schema":{"type":"string"}}}}}}},"/v5/changelog":{"get":{"tags":["Discovery"],"summary":"Structured version changelog","description":"JSON feed of major milestones and version changes. Public, no auth.","responses":{"200":{"description":"Changelog entries","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v5/webhooks/unsubscribe":{"delete":{"tags":["Webhooks"],"summary":"Unsubscribe from webhooks (legacy)","description":"Legacy DELETE endpoint. Removes a webhook subscription by subscription_id in request body. Prefer DELETE /v5/webhooks/{webhook_id}.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["subscription_id"],"properties":{"subscription_id":{"type":"string"}}}}}},"responses":{"204":{"description":"Unsubscribed"},"401":{"description":"Missing API key"},"404":{"description":"Subscription not found"}}}}}}