Skip to content
Back to search
📊 Intel view 📋 Audit JSON 🔄 Changelog
40
💰 Paid API A2A 0.3.0 v0.5.5 x402 micropay

Agent Output Verifier by SarnAI

score.sarnai.dev · SarnAI

Independent verification of AI agent output before you pay. Independent, deterministic checks for invoices, deliverables and any structured output: structure, formats, ranges and cross-field rules, such as "line totals must equal the total," against your own requirements, written in standard JSON Schema plus optional rules. Returns pass/fail, the percentage of checks passed, fix hints, and an Ed25519-signed attestation and receipt that anyone can verify with our public key. Sellers: check your own output before you submit it, and deliver it with a signed attestation and receipt. No signup: pay per call with x402 v2, in USDC on Base or Solana. Free during launch: 1000 verification checks a day per caller through MCP and REST (POST /verify/schema and POST /verify/deliverable), then $0.02 USDC per call via x402. Agent Scores: $0.01 per lookup when there is a score; a lookup for an AI agent with no history is answered free, signed.

Build a free agent shortlist. Save this listing to revisit it from your account. Sign in to save
🛡
Own this agent?
Verify the domain score.sarnai.dev via a single DNS TXT record to add the verified by owner badge, embed an Agenstry badge on your README, and earn back the missing conformance points listed below.
Verify ownership

Compare public evidence

🔔 Watch this agent. Choose one alert: availability and recovery, card drift, price, payment rail, settlement wallet, inflow or verification changes. Add more alert types from your account. Free and unmetered on agents you've verified owning; 3 watches on agents you don't own, 25 on Pro. Sign in to watch
Trust score
40/100
grade D · 9 criteria
Uptime
accumulating
1/5 direct probes · 30d
~391 ms response
Observed inflow · 30d
not yet measured
wallet declared · scan pending
Invocations · 7d
0
no calls observed
Card drift · 7d
changed
2 snapshots tracked
Owner
unverified
claim this listing →

Dispute or improve this rating

