Legacy: Create an onramp
curl --request POST \
--url https://api.daya.co/v1/onramps \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--header 'X-Idempotency-Key: <x-idempotency-key>' \
--data '
{
"type": "<string>",
"customer": {
"customer.customer_id": "<string>",
"customer.email": "<string>",
"customer.first_name": "<string>",
"customer.last_name": "<string>",
"customer.verification": {
"customer.verification.bvn": "<string>",
"customer.verification.phone_number": "<string>",
"customer.verification.image_url": "<string>"
}
},
"rate_id": "<string>",
"amount": 123,
"developer_fee": {
"developer_fee.percentage": "<string>"
},
"settlement": {
"settlement.mode": "<string>",
"settlement.asset": "<string>",
"settlement.chain": "<string>",
"settlement.destination_address": "<string>"
}
}
'import requests
url = "https://api.daya.co/v1/onramps"
payload = {
"type": "<string>",
"customer": {
"customer.customer_id": "<string>",
"customer.email": "<string>",
"customer.first_name": "<string>",
"customer.last_name": "<string>",
"customer.verification": {
"customer.verification.bvn": "<string>",
"customer.verification.phone_number": "<string>",
"customer.verification.image_url": "<string>"
}
},
"rate_id": "<string>",
"amount": 123,
"developer_fee": { "developer_fee.percentage": "<string>" },
"settlement": {
"settlement.mode": "<string>",
"settlement.asset": "<string>",
"settlement.chain": "<string>",
"settlement.destination_address": "<string>"
}
}
headers = {
"X-Api-Key": "<x-api-key>",
"X-Idempotency-Key": "<x-idempotency-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Api-Key': '<x-api-key>',
'X-Idempotency-Key': '<x-idempotency-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: '<string>',
customer: {
'customer.customer_id': '<string>',
'customer.email': '<string>',
'customer.first_name': '<string>',
'customer.last_name': '<string>',
'customer.verification': {
'customer.verification.bvn': '<string>',
'customer.verification.phone_number': '<string>',
'customer.verification.image_url': '<string>'
}
},
rate_id: '<string>',
amount: 123,
developer_fee: {'developer_fee.percentage': '<string>'},
settlement: {
'settlement.mode': '<string>',
'settlement.asset': '<string>',
'settlement.chain': '<string>',
'settlement.destination_address': '<string>'
}
})
};
fetch('https://api.daya.co/v1/onramps', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.daya.co/v1/onramps",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => '<string>',
'customer' => [
'customer.customer_id' => '<string>',
'customer.email' => '<string>',
'customer.first_name' => '<string>',
'customer.last_name' => '<string>',
'customer.verification' => [
'customer.verification.bvn' => '<string>',
'customer.verification.phone_number' => '<string>',
'customer.verification.image_url' => '<string>'
]
],
'rate_id' => '<string>',
'amount' => 123,
'developer_fee' => [
'developer_fee.percentage' => '<string>'
],
'settlement' => [
'settlement.mode' => '<string>',
'settlement.asset' => '<string>',
'settlement.chain' => '<string>',
'settlement.destination_address' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <x-api-key>",
"X-Idempotency-Key: <x-idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.daya.co/v1/onramps"
payload := strings.NewReader("{\n \"type\": \"<string>\",\n \"customer\": {\n \"customer.customer_id\": \"<string>\",\n \"customer.email\": \"<string>\",\n \"customer.first_name\": \"<string>\",\n \"customer.last_name\": \"<string>\",\n \"customer.verification\": {\n \"customer.verification.bvn\": \"<string>\",\n \"customer.verification.phone_number\": \"<string>\",\n \"customer.verification.image_url\": \"<string>\"\n }\n },\n \"rate_id\": \"<string>\",\n \"amount\": 123,\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n },\n \"settlement\": {\n \"settlement.mode\": \"<string>\",\n \"settlement.asset\": \"<string>\",\n \"settlement.chain\": \"<string>\",\n \"settlement.destination_address\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<x-api-key>")
req.Header.Add("X-Idempotency-Key", "<x-idempotency-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.daya.co/v1/onramps")
.header("X-Api-Key", "<x-api-key>")
.header("X-Idempotency-Key", "<x-idempotency-key>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"<string>\",\n \"customer\": {\n \"customer.customer_id\": \"<string>\",\n \"customer.email\": \"<string>\",\n \"customer.first_name\": \"<string>\",\n \"customer.last_name\": \"<string>\",\n \"customer.verification\": {\n \"customer.verification.bvn\": \"<string>\",\n \"customer.verification.phone_number\": \"<string>\",\n \"customer.verification.image_url\": \"<string>\"\n }\n },\n \"rate_id\": \"<string>\",\n \"amount\": 123,\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n },\n \"settlement\": {\n \"settlement.mode\": \"<string>\",\n \"settlement.asset\": \"<string>\",\n \"settlement.chain\": \"<string>\",\n \"settlement.destination_address\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.daya.co/v1/onramps")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Api-Key"] = '<x-api-key>'
request["X-Idempotency-Key"] = '<x-idempotency-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"<string>\",\n \"customer\": {\n \"customer.customer_id\": \"<string>\",\n \"customer.email\": \"<string>\",\n \"customer.first_name\": \"<string>\",\n \"customer.last_name\": \"<string>\",\n \"customer.verification\": {\n \"customer.verification.bvn\": \"<string>\",\n \"customer.verification.phone_number\": \"<string>\",\n \"customer.verification.image_url\": \"<string>\"\n }\n },\n \"rate_id\": \"<string>\",\n \"amount\": 123,\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n },\n \"settlement\": {\n \"settlement.mode\": \"<string>\",\n \"settlement.asset\": \"<string>\",\n \"settlement.chain\": \"<string>\",\n \"settlement.destination_address\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"onramp_id": "onramp_3j5k8n2q",
"type": "TEMPORARY",
"status": "ACTIVE",
"amount": "50000.50",
"rate_id": "rate_8x7k2mq9p",
"payment_reference": "DAYA-3J5K8N2Q",
"developer_fee": {
"percentage": "2.5"
},
"virtual_account": {
"account_number": "9876543210",
"account_name": "Daya - user@example.com",
"bank_name": "Wema Bank",
"expires_at": "2026-01-14T15:30:00Z"
},
"expires_at": "2026-01-14T15:30:00Z",
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
},
"created_at": "2026-01-14T15:05:12Z"
}
{
"onramp_id": "onramp_7k3m5n8q",
"type": "TEMPORARY",
"status": "ACTIVE",
"amount": "50000.50",
"rate_id": "rate_8x7k2mq9p",
"payment_reference": "DAYA-7K3M5N8Q",
"virtual_account": {
"account_number": "1122334455",
"account_name": "Daya - user@example.com",
"bank_name": "Wema Bank",
"expires_at": "2026-01-14T15:30:00Z"
},
"expires_at": "2026-01-14T15:30:00Z",
"settlement": {
"mode": "INTERNAL_BALANCE"
},
"created_at": "2026-01-14T15:05:12Z"
}
{
"type": "PERMANENT",
"permanent_onramp_id": "850e8400-e29b-41d4-a716-446655440000",
"active_settlement_id": "950e8400-e29b-41d4-a716-446655440000",
"customer_id": "650e8400-e29b-41d4-a716-446655440000",
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
},
"virtual_account": {
"account_number": "1234567890",
"bank_name": "Wema Bank",
"account_name": "Daya-John Doe"
}
}
Onramps
Legacy: Create an onramp
Legacy route for creating an NGN receive flow
POST
/
v1
/
onramps
Legacy: Create an onramp
curl --request POST \
--url https://api.daya.co/v1/onramps \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--header 'X-Idempotency-Key: <x-idempotency-key>' \
--data '
{
"type": "<string>",
"customer": {
"customer.customer_id": "<string>",
"customer.email": "<string>",
"customer.first_name": "<string>",
"customer.last_name": "<string>",
"customer.verification": {
"customer.verification.bvn": "<string>",
"customer.verification.phone_number": "<string>",
"customer.verification.image_url": "<string>"
}
},
"rate_id": "<string>",
"amount": 123,
"developer_fee": {
"developer_fee.percentage": "<string>"
},
"settlement": {
"settlement.mode": "<string>",
"settlement.asset": "<string>",
"settlement.chain": "<string>",
"settlement.destination_address": "<string>"
}
}
'import requests
url = "https://api.daya.co/v1/onramps"
payload = {
"type": "<string>",
"customer": {
"customer.customer_id": "<string>",
"customer.email": "<string>",
"customer.first_name": "<string>",
"customer.last_name": "<string>",
"customer.verification": {
"customer.verification.bvn": "<string>",
"customer.verification.phone_number": "<string>",
"customer.verification.image_url": "<string>"
}
},
"rate_id": "<string>",
"amount": 123,
"developer_fee": { "developer_fee.percentage": "<string>" },
"settlement": {
"settlement.mode": "<string>",
"settlement.asset": "<string>",
"settlement.chain": "<string>",
"settlement.destination_address": "<string>"
}
}
headers = {
"X-Api-Key": "<x-api-key>",
"X-Idempotency-Key": "<x-idempotency-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Api-Key': '<x-api-key>',
'X-Idempotency-Key': '<x-idempotency-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: '<string>',
customer: {
'customer.customer_id': '<string>',
'customer.email': '<string>',
'customer.first_name': '<string>',
'customer.last_name': '<string>',
'customer.verification': {
'customer.verification.bvn': '<string>',
'customer.verification.phone_number': '<string>',
'customer.verification.image_url': '<string>'
}
},
rate_id: '<string>',
amount: 123,
developer_fee: {'developer_fee.percentage': '<string>'},
settlement: {
'settlement.mode': '<string>',
'settlement.asset': '<string>',
'settlement.chain': '<string>',
'settlement.destination_address': '<string>'
}
})
};
fetch('https://api.daya.co/v1/onramps', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.daya.co/v1/onramps",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => '<string>',
'customer' => [
'customer.customer_id' => '<string>',
'customer.email' => '<string>',
'customer.first_name' => '<string>',
'customer.last_name' => '<string>',
'customer.verification' => [
'customer.verification.bvn' => '<string>',
'customer.verification.phone_number' => '<string>',
'customer.verification.image_url' => '<string>'
]
],
'rate_id' => '<string>',
'amount' => 123,
'developer_fee' => [
'developer_fee.percentage' => '<string>'
],
'settlement' => [
'settlement.mode' => '<string>',
'settlement.asset' => '<string>',
'settlement.chain' => '<string>',
'settlement.destination_address' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <x-api-key>",
"X-Idempotency-Key: <x-idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.daya.co/v1/onramps"
payload := strings.NewReader("{\n \"type\": \"<string>\",\n \"customer\": {\n \"customer.customer_id\": \"<string>\",\n \"customer.email\": \"<string>\",\n \"customer.first_name\": \"<string>\",\n \"customer.last_name\": \"<string>\",\n \"customer.verification\": {\n \"customer.verification.bvn\": \"<string>\",\n \"customer.verification.phone_number\": \"<string>\",\n \"customer.verification.image_url\": \"<string>\"\n }\n },\n \"rate_id\": \"<string>\",\n \"amount\": 123,\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n },\n \"settlement\": {\n \"settlement.mode\": \"<string>\",\n \"settlement.asset\": \"<string>\",\n \"settlement.chain\": \"<string>\",\n \"settlement.destination_address\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<x-api-key>")
req.Header.Add("X-Idempotency-Key", "<x-idempotency-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.daya.co/v1/onramps")
.header("X-Api-Key", "<x-api-key>")
.header("X-Idempotency-Key", "<x-idempotency-key>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"<string>\",\n \"customer\": {\n \"customer.customer_id\": \"<string>\",\n \"customer.email\": \"<string>\",\n \"customer.first_name\": \"<string>\",\n \"customer.last_name\": \"<string>\",\n \"customer.verification\": {\n \"customer.verification.bvn\": \"<string>\",\n \"customer.verification.phone_number\": \"<string>\",\n \"customer.verification.image_url\": \"<string>\"\n }\n },\n \"rate_id\": \"<string>\",\n \"amount\": 123,\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n },\n \"settlement\": {\n \"settlement.mode\": \"<string>\",\n \"settlement.asset\": \"<string>\",\n \"settlement.chain\": \"<string>\",\n \"settlement.destination_address\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.daya.co/v1/onramps")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Api-Key"] = '<x-api-key>'
request["X-Idempotency-Key"] = '<x-idempotency-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"<string>\",\n \"customer\": {\n \"customer.customer_id\": \"<string>\",\n \"customer.email\": \"<string>\",\n \"customer.first_name\": \"<string>\",\n \"customer.last_name\": \"<string>\",\n \"customer.verification\": {\n \"customer.verification.bvn\": \"<string>\",\n \"customer.verification.phone_number\": \"<string>\",\n \"customer.verification.image_url\": \"<string>\"\n }\n },\n \"rate_id\": \"<string>\",\n \"amount\": 123,\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n },\n \"settlement\": {\n \"settlement.mode\": \"<string>\",\n \"settlement.asset\": \"<string>\",\n \"settlement.chain\": \"<string>\",\n \"settlement.destination_address\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"onramp_id": "onramp_3j5k8n2q",
"type": "TEMPORARY",
"status": "ACTIVE",
"amount": "50000.50",
"rate_id": "rate_8x7k2mq9p",
"payment_reference": "DAYA-3J5K8N2Q",
"developer_fee": {
"percentage": "2.5"
},
"virtual_account": {
"account_number": "9876543210",
"account_name": "Daya - user@example.com",
"bank_name": "Wema Bank",
"expires_at": "2026-01-14T15:30:00Z"
},
"expires_at": "2026-01-14T15:30:00Z",
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
},
"created_at": "2026-01-14T15:05:12Z"
}
{
"onramp_id": "onramp_7k3m5n8q",
"type": "TEMPORARY",
"status": "ACTIVE",
"amount": "50000.50",
"rate_id": "rate_8x7k2mq9p",
"payment_reference": "DAYA-7K3M5N8Q",
"virtual_account": {
"account_number": "1122334455",
"account_name": "Daya - user@example.com",
"bank_name": "Wema Bank",
"expires_at": "2026-01-14T15:30:00Z"
},
"expires_at": "2026-01-14T15:30:00Z",
"settlement": {
"mode": "INTERNAL_BALANCE"
},
"created_at": "2026-01-14T15:05:12Z"
}
{
"type": "PERMANENT",
"permanent_onramp_id": "850e8400-e29b-41d4-a716-446655440000",
"active_settlement_id": "950e8400-e29b-41d4-a716-446655440000",
"customer_id": "650e8400-e29b-41d4-a716-446655440000",
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
},
"virtual_account": {
"account_number": "1234567890",
"bank_name": "Wema Bank",
"account_name": "Daya-John Doe"
}
}
Overview
Create an onramp through the legacy compatibility route. New integrations should usePOST /v1/funding-accounts with rail: NGN_VIRTUAL_ACCOUNT.
Authentication
string
required
Your merchant API key
string
required
Unique idempotency key to prevent duplicate onramp creation
Request Body
string
required
Onramp typeAllowed values:
TEMPORARY, PERMANENTTEMPORARY: Short-lived VA (25 minutes), locked torate_idPERMANENT: Long-lived VA, uses current rate at settlement
object
required
Customer information. Either
customer_id or email must be provided.Show customer properties
Show customer properties
string
UUID of an existing customer. Either this or
customer.email is required.Example: 650e8400-e29b-41d4-a716-446655440000string
Email for auto-creating a customer. Either this or
customer.customer_id is required.Example: user@example.comstring
Customer first name
string
Customer last name
object
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
Show verification properties
string
required
11-digit Bank Verification NumberExample:
22345678901string
required
Customer’s phone number in 11-digit national or
+234 international form.Example: +2348012345678string
required
Face image for identity matching. Accepts an HTTPS URL to a jpg/png image, or base64-encoded image data up to 1 MiB decoded.Example:
https://example.com/selfie.jpgstring
Rate identifier from
GET /v1/ratesExample: rate_8x7k2mq9pRequired for temporary onramps. Not allowed for permanent onramps.
integer
Principal amount in NGN before any payment-provider collection charge. The exact amount the customer must transfer is returned as
amount in the create response.Example: 50000Required for temporary onramps. Ignored for permanent onramps.
object
Optional fee that your merchant account keeps from each onramp deposit. Omit to use
0%.Show developer_fee properties
Show developer_fee properties
string
required
Percentage of each received deposit that your merchant account keeps. Use a decimal string from
0 to 50. This is a percentage value, not basis points: 0.5 means 0.5%, 2 means 2%, and 50 means 50%.Example: "2.5"object
required
Settlement configuration
Show settlement properties
Show settlement properties
string
required
Settlement modeAllowed values:
ONCHAIN- Settle directly on-chain to the destination addressINTERNAL_BALANCE- Credit merchant USD balance
string
required
Asset typeAllowed values:
USDC, USDTPermanent onramps only support
USDC in v1.string
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.string
On-chain destination address. Required for
ONCHAIN mode.Example: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbRequest Examples
{
"type": "TEMPORARY",
"customer": {
"email": "user@example.com"
},
"rate_id": "rate_8x7k2mq9p",
"amount": 50000,
"developer_fee": {
"percentage": "2.5"
},
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
}
}
{
"type": "TEMPORARY",
"customer": {
"email": "user@example.com"
},
"rate_id": "rate_8x7k2mq9p",
"amount": 50000,
"settlement": {
"mode": "INTERNAL_BALANCE",
"asset": "USDC"
}
}
{
"type": "PERMANENT",
"customer": {
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe",
"verification": {
"bvn": "22345678901",
"phone_number": "+2348012345678",
"image_url": "https://example.com/selfie.jpg"
}
},
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
}
}
{
"type": "PERMANENT",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "SOLANA",
"destination_address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV"
}
}
{
"type": "PERMANENT",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000",
"verification": {
"bvn": "22345678901",
"phone_number": "+2348012345678",
"image_url": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."
}
},
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
}
}
curl --request POST \
--url https://api.daya.co/v1/onramps \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: unique-key-123' \
--header 'Content-Type: application/json' \
--data '{
"type": "TEMPORARY",
"customer": {
"email": "user@example.com"
},
"rate_id": "rate_8x7k2mq9p",
"amount": 50000,
"developer_fee": {
"percentage": "2.5"
},
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
}
}'
curl --request POST \
--url https://api.daya.co/v1/onramps \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: unique-key-456' \
--header 'Content-Type: application/json' \
--data '{
"type": "PERMANENT",
"customer": {
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe",
"verification": {
"bvn": "22345678901",
"phone_number": "+2348012345678",
"image_url": "https://example.com/selfie.jpg"
}
},
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
}
}'
Response
Temporary Onramp Response
string
required
Unique identifier for this onramp
string
required
TEMPORARYstring
required
Current onramp status. New onramps start as
ACTIVE.string
required
Exact amount the customer must transfer in NGN. The payment provider may add a collection charge, so this can differ from the
amount submitted in the request. Required and always returned for temporary onramps as a decimal string. Display and transfer this value exactly; do not recalculate or round it.Example: "50000.50"string
required
Associated rate identifier
string
required
Unique payment reference for the transfer
object
required
Developer fee percentage used for deposits received through this onramp.
Show developer_fee properties
Show developer_fee properties
string
Configured percentage as a decimal string.
object
required
string
required
When onramp expires (~25 minutes from creation)
object
required
Settlement configuration (same as request)
string
required
When onramp was created (ISO 8601 timestamp)
Permanent Onramp Response
string
required
PERMANENTstring
required
Unique identifier for the permanent onramp configuration
string
required
Identifier of the currently active settlement configuration
string
required
The customer this permanent onramp belongs to
object
required
Active settlement configuration
object
required
Success Responses
{
"onramp_id": "onramp_3j5k8n2q",
"type": "TEMPORARY",
"status": "ACTIVE",
"amount": "50000.50",
"rate_id": "rate_8x7k2mq9p",
"payment_reference": "DAYA-3J5K8N2Q",
"developer_fee": {
"percentage": "2.5"
},
"virtual_account": {
"account_number": "9876543210",
"account_name": "Daya - user@example.com",
"bank_name": "Wema Bank",
"expires_at": "2026-01-14T15:30:00Z"
},
"expires_at": "2026-01-14T15:30:00Z",
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
},
"created_at": "2026-01-14T15:05:12Z"
}
{
"onramp_id": "onramp_7k3m5n8q",
"type": "TEMPORARY",
"status": "ACTIVE",
"amount": "50000.50",
"rate_id": "rate_8x7k2mq9p",
"payment_reference": "DAYA-7K3M5N8Q",
"virtual_account": {
"account_number": "1122334455",
"account_name": "Daya - user@example.com",
"bank_name": "Wema Bank",
"expires_at": "2026-01-14T15:30:00Z"
},
"expires_at": "2026-01-14T15:30:00Z",
"settlement": {
"mode": "INTERNAL_BALANCE"
},
"created_at": "2026-01-14T15:05:12Z"
}
{
"type": "PERMANENT",
"permanent_onramp_id": "850e8400-e29b-41d4-a716-446655440000",
"active_settlement_id": "950e8400-e29b-41d4-a716-446655440000",
"customer_id": "650e8400-e29b-41d4-a716-446655440000",
"settlement": {
"mode": "ONCHAIN",
"asset": "USDC",
"chain": "BASE",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
},
"virtual_account": {
"account_number": "1234567890",
"bank_name": "Wema Bank",
"account_name": "Daya-John Doe"
}
}
Error Responses
{
"error": {
"code": "validation_error",
"message": "either customer.customer_id or customer.email is required"
}
}
{
"error": {
"code": "validation_error",
"message": "rate_id is not allowed for permanent onramps"
}
}
{
"error": {
"code": "validation_error",
"message": "invalid settlement mode"
}
}
{
"error": {
"code": "validation_error",
"message": "permanent onramps only support USDC in v1"
}
}
{
"error": {
"code": "validation_error",
"message": "customer is not verified and no verification data provided"
}
}
{
"error": {
"code": "VALIDATION_FAILED",
"message": "BVN verification failed"
}
}
{
"error": {
"code": "INTEGRATION_FAILED",
"message": "Verification provider unavailable, please try again"
}
}
{
"error": {
"code": "rate_expired",
"message": "The specified rate_id has expired",
"details": "Request a new rate via GET /v1/rates"
}
}
{
"error": {
"code": "invalid_address",
"message": "destination_address is not valid for chain BASE"
}
}
{
"error": {
"code": "onramp_creation_limit_exceeded",
"message": "Merchant has exceeded its funding account creation quota"
}
}
Validation Rules
Customer identification
Customer identification
Either
customer.customer_id or customer.email must be provided (not both optional, at least one required).Temporary onramp rules
Temporary onramp rules
rate_idis required and must be a valid, non-expired rate snapshotamountis required- Settlement modes:
ONCHAINorINTERNAL_BALANCE customer.verificationis not required- For
ONCHAIN:chainanddestination_addressare required - For
INTERNAL_BALANCE:chainanddestination_addressmust NOT be set
Permanent onramp rules
Permanent onramp rules
rate_idmust not be providedamountis silently ignored- Settlement modes:
ONCHAINorINTERNAL_BALANCE - For
ONCHAIN:chainanddestination_addressare required - For
INTERNAL_BALANCE:chainanddestination_addressmust NOT be set - If
customer.customer_idis not provided,customer.verificationwithbvn,phone_number, andimage_urlis required - If
customer.customer_idis provided, the customer must either be already verified orcustomer.verificationmust be included
Verification (permanent onramps)
Verification (permanent onramps)
Verification uses BVN + phone number + face matching via an identity provider.Two paths:New customer (
customer.email provided, no customer_id):customer.verificationis required withbvn,phone_number, andimage_url- The system creates or finds the customer by email, runs verification, then provisions the virtual account
customer.customer_id provided):- If already verified: proceeds directly
- If not verified +
customer.verificationprovided: 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
1
Get fresh rate before creation (temporary)
Always call
GET /v1/rates immediately before creating a temporary onramp to ensure maximum validity window.2
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');
}
3
Use customer_id for returning customers
Create customers once via
POST /v1/customers, then reference them by customer_id in subsequent onramp requests.4
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.5
Use idempotency keys
Always include a unique
X-Idempotency-Key header to prevent duplicate onramp creation on retries.Rate Limits
- Funding account creation quota: configured per merchant and shared across temporary and permanent accounts
- 100 API requests per minute per key
Next Steps
List Deposits
Query deposits for an onramp
Customer API
Pre-create customers before onramp requests