[{"data":1,"prerenderedAt":1197},["ShallowReactive",2],{"content-\u002Fchangelog\u002F2026-07-27-customers-rename-sunset":3},{"id":4,"title":5,"author":6,"body":7,"categories":6,"category":1170,"categoryType":1171,"date":1172,"description":1173,"extension":1174,"faq":6,"howto":6,"isBlog":1175,"isChangelog":1176,"meta":1177,"navigation":1176,"path":1192,"rawbody":1193,"seo":1194,"stem":1195,"thumbnail":6,"__hash__":1196},"content\u002Fchangelog\u002F2026-07-27-customers-rename-sunset.md","\"Receivers\" to \"Customers\" migration: final notice and complete guide",null,{"type":8,"value":9,"toc":1146},"minimark",[10,20,36,41,56,124,131,142,146,170,174,381,386,399,412,423,427,433,577,581,594,786,810,814,834,838,852,856,859,869,873,939,947,951,1031,1035,1039,1077,1081,1092,1099,1110,1114,1126,1130],[11,12,13,14,19],"p",{},"The transition period announced in the ",[15,16,18],"a",{"href":17},"\u002Fchangelog\u002F2026-06-04-customers-rename","June 4 changelog"," has ended, and the final release that makes \"customers\" the only name across the BlindPay platform is about to roll out. This post is the complete guide to everything that changes.",[11,21,22,26,27,31,32,35],{},[23,24,25],"strong",{},"Timing: the renames below are not live yet."," They ship with the final release, which will be announced on this changelog. Until then, the ",[28,29,30],"code",{},"receiver_*"," request fields remain the accepted shape on the current API (sending ",[28,33,34],{},"customer_*"," request fields today is rejected). Use this guide, and the AI prompt at the end, to prepare your migration diff now, and deploy it when the release goes live.",[37,38,40],"h2",{"id":39},"endpoints","Endpoints",[11,42,43,44,47,48,51,52,55],{},"Every legacy ",[28,45,46],{},"\u002Freceivers"," path now returns ",[28,49,50],{},"301 Moved Permanently"," pointing at its ",[28,53,54],{},"\u002Fcustomers"," equivalent.",[57,58,59,72],"table",{},[60,61,62],"thead",{},[63,64,65,69],"tr",{},[66,67,68],"th",{},"Was",[66,70,71],{},"Now",[73,74,75,88,100,112],"tbody",{},[63,76,77,83],{},[78,79,80],"td",{},[28,81,82],{},"\u002Fv1\u002Finstances\u002F{id}\u002Freceivers[\u002F...]",[78,84,85],{},[28,86,87],{},"\u002Fv1\u002Finstances\u002F{id}\u002Fcustomers[\u002F...]",[63,89,90,95],{},[78,91,92],{},[28,93,94],{},"\u002Fv1\u002Fe\u002Finstances\u002F{id}\u002Freceivers[\u002F...]",[78,96,97],{},[28,98,99],{},"\u002Fv1\u002Fe\u002Finstances\u002F{id}\u002Fcustomers[\u002F...]",[63,101,102,107],{},[78,103,104],{},[28,105,106],{},"\u002Fv1\u002Finstances\u002F{id}\u002Flimits\u002Freceivers\u002F{id}",[78,108,109],{},[28,110,111],{},"\u002Fv1\u002Finstances\u002F{id}\u002Flimits\u002Fcustomers\u002F{id}",[63,113,114,119],{},[78,115,116],{},[28,117,118],{},"\u002Fv1\u002Finstances\u002F{id}\u002Fexternal-receiver-token",[78,120,121],{},[28,122,123],{},"\u002Fv1\u002Finstances\u002F{id}\u002Fexternal-customer-token",[11,125,126,127,130],{},"This covers the customer collection and item routes plus every sub-resource: bank accounts, wallets, blockchain wallets, virtual accounts, offramp wallets, limits, limit increases, and RFIs. The ",[28,128,129],{},"\u002Fe\u002F"," external invite-flow variants redirect too.",[11,132,133,134,137,138,141],{},"Note that ",[28,135,136],{},"external-receiver-token"," is renamed even though it has no ",[28,139,140],{},"\u002Freceivers\u002F"," path segment.",[37,143,145],{"id":144},"webhooks","Webhooks",[11,147,148,151,152,155,156,159,160,151,163,155,166,169],{},[28,149,150],{},"receiver.new",", ",[28,153,154],{},"receiver.update",", and ",[28,157,158],{},"receiver.delete"," no longer fire. Subscribe to ",[28,161,162],{},"customer.new",[28,164,165],{},"customer.update",[28,167,168],{},"customer.delete"," instead; they carry the same payloads. The dual-emit behavior from the transition window is gone, so you now receive exactly one event per action.",[37,171,173],{"id":172},"renamed-fields","Renamed fields",[57,175,176,187],{},[60,177,178],{},[63,179,180,182,184],{},[66,181,68],{},[66,183,71],{},[66,185,186],{},"Where",[73,188,189,204,219,234,249,263,277,292,306,324,339,353,367],{},[63,190,191,196,201],{},[78,192,193],{},[28,194,195],{},"receiver_id",[78,197,198],{},[28,199,200],{},"customer_id",[78,202,203],{},"Payins, payouts, quotes, transfers, bank accounts, wallets, blockchain wallets, virtual accounts, offramp wallets, limit increases, RFIs, TOS. Also the path segment and list filter.",[63,205,206,211,216],{},[78,207,208],{},[28,209,210],{},"receiver_name",[78,212,213],{},[28,214,215],{},"customer_name",[78,217,218],{},"Customer list filter query parameter",[63,220,221,226,231],{},[78,222,223],{},[28,224,225],{},"receiver_local_amount",[78,227,228],{},[28,229,230],{},"customer_local_amount",[78,232,233],{},"Quotes, payouts",[63,235,236,241,246],{},[78,237,238],{},[28,239,240],{},"receiver_wallet_address",[78,242,243],{},[28,244,245],{},"customer_wallet_address",[78,247,248],{},"Transfers, transfer quotes",[63,250,251,256,261],{},[78,252,253],{},[28,254,255],{},"receiver_network",[78,257,258],{},[28,259,260],{},"customer_network",[78,262,248],{},[63,264,265,270,275],{},[78,266,267],{},[28,268,269],{},"receiver_token",[78,271,272],{},[28,273,274],{},"customer_token",[78,276,248],{},[63,278,279,284,289],{},[78,280,281],{},[28,282,283],{},"receiver_invite_redirect_url",[78,285,286],{},[28,287,288],{},"customer_invite_redirect_url",[78,290,291],{},"Instance settings",[63,293,294,299,304],{},[78,295,296],{},[28,297,298],{},"receiver_rfi_emails_enabled",[78,300,301],{},[28,302,303],{},"customer_rfi_emails_enabled",[78,305,291],{},[63,307,308,313,318],{},[78,309,310],{},[28,311,312],{},"receivers_amount",[78,314,315],{},[28,316,317],{},"customers_amount",[78,319,320,323],{},[28,321,322],{},"GET \u002Fv1\u002Finstances",", the count of customers on the instance",[63,325,326,331,336],{},[78,327,328],{},[28,329,330],{},"receiver_type",[78,332,333],{},[28,334,335],{},"customer_type",[78,337,338],{},"RFI",[63,340,341,346,351],{},[78,342,343],{},[28,344,345],{},"receiver_kyc_status",[78,347,348],{},[28,349,350],{},"customer_kyc_status",[78,352,338],{},[63,354,355,360,365],{},[78,356,357],{},[28,358,359],{},"receiver_aiprise_session_id",[78,361,362],{},[28,363,364],{},"customer_aiprise_session_id",[78,366,338],{},[63,368,369,374,379],{},[78,370,371],{},[28,372,373],{},"receiver_aiprise_user_profile_id",[78,375,376],{},[28,377,378],{},"customer_aiprise_user_profile_id",[78,380,338],{},[382,383,385],"h3",{"id":384},"the-one-field-that-keeps-its-name","The one field that keeps its name",[11,387,388,391,392,395,396,398],{},[28,389,390],{},"receiver_amount"," is ",[23,393,394],{},"not"," renamed. It stays ",[28,397,390],{}," on quotes, payins, payouts, and transfers, because there it means \"the amount the receiving side gets\", a leg of the transaction rather than a reference to the customer resource.",[11,400,401,402,404,405,408,409,411],{},"Do not confuse it with ",[28,403,312],{}," (plural), which ",[23,406,407],{},"is"," renamed to ",[28,410,317],{},". That one is the customer count on an instance.",[11,413,414,415,418,419,422],{},"This is the single reason a blind find-and-replace of ",[28,416,417],{},"receiver"," to ",[28,420,421],{},"customer"," will break your integration.",[37,424,426],{"id":425},"renamed-error-codes","Renamed error codes",[11,428,429,430,432],{},"The ",[28,431,28],{}," field on error responses is a stable identifier meant for programmatic handling, and eleven of them changed prefix.",[57,434,435,443],{},[60,436,437],{},[63,438,439,441],{},[66,440,68],{},[66,442,71],{},[73,444,445,457,469,481,493,505,517,529,541,553,565],{},[63,446,447,452],{},[78,448,449],{},[28,450,451],{},"RECEIVERS_NOT_FOUND",[78,453,454],{},[28,455,456],{},"CUSTOMERS_NOT_FOUND",[63,458,459,464],{},[78,460,461],{},[28,462,463],{},"RECEIVERS_ALREADY_APPROVED",[78,465,466],{},[28,467,468],{},"CUSTOMERS_ALREADY_APPROVED",[63,470,471,476],{},[78,472,473],{},[28,474,475],{},"RECEIVERS_KYC_NOT_APPROVED",[78,477,478],{},[28,479,480],{},"CUSTOMERS_KYC_NOT_APPROVED",[63,482,483,488],{},[78,484,485],{},[28,486,487],{},"RECEIVERS_ONBOARDING_INCOMPLETE",[78,489,490],{},[28,491,492],{},"CUSTOMERS_ONBOARDING_INCOMPLETE",[63,494,495,500],{},[78,496,497],{},[28,498,499],{},"RECEIVERS_INVALID_DATA",[78,501,502],{},[28,503,504],{},"CUSTOMERS_INVALID_DATA",[63,506,507,512],{},[78,508,509],{},[28,510,511],{},"RECEIVERS_INVALID_PHONE",[78,513,514],{},[28,515,516],{},"CUSTOMERS_INVALID_PHONE",[63,518,519,524],{},[78,520,521],{},[28,522,523],{},"RECEIVERS_INVALID_TAX_ID",[78,525,526],{},[28,527,528],{},"CUSTOMERS_INVALID_TAX_ID",[63,530,531,536],{},[78,532,533],{},[28,534,535],{},"RECEIVERS_ID_DOCUMENT_INVALID",[78,537,538],{},[28,539,540],{},"CUSTOMERS_ID_DOCUMENT_INVALID",[63,542,543,548],{},[78,544,545],{},[28,546,547],{},"RECEIVERS_COUNTRY_NOT_SUPPORTED",[78,549,550],{},[28,551,552],{},"CUSTOMERS_COUNTRY_NOT_SUPPORTED",[63,554,555,560],{},[78,556,557],{},[28,558,559],{},"RECEIVERS_ENHANCED_KYC_REQUIRED",[78,561,562],{},[28,563,564],{},"CUSTOMERS_ENHANCED_KYC_REQUIRED",[63,566,567,572],{},[78,568,569],{},[28,570,571],{},"RECEIVERS_BUSINESS_ENHANCED_NOT_AVAILABLE",[78,573,574],{},[28,575,576],{},"CUSTOMERS_BUSINESS_ENHANCED_NOT_AVAILABLE",[37,578,580],{"id":579},"renamed-error-messages","Renamed error messages",[11,582,583,584,587,588,590,591,593],{},"The legacy ",[28,585,586],{},"message"," slug also changed on the errors below. If you branch on ",[28,589,586],{}," rather than ",[28,592,28],{},", update both.",[57,595,596,604],{},[60,597,598],{},[63,599,600,602],{},[66,601,68],{},[66,603,71],{},[73,605,606,618,630,642,654,666,678,690,702,714,726,738,750,762,774],{},[63,607,608,613],{},[78,609,610],{},[28,611,612],{},"receiver_not_found",[78,614,615],{},[28,616,617],{},"customer_not_found",[63,619,620,625],{},[78,621,622],{},[28,623,624],{},"receiver_id_not_found",[78,626,627],{},[28,628,629],{},"customer_id_not_found",[63,631,632,637],{},[78,633,634],{},[28,635,636],{},"receiver_already_approved",[78,638,639],{},[28,640,641],{},"customer_already_approved",[63,643,644,649],{},[78,645,646],{},[28,647,648],{},"receiver_kyc_not_approved",[78,650,651],{},[28,652,653],{},"customer_kyc_not_approved",[63,655,656,661],{},[78,657,658],{},[28,659,660],{},"receiver_not_approved",[78,662,663],{},[28,664,665],{},"customer_not_approved",[63,667,668,673],{},[78,669,670],{},[28,671,672],{},"receiver_limit_not_found",[78,674,675],{},[28,676,677],{},"customer_limit_not_found",[63,679,680,685],{},[78,681,682],{},[28,683,684],{},"receiver_already_has_limit_increase_in_review",[78,686,687],{},[28,688,689],{},"customer_already_has_limit_increase_in_review",[63,691,692,697],{},[78,693,694],{},[28,695,696],{},"vm_invalid_receiver_data",[78,698,699],{},[28,700,701],{},"vm_invalid_customer_data",[63,703,704,709],{},[78,705,706],{},[28,707,708],{},"vm_receiver_country_not_supported",[78,710,711],{},[28,712,713],{},"vm_customer_country_not_supported",[63,715,716,721],{},[78,717,718],{},[28,719,720],{},"vm_unsupported_receiver_type",[78,722,723],{},[28,724,725],{},"vm_unsupported_customer_type",[63,727,728,733],{},[78,729,730],{},[28,731,732],{},"zenus_business_va_requires_business_receiver",[78,734,735],{},[28,736,737],{},"zenus_business_va_requires_business_customer",[63,739,740,745],{},[78,741,742],{},[28,743,744],{},"beneficiary_name_must_match_receiver_for_first_party",[78,746,747],{},[28,748,749],{},"beneficiary_name_must_match_customer_for_first_party",[63,751,752,757],{},[78,753,754],{},[28,755,756],{},"blockchain_wallet_does_not_belong_to_receiver",[78,758,759],{},[28,760,761],{},"blockchain_wallet_does_not_belong_to_customer",[63,763,764,769],{},[78,765,766],{},[28,767,768],{},"sender_and_receiver_networks_must_be_the_same",[78,770,771],{},[28,772,773],{},"sender_and_customer_networks_must_be_the_same",[63,775,776,781],{},[78,777,778],{},[28,779,780],{},"sender_and_receiver_tokens_must_be_the_same",[78,782,783],{},[28,784,785],{},"sender_and_customer_tokens_must_be_the_same",[11,787,788,789,791,792,795,796,798,799,802,803,806,807,809],{},"Two ",[28,790,586],{}," slugs are deliberately unchanged, because they describe the receiving leg of a transaction rather than the customer resource: ",[28,793,794],{},"otc_only_supported_for_sender_without_cover_fees_and_receiver_with_cover_fees",", and every slug involving ",[28,797,390],{},". The ",[28,800,801],{},"currency_type"," request enum also keeps its ",[28,804,805],{},"sender"," and ",[28,808,417],{}," values.",[37,811,813],{"id":812},"deprecation-headers-are-gone","Deprecation headers are gone",[11,815,816,818,819,151,822,825,826,829,830,833],{},[28,817,46],{}," responses no longer carry ",[28,820,821],{},"Deprecation: true",[28,823,824],{},"Sunset",", or ",[28,827,828],{},"Link: rel=\"successor-version\"",". If you set up the CI smoke test suggested in the June changelog, it now passes trivially instead of catching anything. Replace it with a check that asserts no ",[28,831,832],{},"301"," responses from BlindPay.",[37,835,837],{"id":836},"ids-are-unchanged","IDs are unchanged",[11,839,840,841,844,845,848,849,851],{},"Customer IDs keep the ",[28,842,843],{},"re_"," prefix, and customer records keep both ",[28,846,847],{},"id"," and its canonical alias ",[28,850,200],{},". No data migration is needed. Do not rewrite stored IDs.",[37,853,855],{"id":854},"migrate-your-code-with-an-ai-agent","Migrate your code with an AI agent",[11,857,858],{},"If you use an AI coding agent (Claude Code, Codex, Cursor, Windsurf, or similar), paste the prompt below into it from the root of your integration. It contains every rename from this changelog and the June announcement, including the exceptions that make a naive find-and-replace unsafe.",[860,861,867],"pre",{"className":862,"code":864,"language":865,"meta":866},[863],"language-text","Migrate this codebase off the deprecated BlindPay \"receivers\" API surface and onto\n\"customers\". This is a rename of the API surface only: resource IDs are unchanged.\n\nWork through the steps in order and show me a diff before applying anything.\n\nSTEP 1 - Find every call site.\nSearch the whole repo (including tests, fixtures, recorded HTTP cassettes, env\nfiles, OpenAPI\u002FPostman collections, infrastructure config, and docs) for:\n  receivers, receiver_, receiverId, RECEIVERS_, \"receiver.\" (webhook event names)\n\nSTEP 2 - Rewrite URL paths.\n  \u002Fv1\u002Finstances\u002F{id}\u002Freceivers               -> \u002Fv1\u002Finstances\u002F{id}\u002Fcustomers\n  \u002Fv1\u002Fe\u002Finstances\u002F{id}\u002Freceivers             -> \u002Fv1\u002Fe\u002Finstances\u002F{id}\u002Fcustomers\n  \u002Fv1\u002Finstances\u002F{id}\u002Flimits\u002Freceivers\u002F{rid}  -> \u002Fv1\u002Finstances\u002F{id}\u002Flimits\u002Fcustomers\u002F{rid}\n  \u002Fv1\u002Finstances\u002F{id}\u002Fexternal-receiver-token -> \u002Fv1\u002Finstances\u002F{id}\u002Fexternal-customer-token\nApply to all sub-resources as well: bank-accounts, wallets, blockchain-wallets,\nvirtual-accounts, offramp-wallets, limit-increase, rfi.\nThe old paths still answer 301, so nothing breaks immediately, but every call\ncosts an extra round-trip until this is done.\n\nSTEP 3 - Rename request and response fields.\n  receiver_id                      -> customer_id\n  receiver_name                    -> customer_name\n  receiver_local_amount            -> customer_local_amount\n  receiver_wallet_address          -> customer_wallet_address\n  receiver_network                 -> customer_network\n  receiver_token                   -> customer_token\n  receiver_invite_redirect_url     -> customer_invite_redirect_url\n  receiver_rfi_emails_enabled      -> customer_rfi_emails_enabled\n  receivers_amount                 -> customers_amount\n  receiver_type                    -> customer_type\n  receiver_kyc_status              -> customer_kyc_status\n  receiver_aiprise_session_id      -> customer_aiprise_session_id\n  receiver_aiprise_user_profile_id -> customer_aiprise_user_profile_id\n\nSTEP 4 - CRITICAL EXCEPTION. Do NOT rename receiver_amount.\nreceiver_amount (singular) is still called receiver_amount on quotes, payins,\npayouts, and transfers. It means \"amount the receiving side gets\", not a\nreference to the customer resource. Renaming it will break those calls.\nNote the near-miss: receivers_amount (plural, the customer count on\nGET \u002Fv1\u002Finstances) IS renamed to customers_amount. Handle each explicitly.\nNever run a blanket s\u002Freceiver\u002Fcustomer\u002F over this repo.\n\nSTEP 5 - Rename webhook event names and handlers.\n  receiver.new    -> customer.new\n  receiver.update -> customer.update\n  receiver.delete -> customer.delete\nPayloads are identical. Also update the subscription list in the BlindPay\ndashboard; a code-only change will leave your endpoint silent.\nThe old dual-emit is gone, so if a handler was de-duplicating receiver.* against\ncustomer.* for the same action, that workaround can be removed.\n\nSTEP 6 - Rename error codes checked in code.\nAny comparison against the code field on an error response:\n  RECEIVERS_NOT_FOUND -> CUSTOMERS_NOT_FOUND, and the same CUSTOMERS_ prefix\n  swap for ALREADY_APPROVED, KYC_NOT_APPROVED, ONBOARDING_INCOMPLETE,\n  INVALID_DATA, INVALID_PHONE, INVALID_TAX_ID, ID_DOCUMENT_INVALID,\n  COUNTRY_NOT_SUPPORTED, ENHANCED_KYC_REQUIRED,\n  BUSINESS_ENHANCED_NOT_AVAILABLE.\n\nSTEP 6b - Rename error message slugs checked in code.\nIf you branch on the message field instead of code, these changed too:\n  receiver_not_found            -> customer_not_found\n  receiver_id_not_found         -> customer_id_not_found\n  receiver_already_approved     -> customer_already_approved\n  receiver_kyc_not_approved     -> customer_kyc_not_approved\n  receiver_not_approved         -> customer_not_approved\n  receiver_limit_not_found      -> customer_limit_not_found\n  receiver_already_has_limit_increase_in_review\n    -> customer_already_has_limit_increase_in_review\n  vm_invalid_receiver_data      -> vm_invalid_customer_data\n  vm_receiver_country_not_supported -> vm_customer_country_not_supported\n  vm_unsupported_receiver_type  -> vm_unsupported_customer_type\n  zenus_business_va_requires_business_receiver\n    -> zenus_business_va_requires_business_customer\n  beneficiary_name_must_match_receiver_for_first_party\n    -> beneficiary_name_must_match_customer_for_first_party\n  blockchain_wallet_does_not_belong_to_receiver\n    -> blockchain_wallet_does_not_belong_to_customer\n  sender_and_receiver_networks_must_be_the_same\n    -> sender_and_customer_networks_must_be_the_same\n  sender_and_receiver_tokens_must_be_the_same\n    -> sender_and_customer_tokens_must_be_the_same\nLeave unchanged: any slug mentioning receiver_amount, and\notc_only_supported_for_sender_without_cover_fees_and_receiver_with_cover_fees.\n\nSTEP 6c - Do NOT change the currency_type request value.\ncurrency_type still accepts 'sender' and 'receiver'. Sending 'customer' is\ninvalid. This pairs with the receiver_amount exception in step 4.\n\nSTEP 7 - Update the SDK accessor, if you use an official SDK.\n  blindpay.receivers.*  ->  blindpay.customers.*\n  blindpay.receivers.bankAccounts.create(...)\n    ->  blindpay.customers.bankAccounts.create(...)\nMethod signatures are identical; only the accessor renames. Bump to the latest\nrelease of your current major, which added customers with no import changes.\n\nSTEP 8 - Do NOT touch stored IDs.\nCustomer IDs keep the re_ prefix (re_abc123456789). Leave every stored ID,\nfixture, and database value exactly as it is. There is no data migration.\n\nSTEP 9 - Verify.\n  - grep the repo: no receivers, receiver_id, or receiver.* webhook names left\n  - confirm receiver_amount is still present and untouched wherever it was before\n  - run the test suite, and update fixtures or cassettes that assert on renamed\n    fields\n  - check logs for 301 responses from api.blindpay.com; each one is a path you\n    missed\n\nReport anything ambiguous rather than guessing.\n","text","",[28,868,864],{"__ignoreMap":866},[37,870,872],{"id":871},"what-you-need-to-do","What you need to do",[874,875,876,892,898,916,923,933],"ol",{},[877,878,879,880,418,882,884,885,887,888,891],"li",{},"Update API paths from ",[28,881,46],{},[28,883,54],{},", including the ",[28,886,129],{}," invite-flow variants and ",[28,889,890],{},"external-customer-token",".",[877,893,894,895,897],{},"Rename request and response fields per the table above, leaving ",[28,896,390],{}," alone.",[877,899,900,901,903,904,418,907,155,910,903,912,418,914,891],{},"Update error handling: ",[28,902,28],{}," comparisons from ",[28,905,906],{},"RECEIVERS_*",[28,908,909],{},"CUSTOMERS_*",[28,911,586],{},[28,913,30],{},[28,915,34],{},[877,917,918,919,922],{},"Subscribe to ",[28,920,921],{},"customer.*"," webhooks in the dashboard and update your handlers.",[877,924,925,926,929,930,891],{},"Update your SDK to the latest release of its current major, then switch ",[28,927,928],{},"receivers.*"," calls to ",[28,931,932],{},"customers.*",[877,934,935,936,938],{},"Leave stored IDs untouched. The ",[28,937,843],{}," prefix is permanent.",[11,940,941,942,806,944,946],{},"If you completed the migration before July 3, 2026, the only new work is step 3, the error ",[28,943,28],{},[28,945,586],{}," renames, which ship with this release.",[37,948,950],{"id":949},"verification-checklist","Verification checklist",[952,953,954,964,973,980,985,999,1009,1019,1025],"ul",{},[877,955,956,957,959,960,963],{},"Logs show zero ",[28,958,832],{}," responses from ",[28,961,962],{},"api.blindpay.com",", since each one is an unmigrated path",[877,965,966,967,806,970],{},"Logs show zero requests to ",[28,968,969],{},"\u002Fv1\u002Finstances\u002F*\u002Freceivers*",[28,971,972],{},"\u002Fv1\u002Fe\u002Finstances\u002F*\u002Freceivers*",[877,974,975,976,979],{},"No code path reads ",[28,977,978],{},"response.receiver_id"," or any other renamed field",[877,981,982,984],{},[28,983,390],{}," is still read correctly on quotes, payins, payouts, and transfers",[877,986,987,988,990,991,993,994,990,996,998],{},"No code path compares an error ",[28,989,28],{}," against a ",[28,992,906],{}," value, or an error ",[28,995,586],{},[28,997,30],{}," slug",[877,1000,1001,1002,1005,1006],{},"Requests still send ",[28,1003,1004],{},"currency_type: 'receiver'",", not ",[28,1007,1008],{},"'customer'",[877,1010,1011,1012,151,1014,155,1016,1018],{},"Webhook handlers process ",[28,1013,162],{},[28,1015,165],{},[28,1017,168],{},", and the dashboard subscription lists them",[877,1020,1021,1022,1024],{},"SDK updated, with no remaining ",[28,1023,928],{}," accessor calls",[877,1026,1027,1028],{},"Saved dashboard URLs use ",[28,1029,1030],{},"\u002Fcustomers\u002F",[37,1032,1034],{"id":1033},"faq","FAQ",[382,1036,1038],{"id":1037},"what-breaks-if-i-do-nothing","What breaks if I do nothing?",[11,1040,1041,1042,1044,1045,151,1048,151,1051,1054,1055,1058,1059,1061,1062,1065,1066,1068,1069,1071,1072,1068,1074,1076],{},"Requests keep working through the ",[28,1043,832],{}," redirects, at the cost of an extra round-trip per call, as long as your HTTP client follows redirects (browsers, ",[28,1046,1047],{},"curl",[28,1049,1050],{},"requests",[28,1052,1053],{},"axios",", the official SDKs, and Postman all do by default). Three things break outright: ",[28,1056,1057],{},"receiver.*"," webhook subscriptions go silent, code that reads a renamed ",[28,1060,30],{}," response field gets ",[28,1063,1064],{},"undefined",", and error handling that branches on a ",[28,1067,906],{}," ",[28,1070,28],{}," or a ",[28,1073,30],{},[28,1075,586],{}," stops matching.",[382,1078,1080],{"id":1079},"do-i-need-to-migrate-my-stored-ids","Do I need to migrate my stored IDs?",[11,1082,1083,1084,1086,1087,806,1089,1091],{},"No. All IDs keep the ",[28,1085,843],{}," prefix, and both ",[28,1088,847],{},[28,1090,200],{}," carry the same value. We renamed the API surface, not the underlying resource.",[382,1093,1095,1096,1098],{"id":1094},"why-does-receiver_amount-keep-its-name","Why does ",[28,1097,390],{}," keep its name?",[11,1100,1101,1102,1105,1106,1109],{},"Because it does not refer to the customer resource. On a quote or a payment it means the amount landing on the receiving side, the counterpart to ",[28,1103,1104],{},"sender_amount",". Renaming it to ",[28,1107,1108],{},"customer_amount"," would have made it read like a property of the customer record.",[382,1111,1113],{"id":1112},"will-a-find-and-replace-work","Will a find-and-replace work?",[11,1115,1116,1117,1119,1120,1122,1123,1125],{},"Not safely. ",[28,1118,390],{}," must survive untouched while ",[28,1121,312],{}," must change, and stored ",[28,1124,843],{}," IDs must not be rewritten. Use the agent prompt above, which encodes those exceptions, or do the renames field by field.",[382,1127,1129],{"id":1128},"how-do-i-report-issues-with-the-migration","How do I report issues with the migration?",[11,1131,1132,1133,1137,1138,1141,1142,1145],{},"Use the feedback button in the dashboard (under your profile dropdown) or email ",[15,1134,1136],{"href":1135},"mailto:support@blindpay.com","support@blindpay.com"," with ",[28,1139,1140],{},"migration"," in the subject. Including the request ID from the response (",[28,1143,1144],{},"x-blindpay-request-id"," header) speeds up the lookup.",{"title":866,"searchDepth":1147,"depth":1147,"links":1148},2,[1149,1150,1151,1155,1156,1157,1158,1159,1160,1161,1162],{"id":39,"depth":1147,"text":40},{"id":144,"depth":1147,"text":145},{"id":172,"depth":1147,"text":173,"children":1152},[1153],{"id":384,"depth":1154,"text":385},3,{"id":425,"depth":1147,"text":426},{"id":579,"depth":1147,"text":580},{"id":812,"depth":1147,"text":813},{"id":836,"depth":1147,"text":837},{"id":854,"depth":1147,"text":855},{"id":871,"depth":1147,"text":872},{"id":949,"depth":1147,"text":950},{"id":1033,"depth":1147,"text":1034,"children":1163},[1164,1165,1166,1168,1169],{"id":1037,"depth":1154,"text":1038},{"id":1079,"depth":1154,"text":1080},{"id":1094,"depth":1154,"text":1167},"Why does receiver_amount keep its name?",{"id":1112,"depth":1154,"text":1113},{"id":1128,"depth":1154,"text":1129},"Migration","update","2026-07-27","Final call: \u002Freceivers paths will start answering 301, receiver.* webhooks will stop firing, and receiver_* fields plus receiver error codes and messages are renamed. Full field-by-field guide and an AI migration prompt inside.","md",false,true,{"excerpt":1178},{"type":8,"value":1179},[1180,1184],[11,1181,13,1182,19],{},[15,1183,18],{"href":17},[11,1185,1186,26,1188,31,1190,35],{},[23,1187,25],{},[28,1189,30],{},[28,1191,34],{},"\u002Fchangelog\u002F2026-07-27-customers-rename-sunset","---\ntitle: '\"Receivers\" to \"Customers\" migration: final notice and complete guide'\ndescription: 'Final call: \u002Freceivers paths will start answering 301, receiver.* webhooks will stop firing, and receiver_* fields plus receiver error codes and messages are renamed. Full field-by-field guide and an AI migration prompt inside.'\ndate: 2026-07-27\ncategory: Migration\ncategoryType: update\nisChangelog: true\n---\n\nThe transition period announced in the [June 4 changelog](\u002Fchangelog\u002F2026-06-04-customers-rename) has ended, and the final release that makes \"customers\" the only name across the BlindPay platform is about to roll out. This post is the complete guide to everything that changes.\n\n**Timing: the renames below are not live yet.** They ship with the final release, which will be announced on this changelog. Until then, the `receiver_*` request fields remain the accepted shape on the current API (sending `customer_*` request fields today is rejected). Use this guide, and the AI prompt at the end, to prepare your migration diff now, and deploy it when the release goes live.\n\n\u003C!--more-->\n\n## Endpoints\n\nEvery legacy `\u002Freceivers` path now returns `301 Moved Permanently` pointing at its `\u002Fcustomers` equivalent.\n\n| Was | Now |\n| --- | --- |\n| `\u002Fv1\u002Finstances\u002F{id}\u002Freceivers[\u002F...]` | `\u002Fv1\u002Finstances\u002F{id}\u002Fcustomers[\u002F...]` |\n| `\u002Fv1\u002Fe\u002Finstances\u002F{id}\u002Freceivers[\u002F...]` | `\u002Fv1\u002Fe\u002Finstances\u002F{id}\u002Fcustomers[\u002F...]` |\n| `\u002Fv1\u002Finstances\u002F{id}\u002Flimits\u002Freceivers\u002F{id}` | `\u002Fv1\u002Finstances\u002F{id}\u002Flimits\u002Fcustomers\u002F{id}` |\n| `\u002Fv1\u002Finstances\u002F{id}\u002Fexternal-receiver-token` | `\u002Fv1\u002Finstances\u002F{id}\u002Fexternal-customer-token` |\n\nThis covers the customer collection and item routes plus every sub-resource: bank accounts, wallets, blockchain wallets, virtual accounts, offramp wallets, limits, limit increases, and RFIs. The `\u002Fe\u002F` external invite-flow variants redirect too.\n\nNote that `external-receiver-token` is renamed even though it has no `\u002Freceivers\u002F` path segment.\n\n## Webhooks\n\n`receiver.new`, `receiver.update`, and `receiver.delete` no longer fire. Subscribe to `customer.new`, `customer.update`, and `customer.delete` instead; they carry the same payloads. The dual-emit behavior from the transition window is gone, so you now receive exactly one event per action.\n\n## Renamed fields\n\n| Was | Now | Where |\n| --- | --- | --- |\n| `receiver_id` | `customer_id` | Payins, payouts, quotes, transfers, bank accounts, wallets, blockchain wallets, virtual accounts, offramp wallets, limit increases, RFIs, TOS. Also the path segment and list filter. |\n| `receiver_name` | `customer_name` | Customer list filter query parameter |\n| `receiver_local_amount` | `customer_local_amount` | Quotes, payouts |\n| `receiver_wallet_address` | `customer_wallet_address` | Transfers, transfer quotes |\n| `receiver_network` | `customer_network` | Transfers, transfer quotes |\n| `receiver_token` | `customer_token` | Transfers, transfer quotes |\n| `receiver_invite_redirect_url` | `customer_invite_redirect_url` | Instance settings |\n| `receiver_rfi_emails_enabled` | `customer_rfi_emails_enabled` | Instance settings |\n| `receivers_amount` | `customers_amount` | `GET \u002Fv1\u002Finstances`, the count of customers on the instance |\n| `receiver_type` | `customer_type` | RFI |\n| `receiver_kyc_status` | `customer_kyc_status` | RFI |\n| `receiver_aiprise_session_id` | `customer_aiprise_session_id` | RFI |\n| `receiver_aiprise_user_profile_id` | `customer_aiprise_user_profile_id` | RFI |\n\n### The one field that keeps its name\n\n`receiver_amount` is **not** renamed. It stays `receiver_amount` on quotes, payins, payouts, and transfers, because there it means \"the amount the receiving side gets\", a leg of the transaction rather than a reference to the customer resource.\n\nDo not confuse it with `receivers_amount` (plural), which **is** renamed to `customers_amount`. That one is the customer count on an instance.\n\nThis is the single reason a blind find-and-replace of `receiver` to `customer` will break your integration.\n\n## Renamed error codes\n\nThe `code` field on error responses is a stable identifier meant for programmatic handling, and eleven of them changed prefix.\n\n| Was | Now |\n| --- | --- |\n| `RECEIVERS_NOT_FOUND` | `CUSTOMERS_NOT_FOUND` |\n| `RECEIVERS_ALREADY_APPROVED` | `CUSTOMERS_ALREADY_APPROVED` |\n| `RECEIVERS_KYC_NOT_APPROVED` | `CUSTOMERS_KYC_NOT_APPROVED` |\n| `RECEIVERS_ONBOARDING_INCOMPLETE` | `CUSTOMERS_ONBOARDING_INCOMPLETE` |\n| `RECEIVERS_INVALID_DATA` | `CUSTOMERS_INVALID_DATA` |\n| `RECEIVERS_INVALID_PHONE` | `CUSTOMERS_INVALID_PHONE` |\n| `RECEIVERS_INVALID_TAX_ID` | `CUSTOMERS_INVALID_TAX_ID` |\n| `RECEIVERS_ID_DOCUMENT_INVALID` | `CUSTOMERS_ID_DOCUMENT_INVALID` |\n| `RECEIVERS_COUNTRY_NOT_SUPPORTED` | `CUSTOMERS_COUNTRY_NOT_SUPPORTED` |\n| `RECEIVERS_ENHANCED_KYC_REQUIRED` | `CUSTOMERS_ENHANCED_KYC_REQUIRED` |\n| `RECEIVERS_BUSINESS_ENHANCED_NOT_AVAILABLE` | `CUSTOMERS_BUSINESS_ENHANCED_NOT_AVAILABLE` |\n\n## Renamed error messages\n\nThe legacy `message` slug also changed on the errors below. If you branch on `message` rather than `code`, update both.\n\n| Was | Now |\n| --- | --- |\n| `receiver_not_found` | `customer_not_found` |\n| `receiver_id_not_found` | `customer_id_not_found` |\n| `receiver_already_approved` | `customer_already_approved` |\n| `receiver_kyc_not_approved` | `customer_kyc_not_approved` |\n| `receiver_not_approved` | `customer_not_approved` |\n| `receiver_limit_not_found` | `customer_limit_not_found` |\n| `receiver_already_has_limit_increase_in_review` | `customer_already_has_limit_increase_in_review` |\n| `vm_invalid_receiver_data` | `vm_invalid_customer_data` |\n| `vm_receiver_country_not_supported` | `vm_customer_country_not_supported` |\n| `vm_unsupported_receiver_type` | `vm_unsupported_customer_type` |\n| `zenus_business_va_requires_business_receiver` | `zenus_business_va_requires_business_customer` |\n| `beneficiary_name_must_match_receiver_for_first_party` | `beneficiary_name_must_match_customer_for_first_party` |\n| `blockchain_wallet_does_not_belong_to_receiver` | `blockchain_wallet_does_not_belong_to_customer` |\n| `sender_and_receiver_networks_must_be_the_same` | `sender_and_customer_networks_must_be_the_same` |\n| `sender_and_receiver_tokens_must_be_the_same` | `sender_and_customer_tokens_must_be_the_same` |\n\nTwo `message` slugs are deliberately unchanged, because they describe the receiving leg of a transaction rather than the customer resource: `otc_only_supported_for_sender_without_cover_fees_and_receiver_with_cover_fees`, and every slug involving `receiver_amount`. The `currency_type` request enum also keeps its `sender` and `receiver` values.\n\n## Deprecation headers are gone\n\n`\u002Freceivers` responses no longer carry `Deprecation: true`, `Sunset`, or `Link: rel=\"successor-version\"`. If you set up the CI smoke test suggested in the June changelog, it now passes trivially instead of catching anything. Replace it with a check that asserts no `301` responses from BlindPay.\n\n## IDs are unchanged\n\nCustomer IDs keep the `re_` prefix, and customer records keep both `id` and its canonical alias `customer_id`. No data migration is needed. Do not rewrite stored IDs.\n\n## Migrate your code with an AI agent\n\nIf you use an AI coding agent (Claude Code, Codex, Cursor, Windsurf, or similar), paste the prompt below into it from the root of your integration. It contains every rename from this changelog and the June announcement, including the exceptions that make a naive find-and-replace unsafe.\n\n```text\nMigrate this codebase off the deprecated BlindPay \"receivers\" API surface and onto\n\"customers\". This is a rename of the API surface only: resource IDs are unchanged.\n\nWork through the steps in order and show me a diff before applying anything.\n\nSTEP 1 - Find every call site.\nSearch the whole repo (including tests, fixtures, recorded HTTP cassettes, env\nfiles, OpenAPI\u002FPostman collections, infrastructure config, and docs) for:\n  receivers, receiver_, receiverId, RECEIVERS_, \"receiver.\" (webhook event names)\n\nSTEP 2 - Rewrite URL paths.\n  \u002Fv1\u002Finstances\u002F{id}\u002Freceivers               -> \u002Fv1\u002Finstances\u002F{id}\u002Fcustomers\n  \u002Fv1\u002Fe\u002Finstances\u002F{id}\u002Freceivers             -> \u002Fv1\u002Fe\u002Finstances\u002F{id}\u002Fcustomers\n  \u002Fv1\u002Finstances\u002F{id}\u002Flimits\u002Freceivers\u002F{rid}  -> \u002Fv1\u002Finstances\u002F{id}\u002Flimits\u002Fcustomers\u002F{rid}\n  \u002Fv1\u002Finstances\u002F{id}\u002Fexternal-receiver-token -> \u002Fv1\u002Finstances\u002F{id}\u002Fexternal-customer-token\nApply to all sub-resources as well: bank-accounts, wallets, blockchain-wallets,\nvirtual-accounts, offramp-wallets, limit-increase, rfi.\nThe old paths still answer 301, so nothing breaks immediately, but every call\ncosts an extra round-trip until this is done.\n\nSTEP 3 - Rename request and response fields.\n  receiver_id                      -> customer_id\n  receiver_name                    -> customer_name\n  receiver_local_amount            -> customer_local_amount\n  receiver_wallet_address          -> customer_wallet_address\n  receiver_network                 -> customer_network\n  receiver_token                   -> customer_token\n  receiver_invite_redirect_url     -> customer_invite_redirect_url\n  receiver_rfi_emails_enabled      -> customer_rfi_emails_enabled\n  receivers_amount                 -> customers_amount\n  receiver_type                    -> customer_type\n  receiver_kyc_status              -> customer_kyc_status\n  receiver_aiprise_session_id      -> customer_aiprise_session_id\n  receiver_aiprise_user_profile_id -> customer_aiprise_user_profile_id\n\nSTEP 4 - CRITICAL EXCEPTION. Do NOT rename receiver_amount.\nreceiver_amount (singular) is still called receiver_amount on quotes, payins,\npayouts, and transfers. It means \"amount the receiving side gets\", not a\nreference to the customer resource. Renaming it will break those calls.\nNote the near-miss: receivers_amount (plural, the customer count on\nGET \u002Fv1\u002Finstances) IS renamed to customers_amount. Handle each explicitly.\nNever run a blanket s\u002Freceiver\u002Fcustomer\u002F over this repo.\n\nSTEP 5 - Rename webhook event names and handlers.\n  receiver.new    -> customer.new\n  receiver.update -> customer.update\n  receiver.delete -> customer.delete\nPayloads are identical. Also update the subscription list in the BlindPay\ndashboard; a code-only change will leave your endpoint silent.\nThe old dual-emit is gone, so if a handler was de-duplicating receiver.* against\ncustomer.* for the same action, that workaround can be removed.\n\nSTEP 6 - Rename error codes checked in code.\nAny comparison against the code field on an error response:\n  RECEIVERS_NOT_FOUND -> CUSTOMERS_NOT_FOUND, and the same CUSTOMERS_ prefix\n  swap for ALREADY_APPROVED, KYC_NOT_APPROVED, ONBOARDING_INCOMPLETE,\n  INVALID_DATA, INVALID_PHONE, INVALID_TAX_ID, ID_DOCUMENT_INVALID,\n  COUNTRY_NOT_SUPPORTED, ENHANCED_KYC_REQUIRED,\n  BUSINESS_ENHANCED_NOT_AVAILABLE.\n\nSTEP 6b - Rename error message slugs checked in code.\nIf you branch on the message field instead of code, these changed too:\n  receiver_not_found            -> customer_not_found\n  receiver_id_not_found         -> customer_id_not_found\n  receiver_already_approved     -> customer_already_approved\n  receiver_kyc_not_approved     -> customer_kyc_not_approved\n  receiver_not_approved         -> customer_not_approved\n  receiver_limit_not_found      -> customer_limit_not_found\n  receiver_already_has_limit_increase_in_review\n    -> customer_already_has_limit_increase_in_review\n  vm_invalid_receiver_data      -> vm_invalid_customer_data\n  vm_receiver_country_not_supported -> vm_customer_country_not_supported\n  vm_unsupported_receiver_type  -> vm_unsupported_customer_type\n  zenus_business_va_requires_business_receiver\n    -> zenus_business_va_requires_business_customer\n  beneficiary_name_must_match_receiver_for_first_party\n    -> beneficiary_name_must_match_customer_for_first_party\n  blockchain_wallet_does_not_belong_to_receiver\n    -> blockchain_wallet_does_not_belong_to_customer\n  sender_and_receiver_networks_must_be_the_same\n    -> sender_and_customer_networks_must_be_the_same\n  sender_and_receiver_tokens_must_be_the_same\n    -> sender_and_customer_tokens_must_be_the_same\nLeave unchanged: any slug mentioning receiver_amount, and\notc_only_supported_for_sender_without_cover_fees_and_receiver_with_cover_fees.\n\nSTEP 6c - Do NOT change the currency_type request value.\ncurrency_type still accepts 'sender' and 'receiver'. Sending 'customer' is\ninvalid. This pairs with the receiver_amount exception in step 4.\n\nSTEP 7 - Update the SDK accessor, if you use an official SDK.\n  blindpay.receivers.*  ->  blindpay.customers.*\n  blindpay.receivers.bankAccounts.create(...)\n    ->  blindpay.customers.bankAccounts.create(...)\nMethod signatures are identical; only the accessor renames. Bump to the latest\nrelease of your current major, which added customers with no import changes.\n\nSTEP 8 - Do NOT touch stored IDs.\nCustomer IDs keep the re_ prefix (re_abc123456789). Leave every stored ID,\nfixture, and database value exactly as it is. There is no data migration.\n\nSTEP 9 - Verify.\n  - grep the repo: no receivers, receiver_id, or receiver.* webhook names left\n  - confirm receiver_amount is still present and untouched wherever it was before\n  - run the test suite, and update fixtures or cassettes that assert on renamed\n    fields\n  - check logs for 301 responses from api.blindpay.com; each one is a path you\n    missed\n\nReport anything ambiguous rather than guessing.\n```\n\n## What you need to do\n\n1. Update API paths from `\u002Freceivers` to `\u002Fcustomers`, including the `\u002Fe\u002F` invite-flow variants and `external-customer-token`.\n2. Rename request and response fields per the table above, leaving `receiver_amount` alone.\n3. Update error handling: `code` comparisons from `RECEIVERS_*` to `CUSTOMERS_*`, and `message` comparisons from `receiver_*` to `customer_*`.\n4. Subscribe to `customer.*` webhooks in the dashboard and update your handlers.\n5. Update your SDK to the latest release of its current major, then switch `receivers.*` calls to `customers.*`.\n6. Leave stored IDs untouched. The `re_` prefix is permanent.\n\nIf you completed the migration before July 3, 2026, the only new work is step 3, the error `code` and `message` renames, which ship with this release.\n\n## Verification checklist\n\n- Logs show zero `301` responses from `api.blindpay.com`, since each one is an unmigrated path\n- Logs show zero requests to `\u002Fv1\u002Finstances\u002F*\u002Freceivers*` and `\u002Fv1\u002Fe\u002Finstances\u002F*\u002Freceivers*`\n- No code path reads `response.receiver_id` or any other renamed field\n- `receiver_amount` is still read correctly on quotes, payins, payouts, and transfers\n- No code path compares an error `code` against a `RECEIVERS_*` value, or an error `message` against a `receiver_*` slug\n- Requests still send `currency_type: 'receiver'`, not `'customer'`\n- Webhook handlers process `customer.new`, `customer.update`, and `customer.delete`, and the dashboard subscription lists them\n- SDK updated, with no remaining `receivers.*` accessor calls\n- Saved dashboard URLs use `\u002Fcustomers\u002F`\n\n## FAQ\n\n### What breaks if I do nothing?\n\nRequests keep working through the `301` redirects, at the cost of an extra round-trip per call, as long as your HTTP client follows redirects (browsers, `curl`, `requests`, `axios`, the official SDKs, and Postman all do by default). Three things break outright: `receiver.*` webhook subscriptions go silent, code that reads a renamed `receiver_*` response field gets `undefined`, and error handling that branches on a `RECEIVERS_*` `code` or a `receiver_*` `message` stops matching.\n\n### Do I need to migrate my stored IDs?\n\nNo. All IDs keep the `re_` prefix, and both `id` and `customer_id` carry the same value. We renamed the API surface, not the underlying resource.\n\n### Why does `receiver_amount` keep its name?\n\nBecause it does not refer to the customer resource. On a quote or a payment it means the amount landing on the receiving side, the counterpart to `sender_amount`. Renaming it to `customer_amount` would have made it read like a property of the customer record.\n\n### Will a find-and-replace work?\n\nNot safely. `receiver_amount` must survive untouched while `receivers_amount` must change, and stored `re_` IDs must not be rewritten. Use the agent prompt above, which encodes those exceptions, or do the renames field by field.\n\n### How do I report issues with the migration?\n\nUse the feedback button in the dashboard (under your profile dropdown) or email support@blindpay.com with `migration` in the subject. Including the request ID from the response (`x-blindpay-request-id` header) speeds up the lookup.\n",{"title":5,"description":1173},"changelog\u002F2026-07-27-customers-rename-sunset","9Iyn8CZpVkt5-1Dgpeb5cBtivgEXER0vaAmW-3piEBI",1785166519414]