[{"data":1,"prerenderedAt":1308},["ShallowReactive",2],{"content-\u002Fresources\u002Fmore\u002Fstablecoin-payouts-api-integration-checklist":3,"resources-category-stablecoin-payouts-api-integration-checklist":1293},{"title":4,"seoTitle":5,"description":6,"date":7,"updated":7,"category":8,"faq":9,"howto":28,"body":55},"How to integrate a stablecoin payouts API: a developer checklist (2026)","Stablecoin payouts API integration: developer checklist","Integrate a stablecoin payouts API: dev instance, KYC, bank account, quote, payout request, webhooks, rail minimums, go-live checklist and a 12-test plan.","2026-10-23","payments",[10,13,16,19,22,25],{"q":11,"a":12},"Is there a sandbox for BlindPay payouts?","Yes. Development instances are free and never generate invoices. Customers auto-approve, payouts complete automatically, and you use the USDB test token on test networks. The API surface matches production, and requests go to the same hostname, with the instance behind your API key deciding the environment.",{"q":14,"a":15},"How are webhooks delivered?","BlindPay sends signed HTTP callbacks to an https endpoint you register on the instance. Each call carries svix-id, svix-timestamp and svix-signature headers, which you verify with the endpoint's signing secret using the raw body. The svix-id stays the same across redeliveries, so you can use it to deduplicate events.",{"q":17,"a":18},"How do I handle an expired quote?","Read expires_at, which is in epoch milliseconds, and create a new quote when it passes. Payout quotes last 5 minutes by default and can be shorter for SEPA and Faster Payments. Show the customer the new amount before you execute, because fees and rate are locked per quote, not carried over.",{"q":20,"a":21},"How do I test a failed payout?","On a development instance, set the payout quote's request_amount to 66600 before you execute and the payout ends as failed. Use 77700 to force refunded. Any other amount completes. Run both on every change to your handler, since production failures are rare and your recovery code is otherwise untested.",{"q":23,"a":24},"What KYC data is required?","For an individual on KYC Standard: name, date of birth, email, country, address, tax ID, an ID document and a selfie. KYC Enhanced adds proof of address, a source of funds document and the purpose of transactions. A business needs KYB: legal name, tax ID, formation date, address, website, documents and at least one owner.",{"q":26,"a":27},"Do I need to write the integration by hand?","No. BlindPay publishes SDKs for Node.js, Python, Go, PHP and Swift, an OpenAPI spec, a hosted MCP server for AI agents and a CLI. They call the same REST API, so the flow and the checks here apply either way. Use the SDK you prefer, but still test the failure paths yourself.",{"name":29,"steps":30},"Integrate a stablecoin payouts API",[31,34,37,40,43,46,49,52],{"name":32,"text":33},"Create a free development instance","Sign up, create a development instance and generate an API key. Development instances are free, auto-approve customers and complete payouts automatically.",{"name":35,"text":36},"Authenticate with a bearer API key","Send the key in an Authorization Bearer header on every request to https:\u002F\u002Fapi.blindpay.com\u002Fv1, and keep it on your server.",{"name":38,"text":39},"Onboard the recipient with KYC data","Create a customer with the required KYC fields (or KYB for a business) and wait for the kyc_status to reach approved.",{"name":41,"text":42},"Add the recipient bank account","Create a bank account for the customer once, using the fields for the chosen rail, and wait for status approved.",{"name":44,"text":45},"Create a payout quote","Create a quote with the bank_account_id, currency_type, cover_fees, request_amount, network and token. It locks the rate and fees for 5 minutes by default.",{"name":47,"text":48},"Execute the payout","Call the payout endpoint with the quote_id and sender_wallet_address before the quote expires. A quote can back only one payout.",{"name":50,"text":51},"Listen to webhooks for every state change","Register an https endpoint, verify the svix signature headers, and handle payout.new, payout.update, payout.complete and payout.partnerFee.",{"name":53,"text":54},"Move to production","Run the test plan, switch to a production instance and key, use mainnet networks with USDC or USDT, and start with small real payouts.",{"type":56,"value":57,"toc":1278},"minimark",[58,62,76,82,122,127,130,266,285,289,292,321,333,337,343,359,363,366,377,489,547,551,562,622,658,663,667,675,679,682,770,787,791,797,860,893,897,900,979,983,986,1163,1167,1170,1207,1211,1262,1266,1274],[59,60,61],"p",{},"To integrate a stablecoin payouts API, follow eight steps: create a free development instance, authenticate with a bearer API key, onboard the recipient with KYC data, add a bank account, create a quote, execute the payout, listen to webhooks for every state change, and move to production. This page is the checklist, with the requests and tests.",[59,63,64,65,70,71,75],{},"It covers BlindPay's API as of October 2026. For the concept, start with ",[66,67,69],"a",{"href":68},"\u002Fresources\u002Fmore\u002Fwhat-is-a-stablecoin-payouts-api","what a stablecoin payouts API is"," and ",[66,72,74],{"href":73},"\u002Fresources\u002Fmore\u002Fhow-stablecoin-payouts-work-step-by-step","how a stablecoin payout works step by step",". Older pages go deeper on single topics, and this one links them rather than repeating them. BlindPay publishes this post.",[59,77,78],{},[79,80,81],"strong",{},"Key takeaways",[83,84,85,89,101,104,119],"ul",{},[86,87,88],"li",{},"The flow is fixed: add a bank account once, create a quote that locks rate and fees for 5 minutes by default, then execute the payout.",[86,90,91,92,96,97,100],{},"The payout request carries a ",[93,94,95],"code",{},"quote_id"," and a ",[93,98,99],{},"sender_wallet_address",", and one quote can back only one payout.",[86,102,103],{},"Minimums by rail: SWIFT 100 USD, SEPA 50 USDC or 40 EUR, Faster Payments 70 USDC or 50 GBP, every other rail 10 USD sender amount.",[86,105,106,107,110,111,114,115,118],{},"On development instances, a ",[93,108,109],{},"request_amount"," of 66600 forces ",[93,112,113],{},"failed"," and 77700 forces ",[93,116,117],{},"refunded",".",[86,120,121],{},"Build against webhooks, not polling, and verify the signature on every call.",[123,124,126],"h2",{"id":125},"what-does-the-integration-look-like-end-to-end","What does the integration look like end to end?",[59,128,129],{},"One customer, one bank account, one quote and one payout per recipient payment. Everything else is state handling.",[131,132,133,149],"table",{},[134,135,136],"thead",{},[137,138,139,143,146],"tr",{},[140,141,142],"th",{},"Step",[140,144,145],{},"Call or action",[140,147,148],{},"You get",[150,151,152,164,185,200,216,235,255],"tbody",{},[137,153,154,158,161],{},[155,156,157],"td",{},"1",[155,159,160],{},"Create a development instance and API key",[155,162,163],{},"An isolated, free environment",[137,165,166,169,172],{},[155,167,168],{},"2",[155,170,171],{},"Accept terms of service, create a customer with KYC data",[155,173,174,177,178,181,182],{},[93,175,176],{},"kyc_status"," of ",[93,179,180],{},"verifying",", then ",[93,183,184],{},"approved",[137,186,187,190,193],{},[155,188,189],{},"3",[155,191,192],{},"Create a bank account for the customer",[155,194,195,196,199],{},"A ",[93,197,198],{},"ba_..."," ID and status",[137,201,202,205,207],{},[155,203,204],{},"4",[155,206,44],{},[155,208,195,209,212,213],{},[93,210,211],{},"qu_..."," ID, amounts, fees and ",[93,214,215],{},"expires_at",[137,217,218,221,226],{},[155,219,220],{},"5",[155,222,223,224],{},"Execute the payout with ",[93,225,95],{},[155,227,195,228,231,232],{},[93,229,230],{},"po_..."," ID with status ",[93,233,234],{},"processing",[137,236,237,240,243],{},[155,238,239],{},"6",[155,241,242],{},"Receive webhooks",[155,244,245,248,249,248,252],{},[93,246,247],{},"payout.new",", ",[93,250,251],{},"payout.update",[93,253,254],{},"payout.complete",[137,256,257,260,263],{},[155,258,259],{},"7",[155,261,262],{},"Reconcile",[155,264,265],{},"Your ledger matches the payout and fee fields",[59,267,268,272,273,279,280,118],{},[66,269,271],{"href":270},"\u002Fresources\u002Fmore\u002Fhow-to-integrate-a-stablecoin-api","How to integrate a stablecoin API"," covers the wider build, including SDK choice. BlindPay ships SDKs for Node.js, Python, Go, PHP and Swift, plus an ",[66,274,278],{"href":275,"rel":276},"https:\u002F\u002Fapi.blindpay.com\u002Fdoc",[277],"nofollow","OpenAPI spec",", all wrapping the same REST API described in the ",[66,281,284],{"href":282,"rel":283},"https:\u002F\u002Fapi.blindpay.com\u002Freference",[277],"API reference",[123,286,288],{"id":287},"how-do-you-set-up-the-environment-and-authenticate","How do you set up the environment and authenticate?",[59,290,291],{},"Create a development instance, generate an API key and send it as a bearer token. Keep it on your server.",[59,293,294,295,298,299,302,303,307,308,311,312,315,316,320],{},"Development and production expose the same endpoints, fields and response shapes, at the same hostname, ",[93,296,297],{},"https:\u002F\u002Fapi.blindpay.com",". The instance your key belongs to decides the environment. Development instances are free, auto-approve customers and use the ",[93,300,301],{},"USDB"," test token on test networks. ",[66,304,306],{"href":305},"\u002Fresources\u002Fmore\u002Fstablecoin-api-sandbox-vs-production","Sandbox vs production"," lists every difference. Production uses mainnet networks with ",[93,309,310],{},"USDC"," or ",[93,313,314],{},"USDT","; check the ",[66,317,319],{"href":318},"\u002Fdocs\u002Fkb\u002Fsupported-chains","supported chains"," page before you name a network.",[59,322,323,324,327,328,332],{},"Send mutating requests with an ",[93,325,326],{},"Idempotency-Key"," header so a network retry cannot create two payouts. The docs say a key is kept for 24 hours, and a retry only replays if the body matches byte for byte. ",[66,329,331],{"href":330},"\u002Fresources\u002Fmore\u002Fstablecoin-api-idempotency-keys","Idempotency keys for stablecoin APIs"," has the pattern.",[123,334,336],{"id":335},"what-kyc-data-do-you-send-for-the-recipient","What KYC data do you send for the recipient?",[59,338,339,340,342],{},"The customer fields depend on type: individual or business. Create the customer, then wait for ",[93,341,184],{}," before you add a bank account or quote.",[59,344,345,346,349,350,354,355,118],{},"On production, KYC Standard is automated in about 60 seconds. KYC Enhanced (high-risk countries) and KYB Standard take 3 hours to 1 business day. Development instances auto-approve, so a name of ",[93,347,348],{},"Fail"," forces a rejection for testing. The ",[66,351,353],{"href":352},"\u002Fdocs\u002Fkb\u002Fkyc","KYC requirements"," list every field. The compliance side, including who owns what, is in ",[66,356,358],{"href":357},"\u002Fresources\u002Fmore\u002Fstablecoin-payout-compliance","stablecoin payout compliance",[123,360,362],{"id":361},"how-do-you-add-a-bank-account-and-create-a-quote","How do you add a bank account and create a quote?",[59,364,365],{},"Add the bank account once per recipient, then create a quote for each payment.",[59,367,368,369,372,373,376],{},"Bank account fields depend on the rail, so fetch them at runtime from the public rails endpoint instead of hardcoding them. Third-party accounts are allowed, with ",[93,370,371],{},"recipient_relationship"," set to something other than ",[93,374,375],{},"first_party",". Then create the quote against that bank account:",[378,379,384],"pre",{"className":380,"code":381,"language":382,"meta":383,"style":383},"language-bash shiki shiki-themes github-light","curl --request POST \\\n  --url https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fquotes \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --header 'Content-Type: application\u002Fjson' \\\n  --data '{\n  \"bank_account_id\": \"ba_000000000000\",\n  \"currency_type\": \"sender\",\n  \"cover_fees\": false,\n  \"request_amount\": 10000,\n  \"network\": \"sepolia\",\n  \"token\": \"USDB\"\n}'\n","bash","",[93,385,386,406,417,428,438,447,453,459,465,471,477,483],{"__ignoreMap":383},[387,388,391,395,399,403],"span",{"class":389,"line":390},"line",1,[387,392,394],{"class":393},"s7eDp","curl",[387,396,398],{"class":397},"sYu0t"," --request",[387,400,402],{"class":401},"sYBdl"," POST",[387,404,405],{"class":397}," \\\n",[387,407,409,412,415],{"class":389,"line":408},2,[387,410,411],{"class":397},"  --url",[387,413,414],{"class":401}," https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fquotes",[387,416,405],{"class":397},[387,418,420,423,426],{"class":389,"line":419},3,[387,421,422],{"class":397},"  --header",[387,424,425],{"class":401}," 'Authorization: Bearer YOUR_API_KEY'",[387,427,405],{"class":397},[387,429,431,433,436],{"class":389,"line":430},4,[387,432,422],{"class":397},[387,434,435],{"class":401}," 'Content-Type: application\u002Fjson'",[387,437,405],{"class":397},[387,439,441,444],{"class":389,"line":440},5,[387,442,443],{"class":397},"  --data",[387,445,446],{"class":401}," '{\n",[387,448,450],{"class":389,"line":449},6,[387,451,452],{"class":401},"  \"bank_account_id\": \"ba_000000000000\",\n",[387,454,456],{"class":389,"line":455},7,[387,457,458],{"class":401},"  \"currency_type\": \"sender\",\n",[387,460,462],{"class":389,"line":461},8,[387,463,464],{"class":401},"  \"cover_fees\": false,\n",[387,466,468],{"class":389,"line":467},9,[387,469,470],{"class":401},"  \"request_amount\": 10000,\n",[387,472,474],{"class":389,"line":473},10,[387,475,476],{"class":401},"  \"network\": \"sepolia\",\n",[387,478,480],{"class":389,"line":479},11,[387,481,482],{"class":401},"  \"token\": \"USDB\"\n",[387,484,486],{"class":389,"line":485},12,[387,487,488],{"class":401},"}'\n",[59,490,491,493,494,497,498,501,502,505,506,509,510,513,514,248,517,248,520,248,523,248,526,248,529,70,532,534,535,538,539,70,543,118],{},[93,492,109],{}," is an integer in minor units, so 10000 is 100.00. ",[93,495,496],{},"currency_type"," says which side the amount is denominated in: ",[93,499,500],{},"sender"," is the stablecoin, ",[93,503,504],{},"receiver"," is the fiat. ",[93,507,508],{},"cover_fees: false"," takes fees out of the fiat received, and ",[93,511,512],{},"true"," adds them on top, which payroll teams usually want. The response returns ",[93,515,516],{},"sender_amount",[93,518,519],{},"receiver_amount",[93,521,522],{},"flat_fee",[93,524,525],{},"partner_fee_amount",[93,527,528],{},"commercial_quotation",[93,530,531],{},"blindpay_quotation",[93,533,215],{}," in epoch ",[79,536,537],{},"milliseconds",". See ",[66,540,542],{"href":541},"\u002Fdocs\u002Fpayout-quotes","payout quotes",[66,544,546],{"href":545},"\u002Fresources\u002Fmore\u002Fstablecoin-payout-api-pricing","pricing",[123,548,550],{"id":549},"what-does-the-payout-request-look-like","What does the payout request look like?",[59,552,553,554,556,557,561],{},"One POST with the ",[93,555,95],{}," and the funding wallet address. Check the field list in the ",[66,558,560],{"href":559},"\u002Fdocs\u002Fpayouts","payouts docs"," before you ship.",[378,563,565],{"className":380,"code":564,"language":382,"meta":383,"style":383},"curl --request POST \\\n  --url https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fpayouts\u002Fevm \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --header 'Content-Type: application\u002Fjson' \\\n  --data '{\n  \"quote_id\": \"qu_000000000000\",\n  \"sender_wallet_address\": \"YOUR_WALLET_ADDRESS\"\n}'\n",[93,566,567,577,586,594,602,608,613,618],{"__ignoreMap":383},[387,568,569,571,573,575],{"class":389,"line":390},[387,570,394],{"class":393},[387,572,398],{"class":397},[387,574,402],{"class":401},[387,576,405],{"class":397},[387,578,579,581,584],{"class":389,"line":408},[387,580,411],{"class":397},[387,582,583],{"class":401}," https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fpayouts\u002Fevm",[387,585,405],{"class":397},[387,587,588,590,592],{"class":389,"line":419},[387,589,422],{"class":397},[387,591,425],{"class":401},[387,593,405],{"class":397},[387,595,596,598,600],{"class":389,"line":430},[387,597,422],{"class":397},[387,599,435],{"class":401},[387,601,405],{"class":397},[387,603,604,606],{"class":389,"line":440},[387,605,443],{"class":397},[387,607,446],{"class":401},[387,609,610],{"class":389,"line":449},[387,611,612],{"class":401},"  \"quote_id\": \"qu_000000000000\",\n",[387,614,615],{"class":389,"line":455},[387,616,617],{"class":401},"  \"sender_wallet_address\": \"YOUR_WALLET_ADDRESS\"\n",[387,619,620],{"class":389,"line":461},[387,621,488],{"class":401},[59,623,624,625,628,629,70,632,635,636,231,638,640,641,248,644,248,647,70,650,653,654,118],{},"Payout creation is split by network: ",[93,626,627],{},"\u002Fpayouts\u002Fevm"," for EVM and managed wallets, ",[93,630,631],{},"\u002Fpayouts\u002Fstellar",[93,633,634],{},"\u002Fpayouts\u002Fsolana"," for those chains, each with its own request shape. The response returns a ",[93,637,230],{},[93,639,234],{},", and sub-status objects ",[93,642,643],{},"tracking_transaction",[93,645,646],{},"tracking_payment",[93,648,649],{},"tracking_liquidity",[93,651,652],{},"tracking_complete",". If you fund from an external wallet, authorize the exact amount on-chain first. A managed wallet needs no signing, but it is custodial: see ",[66,655,657],{"href":656},"\u002Fresources\u002Fmore\u002Fcustodial-vs-non-custodial-payout-apis","custodial vs non-custodial payout APIs",[59,659,195,660,662],{},[93,661,95],{}," can only back one payout, so a second call with the same quote returns an error. Create a new quote instead.",[123,664,666],{"id":665},"which-flavor-of-the-docs-should-you-read","Which flavor of the docs should you read?",[59,668,669,670,674],{},"BlindPay's docs come in two flavors. Abstracted treats the stablecoin leg as plumbing and walks you through add account, quote, execute. Advanced exposes funding paths and on-chain authorization. Read Abstracted if you think in bank rails, and Advanced if you hold wallets. ",[66,671,673],{"href":672},"\u002Fresources\u002Fmore\u002Fabstracted-vs-advanced-blockchain-payment-api","Abstracted vs advanced blockchain payment APIs"," explains the choice.",[123,676,678],{"id":677},"what-are-the-minimums-by-rail","What are the minimums by rail?",[59,680,681],{},"Check them at quote time. The quote rejects amounts below the minimum, and you should surface that error rather than hardcode the number.",[131,683,684,701],{},[134,685,686],{},[137,687,688,695,698],{},[140,689,690,691,694],{},"Rail (",[93,692,693],{},"type",")",[140,696,697],{},"Minimum",[140,699,700],{},"Error when below",[150,702,703,719,738,757],{},[137,704,705,711,714],{},[155,706,707,708,694],{},"SWIFT (",[93,709,710],{},"international_swift",[155,712,713],{},"100 USD requested amount, before fees",[155,715,716],{},[93,717,718],{},"swift_minimum_is_100_usd",[137,720,721,727,730],{},[155,722,723,724,694],{},"SEPA (",[93,725,726],{},"sepa",[155,728,729],{},"50 USDC by sender amount, or 40 EUR by receiver amount",[155,731,732,248,735],{},[93,733,734],{},"sepa_minimum_is_50_usdc",[93,736,737],{},"sepa_minimum_is_40_eur",[137,739,740,746,749],{},[155,741,742,743,694],{},"Faster Payments (",[93,744,745],{},"faster_payments",[155,747,748],{},"70 USDC by sender amount, or 50 GBP by receiver amount",[155,750,751,248,754],{},[93,752,753],{},"faster_payments_minimum_is_70_usdc",[93,755,756],{},"faster_payments_minimum_is_50_gbp",[137,758,759,762,765],{},[155,760,761],{},"Every other rail (ACH, wire, RTP, Pix, PIX Safe, TED, SPEI, ACH COP, Transfers)",[155,763,764],{},"10 USD sender amount",[155,766,767],{},[93,768,769],{},"LIMITS_AMOUNT_OUT_OF_RANGE",[59,771,772,773,777,778,782,783,786],{},"Payout times from the ",[66,774,776],{"href":775},"\u002Fdocs\u002Fbank-accounts","bank accounts docs",": Pix, PIX Safe, SPEI, Transfers (Argentina) and RTP are instant, wire and TED and ACH COP and SEPA about 1 business day, ACH and SWIFT about 2 business days, and Faster Payments 5 to 30 minutes. The ",[66,779,781],{"href":780},"\u002Fdocs\u002Fkb\u002Fcut-off-times","cut-off times"," reference says SWIFT settlement can take up to 5 business days. All SWIFT payouts start ",[93,784,785],{},"on_hold"," until compliance documents are submitted and approved. For international wires, BlindPay runs SWIFT payments and collections on behalf of (POBO\u002FCOBO), with UETR tracking and MT103 confirmations.",[123,788,790],{"id":789},"how-should-you-handle-webhooks-and-statuses","How should you handle webhooks and statuses?",[59,792,793,794,796],{},"Register an https endpoint on the instance, verify the signature on every call and treat ",[93,795,254],{}," as the terminal signal.",[131,798,799,809],{},[134,800,801],{},[137,802,803,806],{},[140,804,805],{},"Event",[140,807,808],{},"Fires when",[150,810,811,820,834,850],{},[137,812,813,817],{},[155,814,815],{},[93,816,247],{},[155,818,819],{},"A payout is created",[137,821,822,826],{},[155,823,824],{},[93,825,251],{},[155,827,828,829,831,832],{},"A payout changes status, for example ",[93,830,234],{}," to ",[93,833,785],{},[137,835,836,840],{},[155,837,838],{},[93,839,254],{},[155,841,842,843,248,846,311,848],{},"A payout reaches ",[93,844,845],{},"completed",[93,847,113],{},[93,849,117],{},[137,851,852,857],{},[155,853,854],{},[93,855,856],{},"payout.partnerFee",[155,858,859],{},"A payout completes and a partner fee is owed",[59,861,862,863,248,866,70,869,872,873,877,878,883,884,70,888,892],{},"Verify ",[93,864,865],{},"svix-id",[93,867,868],{},"svix-timestamp",[93,870,871],{},"svix-signature"," against the raw body with HMAC-SHA256 and reject timestamps outside a 5 minute tolerance. The ",[66,874,876],{"href":875},"\u002Fdocs\u002Flearn\u002Fwebhooks-verification","verification docs"," have the code. For local testing, ",[66,879,882],{"href":880,"rel":881},"https:\u002F\u002Fwebhook.cool\u002F",[277],"webhook.cool"," gives a temporary URL that logs each request. ",[66,885,887],{"href":886},"\u002Fresources\u002Fmore\u002Fstablecoin-api-webhooks-reconciliation","Webhooks and reconciliation",[66,889,891],{"href":890},"\u002Fresources\u002Fmore\u002Fstablecoin-payout-statuses-explained","payout statuses explained"," cover the handler design.",[123,894,896],{"id":895},"what-is-the-go-live-checklist","What is the go-live checklist?",[59,898,899],{},"Walk this list on the day you switch to production.",[901,902,903,916,922,931,940,953,962,968],"ol",{},[86,904,905,908,909,911,912,118],{},[79,906,907],{},"Quote expiry."," Read ",[93,910,215],{}," and requote after 5 minutes (shorter on SEPA and Faster Payments). See ",[66,913,915],{"href":914},"\u002Fresources\u002Fmore\u002Fhandle-expired-quotes-typescript-python","handling expired quotes",[86,917,918,921],{},[79,919,920],{},"Minimums."," Surface the rail's minimum error to the user instead of failing silently.",[86,923,924,927,928,930],{},[79,925,926],{},"Webhook verification."," Verify signatures, check the timestamp, deduplicate on ",[93,929,865],{},", and allowlist the documented source IPs only as an extra layer.",[86,932,933,936,937,939],{},[79,934,935],{},"Retries."," Send an ",[93,938,326],{}," on every mutating call and retry only on network errors and 5xx.",[86,941,942,945,946,948,949,118],{},[79,943,944],{},"Refund scenarios."," Know your refund wallet, and know that a ",[93,947,113],{}," payout is not refunded automatically: contact ",[66,950,952],{"href":951},"mailto:support@blindpay.com","support@blindpay.com",[86,954,955,958,959,961],{},[79,956,957],{},"Holds."," Holds can take up to 30 days, and a timeout fails the payout. Tell recipients what ",[93,960,785],{}," means.",[86,963,964,967],{},[79,965,966],{},"Reconciliation."," Store the quote ID, payout ID and fee fields against each ledger entry.",[86,969,970,973,974,311,976,978],{},[79,971,972],{},"Production credentials."," New production API key, mainnet networks, ",[93,975,310],{},[93,977,314],{},", and a small first payout.",[123,980,982],{"id":981},"what-is-the-12-item-pre-launch-test-plan","What is the 12-item pre-launch test plan?",[59,984,985],{},"Run all twelve on a development instance and record the result. Expected outcomes come from the docs.",[131,987,988,1001],{},[134,989,990],{},[137,991,992,995,998],{},[140,993,994],{},"#",[140,996,997],{},"Test",[140,999,1000],{},"Expected outcome",[150,1002,1003,1017,1029,1041,1054,1069,1081,1091,1104,1121,1136,1147],{},[137,1004,1005,1007,1010],{},[155,1006,157],{},[155,1008,1009],{},"Create a customer with valid test data",[155,1011,1012,1014,1015],{},[93,1013,176],{}," ends at ",[93,1016,184],{},[137,1018,1019,1021,1026],{},[155,1020,168],{},[155,1022,1023,1024],{},"Create a customer named ",[93,1025,348],{},[155,1027,1028],{},"Rejected, and your onboarding shows the rejection path",[137,1030,1031,1033,1036],{},[155,1032,189],{},[155,1034,1035],{},"Add a bank account for your target rail",[155,1037,1038,1039],{},"Account reaches ",[93,1040,184],{},[137,1042,1043,1045,1048],{},[155,1044,204],{},[155,1046,1047],{},"Create a payout quote at a normal amount",[155,1049,1050,1051,1053],{},"Quote returns amounts, fees and ",[93,1052,215],{}," in milliseconds",[137,1055,1056,1058,1061],{},[155,1057,220],{},[155,1059,1060],{},"Execute the payout with that quote",[155,1062,1063,1064,181,1066,1068],{},"Status ",[93,1065,234],{},[93,1067,845],{}," automatically",[137,1070,1071,1073,1078],{},[155,1072,239],{},[155,1074,1075,1076],{},"Execute twice with the same ",[93,1077,95],{},[155,1079,1080],{},"Second call returns an error, no second payout",[137,1082,1083,1085,1088],{},[155,1084,259],{},[155,1086,1087],{},"Let a quote expire, then execute",[155,1089,1090],{},"Execution fails, and your code requotes",[137,1092,1093,1096,1099],{},[155,1094,1095],{},"8",[155,1097,1098],{},"Quote below the rail minimum",[155,1100,1101,1103],{},[93,1102,769],{}," or the rail-specific error",[137,1105,1106,1109,1115],{},[155,1107,1108],{},"9",[155,1110,1111,1112,1114],{},"Quote with ",[93,1113,109],{}," 66600 and execute",[155,1116,1117,1118,1120],{},"Payout ends ",[93,1119,113],{},", handler marks it failed",[137,1122,1123,1126,1131],{},[155,1124,1125],{},"10",[155,1127,1111,1128,1130],{},[93,1129,109],{}," 77700 and execute",[155,1132,1117,1133,1135],{},[93,1134,117],{},", handler records the refund",[137,1137,1138,1141,1144],{},[155,1139,1140],{},"11",[155,1142,1143],{},"Replay a webhook and send a bad signature",[155,1145,1146],{},"Duplicate is ignored, bad signature is rejected",[137,1148,1149,1152,1157],{},[155,1150,1151],{},"12",[155,1153,1154,1155],{},"Send the same mutating call twice with one ",[93,1156,326],{},[155,1158,1159,1160],{},"Second response replays with ",[93,1161,1162],{},"Idempotency-Replayed: true",[123,1164,1166],{"id":1165},"what-shortcuts-exist-for-ai-agents-and-the-terminal","What shortcuts exist for AI agents and the terminal?",[59,1168,1169],{},"The hosted MCP server and the CLI let you try the flow without writing code first. BlindPay describes itself as the most AI-native stablecoin infrastructure.",[59,1171,1172,1173,1176,1177,1180,1181,1184,1185,248,1188,1191,1192,1196,1197,1201,1202,118],{},"The hosted MCP server at ",[93,1174,1175],{},"https:\u002F\u002Fmcp.blindpay.com\u002Fmcp"," signs in over OAuth and lets an agent quote and track payouts, with a read-only variant at ",[93,1178,1179],{},"https:\u002F\u002Fmcp.blindpay.com\u002Fmcp\u002Freadonly",". Tools carry read-only and destructive annotations, but the server does not block a call by itself, so keep a human confirmation step. The CLI (",[93,1182,1183],{},"@blindpay\u002Fcli",") supports ",[93,1186,1187],{},"--json",[93,1189,1190],{},"blindpay schema"," and predictable exit codes (",[66,1193,1195],{"href":1194},"\u002Fblog\u002Fcli","CLI post","). Read the ",[66,1198,1200],{"href":1199},"\u002Fdocs\u002Fmcp\u002Ftools","MCP docs"," and the ",[66,1203,1206],{"href":1204,"rel":1205},"https:\u002F\u002Fmodelcontextprotocol.io",[277],"Model Context Protocol site",[123,1208,1210],{"id":1209},"methodology-and-sources","Methodology and sources",[59,1212,1213,1214,1218,1219,1218,1222,70,1225,1228,1229,248,1232,248,1234,248,1237,248,1240,248,1242,248,1246,248,1250,248,1254,70,1258,1261],{},"External sources: the ",[66,1215,1217],{"href":282,"rel":1216},[277],"BlindPay API reference",", the ",[66,1220,278],{"href":275,"rel":1221},[277],[66,1223,1206],{"href":1204,"rel":1224},[277],[66,1226,882],{"href":880,"rel":1227},[277],". BlindPay facts come from the ",[66,1230,1231],{"href":559},"payouts",[66,1233,542],{"href":541},[66,1235,1236],{"href":775},"bank accounts",[66,1238,1239],{"href":352},"KYC",[66,1241,781],{"href":780},[66,1243,1245],{"href":1244},"\u002Fdocs\u002Flearn\u002Fwebhooks","webhooks",[66,1247,1249],{"href":1248},"\u002Fdocs\u002Flearn\u002Fidempotency","idempotency",[66,1251,1253],{"href":1252},"\u002Fdocs\u002Flearn\u002Fsandbox-vs-production","sandbox vs production",[66,1255,1257],{"href":1256},"\u002Fdocs\u002Fsdks","SDKs",[66,1259,1260],{"href":1199},"MCP"," docs, checked in October 2026.",[123,1263,1265],{"id":1264},"what-to-do-next","What to do next",[59,1267,1268,1269,1273],{},"Start in the development instance: create a customer, add a bank account, quote and execute a payout, then run the 12 tests above. The ",[66,1270,1272],{"href":1271},"\u002Fdocs\u002Fquickstart-payout","payout quickstart"," walks the whole flow with copyable requests.",[1275,1276,1277],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":383,"searchDepth":408,"depth":408,"links":1279},[1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292],{"id":125,"depth":408,"text":126},{"id":287,"depth":408,"text":288},{"id":335,"depth":408,"text":336},{"id":361,"depth":408,"text":362},{"id":549,"depth":408,"text":550},{"id":665,"depth":408,"text":666},{"id":677,"depth":408,"text":678},{"id":789,"depth":408,"text":790},{"id":895,"depth":408,"text":896},{"id":981,"depth":408,"text":982},{"id":1165,"depth":408,"text":1166},{"id":1209,"depth":408,"text":1210},{"id":1264,"depth":408,"text":1265},[1294,1299,1304],{"path":1295,"title":1296,"description":1297,"date":1298},"\u002Fresources\u002Fmore\u002Fneobank-api-quickstart-first-deposit-first-payout","Neobank API quickstart: from sign-up screen to first deposit and first payout","Map every neobank screen to a BlindPay API call: terms, KYC, wallet, US account details, first deposit, bank account, quote, payout, and webhooks.","2026-10-24",{"path":1300,"title":1301,"description":1302,"date":1303},"\u002Fresources\u002Fmore\u002Fcross-border-stablecoin-payments-go-live-timeline","How long does it take to launch cross-border stablecoin payouts? From first API call to first live payout","The go-live critical path for stablecoin payouts: instance setup, KYB, integration, first customer KYC, and first-payout holds, with each wait.","2026-10-14",{"path":1305,"title":1306,"description":1307,"date":7},"\u002Fresources\u002Fmore\u002Fcheckout-sessions-api-design","Designing a checkout sessions API for local bank payments","How to design a checkout sessions API over local bank rails in 2026: session states, quote vs session lifetime, idempotency, and webhooks.",1794399377536]