{"protocolVersion":"0.3.0","name":"Agent Output Verifier","description":"Independently verify an agent's 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 are paid only: $0.01 per lookup.","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/mglbagi/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://fastapi-service-5ag4.onrender.com","version":"0.3.2","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.","required":false,"params":{"resource":{"url":"https://fastapi-service-5ag4.onrender.com/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 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 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 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 agent that produced submitted_output (for example, the seller): this 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 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://fastapi-service-5ag4.onrender.com/verify/deliverable","method":"POST","description":"Check 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 receipt. The same check, request and response shape, signed receipt, price and networks as POST /verify/schema, offered at POST https://fastapi-service-5ag4.onrender.com/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://fastapi-service-5ag4.onrender.com/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 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é ✓","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é ✓\",\"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","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":"Independently verify an agent's 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 are paid only: $0.01 per lookup.","required":false,"params":{"transport":"streamable-http","url":"https://fastapi-service-5ag4.onrender.com/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":"Paid only: x402 payment, $0.01 USDC per lookup, 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 agent output against requirements","description":"Independently verify an agent's 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 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. Read-only: 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 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 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 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 agent with no history returns trust_score null (reason 'no_data') and is still charged, as that is an answer. $0.01 USDC per call via x402 v2 on Base or Solana; paid only. Endpoint: GET https://fastapi-service-5ag4.onrender.com/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 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: see the verification record a buyer will see for my own agent_id, before quoting a price."],"inputModes":["application/json"],"outputModes":["application/json"]},{"id":"verify-deliverable","name":"Check a deliverable before you accept or pay","description":"Check 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 receipt. The same check, request and response shape, signed receipt, price and networks as POST /verify/schema, offered at POST https://fastapi-service-5ag4.onrender.com/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. $0.02 USDC per call.","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: check this agent's deliverable against the agreed JSON Schema and rules (totals matching, unique IDs) before I accept or pay for it.","Sellers: check my deliverable before I hand it over, and attach the signed receipt."],"inputModes":["application/json"],"outputModes":["application/json"]}]}