> ## Documentation Index
> Fetch the complete documentation index at: https://docs.venlyfinance.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Partner onboarding

> The third onboarding gate: your customer must be accepted by our banking partner before a virtual bank account or pay-out route can be provisioned — and you can now start and watch that step yourself.

Getting an individual from "verified" to "can receive bank money" involves a step you could not see
until Finance API 1.7.0. Once identity verification has cleared and the customer has accepted the
partner terms, their verified data is relayed to our **banking partner**, which runs its own recipient
checks before it will issue bank details or accept a pay-out destination for them.

Until 1.7.0 that step was invisible: it started the first time you tried to provision, and you learned
about it only when the call failed with `409 partner-onboarding-pending`. It is now a readable — and
startable — resource of its own.

## The three gates, side by side

| Gate | Who clears it | Read it at | Blocks |
| - | - | - | - |
| Identity verification | Your customer, on the hosted flow | [`/iv-verification`](/api-reference/Finance-API/parties/get-verification-linkage), `kycStatus` | Everything that moves money |
| [Partner-terms consent](/guides/finance/onboarding/partner-terms-consent) | Your customer, on the consent page | [`/partner-terms`](/api-reference/Finance-API/parties/get-a-partys-partner-terms-consent-state) | Virtual bank accounts, pay-outs |
| **Partner onboarding** | Our banking partner, asynchronously | [`/partner-onboarding`](/api-reference/Finance-API/parties/get-a-partys-partner-onboarding-status) | Virtual bank accounts, pay-out routes |

They are independent. A party can be `VERIFIED`, have `ACCEPTED` the terms, and still be `PENDING`
here.

## Reading the status

```bash theme={null}
curl https://api-staging.venlyfinance.com/v1/parties/{partyId}/partner-onboarding \
  -H "Authorization: Bearer {access_token}"
```

```json Response (200) theme={null}
{
  "success": true,
  "result": {
    "partyId": "7e3b9c2a-1f4d-4a8b-9c11-2d6e8f0a1b22",
    "status": "PENDING"
  }
}
```

| `status` | Meaning | Provisioning answers |
| - | - | - |
| `NOT_STARTED` | The party has not been relayed to a partner yet. A normal `200`, not an error. | Triggers onboarding, then `409 partner-onboarding-pending` |
| `PENDING` | Relayed; the partner is still checking. | `409 partner-onboarding-pending` — retryable |
| `APPROVED` | The gate is satisfied. | Proceeds |
| `REJECTED` | Declined or revoked. | `422 partner-onboarding-rejected` — terminal for that attempt |

Reading never triggers anything. The same value is cached on the party as `partnerOnboardingStatus`,
so a plain [Get a party](/api-reference/Finance-API/parties/get-party-details) shows it too.

## Starting it early

Rather than letting the first virtual-bank-account call kick onboarding off and fail, start it as soon
as the party is verified:

```bash theme={null}
curl -X POST https://api-staging.venlyfinance.com/v1/parties/{partyId}/partner-onboarding \
  -H "Authorization: Bearer {access_token}"
```

The call is asynchronous — it answers `202` with the current status, normally `PENDING` — and
idempotent while onboarding is `PENDING` or `APPROVED`. Poll the read endpoint for the outcome.
Provisioning a virtual bank account after `APPROVED` then succeeds first time.

<Note>
  `REJECTED` is not a dead end. Calling `POST` again re-attempts onboarding, so if the underlying reason
  has been resolved — corrected details, a re-run verification — you can retry without involving Venly.
</Note>

### Preconditions

The request is refused with a **retryable** `409` until the party qualifies:

| `code` | Fix |
| - | - |
| `recipient-not-verified` | Complete [identity verification](/guides/finance/onboarding/lifecycle) first. |
| `party-not-account-holder` | Give the party an active `ACCOUNT_HOLDER` role on an account. |
| `verification-not-provisioned` | Identity verification is not enabled for your company — contact Venly. |

And with a terminal `400 party-type-not-supported` if the party is an `ORGANISATION`: partner
onboarding is individual-scoped.

## Where it fits in the flow

```mermaid theme={null}
flowchart LR
    V["Verified<br/><i>kycStatus VERIFIED</i>"] --> T["Partner terms<br/><i>ACCEPTED</i>"]
    T --> O["Partner onboarding<br/><i>POST → PENDING → APPROVED</i>"]
    O --> P["Provision<br/><i>VBA / payout route</i>"]
```

Front-load all three while your customer is still in your onboarding UI. Verification and consent need
the customer present; partner onboarding does not, so start it the moment verification clears and it
will usually be `APPROVED` before the customer asks for bank details.

## Next steps

<CardGroup cols={2}>
  <Card title="Partner-terms consent" icon="file-signature" href="/guides/finance/onboarding/partner-terms-consent">
    The gate that comes just before this one.
  </Card>

  <Card title="Virtual bank accounts" icon="building-columns" href="/guides/finance/virtual-bank-accounts">
    The first thing partner onboarding unblocks.
  </Card>

  <Card title="Troubleshooting verification" icon="wrench" href="/guides/finance/onboarding/troubleshooting">
    The retryable / terminal split across every onboarding error.
  </Card>

  <Card title="Onboarding lifecycle" icon="route" href="/guides/finance/onboarding/lifecycle">
    All the states, from a new party to an account that can move money.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.