Changelog
Notable changes to the External API and to these docs. Most recent first. Subscribe to webhooks and watch this page to stay ahead of deprecations.
Versioning policy
The API is versioned in the path (/v1). Breaking changes ship under a new version — the current version keeps working. Deprecations are announced here and remain supported throughout a transition window before removal.
Within a version, changes are additive: we may introduce new fields and new enum values without a version bump. Build consumers to tolerate that.
To stay forward-compatible: branch your logic on the stable error type — never on message text — ignore unknown fields rather than rejecting them, and treat any unrecognised enum value as a safe default instead of failing.
Releases
US dollar bank payouts — state must be one of the codes we publish behaviour change 2026-10-02
For ACH_US destinations, the recipient's two-letter state is now checked against the set of codes we publish for that field. It used to be checked only for its format, so a well-formed code we cannot pay out to was accepted, the payment was funded, and the payout failed later when the recipient could not be registered.
- What changes — on
POST /v1/orderswith anACH_USdestination, astateoutside the accepted set returns400witherror: "ValidationError", namingstateand the value you sent. No order is created and no funds are taken. The code is read fromdestinationTransferData.state, or from the recipient's details — thedestinationUserDatayou send when the recipient is new, or the details we already hold for one you have used before — and the first of the two that is well-formed is the one judged. For a recipient you have used before, sendingstateindestinationUserDatadoes not change which value is judged: correct the destination, or the recipient's details. - What to do — send the code shown for
statein the destination fields published by the destination reference forACH_US. All fifty states and the District of Columbia are accepted, and so are American Samoa, Guam, the Northern Mariana Islands, Puerto Rico and the U.S. Virgin Islands. Military codes (AA,AE,AP) are not among the accepted codes. - What does not change — the published format of
stateis still^[A-Z]{2}$, so nothing you send is rejected by the schema that was not rejected before, and no response shape moves. Creating or editing a destination method is also unchanged, and destinations you already stored stay readable: the set is checked when the payment is created. One consequence worth planning for — a destination you stored earlier with a code outside the set must be edited before it can be used again, because every new payment to it is refused.
GET /v1/balances: actions.canBuy and actions.canSell now show which currencies can be converted no action needed 2026-10-02
- What changes — both flags used to be
falsefor every currency. In workspaces where each account’s funds are held in custody, they are nowtruefor every currency the account can convert from its balance, for example EUR and USDC. They stayfalsefor every other currency. - What does not change — in every other workspace both flags are still
false.canDeposit,canWithdraw, the balances and the response shape do not change. - What to do — nothing. If you show buy or sell actions, you can now use these flags to decide when to show them.
Example crypto addresses in the documentation are now unusable placeholders action required 2026-09-30
- What changes — the example wallet addresses shown in these guides and in the OpenAPI document are now addresses that fail the EIP-55 checksum, so no wallet accepts them. The examples they replace were well-formed addresses that a wallet does accept.
- What to do — if you copied an example address into code, tests or fixtures, replace it with a destination of your own. Funds sent to an address copied from documentation are not recoverable.
- What does not change — no endpoint, field, type or response shape.
tokenContractstill shows the real cUSD token contract on Celo, which is the value you are meant to use.
Held crypto deposits: a third-party origin now needs the sender’s address action required 2026-09-30
- What changes —
POST /v1/deposits/holds/{holdId}/travel-rulewith"ownership":"third_party"now requiresthirdParty.addresswithstreet,city,zipandcountryCode(ISO 3166-1 alpha-2). Without it the call returns400naming each missing field. - What to do — also ask your user for the sender’s postal address and send
{"ownership":"third_party","thirdParty":{"name":"…","surname":"…","address":{"street":"…","city":"…","zip":"…","countryCode":"ES"}}}. - What does not change —
{"ownership":"own"}and every response shape: the address is not returned in the hold.
Order and deposit responses and deposit webhooks return only documented fields behaviour change 2026-09-29
- What changes — the responses of
POST /v1/ordersandPOST /v1/deposits(including a replay with the sameIdempotency-Key),GET /v1/deposits/{depositId}andGET /v1/deposits/{depositId}/methods, and thedeposit_completedanddeposit_partially_completedwebhooks, now carry only the fields in the published schema. Undocumented fields that some of them used to include, such asonrampProvider,workspaceId,realFeeanddepositMethodsonPOST /v1/deposits, are no longer sent. - What does not change — every documented field keeps its name and value, including the payment details in
depositInfo. - What to do — nothing, unless you read one of those undocumented fields. In that case, stop reading it.
Held crypto deposits: declare their origin with POST /v1/deposits/holds/{holdId}/travel-rule action required 2026-09-28
Some inbound crypto deposits are held until someone declares who sent them (Travel Rule). A held deposit is not credited until the declaration is filed. You now receive a notification and can answer through the API.
- What changes — a new
deposit_action_requiredwebhook withdata.reason: "travel_rule_origin"and the hold indata.hold. It is re-sent every 6 hours while the hold is unanswered (data.reminder: true). There are three new endpoints:GET /v1/deposits/holds,GET /v1/deposits/holds/{holdId}andPOST /v1/deposits/holds/{holdId}/travel-rule. - What to do — handle
deposit_action_required: ask your user who owns the sending wallet, then send{"ownership":"own"}or{"ownership":"third_party","thirdParty":{"name":"…","surname":"…"}}. Repeating the same answer is safe. A different answer after one was filed returns409, and so does a deposit that is no longer held. - What does not change — deposits that are not held keep crediting exactly as before, and every existing endpoint and webhook is unchanged.
Argentine peso bank payouts — destinationTaxId must be 11 bare digits with a valid check digit action required 2026-09-26
For BANK_DEPOSIT_AR destinations, the recipient's CUIT/CUIL in destinationTaxId is now checked for its exact format and its check digit. The payout rail only accepts the digits, so a hyphenated value used to be accepted at capture and then fail later during the payout.
- What changes — the format is now
^\d{11}$(e.g.20000000001). OnPOST /v1/orders,POST /v1/withdrawalsand destination-method creation or editing withBANK_DEPOSIT_AR, a value with hyphens, spaces or any other character returns400witherror: "ValidationError"and an issue namingdestinationTaxIdthat says it must be exactly 11 digits with no hyphens, spaces or other characters. A value with 11 digits whose check digit does not match returns the same400, naming the check digit. No order is created. - Replaces — the format published on 2026-08-29,
^\d{2}-?\d{8}-?\d$with the example20-00000000-1. The hyphenated form is no longer accepted. - What does not change — AR destinations you saved before this date keep reading, listing and paying out: a stored hyphenated CUIT/CUIL is sent to the payout rail as its digits. Editing one requires the new format.
- What to do — send the 11 digits only, removing hyphens and spaces before sending, and handle the
400by asking your user to re-enter the CUIT/CUIL.GET /v1/currencies/ARS/destination-schemareturns the new format.
The documentation is available as Markdown, llms.txt and openapi.json no action needed 2026-09-25
- What changes — every guide is also published as Markdown at the same address with
.mdinstead of.html(for examplequickstart.md), without navigation or scripts. - New files —
llms.txtlists every page and the specification, andopenapi.jsonis the same OpenAPI document asopenapi.yml, in JSON. - What to do — nothing. Use them to import the specification into your tooling or to hand the documentation to an AI assistant.
China bank payouts validate destinationTaxId as a Unified Social Credit Code action required 2026-09-18
For BANK_DEPOSIT_CN destinations, destinationTaxId is the recipient company's Unified Social Credit Code (USCC). It carries a computable check digit, so a mistyped code can now be rejected when you create the order instead of failing later during the payout.
- What changes — on
POST /v1/ordersand on destination-method creation withBANK_DEPOSIT_CN, adestinationTaxIdthat is not a valid 18-character USCC (GB 32100-2015 alphabet and check digit) returns400witherror: "ValidationError"and an issue namingdestinationTaxId. No order is created. Lowercase letters and surrounding whitespace are accepted: the code is stored in uppercase with the whitespace removed. - What does not change — the field stays optional; a valid code is accepted exactly as before, and every other
BANK_DEPOSIT_CNfield is unchanged. - What to do — validate the code before sending it, or handle the
400by asking your user to re-enter the code. If you have no code for a recipient, omitdestinationTaxIdrather than sending an empty string — an empty string is now rejected too. If you already send correct codes, nothing changes for you.
A Brazilian real deposit method can now be a Pix collection account — depositType: "PIX" no action needed 2026-09-10
The account-level receive details of a Brazilian real (BRL) deposit method may now come back as depositType: "PIX". No other currency returns this shape.
- What changes — a Brazilian real (
BRL) deposit method can now returndepositType: "PIX"with two fields:qrCodeString, the copy-and-paste code the payer pastes into their bank app, andbase64QRCode, the same code rendered as a PNG. - Brazilian real deposit methods can now be created on demand —
POST /v1/deposits/methodswithmethodType: "fiat"acceptscurrency: "BRL", alongsideEUR,USD,GBP,MXNandARS. It previously answered a validation error namingcurrency. base64QRCodeis raw base64, with no data-URI prefix — prependdata:image/png;base64,yourself before using it as an image source.- It carries no
amountand noreferenceCode— the payer enters the amount in their bank app, and the code carries a reference dedicated to this collection account, so there is no separate reference field to show. Do not require either field on this variant. - Pass
qrCodeStringthrough unchanged — the code carries its own checksum over its exact characters, so re-encoding it, trimming it or inserting line breaks makes the payer’s bank app reject it as corrupt. Show it as copyable text and render the image frombase64QRCode. - What does not change — every other
depositTypeon the account view behaves exactly as before, and a deposit method whose details are not payable yet still reads asPENDING. - What to do — nothing, unless you switch exhaustively on
depositTypeand reject unknown values; then add aPIXarm, or fall through to a default instead of failing.
Brazilian real collections have a rail value of their own — PIX no action needed 2026-09-10
A Brazilian real (BRL) collection can now be quoted and reported on the rail PIX, alongside the PIX_BR spelling that already existed. Both are accepted; neither replaces the other.
- Where the new value appears —
originRailonPOST /v1/quotes, andrailon the deposit object returned with a deposit or an order. - What the two values mean —
PIXnames the instrument the collection is actually provisioned as, the copy-and-paste code and QR the payer pays (depositType: "PIX").PIX_BRnames the payment scheme. ABRLquote carrying either value is accepted, and quotes you already send keep working unchanged. - Discover the rails, do not hardcode them —
GET /v1/currencies/BRL/payin-schemalists every accepted spelling underacceptedOriginRailsand the canonical one to send underpayinMethods. Read it instead of pinning a literal, so a corridor that gains a rail does not turn into a validation error on your side. - The Brazilian Pix method now reports its own channel type —
payinMethods[].typeon that same endpoint readspixfor the Pix method, where it previously readbank. Label it as Pix: the payer pastes a code into their bank app and is never given an account number to transfer to. The Brazilian bank-transfer method still readsbank. - Treat rail values as an open set — corridors gain rails without a version bump. If you switch exhaustively on a rail and reject unknown values, add a
PIXarm, or fall through to a default instead of failing. - What to do — map
PIXto the Pix copy-and-paste instruction (depositType: "PIX", carryingqrCodeStringandbase64QRCode) exactly as you would forPIX_BR. Nothing else about the Brazilian corridor changes.
A pending payin instruction can now say that waiting will never produce details — pendingReason: "accountless_per_account_corridor" action required 2026-09-10
pendingReason on a depositType: "PENDING" payin instruction has a second value.
- New value —
accountless_per_account_corridor. It means this corridor collects only into a collection account dedicated to the paying account, the request named no account, and none can be created for it. - Waiting does not resolve it — unlike
collection_account_activating, payable details will never follow for this instruction and no activation webhook will arrive for it. Polling it is an endless loop. - What to do — create the deposit against an account and read the instruction from that response. Treat this value as terminal for the instruction you are holding, and surface it rather than showing the payer a spinner.
A Colombian peso deposit method can now return a payment page instead of bank coordinates action required 2026-09-10
On POST /v1/deposits/methods, GET /v1/deposits/methods and GET /v1/deposits/methods/{methodId}, the depositInfo of a COP method may now arrive as depositType: "PSE" carrying a single url, where it previously always carried bank coordinates.
- Handle
PSEondepositInfo— the object is{ "depositType": "PSE", "url": "..." }and nothing else: no account number, no bank name, no reference. Present theurlas a link the payer opens; there is nothing on it to copy into a bank transfer. - Existing methods are unaffected — a
COPmethod that returns bank coordinates today keeps returning them, with every field intact. The payment-page shape appears only on methods whose collection account is set up for it. - New optional field —
amountPrefilledon aPSEinstruction. Whentruethe page already carries the amount and the payer cannot change it; whenfalseor absent, the payer enters the amount themselves and you must tell them what to pay. - Read the type, not the currency — branch on
depositInfo.depositTyperather than assuming a shape fromcurrency. A currency can serve more than one instruction type, and which one you get can change without a version bump.
US dollar bank payouts — say whether the account is checking or savings no action needed 2026-09-10
An ACH_US destination now takes an optional bankAccountType, which says what kind of bank account receives the money. The US banking network carries it on the payout, and until now we could not tell it apart, so every US payout was sent as a checking account.
- Optional, and it defaults — omit
bankAccountTypeand the payout is sent asCHECKING, which is what happened before this field existed. Nothing you already send needs to change. - Accepted values —
CHECKINGorSAVINGS, in capitals. Any other value is rejected with a validation error rather than quietly treated as a checking account. - Not the same field as
accountType—accountType(PERSONAL/BUSINESS) says whether the recipient is a person or a business.bankAccountTypesays what kind of bank account the money lands in. Both can be sent on the same destination. - Confirm the field list at runtime —
GET /v1/currencies/USD/destination-schema?method=achUSreturns every field, whether it is required, and its accepted values.
US dollar bank payouts — state is now required action required 2026-09-09
An ACH_US destination now requires state, the two-letter code of the recipient’s US state. It was previously not part of the destination; a request that omits it, or sends anything other than a two-letter code, is rejected with a validation error.
- Now required —
state, on everyACH_USdestination you create. This rail also needscityandpostalCode. Each of those two is accepted on the destination, or on the recipient’s details — thedestinationUserDatayou send when the recipient is new, or the details we already hold for one you have used before. - Accepted values — exactly two uppercase letters, for example
NYorCA. A state name such asNew York, or an empty string, is not accepted. - What to do — add
statewherever you build anACH_USdestination, for example onPOST /v1/ordersandPOST /v1/withdrawals. US destinations you already stored keep working on read; an order to a stored recipient whose state we do not hold is rejected when you create it onPOST /v1/orders. For a recipient you have used before, sendingstateindestinationUserDatadoes not lift that — update the destination, or the recipient’s details, with the state. - That rejection is now a
400— an order to a stored recipient whose state we do not hold returnsinvalidParameters(id1008) with HTTP400, naming the field. It previously returnederrorCreatingOrder(id1021) with HTTP500. If you retry on5xx, stop retrying this case and supply the state instead. - Confirm the field list at runtime —
GET /v1/currencies/USD/destination-schema?method=achUSreturns the required fields and their formats. Read it instead of hardcoding this list, and it will stay correct through later changes.
Colombian peso payouts — BANK_DEPOSIT_COL now needs the bank code and the recipient’s ID action required 2026-09-08
A BANK_DEPOSIT_COL destination previously took a recipient name, a payout network id and an account number. The Colombian payout rail needs six fields, so that shape was accepted at creation and then refused at payout. Creating or updating one now requires all six, and each missing field is named in the validation error.
- Now required —
destinationBankCode(four digits, and one of the codes on the supported bank list, e.g.1007Bancolombia),destinationBankAccountType(CORRIENTEorAHORRO),destinationDocumentType(CC,CE,NIT,TIorPP) anddestinationTaxId, alongsidedestinationNameanddestinationBankAccount. - No longer required —
destinationNetworkId. It is now optional and is not used to route the payout. If you were sourcing it fromGET /v1/currencies/COP/networksjust to satisfy the schema, you can stop. - A bank code that is not on the list is refused at creation — a three-digit code, or a bank name where the code belongs, returns a
400naming the field. Previously such a value was accepted, the funds were collected, and only then did the payout fail. - Destinations you already stored keep working on read — an existing Colombian recipient still reads, still lists and still appears on past orders, with every field intact, and you can still rename it. Supply the four fields when you next create or update one; until then it cannot fund a new payout.
BANK_DEPOSIT_COLandACH_COPare equivalent — same payout rail, same six fields, same bank list. They differ only in the key that carries the account number (destinationBankAccounthere,destinationBankAccountNumberonACH_COP). UseACH_COPfor new integrations: the nameBANK_DEPOSIT_COLis also used for a Colombian collection rail, so the same string means two different things depending on where it appears.- Confirm the field list at runtime —
GET /v1/currencies/COP/destination-schema?method=bankDepositCOLreturns the required fields, their formats and the accepted bank codes. Read it instead of hardcoding this list, and it will stay correct through later changes.
A pending payin instruction can now tell you why it is pending no action needed 2026-09-03
A payin instruction with depositType: "PENDING" may now carry an optional pendingReason. It is additive: nothing that exists today changes shape, and the field is simply absent when we cannot classify the reason.
- New optional field —
pendingReasonon aPENDINGpayin instruction. Today the one value iscollection_account_activating, which means the collection account for this payer is being opened and payable details are expected shortly. - A missing value never tells you the wait is short or long — absence means only that no reason is classifiable. Do not infer timing from a missing field.
- It also appears on webhooks — the field rides the deposit instruction wherever it is returned, including webhook payloads. If you validate webhook bodies with a strict parser of your own, allow the new key.
- Only on the transaction-level instruction — an account-level deposit method never carries this field at all, whatever its status.
- Expect more values over time — treat
pendingReasonas an open set and ignore values you do not recognise rather than failing on them.
Idempotency-Key on the money write routes — safe retries behaviour change 2026-09-02
POST /v1/orders, POST /v1/deposits and POST /v1/withdrawals now honour the Idempotency-Key header: repeating the same key with the same payload returns the original response, and exactly one resource ever exists. Full contract: Retrying a write.
- If you do not send the header — nothing changes. Keyless writes behave exactly as before.
- If you already send the header — until now it was ignored on these three routes; it is honoured from this release. Two new outcomes: a malformed key (over 128 characters, characters outside
A-Za-z0-9_-, or the header sent more than once) is rejected with400, and reusing a key with a different payload — or on a different endpoint — is rejected with409. - What to do — send a fresh unique key (a UUID works) per logical attempt, and retry timeouts with the same key. After a definitive failure, verify state and use a new key.
- Ids are unaffected — resource ids remain server-generated and are never derived from your key.
Peruvian sol bank payouts — destinationCCI is now required action required 2026-09-02
A BANK_DEPOSIT_PEN destination now requires destinationCCI. It was previously optional; a request that omits it, or sends it empty, is rejected with a validation error.
- Now required —
destinationCCI, alongside the fields you already send. Send it for every recipient, whichever bank they use. - Accepted values — digits only, 1 to 20 characters. An empty string is no longer accepted.
- What to do — add
destinationCCIwherever you build aBANK_DEPOSIT_PENdestination, for example onPOST /v1/ordersandPOST /v1/withdrawals. Peruvian destinations you already stored keep working on read; supply the CCI when you next create or update one. - Confirm the field list at runtime —
GET /v1/currencies/PEN/destination-schema?method=bankDepositPENreturns the required fields, their formats and their accepted values. Read it instead of hardcoding this list, and it will stay correct through later changes.
Colombian ACH payouts — the bank code is checked against the bank list action required 2026-09-01
On an ACH_COP destination, destinationBankCode must be one of the four-digit codes the Colombian ACH rail publishes. Any other value is now rejected with a validation error naming the field; previously any non-empty string was accepted.
- What changes — the code must be exactly four digits and a bank on the supported list (e.g.
1007Bancolombia,1001Banco de Bogotá). A three-digit code such as001, or a bank name where the code belongs, is refused. - Why — those values were accepted at creation and then refused by the payout rail, after the funds had been collected, leaving the payment in manual review. The check now happens at the boundary, so you get a
400instead of a stuck payment. - What does not change — Colombian
BRE_B_COPpayouts carry no bank code and are untouched, as are all other rails. AnACH_COPdestination you created before this date still reads, lists and appears on orders exactly as before, bank code included, even if its code is not on the list — only creating or updating one is held to the new rule. - What to do — send the four-digit code, not the bank name.
GET /v1/currencies/COP/destination-schema?method=achCOPreturns the accepted codes with their bank names; read it instead of hardcoding the list. If one of your stored destinations carries a code that is no longer accepted, replace it before your next payout — the rail would refuse it.
A rail that is not a collection method for the currency now returns 1008 instead of 1002 action required 2026-09-01
When you send a supported currency together with a rail that the currency is not collected on, the rejection now identifies the real problem — the currency/rail pairing — instead of reporting the currency as unsupported. Affects POST /v1/deposits and POST /v1/orders. The status stays 400.
- What changes — the response for this case carries
error: "ValidationError",errorId: 1008,errorName: "invalidParameters". It previously carriederrorId: 1002,errorName: "notSupportedCurrency"and a message listing currencies that were unrelated to your request. The new message names the currency and the rail you sent, and the collection methods the corridor does accept. - What does not change — the request is still rejected, and it was correctly rejected before: these pairings are not available. Nothing new is accepted. A currency that genuinely has no enabled corridor still returns
errorId: 1002/notSupportedCurrency, unchanged — the two rejections are now distinguishable, which they were not before. - What to do — if you branch on
errorId: 1002to mean “this currency is unsupported”, that branch will no longer be entered for a currency/rail mismatch; handle1008for it, and treat it as a request to fix rather than a currency to drop. CallGET /v1/currenciesand readpayinMethodsto discover the rails each currency is collected on.
Deposits take originNetworkId to choose the mobile-money collection network action required 2026-09-01
POST /v1/deposits accepts a new optional originNetworkId, and a mobile-money collection that needs the payer's network now answers 400.
- What changes — you may send
originNetworkId, one of theidvalues fromGET /v1/currencies/{currency}/networks?rail={rail}&rampType=deposit, passing the same rail you send on the deposit. An id that corridor does not publish is rejected with400, and so is anoriginNetworkIdsent on a rail that is not mobile money. - What changes — where a mobile-money collection offers more than one network and you send no
originNetworkId, the response is400naming the field. It used to be500: do not retry it, resend with a network. - What does not change — the field is optional. Omit it and every request you send today is accepted unchanged; a collection with one network still resolves it for you.
- What to do — nothing, unless you collect by mobile money; then read the networks for the currency and send the payer's choice as
originNetworkId.
Argentine peso (ARS) is now a supported fiat currency for POST /v1/deposits/methods no action needed 2026-08-31
- What changes —
POST /v1/deposits/methodswithmethodType: "fiat"now acceptscurrency: "ARS". - What does not change — every other supported fiat currency, and every existing request, behaves exactly as before.
- What to do — nothing, unless you want to provision a dedicated ARS receiving account on demand; then send
currency: "ARS"withmethodType: "fiat".
Argentine peso bank payouts — the recipient tax ID is now required action required 2026-08-29
A BANK_DEPOSIT_AR destination must carry destinationTaxId: the recipient's CUIT/CUIL. It was optional; a request that creates an AR destination without it is now rejected with a validation error naming the field.
- Now required —
destinationTaxId, format^\d{2}-?\d{8}-?\d$(e.g.20-00000000-1), alongsidedestinationName,destinationNetworkIdanddestinationBankAccount. - Where — wherever you send a
BANK_DEPOSIT_ARdestinationTransferDatainline:POST /v1/ordersandPOST /v1/withdrawals. Destinations saved through the app are held to the same rule. - Why — the payout is registered against the recipient's own tax ID. Previously an AR destination without one could be registered under the payer's tax ID; that fallback is gone, and an empty value is now refused at capture instead of failing later at payout.
- What does not change — AR destinations you created before this date keep reading, listing and appearing on orders unchanged. Editing one requires adding the CUIT/CUIL; paying out from one without it is refused by the rail and routed to manual review, never re-attributed.
- Confirm the field list at runtime —
GET /v1/currencies/ARS/destination-schemareturns the required fields and their formats. Read it instead of hardcoding this list.
Withdrawals can declare a third-party destination with beneficiary no action needed 2026-08-28
POST /v1/withdrawals accepts a new optional beneficiary object for payouts to a wallet that is not the account holder's own.
- What changes — you may send
beneficiarywithname,surnameandrelationship: "third_party". When present, bothnameandsurnameare required. - What does not change — omit
beneficiaryand the withdrawal behaves exactly as before. Every existing request is accepted unchanged. - What to do — nothing, unless you pay out to a third party's wallet; then send
beneficiarywith the recipient's real name and surname.
The withdrawal approval endpoint has been removed action required 2026-08-28
POST /v1/withdrawals/approve no longer exists.
- What changes —
POST /v1/withdrawals/approvenow returns404. Withdrawals created through the API were never held for this approval step. - What to do — if you call this endpoint, remove that call. A created withdrawal proceeds without it.
KYC profile: pep is replaced by pepDeclaration, and profession is a sector code action required 2026-08-20
Two fields on POST /v1/kyc/data change. Requests keep succeeding either way — no new error is returned — but a value we no longer recognise is not recorded.
- What changes —
pep(boolean) is removed. SendpepDeclarationinstead, with one ofno,yes,family(immediate family member of a politically exposed person) orrelated(known close associate of one). Omit the field when the holder has not answered; never sendnoto mean unanswered. - What changes —
professionis now an activity sector code, a short numeric code such as24. Free text such as"Nurse"is still accepted by the request but is not recorded: it counts as not declared, and the holder is asked to choose a sector while completing verification. - What to do — if you send
pep, switch topepDeclaration:pepis now ignored, so a declaration sent under the old key is not stored. If you send a free-textprofession, either send a sector code or omit the field. Both fields stay optional, andmissingFieldsin the response tells you what is still outstanding.
Orders now return externalReference under the name you send it no action needed 2026-08-18
You set externalReference when creating an order. Until now the order read back carried that value under a misspelled key, externalRefeference, with a doubled e.
- What changes —
GET /v1/ordersandGET /v1/orders/{orderId}now returnexternalReferencewith the value you supplied. Reconciling on the key you wrote with works. - What does not change — on
GET /v1/orders,externalRefeferenceis still returned with the same value. It is now marked deprecated in the spec and will be removed in a future major version. - Also —
POST /v1/ordersnow echoesexternalReferenceon the create response, so you can confirm what you sent without a second call. The correct spelling is returned onGET /v1/orders,GET /v1/orders/{orderId},POST /v1/ordersandPOST /v1/pending-payments/{transferId}/create-order; the deprecated key was never present on the create or single-order responses and is not being added there. - What to do — nothing today. When convenient, switch your reads to
externalReference; if you branch on the presence ofexternalRefeference, note that both keys are present. - What changes — when the lookup behind either endpoint is temporarily unavailable, you get
503witherror: "ExternalServiceError". Previously both returned200— an emptynetworksarray, orlimits: null. - What does not change — a successful response is identical. An empty array still means the corridor genuinely has no matching networks, and
limits: nullstill means no bounds are published for it. - What to do — handle
503on both endpoints by retrying. If you cache either result, only cache a200: an empty list is settled, a503is unknown.
Corridor discovery returns 503 when a lookup is unavailable action required 2026-08-18
GET /v1/currencies/{currency}/networks and GET /v1/currencies/{currency}/limits now tell an empty answer apart from an answer they could not obtain.
Collections in ARS, COP, CLP, BOB and TWD are no longer available action required 2026-08-07
These five currencies can no longer be used as the origin of a quote or an order — you cannot collect funds in them. Paying out to all five is unchanged and continues to work.
- What changes —
POST /v1/quotesandPOST /v1/ordersrejectoriginCurrencyofARS,COP,CLP,BOBorTWDwith a validation error naming the currency. - What does not change —
destinationCurrencystill accepts all five. Payouts, destination schemas and existing payout methods are untouched. - What to do — stop offering these five as collection currencies. Orders already created are unaffected.
- Check availability at runtime —
GET /v1/currenciesreturns what each currency can do today. Read it instead of hardcoding a list, and it will stay correct through later changes.
Chilean peso bank payouts — three fields are now required action required 2026-08-07
A BANK_DEPOSIT_CL destination now takes five fields. Three of them were previously optional and are enforced today — a request that omits any of them is rejected with a validation error.
- Now required —
destinationBankName,destinationBankAccountTypeanddestinationTaxId, alongside thedestinationNameanddestinationBankAccountyou already send. - Accepted values —
destinationBankAccountTypeisCORRIENTEorAHORRO.destinationTaxIdis the recipient's RUT. - What to do — add the three fields wherever you build a
BANK_DEPOSIT_CLdestination, for example onPOST /v1/ordersandPOST /v1/withdrawals. - Confirm the field list at runtime —
GET /v1/currencies/CLP/destination-schemareturns the required fields, their formats and their accepted values. Read it instead of hardcoding this list, and it will stay correct through later changes.
Unreleased 2026-08-13
- New: fetch a single conversation —
GET /v1/conversations/{conversationId}?endUserEmail=returns one conversation. Previously you had to list an end-user's conversations and pick it out.endUserEmailis required: a conversation is addressed by end-user and id. Additive — nothing you send today changes. - Unrecognised query parameters are now rejected on the list endpoints —
/v1/deposits,/v1/orders,/v1/withdrawals,/v1/pending-paymentsand their/countvariants. A misspelled filter such as?limitt=5previously returned200with the parameter ignored; it now returns400. If you send any parameter not listed for the endpoint, remove it. cityandpostalCodeare required when paying out toSEPA,ACH_USorGBP_BANK_TRANSFER. Send them in eitherdestinationTransferDataordestinationUserData— either location satisfies the requirement. Requests missing both are now rejected at submission with a400naming the field, instead of failing later during payout.- Clearer payout errors. A missing recipient address now returns a message naming the field and where to put it, rather than a generic "user data is not valid".
- New:
refundStatuson pending payments.GET /v1/pending-paymentsandGET /v1/pending-payments/{transferId}may now returnrefundStatus— one ofpending_approval,returning,returned,failed. The field is absent when no refund is in progress. Onlyreturnedmeans the payer has the money back: do not readreturningas complete. While the field is present the payment cannot be linked to an order or a deposit, so stop offering it for linking. Additive — nothing you send today changes.
v1.0.0 current 2026-07-06
Initial public API (quotes, orders, deposits, withdrawals, webhooks) on stable JSON contracts — and the launch of this documentation site.
| Area | Change |
|---|---|
quotes | Lock an exchange rate and fees for a currency pair. |
orders | Commit a quote to a payout destination and track it to completion. |
deposits | Collect funds locally into a workspace balance. |
withdrawals | Pay out locally from a workspace balance. |
KYC | Onboard and verify entities before they transact. |
webhooks | Signed event notifications for state changes. |
discovery | Per-currency capability discovery via /v1/currencies/*. |
banking accounts | Manage the banking accounts behind deposits and withdrawals. |
docs | Modern API documentation launched — this site. |
Deprecated — the generic LOCALBANK deposit type is deprecated in favour of corridor-specific types (e.g. SEPA, PIX, and country-specific bank types). Discover the exact type per currency with GET /v1/currencies/{currency}/payin-schema. It is still returned on historical records for backward compatibility.
Upcoming
A cleaner, more consistent contract is planned: prefixed resource ids, a unified error envelope, 429 rate limiting with Retry-After, and standardized timestamps. It will ship under the versioning policy above — existing /v1 contracts keep working, and every change lands on this page first.