Reference

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/orders with an ACH_US destination, a state outside the accepted set returns 400 with error: "ValidationError", naming state and the value you sent. No order is created and no funds are taken. The code is read from destinationTransferData.state, or from the recipient's details — the destinationUserData you 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, sending state in destinationUserData does not change which value is judged: correct the destination, or the recipient's details.
  • What to do — send the code shown for state in the destination fields published by the destination reference for ACH_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 state is 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 false for every currency. In workspaces where each account’s funds are held in custody, they are now true for every currency the account can convert from its balance, for example EUR and USDC. They stay false for 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. tokenContract still 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-rule with "ownership":"third_party" now requires thirdParty.address with street, city, zip and countryCode (ISO 3166-1 alpha-2). Without it the call returns 400 naming 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/orders and POST /v1/deposits (including a replay with the same Idempotency-Key), GET /v1/deposits/{depositId} and GET /v1/deposits/{depositId}/methods, and the deposit_completed and deposit_partially_completed webhooks, now carry only the fields in the published schema. Undocumented fields that some of them used to include, such as onrampProvider, workspaceId, realFee and depositMethods on POST /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_required webhook with data.reason: "travel_rule_origin" and the hold in data.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} and POST /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 returns 409, 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). On POST /v1/orders, POST /v1/withdrawals and destination-method creation or editing with BANK_DEPOSIT_AR, a value with hyphens, spaces or any other character returns 400 with error: "ValidationError" and an issue naming destinationTaxId that 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 same 400, naming the check digit. No order is created.
  • Replaces — the format published on 2026-08-29, ^\d{2}-?\d{8}-?\d$ with the example 20-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 400 by asking your user to re-enter the CUIT/CUIL. GET /v1/currencies/ARS/destination-schema returns 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 .md instead of .html (for example quickstart.md), without navigation or scripts.
  • New files — llms.txt lists every page and the specification, and openapi.json is the same OpenAPI document as openapi.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/orders and on destination-method creation with BANK_DEPOSIT_CN, a destinationTaxId that is not a valid 18-character USCC (GB 32100-2015 alphabet and check digit) returns 400 with error: "ValidationError" and an issue naming destinationTaxId. 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_CN field is unchanged.
  • What to do — validate the code before sending it, or handle the 400 by asking your user to re-enter the code. If you have no code for a recipient, omit destinationTaxId rather 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 return depositType: "PIX" with two fields: qrCodeString, the copy-and-paste code the payer pastes into their bank app, and base64QRCode, the same code rendered as a PNG.
  • Brazilian real deposit methods can now be created on demand — POST /v1/deposits/methods with methodType: "fiat" accepts currency: "BRL", alongside EUR, USD, GBP, MXN and ARS. It previously answered a validation error naming currency.
  • base64QRCode is raw base64, with no data-URI prefix — prepend data:image/png;base64, yourself before using it as an image source.
  • It carries no amount and no referenceCode — 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 qrCodeString through 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 from base64QRCode.
  • What does not change — every other depositType on the account view behaves exactly as before, and a deposit method whose details are not payable yet still reads as PENDING.
  • What to do — nothing, unless you switch exhaustively on depositType and reject unknown values; then add a PIX arm, 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 — originRail on POST /v1/quotes, and rail on the deposit object returned with a deposit or an order.
  • What the two values mean — PIX names the instrument the collection is actually provisioned as, the copy-and-paste code and QR the payer pays (depositType: "PIX"). PIX_BR names the payment scheme. A BRL quote 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-schema lists every accepted spelling under acceptedOriginRails and the canonical one to send under payinMethods. 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[].type on that same endpoint reads pix for the Pix method, where it previously read bank. 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 reads bank.
  • 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 PIX arm, or fall through to a default instead of failing.
  • What to do — map PIX to the Pix copy-and-paste instruction (depositType: "PIX", carrying qrCodeString and base64QRCode) exactly as you would for PIX_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 PSE on depositInfo — the object is { "depositType": "PSE", "url": "..." } and nothing else: no account number, no bank name, no reference. Present the url as a link the payer opens; there is nothing on it to copy into a bank transfer.
  • Existing methods are unaffected — a COP method 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 — amountPrefilled on a PSE instruction. When true the page already carries the amount and the payer cannot change it; when false or absent, the payer enters the amount themselves and you must tell them what to pay.
  • Read the type, not the currency — branch on depositInfo.depositType rather than assuming a shape from currency. 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 bankAccountType and the payout is sent as CHECKING, which is what happened before this field existed. Nothing you already send needs to change.
  • Accepted values — CHECKING or SAVINGS, 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. bankAccountType says 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=achUS returns 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 every ACH_US destination you create. This rail also needs city and postalCode. Each of those two is accepted on the destination, or on the recipient’s details — the destinationUserData you 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 NY or CA. A state name such as New York, or an empty string, is not accepted.
  • What to do — add state wherever you build an ACH_US destination, for example on POST /v1/orders and POST /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 on POST /v1/orders. For a recipient you have used before, sending state in destinationUserData does 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 returns invalidParameters (id 1008) with HTTP 400, naming the field. It previously returned errorCreatingOrder (id 1021) with HTTP 500. If you retry on 5xx, stop retrying this case and supply the state instead.
  • Confirm the field list at runtime — GET /v1/currencies/USD/destination-schema?method=achUS returns 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. 1007 Bancolombia), destinationBankAccountType (CORRIENTE or AHORRO), destinationDocumentType (CC, CE, NIT, TI or PP) and destinationTaxId, alongside destinationName and destinationBankAccount.
  • No longer required — destinationNetworkId. It is now optional and is not used to route the payout. If you were sourcing it from GET /v1/currencies/COP/networks just 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 400 naming 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_COL and ACH_COP are equivalent — same payout rail, same six fields, same bank list. They differ only in the key that carries the account number (destinationBankAccount here, destinationBankAccountNumber on ACH_COP). Use ACH_COP for new integrations: the name BANK_DEPOSIT_COL is 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=bankDepositCOL returns 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 — pendingReason on a PENDING payin instruction. Today the one value is collection_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 pendingReason as 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 with 400, and reusing a key with a different payload — or on a different endpoint — is rejected with 409.
  • 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 destinationCCI wherever you build a BANK_DEPOSIT_PEN destination, for example on POST /v1/orders and POST /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=bankDepositPEN returns 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. 1007 Bancolombia, 1001 Banco de Bogotá). A three-digit code such as 001, 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 400 instead of a stuck payment.
  • What does not change — Colombian BRE_B_COP payouts carry no bank code and are untouched, as are all other rails. An ACH_COP destination 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=achCOP returns 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 carried errorId: 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: 1002 to mean “this currency is unsupported”, that branch will no longer be entered for a currency/rail mismatch; handle 1008 for it, and treat it as a request to fix rather than a currency to drop. Call GET /v1/currencies and read payinMethods to 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 the id values from GET /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 with 400, and so is an originNetworkId sent 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 is 400 naming the field. It used to be 500: 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/methods with methodType: "fiat" now accepts currency: "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" with methodType: "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), alongside destinationName, destinationNetworkId and destinationBankAccount.
  • Where — wherever you send a BANK_DEPOSIT_AR destinationTransferData inline: POST /v1/orders and POST /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-schema returns 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 beneficiary with name, surname and relationship: "third_party". When present, both name and surname are required.
  • What does not change — omit beneficiary and 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 beneficiary with 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/approve now returns 404. 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. Send pepDeclaration instead, with one of no, yes, family (immediate family member of a politically exposed person) or related (known close associate of one). Omit the field when the holder has not answered; never send no to mean unanswered.
  • What changes — profession is now an activity sector code, a short numeric code such as 24. 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 to pepDeclaration: pep is now ignored, so a declaration sent under the old key is not stored. If you send a free-text profession, either send a sector code or omit the field. Both fields stay optional, and missingFields in 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/orders and GET /v1/orders/{orderId} now return externalReference with the value you supplied. Reconciling on the key you wrote with works.
  • What does not change — on GET /v1/orders, externalRefeference is 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/orders now echoes externalReference on the create response, so you can confirm what you sent without a second call. The correct spelling is returned on GET /v1/orders, GET /v1/orders/{orderId}, POST /v1/orders and POST /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 of externalRefeference, note that both keys are present.
  • 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.

    • What changes — when the lookup behind either endpoint is temporarily unavailable, you get 503 with error: "ExternalServiceError". Previously both returned 200 — an empty networks array, or limits: null.
    • What does not change — a successful response is identical. An empty array still means the corridor genuinely has no matching networks, and limits: null still means no bounds are published for it.
    • What to do — handle 503 on both endpoints by retrying. If you cache either result, only cache a 200: an empty list is settled, a 503 is unknown.

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/quotes and POST /v1/orders reject originCurrency of ARS, COP, CLP, BOB or TWD with a validation error naming the currency.
  • What does not change — destinationCurrency still 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/currencies returns 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, destinationBankAccountType and destinationTaxId, alongside the destinationName and destinationBankAccount you already send.
  • Accepted values — destinationBankAccountType is CORRIENTE or AHORRO. destinationTaxId is the recipient's RUT.
  • What to do — add the three fields wherever you build a BANK_DEPOSIT_CL destination, for example on POST /v1/orders and POST /v1/withdrawals.
  • Confirm the field list at runtime — GET /v1/currencies/CLP/destination-schema returns 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. endUserEmail is 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-payments and their /count variants. A misspelled filter such as ?limitt=5 previously returned 200 with the parameter ignored; it now returns 400. If you send any parameter not listed for the endpoint, remove it.
  • city and postalCode are required when paying out to SEPA, ACH_US or GBP_BANK_TRANSFER. Send them in either destinationTransferData or destinationUserData — either location satisfies the requirement. Requests missing both are now rejected at submission with a 400 naming 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: refundStatus on pending payments. GET /v1/pending-payments and GET /v1/pending-payments/{transferId} may now return refundStatus — one of pending_approval, returning, returned, failed. The field is absent when no refund is in progress. Only returned means the payer has the money back: do not read returning as 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.

AreaChange
quotesLock an exchange rate and fees for a currency pair.
ordersCommit a quote to a payout destination and track it to completion.
depositsCollect funds locally into a workspace balance.
withdrawalsPay out locally from a workspace balance.
KYCOnboard and verify entities before they transact.
webhooksSigned event notifications for state changes.
discoveryPer-currency capability discovery via /v1/currencies/*.
banking accountsManage the banking accounts behind deposits and withdrawals.
docsModern 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.

← Prev
Glossary