Skip to main content

API onboarding (headless)

This mode is intended for partners who want full control over the UI. You collect merchant data in your own interface and send it to dpay in segments through the API. Actions that legally must be performed by the person concerned (contact and identity verification, declarations, agreement signing, and the verification transfer) are completed by the merchant in a short dpay-hosted hand-off.

Hybrid model

You submit structured data (company, bank account, beneficial owners, and documents) through the API and render it in your own UI. Personal actions (identity verification, PEP declarations, and agreement signing) remain hosted by dpay. This is a security and compliance requirement and cannot be moved into your UI.

Complete flow

Step 1: create a draft

A draft requires the contact details of the person opening the account and the accepted consents. The response contains ref (your partner_external_ref), which you use to address all subsequent calls.

POST/api/partner/v1/onboardingCreate an onboarding draft (idempotent by partner_external_ref).Full contract in the API Reference

Draft creation is idempotent. Repeating POST /onboarding with the same partner_external_ref returns the existing draft (200) instead of creating a duplicate. The response does not contain the hosted flow URL. You receive it from finalize or GET /onboarding/{ref} in the next_action.url field.

Step 2: submit data in segments

Complete the draft using independent segments. You can submit each segment separately and multiple times, with each request overwriting the previous value. Once the account is active, write segments can no longer be edited and return 409.

Company details

This segment determines the entity type (an individual or a company) and, for a company, collects registration and address data. After receiving the Polish tax identifier (NIP), dpay retrieves data from public registers. An entity removed from the register results in 422.

PATCH/api/partner/v1/onboarding/{ref}/companyCompany details / entity type.Full contract in the API Reference

Bank account and transaction profile

This segment contains the bank account to which the merchant will receive settlements and payouts, together with the business profile required by AML regulations. You must determine the entity type first with PATCH /company.

PATCH/api/partner/v1/onboarding/{ref}/bank-accountSettlement account and transaction profile (AML).Full contract in the API Reference

Identity and representation details

This segment prefills the primary applicant's identity. It applies to an individual or the owner of a sole proprietorship. For a company represented by multiple people, the representative's identity is established in the hosted flow, and this segment returns 422. Identity verification and PEP declarations always remain in the hand-off.

PATCH/api/partner/v1/onboarding/{ref}/identityPrefill the primary applicant's identity.Full contract in the API Reference

The representation segment applies only to companies represented by multiple people (422 in other cases). The response indicates the representation mode and whether an invitation or power of attorney is required.

PATCH/api/partner/v1/onboarding/{ref}/representationRepresentation of a company with multiple representatives.Full contract in the API Reference

Documents, beneficial owners, and invitations

Upload a document as a file (multipart or base64) with the document type and entity, or as a regulated-activity document. The response returns document_id. Store it so you can attach a power of attorney to an invitation for an authorised representative. A duplicate regulated-activity document returns 409.

POST/api/partner/v1/onboarding/{ref}/documentsUpload a document (multipart or base64).Full contract in the API Reference

Beneficial owners apply to companies represented by multiple people. Add them together with their identity, address, document, and declarations. You can also delete an existing entry.

POST/api/partner/v1/onboarding/{ref}/beneficiariesAdd a beneficial owner.Full contract in the API Reference DELETE/api/partner/v1/onboarding/{ref}/beneficiaries/{uuid}Remove a beneficial owner.Full contract in the API Reference

If another person (a board member or beneficial owner) must complete the personal actions, invite that person. They receive their own hosted-flow link. An invitation is idempotent by external_ref (a repeat request does not send a second SMS), and both the responses and invitation list exclude the invitee's personal data. You can resend an invitation (a cooldown applies; resending too quickly returns 429) or cancel it, which invalidates the link.

