October 12th 2026
Added
[Wallet creation]
You can now create wallets in additional currencies directly through the API.
- Added POST /wallet — create a client wallet in a requested
currency_code. A client can hold at most one wallet per currency, so the call is idempotent:201returns the new wallet,200returns your existing wallet in that currency unchanged - Added POST /wallet/{'{user_token}'} — create a wallet for a user, with an optional
fee_wallet_tokennaming one of your client wallets to pay the fees of payouts funded from the new wallet
Added
[Wallet details]
You can now look up a single wallet by its token.
- Added GET /wallets/{'{wallet_token}'} — works for your own client wallets and your users' wallets
The wallet object has also been extended: typenow distinguishesCLIENT_FUNDSandSUBLEDGER_FUNDSwallets alongsideUSER_FUNDSandMASSPAY_CARD- New
fee_wallet_token(on the single-wallet endpoint) shows which client wallet pays the wallet's fees, when one is set - New
wiring_instructionsreturns the wire/ACH deposit details of the bank account funding the wallet, when available. The object is the bank's own record passed through as-is, so keys vary by bank (e.g. Cross River returnsaccountNumber,routingNumber,accountType,title,currency,status) — treat the values as display text for your payer
Added
[Payout sender attribution]
You can now identify the true originator when initiating a payout on behalf of another party.
- POST /payout/{'{user_token}'} accepts an optional
sender_user_tokenreferencing the sending user; when omitted, you (the client) remain the sender of record - The sender is echoed back on payout status responses, and transaction history entries include
sender_user_tokenplus the sender'sfirst_name/last_nameorbusiness_name
Sender details are used for compliance, screening, and reporting, so the value must accurately reflect the true originator of the funds.
Added
[AgeChecker KYC]
Added support for the AgeChecker.Net age verification provider.
- Added PUT /payout/user/{'{user_token}'}/kyc/agechecker
Link an AgeChecker verificationuuidto a user, and MassPay will fetch the verification status and verified buyer data (name, date of birth, address). Only anacceptedverification is imported.
Added
[New webhook events]
The webhook event catalog now includes:
payin_deposit.returnedandpayin_deposit.return_completed— track deposit returns initiated via the deposit return endpointfile_upload_req.created,file_upload_req.status, andfile_upload_req.verified— follow the lifecycle of file upload requests
Subscribe via POST /payout/account/webhooks.
Added
[OAuthGrant attribute]
Added OAuthGrant as a user attribute type, supporting payout destinations authorized through a provider OAuth flow (e.g. Cash App).
Improved
[File upload request lifecycle]
File upload requests now report rejections. When MassPay operations rejects uploaded files, a replacement request is opened automatically for the same requirement.
- New
statusfield on file upload request responses:pending,uploaded,verified, orrejected - New
is_rejected,rejection_reason, andtime_rejectedfields - New
replacement_file_upload_token(andreplacement_file_upload_linkon the single-request endpoint) pointing to the replacement request - A rejection fires
file_upload_req.status(withevent_typefile_upload_req_rejected) andfile_upload_req.createdfor the replacement
A rejected request no longer counts toward any requirement.
Improved
[Payout initiation]
POST /payout/{'{user_token}'} validation and documentation have been tightened.
destination_tokenis no longer required — when omitted, the last destination used for the user applies (destination_currency_codeandsource_tokenremain required)- Token parameters now accept both bare UUIDs and prefixed forms (
usr_,dest_,attr_set_,clnt_wlt_, etc.); examples and patterns updated throughout client_transfer_iduniqueness is now documented: a value already carried by another payout is rejected with400andDuplicate client id. Existing payout token: payout_<uuid>inerror.details. By default a value becomes reusable once the earlier payout isERRORorEXPIRED(or aPENDINGquote past expiration); accounts configured for strict uniqueness never allow reuseexpirationis now documented as UTC RFC 3339 with millisecond precision (e.g.2026-08-22T17:40:46.881Z)
Improved
[Status refresh and webhooks]
Clarified force_status_update behavior on payout status and pay-in status: when the partner answers, the corresponding payout.status / payin.status webhook is sent whether or not the status changed. Never set it from inside a webhook handler — the handler would send itself the next event.
Improved
[Transaction history]
- New
RETURNEDstatus for returned transactions - Cancelled payouts now appear twice in history: the original entry with
CANCELLED_AT_LATER_TIMEat creation time, and a secondCANCELLEDentry at the time the cancellation happened and the funds came back. The payout itself has the single statusCANCELLED - The ledger gained a
payin_deposit_returnentry type
Improved
[Payout reversals]
Reversal status responses now include a status_reason with the reason code when available (e.g. R01 - Insufficient Funds).
Improved
[Business enrollment]
POST /business accepts a new partner_pays_transaction_fees flag (default false): when true, the enrolling partner assumes the transaction fees incurred by the business.
Improved
[Documentation cleanup]
- POST /payout/account/api-key: documented that a new API key becomes valid a few seconds after the response (rarely a few minutes), not instantly
- Webhook
secretdocumentation now spells out the signature scheme: HMAC-SHA512 over<t>|<body>, delivered in theX-MassPay-Signatureheader - Wallet transfers: documented that
amountaccepts up to 5 decimal places - Corrected webhook listing examples to show real
event_typesvalues
Changed
[Webhook listing response]
Breaking: in the GET /payout/account/webhooks response, the webhook_token field is renamed to token. The value is unchanged — it is still the token returned as webhook_token when the webhook was created, and the value to use when deleting a webhook. Update any code reading webhook_token from the listing.