{"openapi":"3.1.0","info":{"title":"Spend7 API","version":"2026.08.2","description":"Score an agent-initiated payment before it settles.\n\nPOST a payment intent (amount, merchant, agent id and rail) and get back a 0-100 risk score, an `allow` / `flag` / `deny` decision, and the signals that produced it. `deny` means do not execute. `flag` means step up to a human or an explicit confirmation; it is not a soft allow.\n\nTwo modes, and the response always names which one ran. In **stored** mode an API key identifies the account and the score is computed against that account's configured spend caps and its own payment ledger; the decision is persisted and becomes both history for the next check and evidence if the payment is later disputed. In **stateless** mode you send a `context` object containing your own limits and history; nothing stored is read and nothing is written. There is no third mode in which a missing ledger is quietly treated as an empty one, which would look identical to a clean bill of health.\n\nDecision thresholds: score ≥ 80 denies, ≥ 50 flags. A decisive signal (a hard spend-cap breach, a blocked merchant, a confirmed bad counterparty, or a broken protocol invariant) denies regardless of the total.\n\nRail coverage: x402 and AP2. Sending the rail-specific block is what unlocks protocol-level checks; an intent without it scores on behaviour alone.\n\nRuleset scope: Behavioural scoring against the calling account's own payment history, spend-cap policy evaluation, merchant-category priors, and protocol-level checks for x402 and AP2. Cross-agent and cross-merchant graph signals are computed on paid plans only.","contact":{"name":"Spend7","url":"https://spend7.com","email":"notifications@mail.spend7.com"},"license":{"name":"Proprietary","url":"https://spend7.com/terms"}},"servers":[{"url":"https://spend7.com"}],"security":[{},{"apiKey":[]}],"tags":[{"name":"Risk","description":"Score a payment before it settles."},{"name":"Policy","description":"Spend caps and merchant lists."},{"name":"Log","description":"The read-only record of every decision."},{"name":"Claims","description":"Chargeback-assist and evidence packets."},{"name":"Account","description":"API keys."}],"paths":{"/api/v1/risk-check":{"post":{"tags":["Risk"],"operationId":"riskCheck","summary":"Score a payment intent and return allow / flag / deny","description":"The endpoint an agent's payment client calls before executing a payment above its threshold. Returns the score, the decision, every signal that contributed with the numbers it fired on, every spend cap that was evaluated (breached or not), and the ruleset version and hash the decision was made under.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskCheckRequest"},"examples":{"x402Payment":{"summary":"x402 payment with the quote attached","value":{"intent":{"agentId":"research-agent-01","amountMinor":4200,"currency":"USD","merchantId":"api.example-data.com","merchantName":"Example Data API","category":"data_api","rail":"x402","reference":"job-8813","x402":{"maxAmountRequiredMinor":5000,"authorizedAmountMinor":4200,"network":"base","asset":"USDC","payTo":"0x1234abcd5678ef901234abcd5678ef901234abcd","nonce":"0x9f3c…","maxTimeoutSeconds":60,"quoteAgeSeconds":4,"scheme":"exact"}}}},"ap2Payment":{"summary":"AP2 payment with intent and cart mandates","value":{"intent":{"agentId":"procurement-agent","amountMinor":14800,"currency":"USD","merchantId":"shop.example.com","category":"physical_goods","rail":"ap2","ap2":{"intentMandatePresent":true,"cartMandatePresent":true,"mandateSigned":true,"mandateExpiresAt":"2026-12-31T00:00:00Z","intentMaxAmountMinor":20000,"cartTotalMinor":14800,"allowedMerchants":["shop.example.com"],"modality":"human-not-present"}}}},"statelessCapBreach":{"summary":"Stateless: a gift-card purchase that breaches a daily cap","value":{"intent":{"agentId":"shopping-agent","amountMinor":90000,"currency":"USD","merchantId":"giftcards.example","category":"gift_cards","rail":"other"},"context":{"limits":[{"scope":"agent","agentId":"shopping-agent","window":"daily","capMinor":50000,"currency":"USD"}],"history":[{"agentId":"shopping-agent","merchantId":"shop.example.com","amountMinor":2400,"currency":"USD","decision":"allow","createdAt":"2026-08-08T09:00:00Z"}]}}}}}}},"responses":{"200":{"description":"The decision","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskDecision"}}}},"400":{"description":"Body was not valid JSON"},"401":{"description":"An API key was presented but did not verify, or stored-mode scoring was requested without one"},"402":{"description":"Quota exhausted on the free tier"},"422":{"description":"The intent failed schema validation"},"429":{"description":"Rate limited"},"503":{"description":"No ledger to score against: no database configured and no inline context supplied"}}}},"/api/v1/spend-limits":{"get":{"tags":["Policy"],"operationId":"getSpendLimits","summary":"The spend caps and merchant lists in force","security":[{"apiKey":[]}],"responses":{"200":{"description":"Caps and lists"},"401":{"description":"No API key or session"},"503":{"description":"No database configured"}}},"put":{"tags":["Policy"],"operationId":"replaceSpendLimits","summary":"Replace the caps and lists wholesale","description":"Replace rather than patch, in one transaction. A caps policy that can be half-applied is one nobody can reason about, and a partial write would silently loosen a cap.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpendLimitsRequest"},"examples":{"perAgentDaily":{"summary":"A daily cap per agent, a per-payment ceiling, and a blocked category","value":{"limits":[{"scope":"agent","agentId":"research-agent-01","window":"daily","capMinor":25000,"currency":"USD"},{"scope":"global","window":"per_transaction","capMinor":10000,"currency":"USD"},{"scope":"category","category":"cloud_infrastructure","window":"monthly","capMinor":500000,"currency":"USD","action":"flag"}],"lists":{"blockedCategories":["gambling","gift_cards"]}}}}}}},"responses":{"200":{"description":"The saved policy"},"401":{"description":"No API key or session"},"422":{"description":"Payload failed validation; nothing was changed"},"500":{"description":"Write failed; the previous policy is still in force"}}}},"/api/v1/transactions":{"get":{"tags":["Log"],"operationId":"listTransactions","summary":"The read-only decision log","description":"Every scored payment with its decision, score and rail. Read-only by design: an audit trail you can rewrite is not an audit trail, so there is no edit or delete endpoint.","security":[{"apiKey":[]}],"parameters":[{"name":"agentId","in":"query","schema":{"type":"string"}},{"name":"merchantId","in":"query","schema":{"type":"string"}},{"name":"decision","in":"query","schema":{"type":"string","enum":["allow","flag","deny"]}},{"name":"rail","in":"query","schema":{"type":"string","enum":["x402","ap2","other"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"Decisions, newest first, with a summary by outcome"},"401":{"description":"No API key or session"},"503":{"description":"No database configured"}}}},"/api/v1/claims":{"get":{"tags":["Claims"],"operationId":"listClaims","summary":"Claims raised on this account","security":[{"apiKey":[]}],"responses":{"200":{"description":"Claims with links to their evidence packets"}}},"post":{"tags":["Claims"],"operationId":"raiseClaim","summary":"Raise a chargeback-assist claim against a scored payment","description":"Builds an evidence packet from what was recorded at the time: the decision, its signals, the ruleset hash in force, and the surrounding activity by the same agent and to the same merchant. Nothing is re-scored: re-running today's engine over an old payment would describe a decision that was never made.\n\nPaid capability. Spend7 does not underwrite the loss; no liability backstop is offered or priced.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRequest"},"examples":{"unauthorized":{"value":{"paymentId":"5f0f…","reason":"unauthorized","lossMinor":90000,"narrative":"The agent's API key was rotated after a leak; this payment postdates it."}}}}}},"responses":{"201":{"description":"The claim and its evidence packet"},"401":{"description":"No API key or session"},"402":{"description":"Free plan: chargeback-assist is a paid capability"},"404":{"description":"No scored payment with that id on this account"},"422":{"description":"Payload failed validation"}}}},"/api/v1/claims/{id}/evidence":{"get":{"tags":["Claims"],"operationId":"getClaimEvidence","summary":"The evidence packet for a claim, as PDF or JSON","security":[{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","schema":{"type":"string","enum":["pdf","json"]},"description":"Defaults to pdf."}],"responses":{"200":{"description":"The packet","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"object"}}}},"404":{"description":"No claim with that id on this account"}}}},"/api/keys":{"get":{"tags":["Account"],"operationId":"listApiKeys","summary":"List API keys on the signed-in account","responses":{"200":{"description":"Key prefixes; the secret is never retrievable"}}},"post":{"tags":["Account"],"operationId":"createApiKey","summary":"Issue an API key, returned in plaintext exactly once","responses":{"201":{"description":"The new key"}}},"delete":{"tags":["Account"],"operationId":"revokeApiKey","summary":"Revoke an API key","description":"Revocation is the second half of rotation: issue the replacement, cut over, then revoke the old key. A revoked key stops verifying immediately and every endpoint returns 401 for it.","parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string"},"description":"Id of the key to revoke, as returned by listApiKeys."}],"responses":{"200":{"description":"The key was revoked"},"404":{"description":"No active key with that id on this account"}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key from the dashboard, sent as `Authorization: Bearer sp7_live_…`. The `X-API-Key` header is accepted as an alternative."}},"schemas":{"RiskCheckRequest":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"intent":{"type":"object","properties":{"agentId":{"type":"string","minLength":1,"maxLength":200,"description":"Stable identifier for the agent initiating the payment. The unit a cap binds to."},"amountMinor":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Amount in the smallest unit of `currency`: 1250 is $12.50 in USD, and 1000000 is 1 USDC (6 decimals). Must fit in a JSON safe integer (2^53-1); assets with 18-decimal base units cannot express whole-token amounts in this field."},"currency":{"type":"string","minLength":3,"maxLength":10,"description":"Currency or settlement asset of the amount, e.g. \"USD\" or \"USDC\". Amounts are in the smallest unit of this currency."},"merchantId":{"type":"string","minLength":1,"maxLength":200,"description":"Stable merchant or counterparty identifier: a domain, an address, your own id."},"merchantName":{"type":"string","maxLength":300},"category":{"description":"Merchant category. Sets the prior the score starts from. Defaults to unknown.","type":"string","enum":["ai_inference","cloud_infrastructure","data_api","saas_subscription","digital_goods","physical_goods","travel","advertising","financial_services","crypto_exchange","gift_cards","money_transfer","gambling","adult","unknown"]},"rail":{"type":"string","enum":["x402","ap2","other"],"description":"Rail the payment will settle on. \"x402\" and \"ap2\" unlock protocol-level checks; \"other\" scores on behaviour alone."},"reference":{"description":"Your own reference. Echoed back and stored.","type":"string","maxLength":200},"humanPresent":{"description":"True when a person approved this specific payment in the moment.","type":"boolean"},"x402":{"type":"object","properties":{"maxAmountRequiredMinor":{"description":"maxAmountRequired from the 402 quote. Checked against what the client will sign.","type":"integer","minimum":0,"maximum":9007199254740991},"authorizedAmountMinor":{"description":"Amount the client is about to authorize. Defaults to amountMinor when absent.","type":"integer","minimum":0,"maximum":9007199254740991},"network":{"description":"Settlement network from the quote, e.g. \"base\".","type":"string","maxLength":60},"asset":{"description":"Asset the quote named.","type":"string","maxLength":120},"settlementAsset":{"description":"Asset settlement will actually happen in, when it differs from the quote.","type":"string","maxLength":120},"payTo":{"description":"Pay-to address from the quote.","type":"string","maxLength":200},"nonce":{"description":"Authorization nonce, used to detect replay.","type":"string","maxLength":200},"maxTimeoutSeconds":{"type":"integer","minimum":0,"maximum":86400},"quoteAgeSeconds":{"description":"Seconds since the quote was issued.","type":"number","minimum":0,"maximum":86400},"facilitator":{"type":"string","maxLength":200},"scheme":{"description":"Payment scheme from the quote, e.g. \"exact\".","type":"string","maxLength":60}},"additionalProperties":false},"ap2":{"type":"object","properties":{"intentMandatePresent":{"type":"boolean"},"cartMandatePresent":{"type":"boolean"},"mandateSigned":{"description":"Whether the mandate carries a verifiable signature.","type":"boolean"},"mandateExpiresAt":{"description":"Mandate expiry, ISO 8601.","type":"string","maxLength":40},"intentMaxAmountMinor":{"description":"Price ceiling the intent mandate constrained the agent to.","type":"integer","minimum":0,"maximum":9007199254740991},"cartTotalMinor":{"description":"Total the cart mandate commits to.","type":"integer","minimum":0,"maximum":9007199254740991},"allowedMerchants":{"description":"Merchants the mandate scoped this agent to. Absent or empty means unscoped.","maxItems":500,"type":"array","items":{"type":"string","maxLength":200}},"modality":{"type":"string","enum":["human-present","human-not-present"]},"mandateId":{"type":"string","maxLength":200}},"additionalProperties":false},"metadata":{"type":"object","propertyNames":{"type":"string","maxLength":80},"additionalProperties":{"anyOf":[{"type":"string","maxLength":500},{"type":"number"},{"type":"boolean"}]}}},"required":["agentId","amountMinor","currency","merchantId","rail"],"additionalProperties":false},"context":{"description":"Supply to score statelessly against your own ledger instead of the one Spend7 stores. When present it replaces stored history and limits entirely.","type":"object","properties":{"limits":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","maxLength":80},"scope":{"type":"string","enum":["global","agent","merchant","category","agent_merchant"],"description":"What the cap binds to."},"agentId":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"merchantId":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"category":{"anyOf":[{"type":"string","enum":["ai_inference","cloud_infrastructure","data_api","saas_subscription","digital_goods","physical_goods","travel","advertising","financial_services","crypto_exchange","gift_cards","money_transfer","gambling","adult","unknown"]},{"type":"null"}]},"window":{"type":"string","enum":["per_transaction","hourly","daily","weekly","monthly"],"description":"Rolling window the cap is measured over. Rolling, not calendar."},"capMinor":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"The cap, in the smallest unit of currency."},"currency":{"type":"string","minLength":3,"maxLength":10,"description":"Currency or settlement asset of the amount, e.g. \"USD\" or \"USDC\". Amounts are in the smallest unit of this currency."},"action":{"description":"What a breach does. \"deny\" (default) is decisive; \"flag\" makes the cap advisory.","type":"string","enum":["deny","flag"]},"enabled":{"type":"boolean"}},"required":["scope","window","capMinor","currency"],"additionalProperties":false}},"lists":{"type":"object","properties":{"blockedMerchants":{"maxItems":2000,"type":"array","items":{"type":"string","maxLength":200}},"allowedMerchants":{"maxItems":2000,"type":"array","items":{"type":"string","maxLength":200}},"blockedCategories":{"maxItems":30,"type":"array","items":{"type":"string","enum":["ai_inference","cloud_infrastructure","data_api","saas_subscription","digital_goods","physical_goods","travel","advertising","financial_services","crypto_exchange","gift_cards","money_transfer","gambling","adult","unknown"]}},"merchantAllowlistStrict":{"type":"boolean"}},"additionalProperties":false},"history":{"description":"The agent's recent payments, in any order. Used for caps, baselines and velocity.","maxItems":1000,"type":"array","items":{"type":"object","properties":{"agentId":{"type":"string","maxLength":200},"merchantId":{"type":"string","maxLength":200},"amountMinor":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Amount in the smallest unit of `currency`: 1250 is $12.50 in USD, and 1000000 is 1 USDC (6 decimals). Must fit in a JSON safe integer (2^53-1); assets with 18-decimal base units cannot express whole-token amounts in this field."},"currency":{"type":"string","minLength":3,"maxLength":10,"description":"Currency or settlement asset of the amount, e.g. \"USD\" or \"USDC\". Amounts are in the smallest unit of this currency."},"category":{"anyOf":[{"type":"string","enum":["ai_inference","cloud_infrastructure","data_api","saas_subscription","digital_goods","physical_goods","travel","advertising","financial_services","crypto_exchange","gift_cards","money_transfer","gambling","adult","unknown"]},{"type":"null"}]},"decision":{"type":"string","enum":["allow","flag","deny"]},"createdAt":{"type":"string","maxLength":40,"description":"ISO 8601."}},"required":["agentId","merchantId","amountMinor","currency","decision","createdAt"],"additionalProperties":false}},"seenNonces":{"maxItems":1000,"type":"array","items":{"type":"string","maxLength":200}}},"additionalProperties":false},"record":{"description":"Whether to persist the decision to the transaction log. Defaults to true for authenticated callers scoring against stored history, and false in stateless mode.","type":"boolean"}},"required":["intent"],"additionalProperties":false},"PaymentIntent":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"agentId":{"type":"string","minLength":1,"maxLength":200,"description":"Stable identifier for the agent initiating the payment. The unit a cap binds to."},"amountMinor":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Amount in the smallest unit of `currency`: 1250 is $12.50 in USD, and 1000000 is 1 USDC (6 decimals). Must fit in a JSON safe integer (2^53-1); assets with 18-decimal base units cannot express whole-token amounts in this field."},"currency":{"type":"string","minLength":3,"maxLength":10,"description":"Currency or settlement asset of the amount, e.g. \"USD\" or \"USDC\". Amounts are in the smallest unit of this currency."},"merchantId":{"type":"string","minLength":1,"maxLength":200,"description":"Stable merchant or counterparty identifier: a domain, an address, your own id."},"merchantName":{"type":"string","maxLength":300},"category":{"description":"Merchant category. Sets the prior the score starts from. Defaults to unknown.","type":"string","enum":["ai_inference","cloud_infrastructure","data_api","saas_subscription","digital_goods","physical_goods","travel","advertising","financial_services","crypto_exchange","gift_cards","money_transfer","gambling","adult","unknown"]},"rail":{"type":"string","enum":["x402","ap2","other"],"description":"Rail the payment will settle on. \"x402\" and \"ap2\" unlock protocol-level checks; \"other\" scores on behaviour alone."},"reference":{"description":"Your own reference. Echoed back and stored.","type":"string","maxLength":200},"humanPresent":{"description":"True when a person approved this specific payment in the moment.","type":"boolean"},"x402":{"type":"object","properties":{"maxAmountRequiredMinor":{"description":"maxAmountRequired from the 402 quote. Checked against what the client will sign.","type":"integer","minimum":0,"maximum":9007199254740991},"authorizedAmountMinor":{"description":"Amount the client is about to authorize. Defaults to amountMinor when absent.","type":"integer","minimum":0,"maximum":9007199254740991},"network":{"description":"Settlement network from the quote, e.g. \"base\".","type":"string","maxLength":60},"asset":{"description":"Asset the quote named.","type":"string","maxLength":120},"settlementAsset":{"description":"Asset settlement will actually happen in, when it differs from the quote.","type":"string","maxLength":120},"payTo":{"description":"Pay-to address from the quote.","type":"string","maxLength":200},"nonce":{"description":"Authorization nonce, used to detect replay.","type":"string","maxLength":200},"maxTimeoutSeconds":{"type":"integer","minimum":0,"maximum":86400},"quoteAgeSeconds":{"description":"Seconds since the quote was issued.","type":"number","minimum":0,"maximum":86400},"facilitator":{"type":"string","maxLength":200},"scheme":{"description":"Payment scheme from the quote, e.g. \"exact\".","type":"string","maxLength":60}},"additionalProperties":false},"ap2":{"type":"object","properties":{"intentMandatePresent":{"type":"boolean"},"cartMandatePresent":{"type":"boolean"},"mandateSigned":{"description":"Whether the mandate carries a verifiable signature.","type":"boolean"},"mandateExpiresAt":{"description":"Mandate expiry, ISO 8601.","type":"string","maxLength":40},"intentMaxAmountMinor":{"description":"Price ceiling the intent mandate constrained the agent to.","type":"integer","minimum":0,"maximum":9007199254740991},"cartTotalMinor":{"description":"Total the cart mandate commits to.","type":"integer","minimum":0,"maximum":9007199254740991},"allowedMerchants":{"description":"Merchants the mandate scoped this agent to. Absent or empty means unscoped.","maxItems":500,"type":"array","items":{"type":"string","maxLength":200}},"modality":{"type":"string","enum":["human-present","human-not-present"]},"mandateId":{"type":"string","maxLength":200}},"additionalProperties":false},"metadata":{"type":"object","propertyNames":{"type":"string","maxLength":80},"additionalProperties":{"anyOf":[{"type":"string","maxLength":500},{"type":"number"},{"type":"boolean"}]}}},"required":["agentId","amountMinor","currency","merchantId","rail"],"additionalProperties":false},"SpendLimitsRequest":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"limits":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","maxLength":80},"scope":{"type":"string","enum":["global","agent","merchant","category","agent_merchant"],"description":"What the cap binds to."},"agentId":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"merchantId":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"category":{"anyOf":[{"type":"string","enum":["ai_inference","cloud_infrastructure","data_api","saas_subscription","digital_goods","physical_goods","travel","advertising","financial_services","crypto_exchange","gift_cards","money_transfer","gambling","adult","unknown"]},{"type":"null"}]},"window":{"type":"string","enum":["per_transaction","hourly","daily","weekly","monthly"],"description":"Rolling window the cap is measured over. Rolling, not calendar."},"capMinor":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"The cap, in the smallest unit of currency."},"currency":{"type":"string","minLength":3,"maxLength":10,"description":"Currency or settlement asset of the amount, e.g. \"USD\" or \"USDC\". Amounts are in the smallest unit of this currency."},"action":{"description":"What a breach does. \"deny\" (default) is decisive; \"flag\" makes the cap advisory.","type":"string","enum":["deny","flag"]},"enabled":{"type":"boolean"}},"required":["scope","window","capMinor","currency"],"additionalProperties":false}},"lists":{"type":"object","properties":{"blockedMerchants":{"maxItems":2000,"type":"array","items":{"type":"string","maxLength":200}},"allowedMerchants":{"maxItems":2000,"type":"array","items":{"type":"string","maxLength":200}},"blockedCategories":{"maxItems":30,"type":"array","items":{"type":"string","enum":["ai_inference","cloud_infrastructure","data_api","saas_subscription","digital_goods","physical_goods","travel","advertising","financial_services","crypto_exchange","gift_cards","money_transfer","gambling","adult","unknown"]}},"merchantAllowlistStrict":{"type":"boolean"}},"additionalProperties":false}},"required":["limits"],"additionalProperties":false},"ClaimRequest":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"paymentId":{"type":"string","minLength":1,"maxLength":80,"description":"The paymentId returned by /api/v1/risk-check for the payment being disputed."},"reason":{"type":"string","enum":["unauthorized","not_delivered","duplicate","wrong_amount","merchant_fraud","agent_malfunction"],"description":"Why the payment is being disputed."},"lossMinor":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Amount being claimed, in the smallest currency unit."},"narrative":{"description":"Your account of what happened. Included verbatim in the evidence packet.","type":"string","maxLength":4000},"contactEmail":{"type":"string","maxLength":200,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["paymentId","reason","lossMinor"],"additionalProperties":false},"Signal":{"type":"object","properties":{"id":{"type":"string","description":"Stable signal identifier."},"label":{"type":"string"},"points":{"type":"number","description":"Contribution to the score, capped per signal."},"detail":{"type":"string","description":"What fired, on what numbers."},"decisive":{"type":"boolean","description":"True when this signal denies regardless of the total."},"graph":{"type":"boolean","description":"True for a paid cross-account signal."}}},"CapUsage":{"type":"object","description":"One evaluated spend cap, breached or not.","properties":{"limit":{"type":"object"},"usedMinor":{"type":"integer","description":"Already spent in the window."},"wouldBeMinor":{"type":"integer","description":"Total after this payment."},"capMinor":{"type":"integer"},"breached":{"type":"boolean"},"fractionUsed":{"type":"number"}}},"RiskDecision":{"type":"object","properties":{"decision":{"type":"string","enum":["allow","flag","deny"],"description":"deny: do not execute. flag: step up to a human or an explicit confirmation. allow: execute."},"score":{"type":"integer","minimum":0,"maximum":100},"signals":{"type":"array","items":{"$ref":"#/components/schemas/Signal"}},"caps":{"type":"array","items":{"$ref":"#/components/schemas/CapUsage"}},"summary":{"type":"string"},"recommendedAction":{"type":"string"},"graphScoring":{"type":"object","properties":{"ran":{"type":"boolean"},"reason":{"type":"string"}},"description":"Whether cross-account graph scoring ran, and why not when it did not."},"contextSource":{"type":"string","enum":["ledger","request"],"description":"Which ledger the score was computed against."},"paymentId":{"type":["string","null"],"description":"Set when the decision was persisted. Pass it to /api/v1/claims to dispute the payment later. Null means the decision was not recorded."},"ruleset":{"type":"object","properties":{"version":{"type":"string"},"hash":{"type":"string"}}},"evaluatedAt":{"type":"string","format":"date-time"}}}}},"x-ruleset":{"version":"2026.08.2","hash":"56b4afe661f7062b","scope":"Behavioural scoring against the calling account's own payment history, spend-cap policy evaluation, merchant-category priors, and protocol-level checks for x402 and AP2. Cross-agent and cross-merchant graph signals are computed on paid plans only.","thresholds":{"deny":80,"flag":50},"categories":["ai_inference","cloud_infrastructure","data_api","saas_subscription","digital_goods","physical_goods","travel","advertising","financial_services","crypto_exchange","gift_cards","money_transfer","gambling","adult","unknown"],"rails":["x402","ap2","other"]}}