Skip to main content
In this guide you’ll read an account’s requirements, resolve the reference data some fields need, submit values and documents, and watch the account move to review. By the end onboarding lives entirely inside your own product. A recipient-only account’s requirements are short: identity and a payout destination, little else. An account that also holds a merchant capability has a longer list, since accepting payments carries its own set of fields. Building this interface once means rendering whichever list a given account actually has, not assuming the short one.
This is a standing commitment. Requirements change as regulation changes, and a new requirement arrives as a field your interface does not render, so accounts stall with nothing visibly wrong. The hosted link picks those changes up on its own.

Before you start

  • An account with capabilities requested. See Create an account.
  • An API key with connected_accounts:read and connected_accounts:write.

Steps

1

Read the account's requirements

Read the account. requirements.entries[] is the field-level view: every outstanding field, its state, and the capabilities it holds up.
Render entries as your form, and use restricts_capabilities to tell the account holder what each remaining field unlocks. See Requirements for every state.Add ?include=requirements.values to read back what has already been submitted. This is useful for prefilling an edit, and for resolving a person index like persons.0 to a name.
2

Resolve the reference data

Some fields cannot be typed freely. Fetch the valid values first.
momo returns mobile money operators the same way. Before you submit a bank account, confirm it resolves to a real account name:
These are not account-scoped (the NG bank list is the same for every account), so there is no account in the path.Send country on every call. If you leave it out, we use your own account’s country. So if your account is set to another country, a Nigerian bank comes back resolved: false.In sandbox, use account 0000000000 with bank code 033. Other account numbers do not resolve there. In live, lookups go to the bank, so use a real account number.
Resolving before submission turns a rejected requirement days later into an inline error while the account holder is still on the page.
3

Collect the documents

A document requirement (a person’s identity document, a certificate of incorporation) is a file. You can upload it yourself and attach it, as shown in Verify an account’s identity. Or mint an account link and send the account holder to it, so they upload it in the hosted flow:
See Hosted onboarding.
4

Submit

Submitting is an account write: POST /v1/accounts/{account_id} with a fields body, keyed by the same field keys requirements.entries[] returned. Omitting a field leaves it untouched, so you can build up a submission over several calls. But every field you do send is validated together, and if any one of them is rejected the call fails with 400 INVALID_REQUIREMENT_FIELD and none of the fields in it are saved, not even the ones that were fine. Contact details and capability requests in the same call are applied before the fields are validated, so a rejection does not undo them. A field that is only incomplete does not fail the call: it stays outstanding in requirements. See Requirements for the payout_destination shape and its rejection codes.The same call can set contact details and request capabilities, so a form submit is one round trip.
account_name aside, we ask the bank for the name on the account. It must match the person’s name, or the company’s registered name, or the destination is refused with code account_name_mismatch. See The payout_destination shape.An empty currently_due does not mean the account is finished. What was submitted sits in pending_verification until it is checked, so read every bucket, not only currently_due, before you tell the account holder there is nothing left to do.
5

Re-read the account

Submitted fields move to pending_verification while they are checked. Anything rejected comes back as currently_due with an entry in errors, whose reason is written for display to the account holder. See Requirements for the full state diagram.

What happens next

Once every requirement bucket is empty and the checks pass, each capability goes live, which arrives as capability.updated. Some capabilities are also reviewed by our team first. See How a capability goes live. Do not poll for it. See Monitor onboarding.

Errors

Submitting requirement values returns the standard error envelope.

Next steps