POST/api/partner/v1/onboarding/{ref}/invitationsInvite another person (representative / beneficial owner).Full contract in the API Reference GET/api/partner/v1/onboarding/{ref}/invitationsList invitations (without personal data).Full contract in the API Reference POST/api/partner/v1/onboarding/{ref}/invitations/{id}/resendResend an invitation.Full contract in the API Reference DELETE/api/partner/v1/onboarding/{ref}/invitations/{id}Cancel an invitation.Full contract in the API Reference
Prefill from public registers

You do not need to collect everything manually. After receiving a NIP, dpay can prefill company and beneficial-owner data from public registers. In practice, it is often enough to submit the NIP and bank account, with the merchant confirming the remaining details in the hand-off.

Step 3: finalize

After submitting all data, call finalize. This is a read-only operation: it checks whether the data is complete and returns the hosted hand-off. It always returns 200, even when data is missing.

POST/api/partner/v1/onboarding/{ref}/finalizeCheck completeness and retrieve the hosted hand-off.Full contract in the API Reference
  • next_action.url is the hosted resume URL. It authenticates the merchant using a token in the path and takes the merchant to the correct step.
  • next_action.embeddable indicates whether the URL can be embedded in an iframe. It is true when your domain is registered for embedding. If it is false, redirect the top-level window to next_action.url.
  • missing is a list of missing-data codes. An empty list means the data is complete, but the merchant must still perform the personal actions at next_action.url.

Missing-data codes (missing[])

CodeMeaning
account_type.missingThe entity type has not been selected (call PATCH /company first).
company.nip_missingNIP / company registration data is missing.
bank.account_missingBank account / transaction profile is missing.
identity.pesel_missingThe primary applicant's identity is missing (individual / sole proprietorship).
representation.requiredThe representation method has not been selected (company with multiple representatives).
beneficiaries.requiredNo beneficial owner or pending invitation exists.
documents.requiredDocuments are outstanding, including base company documents.

Step 4: hand off personal actions

Redirect the merchant to next_action.url (or embed it through the SDK) so the merchant can complete actions that cannot be performed through the API:

  • contact verification (SMS and email codes),
  • identity verification,
  • declarations, including PEP declarations,
  • agreement signing (SMS code),
  • verification transfer.

You receive a webhook after every status change.

Resuming and embedding (resume token)

The resume token is the final segment of the next_action.url path (48 characters, without a prefix). You can embed the hand-off in your page through the SDK:

<script src="https://panel.dpay.pl/sdk/dpay-onboarding-sdk.js"></script>
<script>
DpayOnboarding.mountResume('#dpay-onboarding', {
token: '<token from next_action.url>',
ref: 'invoice-customer-123',
onEvent: function (e) { /* { type, payload } */ },
});
</script>

Iframe onboarding describes the event catalogue and other options. If next_action.embeddable is false, redirect the merchant to next_action.url instead of embedding it.

The resume token is sensitive and time-limited

The token grants access to complete this merchant's onboarding, so treat it as a secret. Do not log it or include it in shared URLs. The link remains valid for 45 days and stops working after account activation; in either case it returns 410 Gone. Repeating POST /onboarding with the same ref returns the existing draft without replacing the token. Contact dpay after the link expires.

Onboarding status

You can read the status of an individual onboarding flow at any time. next_action is always an object, although its url can be null, and the invited list contains no personal data about invitees.

GET/api/partner/v1/onboarding/{ref}Status of an individual onboarding flow.Full contract in the API Reference

A separate cursor-paginated endpoint returns all onboarding flows for your channel. See account lifecycle for the meaning of each status.

GET/api/partner/v1/onboardingList the channel's onboarding flows (cursor pagination).Full contract in the API Reference
Source of truth

React to changes using webhooks (push), and use GET /onboarding/{ref} as a supplementary check (pull). Do not poll the status every second.

Error codes

CodeMeaning
401Missing, invalid, or revoked partner key.
403The key does not have the required scope.
404Unknown ref within your channels.
409Onboarding is already active, so its data can no longer be edited (or a regulated-activity document is duplicated).
410The resume link has expired or the account is already active (hosted route).
422Validation error, or the segment does not apply to this entity type.
429Invitation resend cooldown.