{"schema_version":"datoka.api.catalog.v1","service":"Datoka API","version":"0.3.14","access":"public_x402","operations":[{"id":"prepare_api_exchange","description":"Free validation before buying a receipt. Supply an event built locally with the SDK from real captured bytes; never fabricate hashes. Returns the commitment without issuing a receipt or paying. Use when retaining verifiable evidence of an API response for a handoff or archive.","http":{"method":"POST","path":"/v1/operations/prepare_api_exchange"},"mcp":"prepare_api_exchange","read_only":true,"requires_authentication":false,"idempotent":true,"available":true,"payment_enabled":false,"price":{"kind":"free"},"input_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"event":{"type":"object","properties":{"version":{"type":"string","const":"datoka.api.exchange.v1","description":"Declaration format version; preserve this literal."},"attestation":{"type":"string","const":"client_declared","description":"The caller declares the exchange; Datoka does not independently observe it."},"apiId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Caller-chosen API identifier; not a certified provider identity."},"exchangeId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Stable identifier for one declared HTTP exchange."},"method":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"],"description":"Actual HTTP method of the locally captured exchange, for example GET."},"status":{"type":"integer","minimum":200,"maximum":599,"description":"Actual HTTP response status, including error responses; for example 200 or 404."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC start with milliseconds, for example 2026-10-07T08:00:00.000Z."},"completedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC completion with milliseconds; must be at or after startedAt."},"targetHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of the exact UTF-8 target URL, computed locally. Never invent a digest or send the URL itself."},"requestBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application request bytes; null means no body, not an empty body."},"responseBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application response bytes after HTTP decoding. Preserve those bytes; do not reserialize JSON."},"requestHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected request headers. Never send raw headers."},"responseHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected response headers."},"bodyEncoding":{"type":"string","const":"application_bytes","description":"Hash application bytes after HTTP decoding, without JSON reserialization."},"headerEncoding":{"type":"string","const":"jcs-selected-headers-v1","description":"Use the SDK header selection and JCS canonicalization before hashing."}},"required":["version","attestation","apiId","exchangeId","method","status","startedAt","completedAt","targetHash","requestBodyHash","responseBodyHash","requestHeadersHash","responseHeadersHash","bodyEncoding","headerEncoding"],"additionalProperties":false,"description":"Commitment-only HTTP exchange declaration built locally with the SDK. No raw URLs, headers or bodies."}},"required":["event"],"additionalProperties":false},"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"event":{"type":"object","properties":{"version":{"type":"string","const":"datoka.api.exchange.v1","description":"Declaration format version; preserve this literal."},"attestation":{"type":"string","const":"client_declared","description":"The caller declares the exchange; Datoka does not independently observe it."},"apiId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Caller-chosen API identifier; not a certified provider identity."},"exchangeId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Stable identifier for one declared HTTP exchange."},"method":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"],"description":"Actual HTTP method of the locally captured exchange, for example GET."},"status":{"type":"integer","minimum":200,"maximum":599,"description":"Actual HTTP response status, including error responses; for example 200 or 404."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC start with milliseconds, for example 2026-10-07T08:00:00.000Z."},"completedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC completion with milliseconds; must be at or after startedAt."},"targetHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of the exact UTF-8 target URL, computed locally. Never invent a digest or send the URL itself."},"requestBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application request bytes; null means no body, not an empty body."},"responseBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application response bytes after HTTP decoding. Preserve those bytes; do not reserialize JSON."},"requestHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected request headers. Never send raw headers."},"responseHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected response headers."},"bodyEncoding":{"type":"string","const":"application_bytes","description":"Hash application bytes after HTTP decoding, without JSON reserialization."},"headerEncoding":{"type":"string","const":"jcs-selected-headers-v1","description":"Use the SDK header selection and JCS canonicalization before hashing."}},"required":["version","attestation","apiId","exchangeId","method","status","startedAt","completedAt","targetHash","requestBodyHash","responseBodyHash","requestHeadersHash","responseHeadersHash","bodyEncoding","headerEncoding"],"additionalProperties":false,"description":"Commitment-only HTTP exchange declaration built locally with the SDK. No raw URLs, headers or bodies."},"commitment":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256"},"encoding":{"type":"string","const":"jcs"},"digest":{"type":"string"}},"required":["algorithm","encoding","digest"],"additionalProperties":false},"chain":{"type":"string"}},"required":["event","commitment","chain"],"additionalProperties":false}},{"id":"issue_api_receipt","description":"Buy a portable signed commitment to a declared API exchange when a recipient needs independently verifiable receipt integrity: response handoff, archived decision input, or change investigation. Costs 0.002 USDC per receipt via x402 when enabled; verification is free. A local log may suffice for disposable data. Requires caller-approved budget. Keep event, idempotency key and original payment unchanged on retry. Attests a client declaration, not provider origin, content truth or independent observation.","http":{"method":"POST","path":"/v1/operations/issue_api_receipt"},"mcp":"issue_api_receipt","read_only":false,"requires_authentication":false,"idempotent":true,"available":true,"payment_enabled":true,"price":{"kind":"x402","model":"per_receipt","amount":"0.002","currency":"USDC","network":"eip155:8453","pilot_only":false},"input_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"event":{"type":"object","properties":{"version":{"type":"string","const":"datoka.api.exchange.v1","description":"Declaration format version; preserve this literal."},"attestation":{"type":"string","const":"client_declared","description":"The caller declares the exchange; Datoka does not independently observe it."},"apiId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Caller-chosen API identifier; not a certified provider identity."},"exchangeId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Stable identifier for one declared HTTP exchange."},"method":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"],"description":"Actual HTTP method of the locally captured exchange, for example GET."},"status":{"type":"integer","minimum":200,"maximum":599,"description":"Actual HTTP response status, including error responses; for example 200 or 404."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC start with milliseconds, for example 2026-10-07T08:00:00.000Z."},"completedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC completion with milliseconds; must be at or after startedAt."},"targetHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of the exact UTF-8 target URL, computed locally. Never invent a digest or send the URL itself."},"requestBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application request bytes; null means no body, not an empty body."},"responseBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application response bytes after HTTP decoding. Preserve those bytes; do not reserialize JSON."},"requestHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected request headers. Never send raw headers."},"responseHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected response headers."},"bodyEncoding":{"type":"string","const":"application_bytes","description":"Hash application bytes after HTTP decoding, without JSON reserialization."},"headerEncoding":{"type":"string","const":"jcs-selected-headers-v1","description":"Use the SDK header selection and JCS canonicalization before hashing."}},"required":["version","attestation","apiId","exchangeId","method","status","startedAt","completedAt","targetHash","requestBodyHash","responseBodyHash","requestHeadersHash","responseHeadersHash","bodyEncoding","headerEncoding"],"additionalProperties":false,"description":"Commitment-only HTTP exchange declaration built locally with the SDK. No raw URLs, headers or bodies."},"idempotencyKey":{"type":"string","pattern":"^[\\x21-\\x7e]{16,200}$","description":"One stable key per purchase, saved before payment. Keep it, the event and original payment authorization unchanged on retries."}},"required":["event","idempotencyKey"],"additionalProperties":false},"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"event":{"type":"object","properties":{"version":{"type":"string","const":"datoka.api.exchange.v1","description":"Declaration format version; preserve this literal."},"attestation":{"type":"string","const":"client_declared","description":"The caller declares the exchange; Datoka does not independently observe it."},"apiId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Caller-chosen API identifier; not a certified provider identity."},"exchangeId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Stable identifier for one declared HTTP exchange."},"method":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"],"description":"Actual HTTP method of the locally captured exchange, for example GET."},"status":{"type":"integer","minimum":200,"maximum":599,"description":"Actual HTTP response status, including error responses; for example 200 or 404."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC start with milliseconds, for example 2026-10-07T08:00:00.000Z."},"completedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC completion with milliseconds; must be at or after startedAt."},"targetHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of the exact UTF-8 target URL, computed locally. Never invent a digest or send the URL itself."},"requestBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application request bytes; null means no body, not an empty body."},"responseBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application response bytes after HTTP decoding. Preserve those bytes; do not reserialize JSON."},"requestHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected request headers. Never send raw headers."},"responseHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected response headers."},"bodyEncoding":{"type":"string","const":"application_bytes","description":"Hash application bytes after HTTP decoding, without JSON reserialization."},"headerEncoding":{"type":"string","const":"jcs-selected-headers-v1","description":"Use the SDK header selection and JCS canonicalization before hashing."}},"required":["version","attestation","apiId","exchangeId","method","status","startedAt","completedAt","targetHash","requestBodyHash","responseBodyHash","requestHeadersHash","responseHeadersHash","bodyEncoding","headerEncoding"],"additionalProperties":false,"description":"Commitment-only HTTP exchange declaration built locally with the SDK. No raw URLs, headers or bodies."},"receipt":{"type":"object","properties":{"body":{"type":"object","properties":{"version":{"type":"string","const":"datoka.receipt.v1"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"issuer":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"keyId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"issuedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"},"request":{"type":"object","properties":{"scope":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"chain":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"eventType":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"subject":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256"},"encoding":{"type":"string","enum":["jcs","bytes"]},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["algorithm","encoding","digest"],"additionalProperties":false}},"required":["scope","chain","eventType","subject"],"additionalProperties":false},"sequence":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"previous":{"anyOf":[{"type":"string","pattern":"^[a-f0-9]{64}$"},{"type":"null"}]}},"required":["version","id","issuer","keyId","issuedAt","request","sequence","previous"],"additionalProperties":false},"algorithm":{"type":"string","const":"Ed25519"},"signature":{"type":"string","pattern":"^[A-Za-z0-9_-]{86}$"}},"required":["body","algorithm","signature"],"additionalProperties":false,"description":"Unmodified signed receipt returned by issuance or the public synthetic demo; verify against trusted issuer keys."}},"required":["event","receipt"],"additionalProperties":false}},{"id":"verify_api_receipt","description":"Free signature and declaration verification. To try before buying, read datoka-api://demo-receipt or /demo/receipt.json and pass the returned JSON here. No wallet needed for public verification. Verifies issuer, scope and event commitment; compare original response bytes locally with the SDK or /verify/.","http":{"method":"POST","path":"/v1/operations/verify_api_receipt"},"mcp":"verify_api_receipt","read_only":true,"requires_authentication":false,"idempotent":true,"available":true,"payment_enabled":false,"price":{"kind":"free"},"input_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"event":{"type":"object","properties":{"version":{"type":"string","const":"datoka.api.exchange.v1","description":"Declaration format version; preserve this literal."},"attestation":{"type":"string","const":"client_declared","description":"The caller declares the exchange; Datoka does not independently observe it."},"apiId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Caller-chosen API identifier; not a certified provider identity."},"exchangeId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Stable identifier for one declared HTTP exchange."},"method":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"],"description":"Actual HTTP method of the locally captured exchange, for example GET."},"status":{"type":"integer","minimum":200,"maximum":599,"description":"Actual HTTP response status, including error responses; for example 200 or 404."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC start with milliseconds, for example 2026-10-07T08:00:00.000Z."},"completedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"Declared UTC completion with milliseconds; must be at or after startedAt."},"targetHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of the exact UTF-8 target URL, computed locally. Never invent a digest or send the URL itself."},"requestBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application request bytes; null means no body, not an empty body."},"responseBodyHash":{"anyOf":[{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false},{"type":"null"}],"description":"SHA-256 of exact application response bytes after HTTP decoding. Preserve those bytes; do not reserialize JSON."},"requestHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected request headers. Never send raw headers."},"responseHeadersHash":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256","description":"Digest algorithm; always sha256."},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of exact locally captured bytes, encoded as 64 lowercase hexadecimal characters."}},"required":["algorithm","digest"],"additionalProperties":false,"description":"SHA-256 of locally canonicalized selected response headers."},"bodyEncoding":{"type":"string","const":"application_bytes","description":"Hash application bytes after HTTP decoding, without JSON reserialization."},"headerEncoding":{"type":"string","const":"jcs-selected-headers-v1","description":"Use the SDK header selection and JCS canonicalization before hashing."}},"required":["version","attestation","apiId","exchangeId","method","status","startedAt","completedAt","targetHash","requestBodyHash","responseBodyHash","requestHeadersHash","responseHeadersHash","bodyEncoding","headerEncoding"],"additionalProperties":false,"description":"Commitment-only HTTP exchange declaration built locally with the SDK. No raw URLs, headers or bodies."},"receipt":{"type":"object","properties":{"body":{"type":"object","properties":{"version":{"type":"string","const":"datoka.receipt.v1"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"issuer":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"keyId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"issuedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"},"request":{"type":"object","properties":{"scope":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"chain":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"eventType":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"subject":{"type":"object","properties":{"algorithm":{"type":"string","const":"sha256"},"encoding":{"type":"string","enum":["jcs","bytes"]},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["algorithm","encoding","digest"],"additionalProperties":false}},"required":["scope","chain","eventType","subject"],"additionalProperties":false},"sequence":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"previous":{"anyOf":[{"type":"string","pattern":"^[a-f0-9]{64}$"},{"type":"null"}]}},"required":["version","id","issuer","keyId","issuedAt","request","sequence","previous"],"additionalProperties":false},"algorithm":{"type":"string","const":"Ed25519"},"signature":{"type":"string","pattern":"^[A-Za-z0-9_-]{86}$"}},"required":["body","algorithm","signature"],"additionalProperties":false,"description":"Unmodified signed receipt returned by issuance or the public synthetic demo; verify against trusted issuer keys."}},"required":["event","receipt"],"additionalProperties":false},"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"valid":{"type":"boolean","const":true},"receiptId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"scope":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"apiId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Caller-chosen API identifier; not a certified provider identity."},"exchangeId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"Stable identifier for one declared HTTP exchange."},"attestation":{"type":"string","const":"client_declared"}},"required":["valid","receiptId","scope","apiId","exchangeId","attestation"],"additionalProperties":false}},{"id":"get_api_public_keys","description":"Return issuer public keys. Establish issuer trust independently before offline verification.","http":{"method":"POST","path":"/v1/operations/get_api_public_keys"},"mcp":"get_api_public_keys","read_only":true,"requires_authentication":false,"idempotent":true,"available":true,"payment_enabled":false,"price":{"kind":"free"},"input_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false},"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"issuer":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"keys":{"type":"array","items":{"type":"object","properties":{"keyId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"},"jwk":{"type":"object","properties":{"kty":{"type":"string","const":"OKP"},"crv":{"type":"string","const":"Ed25519"},"x":{"type":"string"},"key_ops":{"type":"array","items":{"type":"string"}},"ext":{"type":"boolean"}},"required":["kty","crv","x"],"additionalProperties":false}},"required":["keyId","jwk"],"additionalProperties":false}}},"required":["issuer","keys"],"additionalProperties":false}}]}