Create business customers
This guide describes how to create and onboard your customers.
This is a new customer onboarding flow, which is recommended for all new integrations.
If you already have an existing integration with Customers API v.1, you can continue using it. BVNK will continue to support this API v.1 going forward.
The onboarding flow is asynchronous: after you create a customer, BVNK processes the application and notifies you via webhooks when action is required or when verification is complete.
You can customize the customer creation and onboarding according to your own platform flow. The modular approach allows you to call endpoints for adding documents or sharing data in any order.
The data and documents you must submit depend on your use case and on the BVNK entity (US or EU) your account is assigned to. See the compliance requirements for the full list.
When onboarding a customer, they pass through the following stages:

| Status | Description |
|---|---|
INFO_REQUIRED | The customer data is submitted partially. Provide other information or documents. |
PENDING | The customer data is submitted and waiting for the BVNK review. |
VERIFIED | Customer verification has been succesfully completed. |
ACTIONS_REQUIRED | Additional actions are required from the partner/customer. |
REJECTED | Customer checks failed. Customer onboarding is not possible. |
TERMINATED | The customer is removed by BVNK or partner. |
Prerequisites
Before you start, make sure you have:
- A BVNK account with Embedded Partner capabilities enabled.
- API keys generated via the BVNK Portal.
- Webhook endpoint configured to receive status change events from BVNK.
- Familiarity with BVNK's compliance requirements for business customers.
Create agreements
Agreements must be presented, signed, and stored before a customer record exists. This is useful when you want your prospect to accept the terms during sign-up, and only commit a customer to BVNK once the paperwork is in order.
Each agreement has one of the following statuses:
| Status | Description |
|---|---|
PENDING | Agreement created and awaiting a response from the customer. |
ACCEPTED | Customer accepted the agreement. |
REJECTED | Customer rejected the agreement. |
The typical flow is:
-
Create an agreement working set for the prospective customer by sending the
POST platform/v2/agreementsrequest.In the request, provide the data that will help BVNK determine the agreements relevant to your use case. Supply a
referencethat is unique within your account. You will reuse it to retrieve the set, to bulk-respond, and to bind the working set to a customer later.{"reference": "b3a4c1e2-9a1f-4c2b-8f11-7c2e5d4f9a01","useCase": "STABLECOIN_PAYOUTS","customerType": "COMPANY","countryCode": "DE"}The response returns the following values:
- Agreement's
id. When creating a customer, you will use this ID to pull the customer's agreement. - Current
status.PENDINGon creation. expiresAt: the session is valid only for this period, and the agreement must be accepted before it expires.
Save the
referenceand the returnedidvalues for the subsequent steps. - Agreement's
-
Share the agreements with your customer and collect their responses. When you need to refresh the document URLs (for example, if the presigned URL has expired), use any of the following:
GET platform/v2/agreementsto list the full customer agreements along with their actual status.GET platform/v2/agreements/{id}to fetch a single agreement.GET platform/v2/agreements/{id}/contentto get the content of an agreement available for download via a link. Use this to share the agreement in the text form with your customer.
The agreements are valid for one year.
-
Submit the customer's decisions by sending the
POST platform/v2/agreements/actionsrequest. The call is scoped byreferenceand accepts up to 50ACCEPT/REJECTactions in one request.{"reference": "b3a4c1e2-9a1f-4c2b-8f11-7c2e5d4f9a01","actions": [{"agreementId": "06d119bc-64f6-46b2-aea2-3ff94c4c616f","type": "ACCEPT"},{"agreementId": "6b4f0f2a-5c7d-4f1e-9c2a-1a9e2e1b3f48","type": "REJECT"}]}The response is a paginated list of per-item outcomes: successful items carry the updated
status, and failed items carry anerror. -
When you subsequently create the customer via
POST platform/v2/customers, pass the samereferenceso the signed agreements are bound to the new customer record. You do not need to re-sign or reassign them.
Reusing an Idempotency-Key with a different payload returns 409. The same 409 is returned if the reference is already bound to an existing customer. If the agreements upstream is temporarily unavailable, both the create and bulk-actions endpoints return 502 — retry with the same Idempotency-Key.
Create business customers
Business customer creation and onboarding is only available for the embedded delivery model. This flow requires verification of the legal entity (KYB) and related individuals, including directors, UBOs, and authorised signatories (KYC). The specific data and document requirements depend on jurisdiction (US or EU) and onboarding model:
- BVNK-Managed: You submit structured data and raw identity documents (ID front/back, selfie, proof of address) via BVNK's Onboarding API. BVNK performs identity verification (ID&V) via partner services. Recommended when you don't have an existing KYC/KYB programme or want BVNK to handle the full verification lifecycle.
- Partner-managed: Available to regulated partners with an appropriate AML programme.. You perform ID&V using your own processes and pass verification metadata (document type, number, expiry, liveness timestamp, address verification type) along with a customer risk score and EDD attestation to BVNK. Note that some features of the BVNK-Managed model are not available for the Partner-managed model. To learn more, contact your BVNK account manager.
The typical BVNK-Managed flow for a business customer follows these steps:
You can perform steps 3-5 in any order.
-
Create a customer by sending the
POST platform/v2/customersrequest with the minimum required fields. In practice you should still send a completebusinessProfileand jurisdiction-specificassociatesfields so onboarding is not stalled.{"useCase": "STABLECOIN_PAYOUTS","reference": "partner-ref-001","company": {"name": "Krause Fintech GmbH","entityType": "CORPORATION","taxIdentification": {"number": "DE123456789","taxResidenceCountryCode": "DE"},"registrationNumber": "HRB 123456","incorporationDate": "2019-01-15","businessOperationsStartDate": "2019-02-01","address": {"addressLine1": "Heidestrasse 19","city": "Cologne","postalCode": "51247","countryCode": "DE"},"isOperationalAddressDifferent": false,"businessProfile": {"description": "German fintech company specializing in payment solutions and financial software","naicsCode": "5239","monthlyExpectedVolumes": "FROM_100K_TO_1M","website": "https://www.krause-fintech.de","customerTypes": "Both","prohibitedJurisdictionsExposure": false,"annualIncomingTransactionValue": "500000","annualOutgoingTransactionValue": "250000","jurisdictionalPortfolioDistribution": [{"country": "DE","percentage": 45},{"country": "FR","percentage": 35},{"country": "DE","percentage": 25}],"isRegulated": true,"regulatorInformation": {"regulatorName": "BaFin","regulatorJurisdiction": "DE"},"isPubliclyListed": false,"sourceOfFunds": "COMMERCIAL_ACTIVITIES","intendedUseOfAccount": "SUPPLIER_VENDOR_PAYMENTS"},"associates": [{"person": {"firstName": "Freya","lastName": "Krause","dateOfBirth": "1982-03-24","nationality": "DE","birthCountryCode": "DE","address": {"addressLine1": "Heidestrasse 19","city": "Cologne","postalCode": "51247","countryCode": "DE"},"contactInfo": {"emailAddress": "freya.krause@krause-fintech.de"},"taxIdentification": {"number": "21/815/08150","taxResidenceCountryCode": "DE"},"position": "Geschaeftsfuehrer"},"titles": ["UBO","DIRECTOR","SIGNATORY","ACCOUNT_REPRESENTATIVE"],"ownership": {"percentage": "100","type": "DIRECT"}}]}}The response includes the customer's
idand initialstatus(for exampleNOT_STARTED). Save the returned associate, agreement, and customer IDs, and your external references for later steps. -
Retrieve the customer's status and the list of documents required for compliance by sending the
GET platform/v2/customers/{id}request with the customer's ID you received in the response from step 1.In the response, you will receive the ID and the status of the customer.
{"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6","reference": "partner-ref-001","status": "PENDING","type": "COMPANY","model": "EMBEDDED_BVNK_MANAGED","useCase": "FIAT","name": "Acme Ltd","createdAt": "2026-04-28T11:39:12.788Z","updatedAt": "2026-04-28T11:39:12.788Z","authenticatedLink": {"link": "https://onboarding.bvnk.com/link/eyJhbGciOi...","expiresAt": "2026-04-28T12:39:12.788Z"},"requiredActions": [{"type": "DATA","code": "PROOF_OF_DIRECTORSHIP","category": "DOCUMENT_REQUIREMENTS","description": "Proof of directorship/trustees dated within the past 6 months"},{"type": "DATA","code": "CERTIFICATE_OF_INCORPORATION","category": "DOCUMENT_REQUIREMENTS","description": "Business Formation Document"},{"type": "DATA","code": "PROOF_OF_OPERATIONAL_ADDRESS","category": "DOCUMENT_REQUIREMENTS","description": "Proof of Operational Address"},{"type": "DATA","code": "CORPORATE_STRUCTURE","category": "DOCUMENT_REQUIREMENTS","description": "Capitalization Table / Ownership Structure"},{"type": "DATA","code": "ARTICLE_OF_ASSOCIATION","category": "DOCUMENT_REQUIREMENTS","description": "Article of association"},{"type": "DATA","code": "MEMORANDUM","category": "DOCUMENT_REQUIREMENTS","description": "Memorandum"},{"type": "DATA","code": "REQUIRED_ALL_ASSOCIATES_VALID","category": "ASSOCIATES","description": "All associates must have valid status prior to submission."}],"company": {"name": "Acme Ltd","entityType": "CORPORATION","registrationNumber": "12345678","taxIdentification": {"number": "GB123456789","taxResidenceCountryCode": "DE"},"incorporationDate": "2018-05-12","businessOperationsStartDate": "2018-06-01","address": {"addressLine1": "Friedrichstraße 123","addressLine2": "Suite 400","city": "Berlin","postalCode": "10117","countryCode": "DE"},"associates": [{"person": {"firstName": "Jane","lastName": "Smith","dateOfBirth": "1985-09-23","nationality": "DE","birthCountryCode": "DE"},"titles": ["UBO","DIRECTOR","SIGNATORY"],"ownership": {"type": "DIRECT","percentage": "100"}}]}} -
Upload the required company documents by sending the
POST platform/v2/customers/{customerId}/documentsrequest with the customer's ID you received in the response from step 1.Upload documents sequentially. You can add up to three documents in a batch. Add a one-second delay between uploads to stay within rate limits. For the list of the required documents, see Business documents (KYB) in the Compliance requirements reference.
tipFor documents in unsupported languages, a professionally notarised English translation is permitted.
In the response, you will see the documents accepted for processing.
{"id": "9b0c4f1d-7aa2-4c7e-8d55-f8b4a1d6c210","customerId": "0a184641-30e2-4414-871f-3db1c683900e","totalDocuments": 3,"successCount": 3,"failureCount": 0,"documents": [{"documentId": "b8f8a6b5-8f44-4b7c-8d1e-4a6a5a9b4a21","type": "CERTIFICATE_OF_INCORPORATION","filename": "certificate.pdf","description": "Certificate of Incorporation","status": "STORED","uploadedAt": "2026-04-22T10:58:35.056865Z"}],"createdAt": "2026-04-22T10:58:35.056865Z"} -
Upload associate ID documents by sending the
POST platform/v2/customers/{customerId}/associates/{associateId}/identification-documentsrequest with the associate ID you received in the response from step 2.For the list of the required documents, see Identity verification (associates) in the Compliance requirements reference.
{"metadata": [{"type": "PASSPORT","name": "passport.pdf","countryCode": "DE"}]}In the response, you will receive the associate ID and the number of documents accepted for processing.
{"id": "4b0b8e2e-2f4e-4bfa-86d2-95aed0512c5f","associateId": "07b099fa-e1ee-4ad4-9cc4-6f2513a5a240","acceptedDocumentCount": 1,"createdAt": "2026-04-22T11:00:35.056865Z"}
- Wait for the webhook or poll the status by sending the
GET platform/v2/customers/{id}request. The response includes onboarding ID, status, timestamps,associates(includingrequiredDocumentsandvalidationErrors), andagreements.
Customer review
Onboarding completes automatically once all of the conditions are met:
- You uploaded company documents, and they are accepted for processing.
- You uploaded associate identity documents, and they are accepted for processing.
- All assigned agreements accepted.
There is no separate "complete" or "submit" API call. Once all conditions are met, BVNK triggers verification for all associates and the company entity. The customer transitions through processing states, and you receive the final outcome via webhook.
Onboarding statuses
Customer status flow
Agreement status
| Status | Description |
|---|---|
PENDING | Agreement assigned to the customer and awaiting a response. |
ACCEPTED | Customer accepted the agreement. |
REJECTED | Customer rejected the agreement. |
Customer verification status
| Status | Description |
|---|---|
VERIFIED | Customer verified and approved. Wallets and products can be provisioned. |
REJECTED | Verification failed. The customer cannot proceed. |
SUSPENDED | Account suspended (post-onboarding). |
Document rejection and resubmission
When a document is rejected, the status response includes rejection details:
{
"docSetType": "SELFIE",
"types": ["SELFIE"],
"status": "REJECTED",
"rejectLabels": ["BAD_SELFIE"],
"clientComment": "A new liveness check has been requested."
}
Handle rejections programmatically. Parse rejectLabels to determine whether to resubmit or surface a failure to your user. To resubmit, upload the corrected document to the same endpoint. The rejected document is replaced.
Webhooks
Webhooks must be used as the primary mechanism for tracking status changes. Use polling only as a fallback.
To receive updates on each step of the onboarding process, configure your webhook endpoint in the BVNK Portal. BVNK sends notifications for key lifecycle events.
| Event URN | Trigger |
|---|---|
bvnk:customers:status-change | Customer's onboarding status changes. |
bvnk:customers:agreements:status-change | Agreement is accepted or rejected by the customer. |
bvnk:customers:associates:status-change | Associate's onboarding validation state changes. |
bvnk:customers:associates:documents:status-change | Status of one or more associate documents changes. |
bvnk:customers:documents:status-change | Status of one or more company-level documents changes. |
Use bvnk:customers:status-change as the primary driver for your onboarding flow. When you receive a status change, call the status endpoint to retrieve the current requirements.
Error handling
| Scenario | Response status code | Resolution |
|---|---|---|
| Missing required field | 400 | Check the error message for the specific missing field. |
| Invalid industry / volume value | 400 | Use accepted enum values from the API definitions. |
| No associates provided | 400 | Include at least one associate with a valid title. |
| Associate missing required role | 400 | At least one associate must hold BUSINESS_OWNER or DIRECTOR title. |
| Documents not yet synced | 400: DOCUMENTS_NOT_READY | Wait for all documents to reach PENDING status. |