{"openapi":"3.1.0","jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","info":{"title":"Hosannaith","version":"1.0.0","summary":"Reliability oracle for x402 endpoints on Algorand.","description":"Independently and continuously monitors x402 endpoints and returns a reliability score (uptime, correct 402 behaviour, latency percentiles) so an agent can decide whether to trust an endpoint before paying it. Paid operations settle in USDC on Algorand mainnet via x402; their payment terms are in each operation's \"x-x402\" extension. Response objects are additive-only: new optional fields may appear; existing fields never change. When signing is enabled, every result carries spec_version, generated_at and an ES256 signature verifiable against /.well-known/hosannaith-keys.json (see docs/attestation.md).","license":{"name":"Apache-2.0","identifier":"Apache-2.0"},"contact":{"url":"https://hosannaith.com"}},"servers":[{"url":"https://api.hosannaith.com"}],"tags":[{"name":"Reliability","description":"Paid (x402) reliability scores."},{"name":"Discovery","description":"Free documents for agents and tooling."}],"paths":{"/reliability":{"get":{"operationId":"getReliability","summary":"Reliability score for one x402 endpoint","description":"Reliability score (0-100) for a given x402 endpoint: uptime, correct 402 behaviour, and latency percentiles from continuous independent monitoring. Pass ?target=<endpoint-url>.","tags":["Reliability"],"x-x402":{"scheme":"exact","price":"$1.00","amount":"1000000","asset":"31566704","network":"algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=","payTo":"BEACJLUDOSVMS6SUQEUAHWRI4VAAX7G4CVFOL3DWH2R4XHTLXT6VG5TFYU","tag":"x402-global-challenge"},"parameters":[{"name":"target","in":"query","required":true,"description":"Full URL of the x402 endpoint to score.","schema":{"type":"string","format":"uri"}}],"responses":{"200":{"description":"Reliability result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckResult"}}}},"400":{"description":"Missing or invalid target.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Payment required (x402 v2). The PAYMENT-REQUIRED response header carries the base64-encoded JSON payment requirements. Pay with any x402 client and retry with the PAYMENT-SIGNATURE header. This response is produced by the x402 payment middleware."},"500":{"description":"Internal error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/reliability/batch":{"post":{"operationId":"getReliabilityBatch","summary":"Reliability scores for up to 50 x402 endpoints","description":"Reliability scores for up to 50 x402 endpoints in one call. POST JSON body {\"targets\":[\"<endpoint-url>\", ...]}. Returns a results array (same per-target shape as GET /reliability). Monitored targets return a history-based score; unmonitored targets return \"unknown\" and are enrolled for ongoing monitoring.","tags":["Reliability"],"x-x402":{"scheme":"exact","price":"$7.00","amount":"7000000","asset":"31566704","network":"algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=","payTo":"BEACJLUDOSVMS6SUQEUAHWRI4VAAX7G4CVFOL3DWH2R4XHTLXT6VG5TFYU","tag":"x402-global-challenge"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["targets"],"properties":{"targets":{"type":"array","minItems":1,"items":{"type":"string","format":"uri"},"description":"Endpoint URLs. Duplicates are removed; at most 50 are scored."}}}}}},"responses":{"200":{"description":"Batch result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResult"}}}},"400":{"description":"Body is not { \"targets\": [...] }.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Payment required (x402 v2). The PAYMENT-REQUIRED response header carries the base64-encoded JSON payment requirements. Pay with any x402 client and retry with the PAYMENT-SIGNATURE header. This response is produced by the x402 payment middleware."},"500":{"description":"Internal error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/health":{"get":{"summary":"Liveness check","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{}}}}}},"/.well-known/x402":{"get":{"summary":"x402 discovery document","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{}}}}}},"/.well-known/hosannaith-keys.json":{"get":{"summary":"Public keys for verifying signed results (JWKS + revoked_keys)","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{}}}}}},"/reports/{id}.json":{"get":{"summary":"Signed, dated public reliability report","tags":["Discovery"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"}}],"responses":{"200":{"description":"Signed report (verify per docs/attestation.md).","content":{"application/json":{}}},"404":{"description":"No such report.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/llms.txt":{"get":{"summary":"Agent-facing guide","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"text/plain":{}}}}}},"/openapi.json":{"get":{"summary":"This document","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{}}}}}},"/schema/check-result.json":{"get":{"summary":"JSON Schema of a reliability result","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{}}}}}},"/schema/batch-result.json":{"get":{"summary":"JSON Schema of a batch result","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{}}}}}},"/schema/problem.json":{"get":{"summary":"JSON Schema of an error body (RFC 9457)","tags":["Discovery"],"responses":{"200":{"description":"OK","content":{"application/json":{}}}}}}},"components":{"schemas":{"CheckResult":{"title":"Hosannaith reliability result","description":"Response of GET /reliability and of each item in POST /reliability/batch results.","type":"object","required":["target","checkId","status","score","detail","observedAt"],"properties":{"target":{"type":"string","description":"The endpoint URL that was scored, as requested."},"checkId":{"const":"reliability"},"status":{"enum":["pass","degraded","fail","unknown"],"description":"pass: score >= 90. degraded: 60-89. fail: < 60. unknown: not enough data to score."},"score":{"type":["number","null"],"minimum":0,"maximum":100,"description":"0-100 composite (0.6 uptime + 0.4 correct-402 - latency penalty); null below 5 observations."},"detail":{"type":"object","description":"Supporting statistics for a reliability result. For a batch target with no history yet (confidence \"pending\") only observations, windowHours and confidence are present.","required":["observations","windowHours","confidence"],"properties":{"observations":{"type":"integer","minimum":0,"description":"Probes in the scoring window."},"windowHours":{"type":"number","exclusiveMinimum":0,"description":"Length of the scoring window."},"confidence":{"enum":["history","one-shot","pending"],"description":"\"history\": scored from accumulated monitoring. \"one-shot\": first sighting, one live probe (score is null). \"pending\": batch only; no history yet, now enrolled for monitoring."},"uptimePct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"Probes where the endpoint was serving (reachable and not 5xx), in percent."},"correct402Pct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"Gating-determinate probes (402 vs unpaid 2xx) that returned 402, in percent. Null when no probe was determinate; other 4xx are indeterminate for an unpaid probe and excluded."},"p50LatencyMs":{"type":["integer","null"],"minimum":0,"description":"Median latency of serving probes."},"p95LatencyMs":{"type":["integer","null"],"minimum":0,"description":"95th percentile latency of serving probes. With fewer than 20 samples it equals the slowest sample."},"p99LatencyMs":{"type":["integer","null"],"minimum":0,"description":"99th percentile latency of serving probes. Null below 20 latency samples."},"score":{"type":["number","null"],"minimum":0,"maximum":100,"description":"Same as the top-level score."},"firstObservedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"},{"type":"null"}],"description":"Oldest probe in the window."},"lastObservedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"},{"type":"null"}],"description":"Newest probe in the window."},"availability_pct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"OpenEAGO SLO alias of uptimePct."},"error_rate_pct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"OpenEAGO SLO view: 100 - uptimePct, the share of probes that were 5xx or unreachable. Client-side 4xx are not counted as errors: for an unpaid probe they are indeterminate."},"protocol_conformance_pct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"OpenEAGO SLO alias of correct402Pct."},"score_normalized":{"type":["number","null"],"minimum":0,"maximum":1,"description":"The 0-100 score rescaled to [0, 1] (score / 100)."}}},"observedAt":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$","description":"When this result was computed."},"spec_version":{"type":"string","pattern":"^\\d+\\.\\d+\\.\\d+$","description":"Version of the signed attestation format (semver). Present on signed results."},"generated_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$","description":"When the result was signed. Present on signed results."},"signature":{"type":"object","description":"ES256 signature over the RFC 8785 canonical JSON of this object without its own `signature`. Public keys: /.well-known/hosannaith-keys.json. Present on signed results.","required":["alg","kid","sig"],"properties":{"alg":{"const":"ES256"},"kid":{"type":"string","description":"RFC 7638 thumbprint of the signing key."},"sig":{"type":"string","pattern":"^[A-Za-z0-9_-]{86}$","description":"Raw 64-byte r||s, base64url, no padding."}}}}},"BatchResult":{"title":"Hosannaith batch reliability result","description":"Response of POST /reliability/batch.","type":"object","required":["results","count","requested","capped","observedAt"],"properties":{"results":{"type":"array","items":{"type":"object","required":["target","checkId","status","score","detail","observedAt"],"properties":{"target":{"type":"string","description":"The endpoint URL that was scored, as requested."},"checkId":{"const":"reliability"},"status":{"enum":["pass","degraded","fail","unknown"],"description":"pass: score >= 90. degraded: 60-89. fail: < 60. unknown: not enough data to score."},"score":{"type":["number","null"],"minimum":0,"maximum":100,"description":"0-100 composite (0.6 uptime + 0.4 correct-402 - latency penalty); null below 5 observations."},"detail":{"type":"object","description":"Supporting statistics for a reliability result. For a batch target with no history yet (confidence \"pending\") only observations, windowHours and confidence are present.","required":["observations","windowHours","confidence"],"properties":{"observations":{"type":"integer","minimum":0,"description":"Probes in the scoring window."},"windowHours":{"type":"number","exclusiveMinimum":0,"description":"Length of the scoring window."},"confidence":{"enum":["history","one-shot","pending"],"description":"\"history\": scored from accumulated monitoring. \"one-shot\": first sighting, one live probe (score is null). \"pending\": batch only; no history yet, now enrolled for monitoring."},"uptimePct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"Probes where the endpoint was serving (reachable and not 5xx), in percent."},"correct402Pct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"Gating-determinate probes (402 vs unpaid 2xx) that returned 402, in percent. Null when no probe was determinate; other 4xx are indeterminate for an unpaid probe and excluded."},"p50LatencyMs":{"type":["integer","null"],"minimum":0,"description":"Median latency of serving probes."},"p95LatencyMs":{"type":["integer","null"],"minimum":0,"description":"95th percentile latency of serving probes. With fewer than 20 samples it equals the slowest sample."},"p99LatencyMs":{"type":["integer","null"],"minimum":0,"description":"99th percentile latency of serving probes. Null below 20 latency samples."},"score":{"type":["number","null"],"minimum":0,"maximum":100,"description":"Same as the top-level score."},"firstObservedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"},{"type":"null"}],"description":"Oldest probe in the window."},"lastObservedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"},{"type":"null"}],"description":"Newest probe in the window."},"availability_pct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"OpenEAGO SLO alias of uptimePct."},"error_rate_pct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"OpenEAGO SLO view: 100 - uptimePct, the share of probes that were 5xx or unreachable. Client-side 4xx are not counted as errors: for an unpaid probe they are indeterminate."},"protocol_conformance_pct":{"type":["number","null"],"minimum":0,"maximum":100,"description":"OpenEAGO SLO alias of correct402Pct."},"score_normalized":{"type":["number","null"],"minimum":0,"maximum":1,"description":"The 0-100 score rescaled to [0, 1] (score / 100)."}}},"observedAt":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$","description":"When this result was computed."},"spec_version":{"type":"string","pattern":"^\\d+\\.\\d+\\.\\d+$","description":"Version of the signed attestation format (semver). Present on signed results."},"generated_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$","description":"When the result was signed. Present on signed results."},"signature":{"type":"object","description":"ES256 signature over the RFC 8785 canonical JSON of this object without its own `signature`. Public keys: /.well-known/hosannaith-keys.json. Present on signed results.","required":["alg","kid","sig"],"properties":{"alg":{"const":"ES256"},"kid":{"type":"string","description":"RFC 7638 thumbprint of the signing key."},"sig":{"type":"string","pattern":"^[A-Za-z0-9_-]{86}$","description":"Raw 64-byte r||s, base64url, no padding."}}}}}},"count":{"type":"integer","minimum":0,"description":"Targets scored, after dedupe and the cap."},"requested":{"type":"integer","minimum":0,"description":"Targets sent by the caller."},"capped":{"type":"boolean","description":"True when more targets were sent than the cap allows."},"observedAt":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"},"spec_version":{"type":"string","pattern":"^\\d+\\.\\d+\\.\\d+$","description":"Version of the signed attestation format (semver). Present on signed results."},"generated_at":{"type":"string","format":"date-time","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$","description":"When the result was signed. Present on signed results."},"signature":{"type":"object","description":"ES256 signature over the RFC 8785 canonical JSON of this object without its own `signature`. Public keys: /.well-known/hosannaith-keys.json. Present on signed results.","required":["alg","kid","sig"],"properties":{"alg":{"const":"ES256"},"kid":{"type":"string","description":"RFC 7638 thumbprint of the signing key."},"sig":{"type":"string","pattern":"^[A-Za-z0-9_-]{86}$","description":"Raw 64-byte r||s, base64url, no padding."}}}}},"Problem":{"title":"Problem Details (RFC 9457)","type":"object","required":["type","title","status"],"properties":{"type":{"type":"string","description":"Problem type URI; \"about:blank\" means the HTTP status says it all."},"title":{"type":"string"},"status":{"type":"integer","minimum":400,"maximum":599},"detail":{"type":"string"},"instance":{"type":"string"},"error":{"type":"string","description":"Legacy alias of detail."}}}}}}