{"openapi":"3.1.0","info":{"title":"Settle","version":"0.1.0","description":"Programmable escrow infrastructure for the agent economy.","license":{"name":"Proprietary"}},"servers":[{"url":"/"}],"paths":{"/x402/deferred/offer":{"post":{"summary":"Create an x402 deferred offer","operationId":"createDeferredOffer","description":"Returns a machine-readable x402-shaped deferred offer plus the canonical signing payload an agent signs before commitment.","requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/CreateContractRequest"},{"type":"object","required":["resource"],"properties":{"resource":{"type":"string","format":"uri"},"terms_url":{"type":"string","format":"uri"}}}]}}}},"responses":{"200":{"description":"Deferred offer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeferredOfferResponse"}}}},"400":{"description":"Invalid request body"}}}},"/x402/deferred/commit":{"post":{"summary":"Commit a signed x402 deferred offer","operationId":"commitDeferredOffer","description":"Verifies the agent signature over the deferred offer payload, then creates a new escrow or attaches the commitment to an existing contract. Funding and condition verification are still required before payout.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeferredCommitRequest"}}}},"responses":{"200":{"description":"Commitment attached to existing contract"},"201":{"description":"Commitment accepted and escrow created","content":{"application/json":{"schema":{"type":"object","required":["committed","contract"],"properties":{"committed":{"type":"boolean"},"contract":{"$ref":"#/components/schemas/Contract"},"claim_token":{"type":"string"},"confirmation_token":{"type":"string","description":"Returned only for manual conditions. Bearer token for manual confirmation."}}}}}},"400":{"description":"Invalid commitment body"},"401":{"description":"Invalid signature"},"404":{"description":"Existing contract not found"}}}},"/escrow/create":{"post":{"summary":"Create an escrow contract","operationId":"createEscrow","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContractRequest"}}}},"responses":{"201":{"description":"Contract created in state pending_funding","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Contract"},{"type":"object","properties":{"claim_token":{"type":"string"},"confirmation_token":{"type":"string","description":"Returned only for manual conditions. Bearer token for manual confirmation."}}}]}}}},"400":{"description":"Invalid request body"}}}},"/escrow/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"summary":"Get a contract by id","operationId":"getEscrow","responses":{"200":{"description":"Contract","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contract"}}}},"404":{"description":"Not found"}}}},"/escrow/{id}/status":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"summary":"Lightweight status","operationId":"getEscrowStatus","responses":{"200":{"description":"Status","content":{"application/json":{"schema":{"type":"object","required":["id","state","deadline"],"properties":{"id":{"type":"string"},"state":{"$ref":"#/components/schemas/ContractState"},"deadline":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Not found"}}}},"/escrow/{id}/verify":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Check the condition; auto-authorize deterministic payouts when possible","operationId":"verifyEscrow","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","description":"Verifier-specific. For manual conditions: { confirmed: true }. For github_pr_merged the body is ignored - the verifier polls GitHub."}}}},"responses":{"200":{"description":"Verification outcome","content":{"application/json":{"schema":{"type":"object","required":["state","met"],"properties":{"state":{"$ref":"#/components/schemas/ContractState"},"met":{"type":"boolean"},"reason":{"type":"string"},"expired":{"type":"boolean"}}}}}},"404":{"description":"Not found"},"409":{"description":"Not held or invalid transition"}}}},"/escrow/{id}/authorize-release":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Authorize payout after the condition passes","operationId":"authorizeRelease","description":"Moves condition_met to settlement_pending when auto-authorization is unavailable or not desired. Payout details must already be registered through /claim. If payout_method and payout_destination are supplied here, claim_token is required and the details are registered before authorization. If payout_method is base_usdc or xlayer_usdg, signs and broadcasts an ERC-20 transfer from the configured operator vault. If payout_method is bridge, creates a Bridge transfer from BRIDGE_SOURCE to payout_destination and records the Bridge transfer id/state on payout.","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"authorized_by":{"type":"string"},"authorization_id":{"type":"string"},"claim_token":{"type":"string","description":"Required when registering payout_method and payout_destination on this call."},"payout_method":{"$ref":"#/components/schemas/PayoutMethod"},"payout_destination":{"type":"string"}}}}}},"responses":{"200":{"description":"Payout authorized; contract is settlement_pending","content":{"application/json":{"schema":{"type":"object","required":["state","payout"],"properties":{"state":{"$ref":"#/components/schemas/ContractState"},"payout":{"$ref":"#/components/schemas/Payout"}}}}}},"400":{"description":"Invalid authorization body"},"404":{"description":"Not found"},"409":{"description":"Condition has not passed or transition is illegal"},"502":{"description":"Payout processor rejected the transfer"},"503":{"description":"Selected payout processor is not configured"}}}},"/escrow/{id}/payout":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"summary":"Get payout status","operationId":"getPayoutStatus","parameters":[{"name":"sync","in":"query","required":false,"schema":{"type":"string","enum":["1"]},"description":"When set to 1 for processor-backed payouts, polls the processor/RPC and applies confirmed / failure state."}],"responses":{"200":{"description":"Payout status","content":{"application/json":{"schema":{"type":"object","required":["id","state","payout"],"properties":{"id":{"type":"string"},"state":{"$ref":"#/components/schemas/ContractState"},"payout":{"$ref":"#/components/schemas/Payout"}}}}}},"404":{"description":"Not found"},"502":{"description":"Payout processor rejected the status lookup"},"503":{"description":"Payout sync requested but the processor is not configured"}}},"post":{"summary":"Confirm payout settlement","operationId":"confirmPayout","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirmation_id":{"type":"string"},"payout_method":{"$ref":"#/components/schemas/PayoutMethod"},"payout_destination":{"type":"string"}}}}}},"responses":{"200":{"description":"Payout confirmed; contract is settled","content":{"application/json":{"schema":{"type":"object","required":["state","payout"],"properties":{"state":{"$ref":"#/components/schemas/ContractState"},"payout":{"$ref":"#/components/schemas/Payout"}}}}}},"400":{"description":"Invalid payout body"},"403":{"description":"Unsigned manual payout confirmation is disabled outside debug mode"},"404":{"description":"Not found"},"409":{"description":"Payout has not been authorized or transition is illegal"},"502":{"description":"Payout processor rejected the status lookup"},"503":{"description":"Payout sync requested but the processor is not configured"}}}},"/webhooks/github":{"post":{"summary":"GitHub webhook receiver","operationId":"githubWebhook","description":"Validates X-Hub-Signature-256 (HMAC-SHA256). On pull_request closed with merged=true, looks up matching contracts and advances them.","responses":{"200":{"description":"Processed or ignored"},"401":{"description":"Invalid signature"},"503":{"description":"GITHUB_WEBHOOK_SECRET not configured"}}}},"/escrow/{id}/fund":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Create a sandbox Stripe PaymentIntent to fund the contract","operationId":"fundEscrow","description":"Creates a sandbox Stripe PaymentIntent for amount_usdc plus optional gas_tip_usdc, tags it with metadata.contract_id, and persists the PI id on the contract. The contract stays in pending_funding until the Stripe webhook fires. Stablecoin escrow is the primary v0.1 rail.","responses":{"200":{"description":"PaymentIntent created","content":{"application/json":{"schema":{"type":"object","required":["payment_intent_id","client_secret","amount","currency"],"properties":{"payment_intent_id":{"type":"string"},"client_secret":{"type":"string"},"amount":{"type":"integer"},"currency":{"type":"string"}}}}}},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"502":{"description":"Stripe API rejected the request"},"503":{"description":"STRIPE_SECRET_KEY not configured"}}}},"/escrow/{id}/checkout":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Create a hosted sandbox Stripe Checkout Session","operationId":"checkoutEscrow","description":"Creates a sandbox Stripe Checkout Session for human card / Link funding. Browser clients receive a 303 redirect to Stripe Checkout. API clients that send Accept: application/json receive { checkout_session_id, url }. The contract stays pending_funding until /webhooks/stripe receives payment_intent.succeeded. Live Stripe funding is planned.","responses":{"200":{"description":"Checkout Session created for API clients","content":{"application/json":{"schema":{"type":"object","required":["checkout_session_id","url"],"properties":{"checkout_session_id":{"type":"string"},"url":{"type":"string","format":"uri"}}}}}},"303":{"description":"Redirect to hosted Stripe Checkout"},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"502":{"description":"Stripe API rejected the request"},"503":{"description":"STRIPE_SECRET_KEY not configured"}}}},"/escrow/{id}/fund-spt":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Fund the contract with a sandbox Stripe shared payment token","operationId":"fundEscrowStripeSpt","description":"Creates and confirms a sandbox Stripe PaymentIntent with payment_method_data[shared_payment_granted_token]. If Stripe returns status=succeeded, the contract advances to held immediately; otherwise the contract keeps the PaymentIntent id and waits for /webhooks/stripe.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["shared_payment_granted_token"],"properties":{"shared_payment_granted_token":{"type":"string","minLength":1}}}}}},"responses":{"200":{"description":"PaymentIntent created and optionally held","content":{"application/json":{"schema":{"type":"object","required":["payment_intent_id","amount","currency","stripe_status","state","held"],"properties":{"payment_intent_id":{"type":"string"},"amount":{"type":"integer"},"currency":{"type":"string"},"stripe_status":{"type":"string"},"state":{"$ref":"#/components/schemas/ContractState"},"held":{"type":"boolean"}}}}}},"400":{"description":"Invalid request body"},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"502":{"description":"Stripe API rejected the request"},"503":{"description":"STRIPE_SECRET_KEY not configured"}}}},"/webhooks/stripe":{"post":{"summary":"Stripe webhook receiver","operationId":"stripeWebhook","description":"Validates Stripe-Signature (HMAC-SHA256 over `<timestamp>.<body>`, 5min tolerance). On payment_intent.succeeded, resolves the contract via metadata.contract_id and fires FUND. Idempotent on redelivery.","responses":{"200":{"description":"Processed or ignored"},"401":{"description":"Invalid signature"},"503":{"description":"STRIPE_WEBHOOK_SECRET not configured"}}}},"/webhooks/payout":{"post":{"summary":"Trusted payout confirmation webhook","operationId":"payoutWebhook","description":"Validates X-Settle-Payout-Signature (HMAC-SHA256 over the raw body). A confirmed notification moves settlement_pending -> settled; a failed notification moves settlement_pending -> payout_failed. Used as the deterministic payout verification path for Link/Stripe-style settlement notifications.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["contract_id","status"],"properties":{"contract_id":{"type":"string"},"status":{"type":"string","enum":["confirmed","failed"]},"confirmation_id":{"type":"string"},"payout_method":{"$ref":"#/components/schemas/PayoutMethod"},"payout_destination":{"type":"string"},"failure_reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Processed or ignored"},"401":{"description":"Invalid signature"},"409":{"description":"Payout was not authorized yet"},"503":{"description":"PAYOUT_WEBHOOK_SECRET not configured"}}}},"/escrow/{id}/fund-usdg":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Fund the contract with USDG on Solana","operationId":"fundEscrowUsdg","description":"Returns a Solana deposit address and a per-contract memo. The agent sends USDG to deposit_address with memo set as a Solana memo (Memo program). The contract advances to \"held\" once the chain webhook confirms the transfer.","responses":{"200":{"description":"USDG funding instructions","content":{"application/json":{"schema":{"type":"object","required":["deposit_address","amount","currency","chain","memo"],"properties":{"deposit_address":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string","enum":["USDG"]},"chain":{"type":"string","enum":["solana"]},"memo":{"type":"string"},"expires_at":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"503":{"description":"USDG_DEPOSIT_ADDRESS not configured"}}}},"/webhooks/usdg-transfer":{"post":{"summary":"USDG transfer webhook (Helius / Solana)","operationId":"usdgTransferWebhook","description":"Validates the chain-webhook HMAC-SHA256 signature, parses the transfer payload (Helius enhanced-tx shape), matches the memo against contract.usdg_funding_ref, and fires FUND if the transfer covers the expected amount. Idempotent on redelivery.","responses":{"200":{"description":"Processed or ignored"},"401":{"description":"Invalid signature"},"503":{"description":"USDG_WEBHOOK_SECRET / USDG_DEPOSIT_ADDRESS / USDG_MINT not configured"}}}},"/escrow/{id}/fund-usdc-base":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Fund the contract with USDC on Base","operationId":"fundEscrowUsdcBase","description":"Returns a deterministic per-contract EVM deposit address. ERC-20 transfers on Base do not use memos; the deposit address identifies the contract.","responses":{"200":{"description":"USDC (Base) funding instructions","content":{"application/json":{"schema":{"type":"object","required":["deposit_address","amount","currency","chain","asset_id","memo"],"properties":{"deposit_address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$"},"amount":{"type":"number"},"currency":{"type":"string","enum":["USDC"]},"chain":{"type":"string","enum":["base"]},"memo":{"type":"null"},"asset_id":{"type":"string","description":"USDC ERC-20 contract address on Base"},"expires_at":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"503":{"description":"EVM deposit seed not configured"}}}},"/escrow/{id}/fund-usdg-xlayer":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Fund the contract with USDG on X Layer","operationId":"fundEscrowUsdgXlayer","description":"Returns a deterministic per-contract EVM deposit address. ERC-20 transfers on X Layer do not use memos; the deposit address identifies the contract.","responses":{"200":{"description":"USDG (X Layer) funding instructions","content":{"application/json":{"schema":{"type":"object","required":["deposit_address","amount","currency","chain","asset_id","memo"],"properties":{"deposit_address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$"},"amount":{"type":"number"},"currency":{"type":"string","enum":["USDG"]},"chain":{"type":"string","enum":["xlayer"]},"memo":{"type":"null"},"asset_id":{"type":"string","description":"USDG ERC-20 contract address on X Layer"},"expires_at":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"503":{"description":"EVM deposit seed not configured"}}}},"/escrow/{id}/walletconnect":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"rail","in":"query","required":false,"schema":{"type":"string","enum":["base_usdc","xlayer_usdg"],"default":"base_usdc"}}],"get":{"summary":"Return a WalletConnect transaction intent for stablecoin funding","operationId":"walletConnectFundingIntent","description":"Returns an eth_sendTransaction intent for WalletConnect-compatible EVM wallets. The wallet signs and broadcasts an ERC-20 transfer to the per-contract deposit address. Then call /escrow/{id}/sync-funding with the tx hash.","responses":{"200":{"description":"WalletConnect-compatible funding intent","content":{"application/json":{"schema":{"type":"object","required":["contract_id","rail","chain","walletconnect","transaction","payment","sync","expires_at"],"properties":{"contract_id":{"type":"string"},"rail":{"type":"string","enum":["base_usdc","xlayer_usdg"]},"chain":{"type":"string","enum":["base","xlayer"]},"walletconnect":{"type":"object","required":["namespace","chain_id","method"],"properties":{"namespace":{"type":"string","enum":["eip155"]},"chain_id":{"type":"string","examples":["eip155:8453","eip155:196"]},"method":{"type":"string","enum":["eth_sendTransaction"]}}},"transaction":{"type":"object","required":["chainId","to","value","data"],"properties":{"chainId":{"type":"string","examples":["0x2105","0xc4"]},"to":{"type":"string","description":"ERC-20 token contract address"},"value":{"type":"string","enum":["0x0"]},"data":{"type":"string","description":"ERC-20 transfer(recipient, amount) calldata"}}},"payment":{"type":"object","required":["token","symbol","decimals","amount","amount_base_units","recipient","memo"],"properties":{"token":{"type":"string"},"symbol":{"type":"string","enum":["USDC","USDG"]},"decimals":{"type":"integer","enum":[6]},"amount":{"type":"number"},"amount_base_units":{"type":"string"},"recipient":{"type":"string"},"memo":{"type":"null"}}},"sync":{"type":"object","required":["method","url","body"],"properties":{"method":{"type":"string","enum":["POST"]},"url":{"type":"string","format":"uri"},"body":{"type":"object","required":["rail","tx_hash"],"properties":{"rail":{"type":"string","enum":["base_usdc","xlayer_usdg"]},"tx_hash":{"type":"string"}}}}},"expires_at":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Unsupported rail"},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"503":{"description":"EVM deposit seed not configured"}}}},"/escrow/{id}/sync-funding":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Sync direct stablecoin funding from an EVM transaction receipt","operationId":"syncEscrowFunding","description":"Verifies a Base USDC or X Layer USDG ERC-20 transfer receipt against the contract deposit address and expected amount. This is the fallback path when the chain webhook misses a valid transfer.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tx_hash"],"properties":{"tx_hash":{"type":"string","pattern":"^0x[0-9a-fA-F]{64}$"},"rail":{"type":"string","enum":["base_usdc","xlayer_usdg"],"default":"base_usdc"}}}}}},"responses":{"200":{"description":"Funding synced, already funded, or no matching transfer found"},"404":{"description":"Not found"},"409":{"description":"Contract has no EVM funding address yet"},"503":{"description":"RPC not configured"}}}},"/escrow/{id}/fund-usdg-eth":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Fund the contract with USDG on Ethereum","operationId":"fundEscrowUsdgEth","description":"Returns a deterministic per-contract deposit address derived from USDG_ETH_MASTER_SEED + contract id (HKDF-SHA256 → secp256k1 → keccak256 → EIP-55 checksum). Send USDG ERC-20 to deposit_address. The contract advances to \"held\" once an Alchemy webhook confirms the transfer.","responses":{"200":{"description":"USDG (Ethereum) funding instructions","content":{"application/json":{"schema":{"type":"object","required":["deposit_address","amount","currency","chain"],"properties":{"deposit_address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$"},"amount":{"type":"number"},"currency":{"type":"string","enum":["USDG"]},"chain":{"type":"string","enum":["ethereum"]},"asset_id":{"type":"string","description":"USDG ERC-20 contract address"},"expires_at":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"503":{"description":"USDG_ETH_MASTER_SEED not configured"}}}},"/escrow/{id}/fund-usdc":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Fund the contract with USDC on Solana","operationId":"fundEscrowUsdc","description":"Returns the USDC ATA on Solana + the contract memo (shared with USDG funding). Send USDC with the memo; the Helius webhook fires FUND.","responses":{"200":{"description":"USDC (Solana) funding instructions","content":{"application/json":{"schema":{"type":"object","required":["deposit_address","amount","currency","chain","memo"],"properties":{"deposit_address":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string","enum":["USDC"]},"chain":{"type":"string","enum":["solana"]},"memo":{"type":"string"},"asset_id":{"type":"string","description":"USDC SPL mint pubkey"},"expires_at":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"503":{"description":"USDC_DEPOSIT_ADDRESS not configured"}}}},"/escrow/{id}/fund-usdc-eth":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Fund the contract with USDC on Ethereum","operationId":"fundEscrowUsdcEth","description":"Returns the same per-contract derived deposit EOA as /fund-usdg-eth (EOAs accept any ERC-20). asset_id distinguishes which contract to send. The Alchemy webhook fires FUND on a matching transfer of either USDG or USDC.","responses":{"200":{"description":"USDC (Ethereum) funding instructions","content":{"application/json":{"schema":{"type":"object","required":["deposit_address","amount","currency","chain","asset_id"],"properties":{"deposit_address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$"},"amount":{"type":"number"},"currency":{"type":"string","enum":["USDC"]},"chain":{"type":"string","enum":["ethereum"]},"asset_id":{"type":"string","description":"USDC ERC-20 contract address"},"expires_at":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Not found"},"409":{"description":"Contract is not in pending_funding"},"503":{"description":"USDG_ETH_MASTER_SEED or USDC_ETH_CONTRACT not configured"}}}},"/escrow/{id}/pay":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"MPP/x402 payment endpoint for rail discovery or Link SPT funding","operationId":"payEscrow","description":"Single POST that URL-pay wallets (Visa @visa/cli, Coinbase x402, Stripe mppx / Link CLI) can call without knowing about Settle-specific endpoints. With payment_credential.shared_payment_granted_token, creates and confirms a sandbox Stripe PaymentIntent and moves pending_funding -> held on success. Without credentials, returns 402 with an x402-shaped { x402Version: 1, accepts: [...] } body listing configured rails. USDC on Base and USDG on X Layer are primary; Stripe points to sandbox /fund when configured. Persists newly-generated memos/addresses on the contract. Returns 200 if already held, 409 if terminal, 503 if no rails are configured.","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"shared_payment_granted_token":{"type":"string"},"payment_credential":{"type":"object","properties":{"shared_payment_granted_token":{"type":"string"}}}}}}}},"responses":{"200":{"description":"Contract is already past pending_funding, or Link SPT funding was processed"},"402":{"description":"Payment required (x402 challenge)","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"x402 scheme"}},"content":{"application/json":{"schema":{"type":"object","required":["x402Version","accepts"],"properties":{"x402Version":{"type":"integer","enum":[1]},"error":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"accepts":{"type":"array","items":{"type":"object","required":["scheme","network","asset","amount","maxAmountRequired"],"properties":{"scheme":{"type":"string","enum":["exact","stripe-checkout"]},"network":{"type":"string","enum":["solana","ethereum","stripe"]},"asset":{"type":"string"},"assetId":{"type":"string"},"amount":{"type":"string"},"maxAmountRequired":{"type":"string"},"resource":{"type":"string"},"description":{"type":"string"},"payTo":{"type":"string"},"memo":{"type":"string"},"endpoint":{"type":"string"},"mimeType":{"type":"string"}}}}}}}}},"404":{"description":"Not found"},"409":{"description":"Contract is in a terminal state"},"503":{"description":"No payment rails configured"}}}},"/webhooks/usdg-transfer-eth":{"post":{"summary":"USDG transfer webhook (Alchemy / Ethereum)","operationId":"usdgTransferEthWebhook","description":"Validates the Alchemy webhook HMAC-SHA256 signature, parses the ADDRESS_ACTIVITY payload, looks up matching contracts by toAddress, and fires FUND if the USDG ERC-20 transfer covers the expected amount. Idempotent on redelivery; transfers to unknown addresses or for the wrong contract are ignored.","responses":{"200":{"description":"Processed or ignored"},"401":{"description":"Invalid signature"},"503":{"description":"USDG_ETH_WEBHOOK_SECRET or USDG_ETH_CONTRACT not configured"}}}}},"components":{"schemas":{"ContractState":{"type":"string","enum":["pending_funding","held","condition_met","settlement_pending","settled","payout_failed","disputed","refunded","expired"]},"PayoutMethod":{"type":"string","enum":["bridge","stripe","base_usdc","xlayer_usdg","usdg_solana","usdc_solana","usdg_ethereum","usdc_ethereum","manual"]},"PayoutStatus":{"type":"string","enum":["not_ready","ready","authorized","submitted","confirmed","failed"]},"Payout":{"type":"object","required":["status"],"properties":{"status":{"$ref":"#/components/schemas/PayoutStatus"},"rail":{"$ref":"#/components/schemas/PayoutMethod"},"destination":{"type":"string"},"authorized_by":{"type":"string"},"authorized_at":{"type":"string","format":"date-time"},"authorization_id":{"type":"string"},"submitted_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"confirmation_id":{"type":"string"},"processor":{"type":"string"},"processor_transfer_id":{"type":"string"},"processor_state":{"type":"string"},"failure_reason":{"type":"string"}}},"DeferredCommitment":{"type":"object","required":["id","scheme","network","resource","signature_agent","signature_input","signature","committed_at"],"properties":{"id":{"type":"string"},"scheme":{"type":"string","enum":["deferred"]},"network":{"type":"string","enum":["settle"]},"resource":{"type":"string","format":"uri"},"terms_url":{"type":"string","format":"uri"},"signature_agent":{"type":"string"},"signature_input":{"type":"string","enum":["settle-deferred-v1"]},"signature":{"type":"string"},"public_key_jwk":{"type":"object","additionalProperties":true},"committed_at":{"type":"string","format":"date-time"}}},"DeferredOffer":{"type":"object","required":["id","scheme","network","resource","escrow","signature_input","commit"],"properties":{"id":{"type":"string"},"scheme":{"type":"string","enum":["deferred"]},"network":{"type":"string","enum":["settle"]},"resource":{"type":"string","format":"uri"},"terms_url":{"type":"string","format":"uri"},"escrow":{"$ref":"#/components/schemas/CreateContractRequest"},"signature_input":{"type":"string","enum":["settle-deferred-v1"]},"signing_payload":{"type":"string"},"commit":{"type":"string","enum":["/x402/deferred/commit"]}}},"DeferredOfferResponse":{"type":"object","required":["x402Version","accepts"],"properties":{"x402Version":{"type":"number","enum":[1]},"accepts":{"type":"array","items":{"$ref":"#/components/schemas/DeferredOffer"}}}},"DeferredCommitRequest":{"type":"object","required":["offer","signature_agent","signature_input","signature","public_key_jwk"],"properties":{"offer":{"$ref":"#/components/schemas/DeferredOffer"},"contract_id":{"type":"string"},"signature_agent":{"type":"string"},"signature_input":{"type":"string","enum":["settle-deferred-v1"]},"signature":{"type":"string"},"public_key_jwk":{"type":"object","additionalProperties":true}}},"ConditionType":{"type":"string","enum":["manual","github_pr_merged","file_delivered","api_response","stripe_invoice_paid","onchain_event"]},"Fallback":{"type":"string","enum":["return_to_client","release_to_provider"]},"Condition":{"type":"object","required":["type","deadline","fallback"],"properties":{"type":{"$ref":"#/components/schemas/ConditionType"},"params":{"type":"object","additionalProperties":{"type":"string"}},"deadline":{"type":"string","format":"date-time"},"fallback":{"$ref":"#/components/schemas/Fallback"}}},"CreateContractRequest":{"type":"object","required":["client_wallet","provider_wallet","condition"],"anyOf":[{"required":["amount_usdc"]},{"required":["amount_usdg"]}],"properties":{"amount_usdc":{"type":"number","exclusiveMinimum":0,"description":"USDC amount. The live v0.1 deployment enforces a small launch cap."},"amount_usdg":{"type":"number","exclusiveMinimum":0,"description":"USDG amount. The live v0.1 deployment enforces a small launch cap."},"gas_tip_percent":{"type":"number","minimum":0,"maximum":10,"description":"Optional payer tip percentage used to fund the operator gas reserve. Added to funding total; provider payout stays amount_usdc."},"client_wallet":{"type":"string","minLength":1},"provider_wallet":{"type":"string","minLength":1},"condition":{"$ref":"#/components/schemas/Condition"}}},"Contract":{"type":"object","required":["id","state","amount_usdc","client_wallet","provider_wallet","condition","created_at"],"properties":{"id":{"type":"string"},"state":{"$ref":"#/components/schemas/ContractState"},"amount_usdc":{"type":"number"},"gas_tip_percent":{"type":"number"},"gas_tip_usdc":{"type":"number"},"client_wallet":{"type":"string"},"provider_wallet":{"type":"string"},"condition":{"$ref":"#/components/schemas/Condition"},"stripe_payment_intent":{"type":"string"},"link_card_id":{"type":"string"},"usdg_funding_ref":{"type":"string"},"usdg_eth_address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$"},"funding_rail":{"type":"string","enum":["stablecoin","stripe_checkout","stripe_link"]},"funding_confirmed_at":{"type":"string","format":"date-time"},"commitment":{"$ref":"#/components/schemas/DeferredCommitment"},"payout":{"$ref":"#/components/schemas/Payout"},"created_at":{"type":"string","format":"date-time"},"funded_at":{"type":"string","format":"date-time"},"released_at":{"type":"string","format":"date-time"}}}}}}