execution

Verify Proof

FREE, no-auth: verify a counterparty's invinoveritas proof — the agent-to-agent trust handshake.

Hand over the signed event another agent gave you (or a proof_id). We recompute the Nostr event id, verify the schnorr signature, and confirm the pubkey IS invinoveritas's PUBLISHED key — so you learn, WITHOUT trusting that agent OR us, whether invinoveritas really issued this verdict/proof. (You can run the exact same NIP-01 check yourself; we're a convenience, not a trust root.) Optionally pass expect_artifact_hash to also confirm the proof covers the exact output you received, or expect_intended_verifier to confirm the proof's declared consumption context matches you. Add verifier_signature alongside expect_intended_verifier to go further -- cryptographically PROVE you hold that address's key (eip155 namespace only) rather than just asserting it.

post/verify-proof

Request

  • Base URL: https://api.babyblueviper.com (the document declares no server; this is the origin it was published from)
  • URL: https://api.babyblueviper.com/verify-proof
  • Auth: none required

Request body

eventobject nullable

The signed proof event {id,pubkey,created_at,kind,tags,content,sig} from a /prove or /review(sign=true) response. Trustless path — no lookup, no trust.

proof_eventobject nullable

Alias for event, accepting the exact key name GET /ledger/{N} itself uses for the same object (proof_event) — added 2026-08-17 after a real caller (大賀俊勝/Toshikatsu, independent verification walk) hit this: Pydantic silently drops an unrecognized field rather than erroring, so posting a /ledger response's proof_event value under that same key previously no-op'd into the 'provide event' error with no hint the key name itself was the problem. If both event and proof_event are provided, event takes precedence.

proof_idstring nullable

Alternatively, a stored attestation proof_id to fetch + verify (convenience).

event_idstring nullable

Alternatively, the Nostr event id from a /review(sign=true), /prove, or /witness proof — fetches the durably-stored full event (independent of relay retention) and verifies it. Use this when you only have {id,pubkey,sig}, not the full event, from wherever the proof was shared.

pq_companion_signatureobject nullable

Optional (added 2026-08-12): the ML-DSA-65 companion signature {algorithm,pq_pubkey,signature_hex,signs} from a proof issued alongside event, if you have one — additively verified and reported as checks.pq_companion_verified, never required. Only used with the event path; event_id/proof_id lookups fetch their own stored companion sig automatically if one exists.

expect_artifact_hashstring nullable

Optional: assert the proof covers THIS artifact (sha256 hex of the output you were handed).

expect_intended_verifierstring nullable

Optional (added 2026-08-16, per safal207's content/generation/consumption-identity framing on crewAIInc/crewAI#4877): assert the proof's declared intended_verifier matches who YOU are, closing the same gap expect_artifact_hash closes for content_identity -- but for consumption_identity. Checks a self-declared field (see /review's own intended_verifier docstring: 'we cannot confirm who will actually present this proof downstream'), so a match confirms the ISSUER's declared intent, not that delivery was actually restricted to you.

verifier_signaturestring nullable

Optional (added 2026-08-16, per atomicdjt's presenter-bound critique on the same thread): an EIP-191 personal_sign signature over the fixed challenge 'invinoveritas-verify-proof:<event_id>', signed by the private key controlling the address in expect_intended_verifier (eip155:* CAIP-10 namespace only). If provided and it recovers to that address, sets checks.intended_verifier_authenticated=true -- this is presenter-bound (you cryptographically proved you hold that key), not just intent-bound (a caller-supplied string anyone could claim). Requires expect_intended_verifier to also be set. Other CAIP-10 namespaces are not yet supported and are reported as such, not silently ignored.

expect_max_age_secondsinteger nullable

Optional (added 2026-08-17, per tyche-dev's mandate-gate design on w3c-cg/ai-agent-protocol#44): by default /verify-proof never rejects on staleness -- age_seconds is purely informational, you decide. Pass this to turn it into an actual MUST-reject gate, symmetric to expect_artifact_hash/expect_intended_verifier: if the proof's age_seconds exceeds this bound, checks.freshness_within_bound=false and valid flips to false. If age_seconds cannot be determined at all (an older proof with no verified_at), this fails CLOSED (freshness_within_bound=false, with a freshness_within_bound_error explaining why) rather than silently passing -- you asked to enforce freshness and we couldn't confirm it, so it does not pass. Omit this param and nothing changes (informational-only, exactly today's behavior).

fault_injectionstring nullable

Public test hook (added 2026-09-28 for draft-krausz-verification-state §3.1): the only accepted value is 'instrument_failure'. The verifier then raises inside its own evaluation path, exactly where an import or library failure would, so the not_evaluated + state_reason=instrument_failure response is reproducible from outside rather than only in our unit tests. The response carries fault_injected so it can never be mistaken for a real failure, and valid stays false. Any other value is a 400.

consumeboolean

Optional (added 2026-09-07, per a nullifier-design comparison against crewAI#4877/ERC-8380): a verdict-issuance layer binding request+decision correctly is not automatically a replay-safe execution-consumption layer -- decision_ref is a pure function, so nothing stopped the identical, still-valid proof from being presented more than once. Pass true at the ACTUAL dispatch point (never earlier -- consuming before you've genuinely acted on it burns the verdict for nothing) to atomically claim single-use consumption of this proof's decision_ref. Sets checks.decision_ref_consumed (true only on the first-ever presentation) and checks.decision_ref_already_consumed (true if some earlier call already consumed it -- a real replay), and flips valid to false on a replay. Absent by default: omit this and nothing changes, matching every other optional check here. Requires decision_ref_recomputes to have passed (a tampered proof cannot burn a real nullifier slot) and only applies to verdict proofs that carry a decision_ref at all (non-applicable otherwise, reported as such, never silently treated as consumed).

expect_pq_bindingboolean

Optional (added 2026-09-01, Vértice/verticecriativo pq-wallet-binding — a non-custodial post-quantum key-binding anchor, PqBindingAnchor.sol, first-write-immutable). Requires expect_intended_verifier to also be an eip155 CAIP-10 address. When true, we independently verify — never trusting Vértice's gateway blindly — that this address has a real, anchored post-quantum key binding: fetch the binding statement, recompute its content-address ourselves via RFC-8785 JCS + sha256, and independently eth_call PqBindingAnchor.bindingOf(address) on a public Sepolia RPC, requiring our own recompute to match BOTH the gateway's claim AND the real on-chain value. Sets checks.pq_binding_verified (true/false/null, derived 1:1 from checks.pq_binding_evidence) and checks.pq_binding_evidence — a genuine three-way read: "verified", "refuted" (a confirmed mismatch or a confirmed-absent on-chain binding — we actually completed the check and it came back negative), or "unverifiable" (the check could not be completed at all — network failure, malformed/unusable gateway data, or bad input; NEVER conflated with "refuted", since that would misreport an incomplete check as a genuine finding) — plus a pq_binding disclosure block (statement, pq_pubkey, which values matched, which RPC answered, and a machine-readable reason code for any non-"verified" result). This is testnet-only as of this field (chain_id 11155111, disclosed in the response) and an IDENTITY provenance claim, not transaction-level quantum safety — a stronger provenance signal on top of verifier_signature's ECDSA proof, not a replacement for it. valid flips to false only when evidence is "refuted"; "unverifiable" never flips valid on its own, since that would let an unrelated network hiccup or gateway data bug reject an otherwise-good proof.

Response

Successful Response

unknown required

Changes

No recorded changes to this operation across all 1 revision of this API.