Breaking changes are announced here and applied to both environments. Exercise them in the
sandbox — it runs fully simulated provider rails — before
updating your production integration.
2026-10-15
Per-customer developer fees can be set with an API key
PUT and DELETE /v1/customers/{id}/developer-fees no longer return 403 step_up_required to a
call made with a secret API key, so you can set a customer’s developer fee straight after creating
the customer through the API. A change made in the console still asks for your second factor. The
fees:write scope, the fee caps and the audit trail are unchanged. Your global fee
(PUT /v1/developer-fees) still has to be changed in the console.
Migration. None.
2026-10-14
Conversion quotes no longer need a funded wallet
POST /v1/treasury/conversion-quotes now prices a conversion even when the wallet’s available
balance does not cover it, so you can show a price before the account deposits. Quotes carry a new
boolean, sufficientBalance: whether the available balance covered sourceDebit when the quote
was priced. Quotes also carry inverseRate, the reciprocal of rate, for showing the price the
other way round. Accepting a quote with sufficientBalance: false returns 422 insufficient_balance,
even if funds land in the meantime; fund the wallet and request a new quote.
Migration. If you relied on the quote request returning 422 insufficient_balance, read
sufficientBalance on the quote instead. Accepting a quote still refuses an unfunded wallet with
the same error.
AUD funding accounts register your account name
A newaud_account funding instrument registers its accountName with the bank alongside your
company name, so a payer’s Confirmation of Payee check matches the name you chose. payeeName on
those instruments is now your accountName. Instruments created earlier keep your company name as
payeeName; the bank cannot add a name to an existing account, so create a new instrument to use a
different name.
Migration. None.
2026-10-11
Transfers carry the exchange rate and your developer fee
Transfers now include two fields once the conversion has executed, onGET /v1/transfers,
GET /v1/transfers/{id} and the transfer.* webhooks:
exchangeRate: destination units per one source unit the conversion executed at, before your developer fee. A decimal string.developerFee:{ "amount": "1.25", "currency": "AUD" }, the developer fee withheld from this conversion. A zero fee reads"0.00". It is omitted on areturned,reversingorreversedtransfer.
API keys show when they were last used; fee schedules show who changed them
- API keys in
GET /v1/api-keysnow includelastUsedAtandlastUsedIp: when the key last authenticated a request, and the client IP it came from. Both arenulluntil the key is used. They update at most once a minute. GET /v1/developer-feesnow includesupdatedByName: the email of the team member who made the last change from the console, orWayexfor a change made by Wayex. It isnullfor a change made with an API key alone, and alwaysnullwhen you read with a publishable key.
Date and status filters for transfers and customers
GET /v1/transfersnow appliesfrom/to(inclusive bounds on the creation time, ISO 8601 with an offset).GET /v1/customersnow appliesstatus(one verification status or a comma-separated list).
400: on transfers, an unparseable from or to, or from later than to; on
customers, an unknown status (invalid_status).
Webhook secret rotation keeps the old secret for 24 hours
For 24 hours after you rotate a webhook signing secret, each delivery is signed with both secrets. The new secret signsX-Wayex-Signature and X-Wayex-Signature-Timestamp as before. The previous
secret signs two extra headers, X-Wayex-Signature-Previous and
X-Wayex-Signature-Timestamp-Previous, in the same formats. Subscriptions in GET /v1/webhooks
show previousSecretExpiresAt while the overlap is open. See
Rotate the signing secret.
Migration. None. To rotate without dropping deliveries, accept a delivery when either signature
matches a secret you hold.
Sandbox API keys start sk_test_ and pk_test_
New keys created in the sandbox start sk_test_ / pk_test_. Production keys still start
sk_live_ / pk_live_. API key responses now include environment (live or test).
Migration. None. Existing keys keep working whatever their prefix. If your code checks for
sk_live_, also accept sk_test_ for sandbox keys.
Off-ramp transfers start at deposit_detected
A transfer funded by a stablecoin deposit on an off-ramp route is now created at deposit_detected,
because the deposit has already arrived. transfer.created carries deposit_detected, and no
separate transfer.updated for deposit_detected follows. Transfers created before this change are
unaffected.
Migration. If you wait for a transfer.updated with deposit_detected, read the status from
transfer.created as well.
Closed payment routes
A payment route closed from the console no longer converts new payments. A payment that lands on a closed route is placedon_hold with references.lastCaseReason set to route_inactive, and Wayex
contacts you to resolve it. POST /v1/transfers/{id}/progress returns 409 route_inactive for a
transfer on a closed route; refund the payer with POST /v1/transfers/{id}/refund instead.
Migration. Treat route_inactive as a known lastCaseReason and 409 code.
2026-10-08
Hold on-ramp payments for your approval
On-ramp payment routes can now hold each payment for your approval instead of converting it automatically. Once Wayex enables the capability for your account, create an AUD-to-stablecoin route withclientGate: true, or turn it on for an existing route with
PUT /v1/payment-routes/{id}/client-gate. Each payment on that route clears screening and then waits
at awaiting_client_action until you call POST /v1/transfers/{id}/progress (convert at the live rate
at that moment) or POST /v1/transfers/{id}/refund (return the full AUD amount to the payer; your
Wayex transfer fee applies). On-ramp routes now also return clientGate and clientGateActive once
the gate has been turned on.
Migration. Two new transfer statuses, awaiting_client_action and refunding, appear only on
routes where you enable clientGate (capability enabled by Wayex). Clients with exhaustive status
enums should add them. API keys holding the transfers:write scope can now progress and refund
client-gated transfers; review keys that hold it.
2026-10-07
Per-customer developer fees
NewGET, PUT and DELETE /v1/customers/{id}/developer-fees set a developer fee override for one
of your customers. The override replaces your global developer fee for that customer (send {} to
charge them none); removing it returns them to your global fee. Same caps as the global fee.
New GET /v1/developer-fees/customers lists the customers that have an override (a custom fee, or
waived), most recently updated first, with cursor pagination.
Migration. None. The endpoints are additive; customers without an override keep your global fee.
2026-09-11
On-ramp deposit instructions carry the account name to enter
Anaud_to_stablecoin route’s instructions.deposit now includes payeeName: the account name
the payer enters alongside the BSB and account number. It is the customer’s verified name (the
name on their KYC/KYB record), and it is registered on the virtual account together with your
company name, so the payer’s bank confirms the payee when they enter either. The instruction
steps name it too.
Before this, the account was registered under your company name only, so a customer entering
their own name failed their bank’s payee check and could only pay by entering “Wayex”.
Migration. None. The field is additive and only present on routes created from this release.
Routes created earlier carry no customer name on the account: keep telling those payers to enter
“Wayex”. Re-create the route to get a named account.
2026-09-04
Breaking · AUD payout destinations are format-checked at creation
POST /v1/payment-routes and POST /v1/customers/{customerId}/payment-routes now validate an AUD
destination when you create the route, not when the payout is built:
bsbmust be six digits, plain or hyphenated —062000and062-000are both accepted and both stored as062000.accountNumbermust be one to nine digits.- A PayID
valuemust be a plausible alias of its declaredtype(an email address, a phone number of 8–15 digits, or an 11-digit ABN). Spaces, brackets and hyphens are tolerated and normalised.
400 on the
create call.
Migration. Nothing changes if you already send well-formed details. If you pass through
user-entered bank details, validate or normalise them before you create the route.
Transfer holds and returns are easier to follow
GET /v1/transferstakes two new query parameters:status(one value or a comma-separated list of lifecycle statuses; an unknown value is a400) andhold_reason(the machine code onreferences.payoutHoldReasonorreferences.lastCaseReason). Pull the held or failed set directly instead of paging everything and filtering client-side.- A payment returned after the transfer completed — an AUD payout sent back by the receiving bank,
or a returned pay-in — now finishes at
reversedon both corridors. The transfer passes throughreturnedandreversingon the way; treat those two as still in flight andreversedas the end state. references.lastCaseReasonandreferences.lastCaseAtreport why a transfer is parked and when. Where the hold is something Wayex has to clear rather than anything about your request, the code readsmanual_or_provider_reviewand needs no action from you.
Treasury account names are capped at 140 characters
accountName on Treasury AUD funding instruments and on bank-account and PayID beneficiary
destinations is now limited to 140 characters and must contain at least two printable characters.
The bank rail cannot carry more, so an unrenderable name is now a 400 at create time instead of a
payout that reserves your funds and then parks.
2026-07-25
Breaking · you name the settlement network when buying stablecoin
POST /v1/treasury/conversion-quotes now requires settlementNetwork when sourceAsset is
"AUD". Wayex no longer selects a chain for that direction.
The network you name is the chain the purchased stablecoin is delivered onto, so it is the chain
your account then holds the balance on and the chain you can withdraw it on. That is your decision,
not ours, and there is no default and no fallback behind it.
settlementNetwork to every AUD-to-stablecoin quote request. Choose from the
runtimeCapabilities entries on GET /v1/treasury, and choose a chain your account can actually
withdraw on. Omitting it now fails with 400 settlement_network_required on the
settlementNetwork parameter.
Two refusals you should treat as “pick a different chain”, not as transient errors:
400unsupported_asset_network— the asset does not settle on that chain, or Wayex cannot receive it there. This is now checked before your account’s enabled pairs, so an unwired chain fails here rather than with422asset_network_unavailable. A pair that is wired but not enabled for your account still returns the422.409conversion_route_conflict— Wayex has a settlement route pinned for that asset and you named a different chain. This check is unchanged, but it is now reachable on every AUD-to-stablecoin quote, because previously nobody sent the field. If a route is pinned for your account, name exactly that chain.
settlementNetwork stays optional
there, Wayex still routes from the chains your account holds the balance on, and a supplied value is
still only an override. Do not make the field mandatory across both directions in your client.
See Choosing the settlement network.
Breaking · free-form maps reject a reserved key
metadata on customers and counterparties, and partyContext, businessIdentity, and glMapping
on Treasury requests, now refuse the reserved key @@wxtype and any @@wxtype.esc… variant, with
400 invalid_request. Nothing is written, including on a PATCH that would otherwise merge. These
keys were previously accepted.
Migration. Only integrations that happen to use that exact key name are affected. Near misses
such as wxtype, @@wxtypes, and my@@wxtype remain ordinary keys. See
Reserved metadata key.
New hold reason · withdrawal_network_not_held
A stablecoin withdrawal on a network your account has no credited deposit and no settled conversion
for is now accepted as held with statusReason withdrawal_network_not_held, instead of
proceeding. The source debit is reserved and nothing is sent until Wayex releases it.
Retrying will not clear it: withdraw on a network you have funded, or convert onto that network
first. The withdrawal preview does not test this restriction, so an unheld network previews cleanly
with canProceed true and is held on create — treat the create response as authoritative. See
Withdrawals on a network you do not hold.
