POST /accounts with
type: international-fx or international-gusd returns 409 ENTITY_ONBOARDING_INCOMPLETE while
anything is outstanding — and reported continuously by GET /limitations on
payment.international:write.
What is checked
The same dot-paths appear in the
409’s details[].validationErrors[].field and in a limitation’s
missingFields, so one mapping in your integration covers both.
Beneficial owners
Read the current set withGET /v2/entities/{entityId}/beneficial-owners, and write it with
PUT /v2/entities/{entityId}/beneficial-owners.
The PUT replaces the whole set. Entries carrying an id are updated, entries without one are
created, and anyone the payload omits is deleted. That is deliberate: ownership percentages are only
meaningful as a set — the provider validates their total — so a partial update has no coherent
meaning. Read the set, modify it, send it back whole.
The three roles
One person usually holds several roles; the example above is all three. The rules the API enforces:
- Exactly one
fx-account-holder— and its absence is what keepspayment.international:writeblocked. More than one is400. - At most one
director. A set still being assembled may have none; the missing-director case is reported byGET /limitationsrather than by rejecting the write. - A
ubomust hold at least 0.25 (25%) and carryownershipPercentage. Anyone below that is not a beneficial owner — give them thedirectortype instead. - At most four
uboentries, and theirownershipPercentagevalues may not total more than 1. Both are checked here rather than left to the provider, whose own error does not say which entry or total was at fault. - At most 20 people in one request.
firstName/lastNameare at least 2 characters, anddateOfBirthmust put the person between 18 and 120 years old.
Identification depends on residency
usResident: true→taxInfowith anssnoritin(9 digits, dashes optional).usResident: false→internationalIdType(passport,driver-licenseornational-id) andinternationalId.
GET returns taxInfo.identifierLast4, the last four characters of
internationalId, and a hasIdentityDocument boolean — never the document itself.
When an identity document is required
Recording the numbers is not always enough: the provider sometimes wants to see the ID. There are exactly two cases, and both are rejected with400 VALIDATION_ERROR naming the person, so you never
discover them from a failed payment later:
- Any non-US resident among the people you record.
- Every beneficial owner — including US residents — when the entity’s
businessTypeissole-proprietorship.
POST /attachments and reference it on the person:
backAttachmentId when you have it, but a front-only upload is
accepted. The two ids must differ.
The attachment must belong to the same entity as the person — an id from another entity is a 404.
Documents are handed to compliance as part of the write: if that hand-off fails the whole request
fails with 503 COMPLIANCE_UPLOAD_FAILED and nothing is saved, so a retry is safe and a person can
never be left on file claiming a document that was never delivered.
Putting it together
GET /limitations still reports a reason after that, read its code: MissingInformation lists
what to send, while LocationRestricted, AccountBlocked and AccountUnderReview are not something
more data will fix — contactEmail, when present, is where to take it.
See also
- International payments — the two rails and their payment payloads
- Payment attachments — uploading documents