Overview
Create an onramp (deposit configuration) that generates a virtual NGN bank account for receiving deposits. Onramps can be temporary (25-minute TTL, locked rate) or permanent (long-lived, floating rate, auto-withdraw only).
Authentication
Unique idempotency key to prevent duplicate onramp creation
Request Body
Onramp type Allowed values: TEMPORARY, PERMANENT
TEMPORARY: Short-lived VA (25 minutes), locked to rate_id
PERMANENT: Long-lived VA, uses current rate at settlement
Customer information. Either customer_id or email must be provided. UUID of an existing customer. Either this or customer.email is required. Example: 650e8400-e29b-41d4-a716-446655440000
Email for auto-creating a customer. Either this or customer.customer_id is required. Example: user@example.com
Verification data. Required for permanent onramps when creating a new customer (no customer_id). For existing customers, required only if the customer is not yet verified. Show verification properties
customer.verification.bvn
11-digit Bank Verification Number Example: 22345678901
customer.verification.image_url
Face image for identity matching. Accepts an HTTPS URL to a jpg/png image, or base64-encoded image data. Example: https://example.com/selfie.jpg
Rate identifier from GET /v1/rates Example: rate_8x7k2mq9pRequired for temporary onramps. Not allowed for permanent onramps.
Expected deposit amount in NGN Example: 50000Optional for temporary onramps. Ignored for permanent onramps.
Settlement configuration Show settlement properties
Settlement mode Allowed values:
ONCHAIN - Settle directly on-chain to the destination address
INTERNAL_BALANCE - Credit merchant USD balance
Asset type Allowed values: USDC, USDTPermanent onramps only support USDC in v1.
Blockchain network. Required for ONCHAIN mode. Allowed values: APTOS, BASE, CELO, ETHEREUM, POLYGON, SOLANA, TRONSee Supported Chains for details on which assets are available on each chain. settlement.destination_address
On-chain destination address. Required for ONCHAIN mode. Example: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
Request Examples
Temporary - On-chain
Temporary - Internal Balance
Permanent - New Customer
Permanent - Existing Verified Customer
Permanent - Existing Unverified Customer
cURL - Temporary
cURL - Permanent
{
"type" : "TEMPORARY" ,
"customer" : {
"email" : "user@example.com"
},
"rate_id" : "rate_8x7k2mq9p" ,
"amount" : 5000000 ,
"settlement" : {
"mode" : "ONCHAIN" ,
"asset" : "USDC" ,
"chain" : "BASE" ,
"destination_address" : "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
}
}
Response
Temporary Onramp Response
Unique identifier for this onramp
Current onramp status. New onramps start as ACTIVE.
Associated rate identifier
Unique payment reference for the transfer
NGN bank account details for receiving deposits Show virtual_account properties
virtual_account.account_number
Virtual account number
virtual_account.account_name
Account name
virtual_account.bank_name
Bank name
virtual_account.bank_code
Nigerian bank code
When onramp expires (~25 minutes from creation)
Settlement configuration (same as request)
When onramp was created (ISO 8601 timestamp)
Permanent Onramp Response
Unique identifier for the permanent onramp configuration
Identifier of the currently active settlement configuration
The customer this permanent onramp belongs to
Active settlement configuration
Permanent NGN bank account details Show virtual_account properties
virtual_account.account_number
Virtual account number
virtual_account.bank_name
Bank name
virtual_account.account_name
Account name (typically “Daya-Customer Name”)
Success Responses
201 Created - Temporary On-chain
201 Created - Temporary Internal Balance
201 Created - Permanent
{
"onramp_id" : "onramp_3j5k8n2q" ,
"type" : "TEMPORARY" ,
"status" : "ACTIVE" ,
"rate_id" : "rate_8x7k2mq9p" ,
"payment_reference" : "DAYA-3J5K8N2Q" ,
"virtual_account" : {
"account_number" : "9876543210" ,
"account_name" : "Daya - user@example.com" ,
"bank_name" : "Wema Bank" ,
"bank_code" : "035"
},
"expires_at" : "2026-01-14T15:30:00Z" ,
"settlement" : {
"mode" : "ONCHAIN" ,
"asset" : "USDC" ,
"chain" : "BASE" ,
"destination_address" : "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
},
"created_at" : "2026-01-14T15:05:12Z"
}
Error Responses
400 Bad Request - Missing customer
400 Bad Request - Rate not allowed for permanent
400 Bad Request - Invalid settlement mode
400 Bad Request - Unsupported asset
400 Bad Request - Customer not verified
400 Bad Request - Verification failed
502 Bad Gateway - Verification provider error
400 Bad Request - Rate expired
400 Bad Request - Invalid address
429 Too Many Requests - Daily limit
{
"error" : {
"code" : "validation_error" ,
"message" : "either customer.customer_id or customer.email is required"
}
}
Validation Rules
Either customer.customer_id or customer.email must be provided (not both optional, at least one required).
rate_id is required and must be a valid, non-expired rate snapshot
amount is optional
Settlement modes: ONCHAIN or INTERNAL_BALANCE
customer.verification is not required
For ONCHAIN: chain and destination_address are required
For INTERNAL_BALANCE: chain and destination_address must NOT be set
rate_id must not be provided
amount is silently ignored
Settlement modes: ONCHAIN or INTERNAL_BALANCE
For ONCHAIN: chain and destination_address are required
For INTERNAL_BALANCE: chain and destination_address must NOT be set
If customer.customer_id is not provided, customer.verification with both bvn and image_url is required
If customer.customer_id is provided, the customer must either be already verified or customer.verification must be included
Verification (permanent onramps)
Verification uses BVN + face matching via an identity provider. Two paths: New customer (customer.email provided, no customer_id):
customer.verification is required with both bvn and image_url
The system creates or finds the customer by email, runs verification, then provisions the virtual account
Existing customer (customer.customer_id provided):
If already verified: proceeds directly
If not verified + customer.verification provided: runs verification first
If not verified + no verification data: returns error
Permanent Onramp Behavior
Settlement updates: If a permanent onramp already exists for a customer, calling this endpoint again updates the settlement configuration (chain, address) without creating a new virtual account. The previous settlement is deactivated and the new one becomes active.
Virtual accounts for permanent onramps do not expire. The same account number is reused across settlement updates.
Best Practices
Get fresh rate before creation (temporary)
Always call GET /v1/rates immediately before creating a temporary onramp to ensure maximum validity window.
Validate destination address
Use a blockchain library to validate addresses before submitting: import { isAddress } from 'ethers' ;
if ( ! isAddress ( destinationAddress )) {
throw new Error ( 'Invalid Ethereum address' );
}
Use customer_id for returning customers
Create customers once via POST /v1/customers, then reference them by customer_id in subsequent onramp requests.
Handle verification errors gracefully
For permanent onramps, verification may fail due to invalid BVN, face mismatch, or provider issues. Handle 400 VALIDATION_FAILED and 502 INTEGRATION_FAILED separately.
Use idempotency keys
Always include a unique X-Idempotency-Key header to prevent duplicate onramp creation on retries.
Rate Limits
1,000 onramp creations per day per merchant
100 API requests per minute per key
Next Steps
List Deposits Query deposits for an onramp
Customer API Pre-create customers before onramp requests