Skip to main content
This is the shortest path to a working Finance API integration. You’ll create a party, open an account linked to it, get the account verified, and then issue a virtual bank account (IBAN).
Base URL (staging): https://api-staging.venlyfinance.com/v1 · Auth: OAuth2 Bearer token — see Authentication. Whether your company is Venly-managed or self-custody changes one step below — see Venly-managed vs self-custody.

Step 1 — Create a party

A party is the person or organisation behind an account. It’s created ACTIVE immediately — there’s no verification step for a party.
curl -X POST https://api-staging.venlyfinance.com/v1/parties \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "partyType": "INDIVIDUAL",
    "externalId": "user-12345",
    "firstName": "Jane",
    "lastName": "Doe"
  }'
Response (201)
{
  "success": true,
  "result": {
    "id": "7e3b9c2a-1f4d-4a8b-9c11-2d6e8f0a1b22",
    "externalId": "user-12345",
    "partyType": "INDIVIDUAL",
    "status": "ACTIVE",
    "firstName": "Jane",
    "lastName": "Doe",
    "createdAt": "2026-01-15T09:30:00",
    "updatedAt": "2026-01-15T09:30:00",
    "version": 0
  }
}
Save the returned id — it’s the partyId you link in the next step. For an organisation, send partyType: ORGANISATION with name (and optional vatNumber) instead of firstName/lastName.

Step 2 — Open an account linked to the party

An account holds the wallet, IBANs, and transfer history. Pass the partyId from Step 1 to link the party as ACCOUNT_HOLDER. The wallet is provisioned automatically. The only difference between company types is the wallet address:
  • Venly-managed — Venly creates and holds the wallet. Don’t send an address.
  • Self-custody — the customer controls the wallet. You must send their address.
curl -X POST https://api-staging.venlyfinance.com/v1/accounts \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "acct-12345",
    "name": "Jane Doe — Main",
    "chain": "BASE",
    "partyId": "7e3b9c2a-1f4d-4a8b-9c11-2d6e8f0a1b22"
  }'
Response (201)
{
  "success": true,
  "result": {
    "id": "b2a1f0e9-8c7d-4e3a-9f21-0a1b2c3d4e5f",
    "externalId": "acct-12345",
    "name": "Jane Doe — Main",
    "kycStatus": "VERIFICATION_PENDING",
    "status": "ACTIVE",
    "createdAt": "2026-01-15T09:30:00",
    "version": 0
  }
}
The account is created with kycStatus: VERIFICATION_PENDING. It exists and can be set up, but it can’t move money yet.
Self-custody omitting address returns 400 "Address is required for SELF_CUSTODY wallet type". See Venly-managed vs self-custody for the full difference (including permits).

Step 3 — Get the account verified

Account verification is reviewed and approved by a Venly admin — there’s no API call to trigger it. Once approved, the account’s kycStatus becomes VERIFIED. Poll the account until it flips:
curl https://api-staging.venlyfinance.com/v1/accounts/b2a1f0e9-8c7d-4e3a-9f21-0a1b2c3d4e5f \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response (200)
{
  "success": true,
  "result": { "id": "b2a1f0e9-8c7d-4e3a-9f21-0a1b2c3d4e5f", "kycStatus": "VERIFIED", "status": "ACTIVE", "version": 1 }
}
Until kycStatus is VERIFIED, creating virtual bank accounts, transfers, payment requests, and pay-in sessions all fail with a KYC error — the exact code and HTTP status depend on the operation (e.g. 400 kyc-not-verified for virtual bank accounts, 422 kyc-required for pay-in sessions). See Account verification.

Step 4 — Create a virtual bank account

With the account verified, issue a EUR IBAN so it can be funded via SEPA. Incoming euros are converted to the targetCryptocurrency and credited to the wallet.
curl -X POST https://api-staging.venlyfinance.com/v1/accounts/b2a1f0e9-8c7d-4e3a-9f21-0a1b2c3d4e5f/virtual-bank-accounts \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Doe — EUR",
    "inCurrency": "EUR",
    "targetCryptocurrency": "USDC",
    "idempotencyKey": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  }'
Response (201)
{
  "success": true,
  "result": {
    "id": "4d5e6f70-8192-4a3b-9c4d-5e6f7081920a",
    "accountId": "b2a1f0e9-8c7d-4e3a-9f21-0a1b2c3d4e5f",
    "bankAccountType": "EUR_SEPA",
    "status": "ACTIVE",
    "currency": "EUR",
    "targetCryptocurrency": "USDC",
    "iban": "DE89370400440532013000",
    "bic": "DEUTDEDB",
    "referenceCode": "VFY-7K2Q-931"
  }
}
Give the iban and referenceCode to your customer — the referenceCode is what links their incoming SEPA payment to this account.

Next steps

Full Integration Walkthrough

Funding, transfers, and tracking — end to end.

Self-custody: approving transfers

Sign a permit so a self-custody account can move funds.

Account verification

States, gating, and what works before verification.

API reference

Every endpoint, field, and example.