This guide walks you end-to-end through the Finance API — from creating your first party to settling a transfer. Every step uses real request and response shapes from the live spec. Run it against staging and you’ll have a working integration in under an hour.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.
Base URL (staging):
https://api-staging.venlyfinance.com/v1
Auth: OAuth2 Bearer token in the Authorization header. Tokens expire after 5 minutes — see the Authentication guide.What you’ll build
By the end of this walkthrough you’ll have:- Onboarded an individual party (your customer)
- Opened an account for them on the Base blockchain
- Provisioned a custodial wallet to hold their crypto
- Issued a EUR IBAN (virtual bank account) so they can fund via SEPA
- Sent an outbound transfer to settle funds
Prerequisites
Before you begin, make sure you have:Sandbox credentials
A
client_id and client_secret from your Venly account manager. Sandbox credentials never touch real money.Step 1 — Authenticate
Exchange your client credentials for a Bearer token. Every subsequent call needs this token in theAuthorization header.
Response
Step 2 — Create a party
A party is the legal identity behind every account — either anINDIVIDUAL (natural person) or an ORGANISATION (company). KYC/KYB is initiated automatically when you create the party.
Response (201)
The
kycStatus starts as PENDING. KYC checks run asynchronously; the party can be referenced immediately, but transfers will be blocked until kycStatus = VERIFIED. Poll GET /parties/{partyId} until it transitions, or watch for it during account creation.Step 3 — Open an account
An account is the container that holds wallets, IBANs, and transfer history. It must reference a blockchain network — currentlyBASE or AVALANCHE.
You can either reference the party you just created (partyId), or create the party inline (party object). The two-call flow shown here is more common in production because it lets KYC progress while you build the rest of the account.
Response (201)
Joint accounts (optional)
To add a second account holder, call the party-roles endpoint:Step 4 — Provision a wallet
Every account needs a custodial wallet to hold its crypto balance. The chain you specify must match the account’s chain.Response (201)
address is a real blockchain address on Base. Funds credited to this wallet are custodied — Venly holds the keys, and your app moves balances via the API.
Step 5 — Issue a virtual bank account (IBAN)
To accept fiat funding, attach a virtual bank account to the account. In Release 1, onlyEUR_SEPA is supported — incoming euros are auto-converted to the cryptocurrency you specify (USDC, EURC, or USDT) and credited to the wallet.
Response (201)
Step 6 — Fund the account
You now have two ways to credit the account:Option A — Customer-initiated SEPA transfer
The customer sends EUR from their personal bank to the IBAN you issued in Step 5, including thereferenceCode in the payment message.
Settlement is typically same-day for SEPA Instant, T+1 for standard SEPA. The wallet balance updates automatically on credit.
Option B — Hosted fiat-to-crypto checkout
For card-funded onboarding, create a payment session. Venly returns a hosted checkout URL you redirect the customer to.paymentUrl — open it in the customer’s browser. Once they complete payment, the wallet is credited and your callbackUrl is invoked.
Step 7 — Send a transfer
With the wallet funded, you can now move money out. Three transfer types are supported:Account-to-Account
Internal — between two Venly accounts. Settles in seconds, no on-chain fee.
Crypto Transfer
External — on-chain to any wallet address. Subject to network fees.
Fiat Transfer
External — SEPA payout to a bank account.
Internal (Account-to-Account)
Fastest path — moves crypto between two Venly-custodied accounts without touching the blockchain.External crypto transfer
Sends USDC on Base to any blockchain address.receiverExternalId/receiverAccountId and provide the destination address — see the Create Crypto Transfer reference.
External fiat transfer (SEPA out)
Step 8 — Track the transfer
Every transfer endpoint returns a transfer object withstatus. Poll for status changes:
| Status | Meaning |
|---|---|
PENDING | Accepted, not yet broadcast |
PROCESSING | Submitted to chain or settlement rail |
COMPLETED | Final — funds delivered |
FAILED | Final — see failureCode and failureReason |
GET /accounts/{accountId}/transfers with pagination parameters.
Webhooks for transfer status changes are not yet available — poll for now. See the roadmap for status updates.
Common pitfalls
403 Forbidden on first transfer
403 Forbidden on first transfer
The party’s
kycStatus is still PENDING. Wait for VERIFIED before initiating outbound transfers. Inbound funding (Step 6) works regardless of KYC state but funds will be held until verification completes.422 on retry with same idempotencyKey
422 on retry with same idempotencyKey
The body changed between calls. Idempotency keys are bound to the exact request body — see Idempotency for the full behaviour matrix. Generate a new UUID for any new request; reuse the same one only when retrying the identical call.
Wallet balance not updating after SEPA wire
Wallet balance not updating after SEPA wire
Check that the customer included the
referenceCode in the payment message. Without it, the wire goes to manual reconciliation (24–48h delay).Token expired mid-flow
Token expired mid-flow
Tokens are valid for 5 minutes. Catch
401 Unauthorized, refresh, and retry the original call. Don’t pre-authenticate every request — cache the token.Next steps
Browse the API reference
Every endpoint, every field, every error code.
Authentication deep-dive
Token refresh patterns, environment URLs, credential rotation.
Permits & allowances
EIP-2612 token approvals for non-custodial flows.
Contact support
Stuck? Email us with your
accountId and the failing request.