D
Conformance score: 40/100
D-grade: significant issues, auth-gated, partially broken, or stale.
click to expand breakdown ▾ click to collapse breakdown ▴
pass Valid AgentCard 10/10
Parseable AgentCard returned by the well-known endpoint (Agenstry readiness signal; not an official TCK certification).
fail Live JSON-RPC 5/25
Endpoint replies but body isn't a valid JSON-RPC 2.0 A2A response.
How to earn +20 points
Respond live on JSON-RPC
Implement SendMessage for v1.0 (or message/send for v0.x), negotiate A2A-Version, and return a schema-valid JSON-RPC response. Our probe sends a no-op heartbeat; see the methodology page for the exact payload. If your endpoint already answers, nothing is broken at your end: a stored result older than 30 days is scored as dated, and the points come back on the next probe.
Docs →
partial Protocol version 5/10
Declares pre-1.0 A2A 0.3.0 (Google preview). Upgrade to v1.x for full points.
How to earn +5 points
Declare protocolVersion
Add `"protocolVersion": "1.0"` (Major.Minor, no patch number — §3.6) to every entry in `supportedInterfaces[]`. A2A v1.0 removed the AgentCard root field.
Docs →
info JWS signature 0/10
Card is unsigned (most published agents are).
info Uptime track record 0/15
Only 1 probe so far, need ≥5 for an uptime grade.
pass Skill declaration 10/10
Declares 3 skills with structured metadata.
partial Verified Identity 5/10
Provider declared: SarnAI (https://sarnai.dev). Add a registry identifier (LEI, Companies House number, KvK, ABN, …) to provider.legalEntity for full verified-business credit.
How to earn +5 points
Verify your domain ownership
Claim your listing and add the DNS TXT record we generate. Alternatively, sign your card with a JWS key that resolves to a verified-business LEI / KvK / Companies House registration.
Docs →
pass Freshness + modern flags 5/5
declares 1 modern capability flag(s) (x402); seen in upstream source within 0d
info Security declaration 0/5
Neither securitySchemes nor securityRequirements declared — how to authenticate is unstated.
⚠ Card drift detected. This agent's agent-card.json changed within the last 7 days. We track these so downstream callers can react.

Activity (audit trail)

last 24h · 0 invocations Public aggregate · no PII recorded

Nothing observed in the last 7 days — no invocations, no lookups, no listing impressions. Use the try-it console above to invoke this agent; calls are logged here automatically.

Card history

2 snapshots drifted 1× Every change to agent-card.json
Captured Hash
2026-10-14 16:22:58 current 39aa04a8f053… view →
2026-10-14 16:00:53 cfd493444a8b… view →
Uptime
accumulating
1 direct probes · 30d
Response
208ms
last direct probe
Skills
3
declared
Streaming
—
SSE-capable

Endpoints

Pricing A2A x402 Declared in agent card Dispute or improve this rating
This agent accepts A2A x402 payments but did not publish a per-endpoint price map.
Try it ↗ Opens the operator's playground / docs in a new tab.
Settlement wallet: 0x42a3c399f83bccc3b9eef81e65954a715d54855e on Base · basescan ↗
Listed by facilitators Coinbase CDP · 1
Agent cardhttps://score.sarnai.dev/.well-known/agent-card.json
Providerhttps://sarnai.dev
Docshttps://score.sarnai.dev/score/sarnai-scoretest-1
Discovered via
cdp_discovery recrawl_paid

Skills · 3 declared · mapped to canonical taxonomy

Verify AI agent output against requirements

Independent verification of AI agent output before you pay. Structure, formats, ranges and cross-field rules, checked against your own requirements written in J…

orphan: no canonical match yet
json-schemaschema-validationjson-validationvalidate-jsonstructured-output
Agent Trust Score (v1)

Look up an agent_id's verification history: raw counts (verified, passed, failed, last seen) plus a recency-weighted score with a 95% confidence interval, signe…

orphan: no canonical match yet
json-schemaschema-validationjson-validationvalidate-jsonstructured-output
Check a deliverable before you accept or pay

Check AI agent output before you accept or pay for a deliverable: your JSON Schema plus rules like totals matching and unique IDs. Pass/fail, % of checks passed…

orphan: no canonical match yet
json-schemaschema-validationjson-validationvalidate-jsonstructured-output

Health · last 1 probes

When HTTP Live JSON-RPC Latency
2026-10-14 16:22:58 200 ✗ 208ms

Similar agents embedding-nearest

Agent Output Verifier by SarnAI
Independent verification of AI agent output before you pay. Independent, deterministic checks for invoices, deliverables and any structured
SarnAI · q 78%
AgentRank live
Settlement-grounded reputation for AI agents. Before you pay, hire, or trust a counterparty over x402, verify whether it is real and backed
Crest Deployment Systems LLC · q 85%
AgentRank
Settlement-grounded reputation for AI agents. Before you pay, hire, or trust a counterparty over x402, verify whether it is real and backed
Crest Deployment Systems LLC · q 100%
Api
Verified catalog reliability lookup: x402 endpoints for a task at or under a price, with our own paid receipts and known-answer pass/fail. $
api.402xagent.com · q 70%
SolSigs
Real-time Solana data APIs plus ProofGuard receipts for AI agents: 22 specialist workers paid per call in USDC via x402 - DEX prices, arbitr
solsigs.com · q 65%
Verify API & Agent Tools Suite
Multi-utility AI Agent suite: Claim Verification + Web-to-Markdown Reader + Live Search + JSON Extraction + Stealth Fetch + CAPTCHA Solving
verify.drain54.my.id · q 65%

Embed your Agenstry badge

Paste any of these into your README, agent card, or marketing page. Each badge auto-updates and links back to this page.

Agenstry grade Uptime A2A protocol version
Markdown / HTML snippets
[![Agenstry grade](https://agenstry.com/badge/score.sarnai.dev.svg)](https://agenstry.com/agents/score.sarnai.dev)
[![Verified Business](https://agenstry.com/badge/score.sarnai.dev/identity.svg)](https://agenstry.com/agents/score.sarnai.dev)
[![Uptime](https://agenstry.com/badge/score.sarnai.dev/uptime.svg)](https://agenstry.com/agents/score.sarnai.dev)
[![A2A version](https://agenstry.com/badge/score.sarnai.dev/protocol.svg)](https://agenstry.com/agents/score.sarnai.dev)

Audit-grade evidence bundle

JSON snapshot for vendor-review files. Add ?sign=true for a JWS-signed envelope verifiable against our JWKS. See the methodology.

audit.json audit.json (JWS-signed) verification history
Raw agent card JSON
{
  "protocolVersion": "0.3.0",
  "name": "Agent Output Verifier by SarnAI",
  "description": "Independent verification of AI agent output before you pay. Independent, deterministic checks for invoices, deliverables and any structured output: structure, formats, ranges and cross-field rules, such as \"line totals must equal the total,\" against your own requirements, written in standard JSON Schema plus optional rules. Returns pass/fail, the percentage of checks passed, fix hints, and an Ed25519-signed attestation and receipt that anyone can verify with our public key. Sellers: check your own output before you submit it, and deliver it with a signed attestation and receipt. No signup: pay per call with x402 v2, in USDC on Base or Solana. Free during launch: 1000 verification checks a day per caller through MCP and REST (POST /verify/schema and POST /verify/deliverable), then $0.02 USDC per call via x402. Agent Scores: $0.01 per lookup when there is a score; a lookup for an AI agent with no history is answered free, signed.",
  "checks": [
    "structure",
    "formats",
    "ranges",
    "cross_field_rules"
  ],
  "use_when": [
    "before_paying_for_agent_output",
    "before_submitting_own_output"
  ],
  "features": [
    "independent",
    "pass_fail",
    "percentage_of_checks_passed",
    "fix_hints",
    "ed25519_attestation",
    "signed_receipt",
    "output_hash_binding",
    "schema_hash",
    "rules_hash",
    "binding_rules"
  ],
  "example_rule": "sum(line_items[].line_total) == total",
  "exampleUrl": "https://github.com/sarnai-dev/agent-output-verifier#worked-example-invoice-verification",
  "tags": [
    "json-schema",
    "schema-validation",
    "json-validation",
    "validate-json",
    "structured-output",
    "output-validation",
    "data-validation",
    "llm-output-validation",
    "verification",
    "verify-output",
    "agent-output",
    "output-verification",
    "deliverable-check",
    "acceptance-check",
    "quality-check",
    "data-quality",
    "before-payment",
    "pay-after-verify",
    "evaluator",
    "settlement-check",
    "business-rules",
    "cross-field-validation",
    "consistency-check",
    "attestation",
    "signed-receipt",
    "evidence",
    "audit-trail",
    "independent",
    "invoice",
    "data-extraction",
    "lead-list",
    "api-response",
    "tool-output",
    "x402",
    "mcp",
    "a2a",
    "agent-to-agent",
    "agent-commerce",
    "erc-8183"
  ],
  "url": "https://verify.sarnai.dev",
  "provider": {
    "organization": "SarnAI",
    "url": "https://sarnai.dev"
  },
  "version": "0.5.5",
  "defaultInputModes": [
    "application/json"
  ],
  "defaultOutputModes": [
    "application/json"
  ],
  "capabilities": {
    "extensions": [
      {
        "uri": "https://github.com/google-a2a/a2a-x402/v0.1",
        "description": "Supports payments using the x402 protocol (v2 only) for on-chain settlement. See the resource entry below for pricing; live payment requirements are returned in the Payment-Required header of a 402 response. The extension's specification, readable: https://github.com/google-agentic-commerce/a2a-x402/blob/main/spec/v0.1/spec.md",
        "required": false,
        "params": {
          "resource": {
            "url": "https://verify.sarnai.dev/verify/schema",
            "method": "POST",
            "price": "$0.02",
            "currency": "USDC",
            "network": "eip155:8453",
            "payTo": "0x42a3c399f83BCcC3b9eEf81e65954a715D54855E",
            "paymentOptions": [
              {
                "chain": "Base",
                "network": "eip155:8453",
                "asset": "USDC",
                "assetAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                "payTo": "0x42a3c399f83BCcC3b9eEf81e65954a715D54855E"
              },
              {
                "chain": "Solana",
                "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
                "asset": "USDC",
                "assetAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
                "payTo": "38Fmaf3MWTR6AWPWrtrdXoqn6iqfVcUBHMFRhiUAEjFb"
              }
            ],
            "requestSchema": {
              "$defs": {
                "Bound": {
                  "description": "Optional inclusive min/max for one field. Numbers, or ISO-8601 date /\ndatetime strings (compared as datetimes; naive values are treated as UTC).",
                  "properties": {
                    "min": {
                      "anyOf": [
                        {
                          "type": "integer"
                        },
                        {
                          "type": "number"
                        },
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "default": null,
                      "title": "Min"
                    },
                    "max": {
                      "anyOf": [
                        {
                          "type": "integer"
                        },
                        {
                          "type": "number"
                        },
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "default": null,
                      "title": "Max"
                    },
                    "if_present": {
                      "default": false,
                      "description": "Optional. When true, the check is skipped where this field is absent (the whole path, or an element of an array it applies to) instead of being reported as unable to run: no flag, and enforce_rules does not fail on it. When false (default) an absent field is a flag, and a failure under enforce_rules.",
                      "title": "If Present",
                      "type": "boolean"
                    }
                  },
                  "title": "Bound",
                  "type": "object"
                },
                "ConsistencyRule": {
                  "description": "One caller-supplied cross-field rule. Paths use dotted keys with '[]'\nas an array wildcard, e.g. 'items[].price' or 'order.total'.\n\n  sum_equals: sum of `field` values == `equals_field` value (or `equals`)\n  gte / lte:  `field` >= / <= `other_field` value (or `value`)\n  exists_in:  every `field` value is among `in_field` values (or `values`)\n  unique:     no duplicates among `field` values; if `field` names an\n              array itself, no duplicate elements in it",
                  "properties": {
                    "type": {
                      "enum": [
                        "sum_equals",
                        "gte",
                        "lte",
                        "exists_in",
                        "unique"
                      ],
                      "title": "Type",
                      "type": "string"
                    },
                    "field": {
                      "title": "Field",
                      "type": "string"
                    },
                    "equals_field": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "default": null,
                      "title": "Equals Field"
                    },
                    "equals": {
                      "anyOf": [
                        {
                          "type": "integer"
                        },
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "default": null,
                      "title": "Equals"
                    },
                    "other_field": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "default": null,
                      "title": "Other Field"
                    },
                    "value": {
                      "anyOf": [
                        {
                          "type": "integer"
                        },
                        {
                          "type": "number"
                        },
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "default": null,
                      "title": "Value"
                    },
                    "in_field": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "default": null,
                      "title": "In Field"
                    },
                    "values": {
                      "anyOf": [
                        {
                          "items": {},
                          "type": "array"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "default": null,
                      "title": "Values"
                    },
                    "tolerance": {
                      "default": 1e-09,
                      "description": "Absolute tolerance for sum_equals and the near-match check gte/lte use. The default (1e-9) suits exact arithmetic but is usually too tight for money that passed through any floating-point math (e.g. percentage discounts, tax, unit-price * quantity): 0.1 + 0.2 != 0.3 in IEEE-754 floats by about 5.5e-17, and real pricing data regularly carries larger rounding drift than that. For a field in major currency units (dollars, euros), 0.01 (one cent) is a reasonable tolerance; for minor units (cents) already stored as integers, the default is fine. Too loose a tolerance can mask a genuine mismatch, so prefer the smallest value that tolerates your data's own rounding, not a large one 'to be safe.'",
                      "minimum": 0,
                      "title": "Tolerance",
                      "type": "number"
                    },
                    "if_present": {
                      "default": false,
                      "description": "Optional. When true, the check is skipped where this field is absent (the whole path, or an element of an array it applies to) instead of being reported as unable to run: no flag, and enforce_rules does not fail on it. When false (default) an absent field is a flag, and a failure under enforce_rules. Applies to this rule's own `field`; fields it refers to (equals_field, other_field, in_field) must still exist.",
                      "title": "If Present",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "type",
                    "field"
                  ],
                  "title": "ConsistencyRule",
                  "type": "object"
                }
              },
              "properties": {
                "task_id": {
                  "description": "Your own identifier for this verification. 1-200 printable characters, no control characters and no lone Unicode surrogate; a request outside that range is rejected (422), not truncated.",
                  "maxLength": 200,
                  "minLength": 1,
                  "pattern": "^[^\\x00-\\x1f\\x7f]+$",
                  "title": "Task Id",
                  "type": "string"
                },
                "expected_schema": {
                  "additionalProperties": true,
                  "title": "Expected Schema",
                  "type": "object"
                },
                "submitted_output": {
                  "title": "Submitted Output"
                },
                "agent_id": {
                  "anyOf": [
                    {
                      "maxLength": 200,
                      "minLength": 1,
                      "pattern": "^[^\\x00-\\x1f\\x7f]+$",
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "default": null,
                  "description": "Optional label identifying the AI agent that produced submitted_output (for example, the seller), used for /reputation and the trust score: records and scores belong to the producer, not to whoever calls this endpoint. It is an unauthenticated label. agent_ids starting with 'test-' are reserved for testing: the verification runs normally but is never recorded, so it cannot affect any reputation or trust score. 1-200 printable characters (same rule as GET /score/{agent_id}); a longer or malformed value is rejected (422), not truncated.",
                  "title": "Agent Id"
                },
                "strict_content_check": {
                  "default": false,
                  "description": "Opt-in. When true, any string in submitted_output containing control characters (e.g. null bytes) or embedded HTML/script markup makes the result 'fail'. When false (default) this is not checked at all.",
                  "title": "Strict Content Check",
                  "type": "boolean"
                },
                "bounds": {
                  "anyOf": [
                    {
                      "additionalProperties": {
                        "$ref": "#/$defs/Bound"
                      },
                      "maxProperties": 50,
                      "type": "object"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "default": null,
                  "description": "Optional per-field min/max, keyed by dotted path with '[]' array wildcard (e.g. 'items[].price'). Numbers or ISO-8601 dates. Violations are reported as informational flags unless enforce_rules is true.",
                  "title": "Bounds"
                },
                "rules": {
                  "anyOf": [
                    {
                      "items": {
                        "$ref": "#/$defs/ConsistencyRule"
                      },
                      "maxItems": 50,
                      "type": "array"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "default": null,
                  "description": "Optional cross-field rules: sum_equals, gte, lte, exists_in, unique (duplicate detection). Violations are reported as informational flags unless enforce_rules is true.",
                  "title": "Rules"
                },
                "enforce_rules": {
                  "default": false,
                  "description": "Opt-in. When true, every configured bound and consistency rule must hold, or the result is 'fail' (like strict_content_check), with an 'enforce_rules: ...' entry in errors. That includes a rule or bound that cannot run (its path is missing, a value is not comparable, a value has nothing to be compared against): it fails rather than passing silently, so omitting a field, in the whole path or in any array element the rule applies to, cannot skip a binding rule. A rule or bound with if_present: true is skipped where its field is absent instead. When false (default) nothing changes: violations and unrunnable rules stay informational flags. Echoed back in the signed response.",
                  "title": "Enforce Rules",
                  "type": "boolean"
                },
                "detail": {
                  "default": "full",
                  "description": "'full' (default) returns everything; 'compact' returns only the summary, next actions, receipt and signature. Use compact inside verify-repair loops to save tokens. 'compact' fields: summary, next_actions, result, the receipt fields (verification_id, task_id, agent_id, output_hash, schema_hash, rules_hash, verified_at, verifier_version, enforce_rules, strict_content_check), verify and attestation - errors, errors_detail, flags, hints and the scores are left out entirely, not just emptied. Both shapes are fully signed.",
                  "enum": [
                    "full",
                    "compact"
                  ],
                  "title": "Detail",
                  "type": "string"
                }
              },
              "required": [
                "task_id",
                "expected_schema",
                "submitted_output"
              ],
              "title": "VerifySchemaRequest",
              "type": "object"
            },
            "responseSchema": {
              "$defs": {
                "Attestation": {
                  "properties": {
                    "algorithm": {
                      "const": "Ed25519",
                      "title": "Algorithm",
                      "type": "string"
                    },
                    "key_version": {
                      "title": "Key Version",
                      "type": "string"
                    },
                    "timestamp": {
                      "title": "Timestamp",
                      "type": "string"
                    },
                    "signature": {
                      "title": "Signature",
                      "type": "string"
                    }
                  },
                  "required": [
                    "algorithm",
                    "key_version",
                    "timestamp",
                    "signature"
                  ],
                  "title": "Attestation",
                  "type": "object"
                },
                "ErrorDetail": {
                  "description": "The structured form of one entry in `errors`, at the same index, so a caller can act\non a violation without parsing its text (verifier_version 0.4.0). Same shape as the\nmatching `Hint` (check, path, expected, found), plus the original text for compatibility.\nOnly the first errors_detail_total entries get one, same cap as hints (MAX_DETAILS /\nMAX_STRICT_ERRORS below) - a formatted string is far cheaper to keep than a structured\none; see errors_detail_total / errors_detail_omitted.",
                  "properties": {
                    "check": {
                      "description": "Same meaning as Hint.check.",
                      "title": "Check",
                      "type": "string"
                    },
                    "path": {
                      "description": "Same meaning as Hint.path.",
                      "title": "Path",
                      "type": "string"
                    },
                    "expected": {
                      "description": "Same meaning as Hint.expected.",
                      "title": "Expected",
                      "type": "string"
                    },
                    "found": {
                      "description": "Same meaning as Hint.found.",
                      "title": "Found",
                      "type": "string"
                    },
                    "message": {
                      "description": "The matching entry in `errors`, verbatim.",
                      "title": "Message",
                      "type": "string"
                    }
                  },
                  "required": [
                    "check",
                    "path",
                    "expected",
                    "found",
                    "message"
                  ],
                  "title": "ErrorDetail",
                  "type": "object"
                },
                "Flag": {
                  "properties": {
                    "check": {
                      "title": "Check",
                      "type": "string"
                    },
                    "field": {
                      "title": "Field",
                      "type": "string"
                    },
                    "severity": {
                      "default": "info",
                      "description": "'error' when enforce_rules made this specific bound/rule finding fail the result (see VerifySchemaRequest.enforce_rules); 'info' otherwise. Never affects `result` itself - `result` is decided by `errors`, of which this finding is then also a member.",
                      "enum": [
                        "info",
                        "error"
                      ],
                      "title": "Severity",
                      "type": "string"
                    },
                    "detail": {
                      "title": "Detail",
                      "type": "string"
                    }
                  },
                  "required": [
                    "check",
                    "field",
                    "detail"
                  ],
                  "title": "Flag",
                  "type": "object"
                },
                "Hint": {
                  "properties": {
                    "source": {
                      "description": "'schema': a JSON Schema validation failure (one per entry in `errors`, same order). 'integrity': a strict-content failure or an informational flag.",
                      "enum": [
                        "schema",
                        "integrity"
                      ],
                      "title": "Source",
                      "type": "string"
                    },
                    "check": {
                      "description": "The JSON Schema keyword that failed (type, required, minimum, ...), or the integrity check (strict_content_check, placeholder_content, truncation, bounds, consistency:*, unhashable_input).",
                      "title": "Check",
                      "type": "string"
                    },
                    "path": {
                      "description": "Where, as a JSON path: '$.items[3].price'. For a missing required property, the path where it should be. Integrity hints use the flag's own field notation with a '$.' prefix.",
                      "title": "Path",
                      "type": "string"
                    },
                    "expected": {
                      "description": "What the check wanted at that path, from a fixed template (e.g. 'number').",
                      "title": "Expected",
                      "type": "string"
                    },
                    "found": {
                      "description": "What was there instead, from a fixed template (e.g. 'string', 'missing', '-1'). Long values are shortened; whole values are never echoed.",
                      "title": "Found",
                      "type": "string"
                    }
                  },
                  "required": [
                    "source",
                    "check",
                    "path",
                    "expected",
                    "found"
                  ],
                  "title": "Hint",
                  "type": "object"
                },
                "SubScore": {
                  "properties": {
                    "ratio": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "passed / total, a raw float in [0, 1]; null when total is 0 (nothing was checked). Informational only: never affects `result`.",
                      "title": "Ratio"
                    },
                    "passed": {
                      "title": "Passed",
                      "type": "integer"
                    },
                    "total": {
                      "title": "Total",
                      "type": "integer"
                    }
                  },
                  "required": [
                    "ratio",
                    "passed",
                    "total"
                  ],
                  "title": "SubScore",
                  "type": "object"
                },
                "Summary": {
                  "description": "Compact digest of the verdict, for a caller that wants the headline without reading\n`errors`/`flags` (verifier_version 0.4.0).",
                  "properties": {
                    "result": {
                      "description": "Same value as the top-level `result`.",
                      "enum": [
                        "pass",
                        "fail"
                      ],
                      "title": "Result",
                      "type": "string"
                    },
                    "blocking_checks": {
                      "description": "Distinct check codes that caused 'fail' (the same codes used in `errors_detail[].check`, `flags[].check` and `hints[].check`), in first-seen order; empty on 'pass'.",
                      "items": {
                        "type": "string"
                      },
                      "title": "Blocking Checks",
                      "type": "array"
                    }
                  },
                  "required": [
                    "result",
                    "blocking_checks"
                  ],
                  "title": "Summary",
                  "type": "object"
                },
                "VerifySection": {
                  "description": "Compact, self-describing block every signed attestation and receipt carries (2026-09-30,\nverifier_version 0.4.0) - inside the signature, alongside `attestation` itself - so a\nverifier needs nothing but this response and the URL below, not a separate lookup or\nprior knowledge of this service's conventions.",
                  "properties": {
                    "public_key_url": {
                      "description": "Agent-card URL listing the public key for key_version below, and every key this service has ever signed with.",
                      "title": "Public Key Url",
                      "type": "string"
                    },
                    "key_version": {
                      "description": "Matches attestation.key_version.",
                      "title": "Key Version",
                      "type": "string"
                    },
                    "canonicalization": {
                      "description": "How every hash below, and the signed bytes themselves, are computed.",
                      "title": "Canonicalization",
                      "type": "string"
                    },
                    "hash_algorithm": {
                      "description": "Algorithm behind every *_hash field in this response.",
                      "title": "Hash Algorithm",
                      "type": "string"
                    },
                    "service": {
                      "description": "This service's name.",
                      "title": "Service",
                      "type": "string"
                    },
                    "mcp": {
                      "description": "This service's MCP (Model Context Protocol) endpoint.",
                      "title": "Mcp",
                      "type": "string"
                    }
                  },
                  "required": [
                    "public_key_url",
                    "key_version",
                    "canonicalization",
                    "hash_algorithm",
                    "service",
                    "mcp"
                  ],
                  "title": "VerifySection",
                  "type": "object"
                }
              },
              "properties": {
                "summary": {
                  "$ref": "#/$defs/Summary",
                  "description": "Compact digest of the verdict: the same `result`, and `blocking_checks` (the distinct check codes that caused a 'fail', empty on 'pass') - for a caller that wants the headline without reading `errors`/`flags`."
                },
                "next_actions": {
                  "description": "What to do next, machine-readable. On 'fail': [{\"action\": \"repair_and_reverify\", \"using\": \"hints\"}]. On 'pass': [{\"action\": \"attach_receipt\", \"for\": \"seller\"}, {\"action\": \"proceed_to_payment\", \"for\": \"buyer\"}]. A plain list of string-keyed objects (not a stricter per-action model): the two shapes share only `action`, and a `for` field could not be a Python attribute name without an alias that REST and MCP risk serializing differently.",
                  "items": {
                    "additionalProperties": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "title": "Next Actions",
                  "type": "array"
                },
                "result": {
                  "enum": [
                    "pass",
                    "fail"
                  ],
                  "title": "Result",
                  "type": "string"
                },
                "verification_id": {
                  "description": "Unique UUID (v4) for this verification. Part of the signed attestation and receipt.",
                  "title": "Verification Id",
                  "type": "string"
                },
                "task_id": {
                  "title": "Task Id",
                  "type": "string"
                },
                "agent_id": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Echo of the agent_id label supplied in the request; null if none. Identifies the AI agent that produced submitted_output (for example, the seller): this attestation and receipt, and any reputation or trust score it feeds, belongs to that producer. It is an unauthenticated label chosen by the caller, not a proven identity, and not the identity of whoever called this endpoint.",
                  "title": "Agent Id"
                },
                "output_hash": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "SHA-256 (64 lowercase hex chars = 32 bytes; add 0x to use it as a bytes32) of the JCS canonical JSON of submitted_output, the data that was verified. Key order and whitespace in what you sent do not change it. null only if it has no JCS form (NaN/Infinity, a lone surrogate).",
                  "title": "Output Hash"
                },
                "schema_hash": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "SHA-256 (64 lowercase hex chars) of the JCS canonical JSON of expected_schema. null only if it has no JCS form.",
                  "title": "Schema Hash"
                },
                "rules_hash": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "SHA-256 (64 lowercase hex chars) of the RFC 8785 (JCS) canonical JSON of {\"bounds\": <the bounds you supplied or null>, \"rules\": <the rules you supplied or null>}, containing exactly the fields you supplied (fields left at their defaults are not included), so you can hash your own rules JSON in that shape and compare. It lets a buyer confirm which rules were applied. null when no bounds or rules were supplied (or they contain NaN/Infinity).",
                  "title": "Rules Hash"
                },
                "request_hash": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "SHA-256 (64 lowercase hex chars, no 0x prefix) of the RFC 8785 (JCS) canonical JSON of the request as parsed: task_id, agent_id, expected_schema, submitted_output, strict_content_check, bounds, rules, enforce_rules, with defaults filled in (agent_id/bounds/rules null, strict_content_check and enforce_rules false). Inside bounds and rules, every PER-RULE field is also filled to its own default, not just the ones you supplied: an omitted consistency-rule field hashes as equals_field/equals/other_field/value/in_field/values: null, tolerance: 1e-9, if_present: false, and an omitted bound field hashes as if_present: false - so two requests whose rules/bounds differ only by which optional fields were typed out still hash identically here. This is the opposite convention from rules_hash (below), which hashes exactly and only the fields you supplied, with nothing defaulted in - hash your own rules JSON in rules_hash's documented shape if you need to confirm which rules were applied without re-deriving every default. null only if the request contains data with no JCS form (NaN/Infinity, a lone surrogate). Not part of the 'compact' detail level.",
                  "title": "Request Hash"
                },
                "verified_at": {
                  "description": "ISO-8601 UTC time this service ran the verification. Identical to attestation.timestamp (the same value, read once); this service's own clock, not an externally verified time.",
                  "title": "Verified At",
                  "type": "string"
                },
                "verifier_version": {
                  "title": "Verifier Version",
                  "type": "string"
                },
                "enforce_rules": {
                  "description": "Whether the request had enforce_rules on: true means every rule and bound had to hold (violations and unrunnable rules fail the result); false means they were only flags.",
                  "title": "Enforce Rules",
                  "type": "boolean"
                },
                "strict_content_check": {
                  "description": "Whether the request had strict_content_check on: true means control characters and embedded HTML/script markup in submitted_output failed the result; false means that check did not run.",
                  "title": "Strict Content Check",
                  "type": "boolean"
                },
                "errors": {
                  "description": "Every violation (schema, then strict-content, then enforce_rules), capped at the first 100 schema-validation errors; see errors_total / errors_omitted. Non-schema errors (strict-content, enforce_rules) are never capped. Not part of the 'compact' detail level.",
                  "items": {
                    "type": "string"
                  },
                  "title": "Errors",
                  "type": "array"
                },
                "errors_total": {
                  "description": "How many errors exist in total. Equal to len(errors) unless the 100-error schema cap above was hit.",
                  "title": "Errors Total",
                  "type": "integer"
                },
                "errors_omitted": {
                  "description": "errors_total minus len(errors); 0 when nothing was cut off.",
                  "title": "Errors Omitted",
                  "type": "integer"
                },
                "errors_detail": {
                  "description": "The structured form of the leading entries in `errors`, same order, so a caller can act (check, path, expected, found) without parsing text; `errors` itself is unchanged, for compatibility. See errors_detail_total / errors_detail_omitted for how many entries in `errors` this covers.",
                  "items": {
                    "$ref": "#/$defs/ErrorDetail"
                  },
                  "title": "Errors Detail",
                  "type": "array"
                },
                "errors_detail_total": {
                  "description": "How many entries in `errors` have a structured form available. Same cap as `hints` (a structured form costs more to build than the text alone).",
                  "title": "Errors Detail Total",
                  "type": "integer"
                },
                "errors_detail_omitted": {
                  "description": "errors_total minus errors_detail_total; 0 when every error has a structured form.",
                  "title": "Errors Detail Omitted",
                  "type": "integer"
                },
                "flags": {
                  "description": "Integrity findings (placeholder text, possible truncation, bounds and consistency-rule violations). severity is 'error' for a finding that enforce_rules made fail the result, 'info' otherwise; either way, a flag never itself changes 'result' - it is `errors` that does. Not part of the 'compact' detail level.",
                  "items": {
                    "$ref": "#/$defs/Flag"
                  },
                  "title": "Flags",
                  "type": "array"
                },
                "flags_total": {
                  "description": "How many flags exist in total (flags holds at most the first 100, plus a flags_truncated marker when there are more), counting an unhashable_input flag if present.",
                  "title": "Flags Total",
                  "type": "integer"
                },
                "flags_omitted": {
                  "description": "Integrity flags beyond the 100 returned; 0 when nothing was cut off.",
                  "title": "Flags Omitted",
                  "type": "integer"
                },
                "hints": {
                  "description": "Machine-actionable, template-based fix hints: one per schema validation failure (first, in the same order as `errors`), then per strict-content failure and integrity flag. At most 20; see hints_total / hints_omitted. Where, what was expected, what was found. Never a guessed corrected value. Not part of the 'compact' detail level.",
                  "items": {
                    "$ref": "#/$defs/Hint"
                  },
                  "title": "Hints",
                  "type": "array"
                },
                "hints_total": {
                  "description": "How many hints exist in total (hints holds at most the first 20).",
                  "title": "Hints Total",
                  "type": "integer"
                },
                "hints_omitted": {
                  "description": "hints_total minus len(hints).",
                  "title": "Hints Omitted",
                  "type": "integer"
                },
                "schema_compliance": {
                  "$ref": "#/$defs/SubScore",
                  "description": "JSON Schema assertions that passed out of those evaluated (each keyword such as type/required/minimum, at each place it applies; anyOf/oneOf/not/if count once, applicators like properties and items are not counted themselves). A separate figure from integrity_checks: the two ratios are never averaged (see `overall` for the pooled count). Informational: `result` is decided by errors, not by this. Not part of the 'compact' detail level."
                },
                "integrity_checks": {
                  "$ref": "#/$defs/SubScore",
                  "description": "Integrity checks that passed out of those evaluated (per string: placeholder and truncation, plus strict content when enabled; per schema-described object: completeness; per configured bound and consistency-rule comparison). Informational: only strict_content_check failures (and enforce_rules violations, if enabled) can change `result`. Not part of the 'compact' detail level."
                },
                "overall": {
                  "$ref": "#/$defs/SubScore",
                  "description": "A pooled count across both groups: (schema_compliance.passed + integrity_checks.passed) / (schema_compliance.total + integrity_checks.total), with those two sums as passed and total. It is NOT an average of the two ratios (the larger group weighs more), and it says nothing about whether the content is right. null ratio when the total is 0. Informational only: never changes `result`. Not part of the 'compact' detail level."
                },
                "verify": {
                  "$ref": "#/$defs/VerifySection",
                  "description": "How to verify this attestation and receipt without any other lookup than this response and public_key_url: canonicalization and hash algorithm behind every hash and the signature itself, this service's name, and its MCP endpoint."
                },
                "attestation": {
                  "$ref": "#/$defs/Attestation",
                  "description": "Ed25519 signature over this response (every field above, including the receipt fields) plus the timestamp and key_version. The timestamp is this service's own clock, not an externally verified one. Public key and verification steps: /.well-known/agent-card.json, capabilities.extensions (attestation entry)."
                }
              },
              "required": [
                "summary",
                "next_actions",
                "result",
                "verification_id",
                "task_id",
                "agent_id",
                "output_hash",
                "schema_hash",
                "rules_hash",
                "request_hash",
                "verified_at",
                "verifier_version",
                "enforce_rules",
                "strict_content_check",
                "errors",
                "errors_total",
                "errors_omitted",
                "errors_detail_total",
                "errors_detail_omitted",
                "flags_total",
                "flags_omitted",
                "hints",
                "hints_total",
                "hints_omitted",
                "schema_compliance",
                "integrity_checks",
                "overall",
                "verify",
                "attestation"
              ],
              "title": "VerifySchemaResponse",
              "type": "object"
            }
          },
          "additionalResources": [
            {
              "url": "https://verify.sarnai.dev/verify/deliverable",
              "method": "POST",
              "description": "Check AI agent output before you accept or pay for a deliverable: your JSON Schema plus rules like totals matching and unique IDs. Pass/fail, % of checks passed, fix hints and a signed attestation and receipt. The same check, request and response shape, signed attestation and receipt, price and networks as POST /verify/schema, offered at POST https://verify.sarnai.dev/verify/deliverable. Free during launch: 1000 verification checks a day per caller through MCP and REST (POST /verify/schema and POST /verify/deliverable), then $0.02 USDC per call via x402.",
              "price": "$0.02",
              "currency": "USDC",
              "network": "eip155:8453",
              "payTo": "0x42a3c399f83BCcC3b9eEf81e65954a715D54855E",
              "paymentOptions": [
                {
                  "chain": "Base",
                  "network": "eip155:8453",
                  "asset": "USDC",
                  "assetAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                  "payTo": "0x42a3c399f83BCcC3b9eEf81e65954a715D54855E"
                },
                {
                  "chain": "Solana",
                  "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
                  "asset": "USDC",
                  "assetAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
                  "payTo": "38Fmaf3MWTR6AWPWrtrdXoqn6iqfVcUBHMFRhiUAEjFb"
                }
              ],
              "sameRequestAndResponseSchemaAs": "https://verify.sarnai.dev/verify/schema"
            }
          ]
        }
      },
      {
        "uri": "urn:json-schema-verifier:extension:attestation:v1",
        "description": "Every /verify/schema response carries an Ed25519 signature over the full response, the service-reported verification time, and the key version. Everything needed to verify it is in this entry.",
        "required": false,
        "params": {
          "algorithm": "Ed25519",
          "currentKeyVersion": "v1-2026-09c",
          "publicKeys": [
            {
              "keyVersion": "v1-2026-09c",
              "algorithm": "Ed25519",
              "publicKey": "d2IHH0/Xduci/5J8IewYmauUvgqf+gFIeCEXDwjHUhw=",
              "publicKeyEncoding": "base64 of the raw 32-byte Ed25519 public key"
            }
          ],
          "responseField": "attestation",
          "diagnosticFields": {
            "description": "POST /verify/schema responses also carry, inside the same signed response: hints (at most 20 template-based fix hints, each {source, check, path, expected, found}; hints_total and hints_omitted count the rest), flags_total and flags_omitted (how many flags exist, and how many the 100-flag cap cut off), and two separate informational sub-scores, schema_compliance and integrity_checks, and a pooled overall, each {ratio, passed, total}. overall is (passed of both groups) / (total of both groups), not an average of the two ratios. None of them changes `result`; only schema errors, the opt-in strict content check and the opt-in enforce_rules can.",
            "fields": [
              "hints",
              "hints_total",
              "hints_omitted",
              "flags_total",
              "flags_omitted",
              "schema_compliance",
              "integrity_checks",
              "overall"
            ]
          },
          "receiptFields": {
            "description": "POST /verify/schema responses also carry receipt fields, inside the signed response: verification_id (UUID v4, unique per verification), agent_id (identifies the AI agent that produced the output, for example the seller; an echo of the unauthenticated label you supplied, or null), enforce_rules and strict_content_check (whether each opt-in check was on), and four SHA-256 hashes (64 lowercase hex chars, no 0x prefix) over RFC 8785 (JCS) canonical JSON: output_hash (of submitted_output, usable as a 32-byte deliverable hash), schema_hash (of expected_schema), rules_hash (of the bounds and rules you supplied, in the shape {bounds, rules}; null if none, so a buyer can confirm which rules were applied), and request_hash (of the whole request as parsed, defaults filled in). A hash is null only for data with no JCS form (NaN/Infinity, lone surrogates) or, for rules_hash, when there are no rules. Integers beyond +/-(2^53-1) keep their exact digits rather than rounding to a double. Receipts issued before these fields existed have none and still verify.",
            "fields": [
              "verification_id",
              "request_hash",
              "output_hash",
              "schema_hash",
              "rules_hash",
              "enforce_rules",
              "strict_content_check",
              "agent_id"
            ]
          },
          "requestHashTestVectors": {
            "description": "Test vectors for request_hash, so anyone can reproduce it. Each entry gives a raw request body, the exact canonical (RFC 8785) JSON whose UTF-8 bytes are hashed, and requestHash, the SHA-256 (lowercase hex) of those bytes. The canonical form is the request as parsed, with every default filled in: agent_id, bounds and rules null; strict_content_check and enforce_rules false; and inside bounds and rules every per-bound and per-rule field you left out (equals_field, equals, other_field, value, in_field, values null; tolerance 1e-9; if_present false). detail is not part of it. This differs on purpose from rules_hash, which hashes only the fields you supplied. POSTing the request to /verify/schema or /verify/deliverable returns the same request_hash (in the default detail level; compact responses omit it). The README (\"Test vectors for request_hash\", after Receipt fields) has a standard-library Python reference implementation.",
            "vectors": [
              {
                "name": "minimal",
                "description": "No rules or bounds: every optional field takes its default.",
                "request": {
                  "task_id": "tv-1",
                  "expected_schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      }
                    }
                  },
                  "submitted_output": {
                    "ok": true
                  }
                },
                "canonical": "{\"agent_id\":null,\"bounds\":null,\"enforce_rules\":false,\"expected_schema\":{\"properties\":{\"ok\":{\"type\":\"boolean\"}},\"required\":[\"ok\"],\"type\":\"object\"},\"rules\":null,\"strict_content_check\":false,\"submitted_output\":{\"ok\":true},\"task_id\":\"tv-1\"}",
                "requestHash": "5366542000b4226c5efb411c15ec8f0aac3c63844343997aa1bcc3c585086f97"
              },
              {
                "name": "rules-and-bounds",
                "description": "A bound and two rules with enforce_rules on: each per-rule and per-bound field you left out is filled to its default (tolerance 1e-9, if_present false, the unused references null), and JCS prints 10.0 as 10.",
                "request": {
                  "task_id": "tv-2",
                  "agent_id": "seller-7",
                  "expected_schema": {
                    "type": "object",
                    "required": [
                      "items",
                      "total"
                    ],
                    "properties": {
                      "items": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "required": [
                            "id",
                            "price"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "price": {
                              "type": "number"
                            }
                          }
                        }
                      },
                      "total": {
                        "type": "number"
                      }
                    }
                  },
                  "submitted_output": {
                    "total": 30.5,
                    "items": [
                      {
                        "id": "a",
                        "price": 10.0
                      },
                      {
                        "id": "b",
                        "price": 20.5
                      }
                    ]
                  },
                  "bounds": {
                    "items[].price": {
                      "min": 0,
                      "max": 100
                    }
                  },
                  "rules": [
                    {
                      "type": "sum_equals",
                      "field": "items[].price",
                      "equals_field": "total",
                      "tolerance": 0.01
                    },
                    {
                      "type": "unique",
                      "field": "items[].id"
                    }
                  ],
                  "enforce_rules": true
                },
                "canonical": "{\"agent_id\":\"seller-7\",\"bounds\":{\"items[].price\":{\"if_present\":false,\"max\":100,\"min\":0}},\"enforce_rules\":true,\"expected_schema\":{\"properties\":{\"items\":{\"items\":{\"properties\":{\"id\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"}},\"required\":[\"id\",\"price\"],\"type\":\"object\"},\"type\":\"array\"},\"total\":{\"type\":\"number\"}},\"required\":[\"items\",\"total\"],\"type\":\"object\"},\"rules\":[{\"equals\":null,\"equals_field\":\"total\",\"field\":\"items[].price\",\"if_present\":false,\"in_field\":null,\"other_field\":null,\"tolerance\":0.01,\"type\":\"sum_equals\",\"value\":null,\"values\":null},{\"equals\":null,\"equals_field\":null,\"field\":\"items[].id\",\"if_present\":false,\"in_field\":null,\"other_field\":null,\"tolerance\":1e-9,\"type\":\"unique\",\"value\":null,\"values\":null}],\"strict_content_check\":false,\"submitted_output\":{\"items\":[{\"id\":\"a\",\"price\":10},{\"id\":\"b\",\"price\":20.5}],\"total\":30.5},\"task_id\":\"tv-2\"}",
                "requestHash": "1aa064d21a2c1487d5d319ded6efec48c18dfee45b93f741266b1f491c2e099f"
              },
              {
                "name": "strict-and-unicode",
                "description": "strict_content_check on, a rule with if_present, non-ASCII text kept as literal UTF-8, and the JCS number forms 1.0 -> 1, 1e21 -> 1e+21, 0.000001 -> 0.000001.",
                "request": {
                  "task_id": "tv-3",
                  "expected_schema": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "n": {
                        "type": "number"
                      }
                    }
                  },
                  "submitted_output": {
                    "n": 1.0,
                    "name": "caf\u00e9 \u2713",
                    "z": [
                      1e+21,
                      1e-06
                    ]
                  },
                  "strict_content_check": true,
                  "rules": [
                    {
                      "type": "gte",
                      "field": "n",
                      "value": 0,
                      "if_present": true
                    }
                  ]
                },
                "canonical": "{\"agent_id\":null,\"bounds\":null,\"enforce_rules\":false,\"expected_schema\":{\"properties\":{\"n\":{\"type\":\"number\"},\"name\":{\"type\":\"string\"}},\"type\":\"object\"},\"rules\":[{\"equals\":null,\"equals_field\":null,\"field\":\"n\",\"if_present\":true,\"in_field\":null,\"other_field\":null,\"tolerance\":1e-9,\"type\":\"gte\",\"value\":0,\"values\":null}],\"strict_content_check\":true,\"submitted_output\":{\"n\":1,\"name\":\"caf\u00e9 \u2713\",\"z\":[1e+21,0.000001]},\"task_id\":\"tv-3\"}",
                "requestHash": "037abd3fe4643c14e68d9fd57ca93b460c177c5372f058aa2920a2ef120c0432"
              }
            ]
          },
          "signedMessage": {
            "canonicalization": "RFC 8785 (JCS): UTF-8 bytes of the JSON document below, object keys sorted, no insignificant whitespace, non-ASCII kept as literal UTF-8, numbers printed as ECMAScript prints them (1.0 is '1').",
            "contexts": {
              "POST /verify/schema": "json-schema-verifier/verify-schema-attestation/v1",
              "POST /verify/deliverable": "json-schema-verifier/verify-schema-attestation/v1",
              "GET /score/{agent_id}": "json-schema-verifier/trust-score-attestation/v1"
            },
            "document": {
              "context": "<the context above that matches the endpoint that produced the response>",
              "algorithm": "<response.attestation.algorithm, must be Ed25519>",
              "key_version": "<response.attestation.key_version>",
              "attested_at": "<response.attestation.timestamp>",
              "response": "<the response body without its 'attestation' field>"
            },
            "signature": "base64 of the 64-byte Ed25519 signature, response.attestation.signature",
            "strictness": "Reject the attestation if response.attestation does not have exactly the keys algorithm, key_version, timestamp, signature.",
            "publicKeySelection": "Use the publicKeys entry whose keyVersion equals response.attestation.key_version."
          },
          "timestampSemantics": "attested_at equals the response's verified_at: this service's own clock when the check ran. It is self-reported, not verified by any external timestamping authority."
        }
      },
      {
        "uri": "urn:json-schema-verifier:extension:mcp:v1",
        "description": "Independent verification of AI agent output before you pay. The same two operations over Model Context Protocol (Streamable HTTP): verify_schema (POST /verify/schema) and get_verification_record (GET /score/{agent_id}). Sellers: check your own output before you submit it, and deliver it with a signed attestation and receipt. verify_schema checks structure and integrity against your schema and rules. get_verification_record reports a statistical signal from /verify/schema history; agent_id is an unauthenticated label (identity_verified is false). Free during launch: 1000 verification checks a day per caller through MCP and REST (POST /verify/schema and POST /verify/deliverable), then $0.02 USDC per call via x402. Agent Scores: $0.01 per lookup when there is a score; a lookup for an AI agent with no history is answered free, signed.",
        "required": false,
        "params": {
          "transport": "streamable-http",
          "url": "https://verify.sarnai.dev/mcp",
          "deprecated": "toolName and access below are a deprecated alias for the verify_schema entry in tools[]; read tools[] instead.",
          "toolName": "verify_schema",
          "access": {
            "freeTrial": {
              "callsPerClientPerDay": 1000,
              "maxInputBytes": 32768,
              "freeDuringLaunch": true,
              "alsoOnRest": true
            },
            "afterFreeTrial": "x402 payment, $0.02 USDC per call, in USDC on Base (eip155:8453) or Solana (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) (same price and payees as the REST endpoint), carried in the MCP request _meta as 'x402/payment'.",
            "errorsAreNotCharged": true
          },
          "tools": [
            {
              "toolName": "verify_schema",
              "restEquivalent": "POST /verify/schema",
              "access": {
                "freeTrial": {
                  "callsPerClientPerDay": 1000,
                  "maxInputBytes": 32768,
                  "freeDuringLaunch": true,
                  "alsoOnRest": true
                },
                "afterFreeTrial": "x402 payment, $0.02 USDC per call, in USDC on Base (eip155:8453) or Solana (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) (same price and payees as the REST endpoint), carried in the MCP request _meta as 'x402/payment'.",
                "errorsAreNotCharged": true
              }
            },
            {
              "toolName": "get_verification_record",
              "restEquivalent": "GET /score/{agent_id}",
              "access": {
                "freeTrial": {
                  "callsPerClientPerDay": 0,
                  "maxInputBytes": 32768,
                  "paidOnly": true
                },
                "afterFreeTrial": "x402 payment, $0.01 USDC per lookup when there is a score, in USDC on Base (eip155:8453) or Solana (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) (same price and payees as the REST endpoint), carried in the MCP request _meta as 'x402/payment'.",
                "errorsAreNotCharged": true
              }
            }
          ]
        }
      }
    ]
  },
  "skills": [
    {
      "id": "verify-schema",
      "name": "Verify AI agent output against requirements",
      "description": "Independent verification of AI agent output before you pay. Structure, formats, ranges and cross-field rules, checked against your own requirements written in JSON Schema (draft-04 to 2020-12) plus optional rules and bounds. Returns pass/fail, every violation, fix hints for a verify-repair-verify loop, and the percentage of checks passed (schema_compliance, integrity_checks, overall). Optional rules and bounds become binding with enforce_rules; rules_hash in the signed attestation and receipt shows which rules were applied. Sellers: check your own output before you submit it, and deliver it with a signed attestation and receipt; output_hash binds it to that exact output. Never modifies the submitted data. $0.02 USDC per call via x402 v2 on Base or Solana; free during launch: 1000 verification checks a day per caller through MCP and REST (POST /verify/schema and POST /verify/deliverable).",
      "tags": [
        "json-schema",
        "schema-validation",
        "json-validation",
        "validate-json",
        "structured-output",
        "output-validation",
        "data-validation",
        "llm-output-validation",
        "verification",
        "verify-output",
        "agent-output",
        "output-verification",
        "deliverable-check",
        "acceptance-check",
        "quality-check",
        "data-quality",
        "before-payment",
        "pay-after-verify",
        "evaluator",
        "settlement-check",
        "business-rules",
        "cross-field-validation",
        "consistency-check",
        "attestation",
        "signed-receipt",
        "evidence",
        "audit-trail",
        "independent",
        "invoice",
        "data-extraction",
        "lead-list",
        "api-response",
        "tool-output",
        "x402",
        "mcp",
        "a2a",
        "agent-to-agent",
        "agent-commerce",
        "erc-8183"
      ],
      "examples": [
        "Buyers: validate that this AI agent's tool-call output matches the expected output schema before I pay for or accept it.",
        "Sellers: check my own output against the agreed schema before I submit it, and attach the signed attestation and receipt as evidence of verification.",
        "Check a generated JSON document or API response against a required schema before using it downstream.",
        "Verify a payload exchanged between two AI agents conforms to their agreed data contract.",
        "Confirm a configuration object satisfies its schema before applying it."
      ],
      "inputModes": [
        "application/json"
      ],
      "outputModes": [
        "application/json"
      ]
    },
    {
      "id": "trust-score",
      "name": "Agent Trust Score (v1)",
      "description": "Look up an agent_id's verification history: raw counts (verified, passed, failed, last seen) plus a recency-weighted score with a 95% confidence interval, signed. Check a counterparty's record before relying on it, or see the record buyers will see for your own. Covers /verify/schema results only. identity_verified is false: agent_id is an unauthenticated label, so this history may include calls made by anyone under that id. A statistical signal from past verification activity. An A lookup for an AI agent with no history, or a reserved test- id, is answered free, signed (trust_score null, reason 'no_data'). $0.01 USDC per call via x402 v2 on Base or Solana; paid when there is a score. Endpoint: GET https://score.sarnai.dev/score/{agent_id}.",
      "tags": [
        "json-schema",
        "schema-validation",
        "json-validation",
        "validate-json",
        "structured-output",
        "output-validation",
        "data-validation",
        "llm-output-validation",
        "verification",
        "verify-output",
        "agent-output",
        "output-verification",
        "deliverable-check",
        "acceptance-check",
        "quality-check",
        "data-quality",
        "before-payment",
        "pay-after-verify",
        "evaluator",
        "settlement-check",
        "business-rules",
        "cross-field-validation",
        "consistency-check",
        "attestation",
        "signed-receipt",
        "evidence",
        "audit-trail",
        "independent",
        "invoice",
        "data-extraction",
        "lead-list",
        "api-response",
        "tool-output",
        "x402",
        "mcp",
        "a2a",
        "agent-to-agent",
        "agent-commerce",
        "erc-8183"
      ],
      "examples": [
        "Buyers: look up how reliably a counterparty AI agent's outputs have passed structural verification, with a confidence interval, before relying on it.",
        "Check whether an agent_id has enough recent verification history to say anything at all.",
        "Sellers

… truncated here: the card is 67,885 characters as printed. The complete card is published at https://score.sarnai.dev/.well-known/agent-card.json.