Create virtual account
curl --request POST \
--url https://api.daya.co/v1/virtual-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"customer_id": "<string>",
"currency": "<string>",
"developer_fee": {
"developer_fee.percentage": "<string>"
}
}
'import requests
url = "https://api.daya.co/v1/virtual-accounts"
payload = {
"customer_id": "<string>",
"currency": "<string>",
"developer_fee": { "developer_fee.percentage": "<string>" }
}
headers = {
"X-Api-Key": "<x-api-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>', 'Content-Type': 'application/json'},
body: JSON.stringify({
customer_id: '<string>',
currency: '<string>',
developer_fee: {'developer_fee.percentage': '<string>'}
})
};
fetch('https://api.daya.co/v1/virtual-accounts', 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/virtual-accounts",
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([
'customer_id' => '<string>',
'currency' => '<string>',
'developer_fee' => [
'developer_fee.percentage' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <x-api-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/virtual-accounts"
payload := strings.NewReader("{\n \"customer_id\": \"<string>\",\n \"currency\": \"<string>\",\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<x-api-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/virtual-accounts")
.header("X-Api-Key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customer_id\": \"<string>\",\n \"currency\": \"<string>\",\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.daya.co/v1/virtual-accounts")
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["Content-Type"] = 'application/json'
request.body = "{\n \"customer_id\": \"<string>\",\n \"currency\": \"<string>\",\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "650e8400-e29b-41d4-a716-446655440000",
"merchant_id": "650e8400-e29b-41d4-a716-446655440001",
"customer_id": "650e8400-e29b-41d4-a716-446655440002",
"provider": "bridge",
"status": "active",
"currency": "eur",
"developer_fee": {
"percentage": "0"
},
"deposit_instructions": {
"bank_name": "Example Bank",
"bank_beneficiary_name": "Ada Lovelace",
"iban": "DE89370400440532013000",
"bic": "DEUTDEDBFRA",
"payment_rails": ["sepa", "sepa_instant"]
},
"created_at": "2026-09-22T12:00:00Z",
"updated_at": "2026-09-22T12:00:00Z"
}
{
"error": {
"code": "VALIDATION_FAILED",
"message": "customer is not approved for SEPA virtual accounts",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "CONFLICT",
"message": "existing EUR virtual account has a different developer fee",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
USD and EUR Virtual Accounts
Create virtual account
Create USD or EUR receiving details for a customer
POST
/
v1
/
virtual-accounts
Create virtual account
curl --request POST \
--url https://api.daya.co/v1/virtual-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"customer_id": "<string>",
"currency": "<string>",
"developer_fee": {
"developer_fee.percentage": "<string>"
}
}
'import requests
url = "https://api.daya.co/v1/virtual-accounts"
payload = {
"customer_id": "<string>",
"currency": "<string>",
"developer_fee": { "developer_fee.percentage": "<string>" }
}
headers = {
"X-Api-Key": "<x-api-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>', 'Content-Type': 'application/json'},
body: JSON.stringify({
customer_id: '<string>',
currency: '<string>',
developer_fee: {'developer_fee.percentage': '<string>'}
})
};
fetch('https://api.daya.co/v1/virtual-accounts', 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/virtual-accounts",
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([
'customer_id' => '<string>',
'currency' => '<string>',
'developer_fee' => [
'developer_fee.percentage' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <x-api-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/virtual-accounts"
payload := strings.NewReader("{\n \"customer_id\": \"<string>\",\n \"currency\": \"<string>\",\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<x-api-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/virtual-accounts")
.header("X-Api-Key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customer_id\": \"<string>\",\n \"currency\": \"<string>\",\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.daya.co/v1/virtual-accounts")
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["Content-Type"] = 'application/json'
request.body = "{\n \"customer_id\": \"<string>\",\n \"currency\": \"<string>\",\n \"developer_fee\": {\n \"developer_fee.percentage\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "650e8400-e29b-41d4-a716-446655440000",
"merchant_id": "650e8400-e29b-41d4-a716-446655440001",
"customer_id": "650e8400-e29b-41d4-a716-446655440002",
"provider": "bridge",
"status": "active",
"currency": "eur",
"developer_fee": {
"percentage": "0"
},
"deposit_instructions": {
"bank_name": "Example Bank",
"bank_beneficiary_name": "Ada Lovelace",
"iban": "DE89370400440532013000",
"bic": "DEUTDEDBFRA",
"payment_rails": ["sepa", "sepa_instant"]
},
"created_at": "2026-09-22T12:00:00Z",
"updated_at": "2026-09-22T12:00:00Z"
}
{
"error": {
"code": "VALIDATION_FAILED",
"message": "customer is not approved for SEPA virtual accounts",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "CONFLICT",
"message": "existing EUR virtual account has a different developer fee",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Overview
Creates a USD or EUR virtual account for a customer. The customer must have completed Tier 2 verification.- A USD account returns US bank details and supports the payment rails listed in
deposit_instructions.payment_rails. - A EUR account returns an IBAN and BIC and supports the SEPA rails listed in
deposit_instructions.payment_rails. - Payments into both account types settle into the merchant USD collection balance.
EUR virtual accounts require additional approval for SEPA access. If a verified customer cannot create a EUR account, contact Daya to confirm eligibility.
Daya does not currently maintain a separate EUR balance. Incoming EUR is converted and settled in USD. The deposit response reports the original EUR amount and the applied exchange rate.
Each customer can have one active EUR virtual account. Repeating the same EUR request returns the existing account when its developer fee matches. A request with a different developer fee returns
409 Conflict.Authentication
string
required
Your merchant API key.
Request body
string
required
Customer ID in UUID format. The customer must have completed Tier 2 verification.Example:
650e8400-e29b-41d4-a716-446655440000string
Funding currency for the account. Use
usd or eur. If omitted, the value defaults to usd. Both currencies settle in USD.Example: eurobject
Optional fee that your merchant account keeps from each settled deposit. Omit this object to use
0%.Show developer_fee properties
Show developer_fee properties
string
required
Percentage of the settled USD deposit that your merchant account keeps after Daya deposit fees. Use a decimal string from
0 to 50.This value is a percentage, not basis points. For example, 0.5 means 0.5%, 2 means 2%, and 50 means 50%.Example: "1.5"Request examples
curl --request POST \
--url https://api.daya.co/v1/virtual-accounts \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"customer_id": "650e8400-e29b-41d4-a716-446655440000",
"currency": "eur"
}'
curl --request POST \
--url https://api.daya.co/v1/virtual-accounts \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"customer_id": "650e8400-e29b-41d4-a716-446655440000",
"currency": "usd",
"developer_fee": {
"percentage": "1.5"
}
}'
Response
string
required
Virtual account ID in UUID format.
string
required
Customer associated with the account.
string
required
Merchant that owns the account.
string
required
Funding currency:
usd or eur.string
required
Account status:
active or inactive.string
required
Virtual account provider.
object
required
Developer fee applied to deposits received through this account.
Show developer_fee properties
Show developer_fee properties
string
Configured percentage as a decimal string.
object
Bank details for funding the account. Fields depend on the account currency.
Show deposit_instructions properties
Show deposit_instructions properties
string
Beneficiary name, when available.
string
Beneficiary address, when available.
string
Receiving bank name, when available.
string
Receiving bank address, when available.
string
US bank routing number. Returned for USD accounts when available.
string
US bank account number. Returned for USD accounts when available.
string
International Bank Account Number. Returned for EUR accounts.
string
Bank Identifier Code. Returned for EUR accounts.
array
Payment rails enabled for this account. Use the returned values instead of assuming rail availability.
string
required
Account creation time in ISO 8601 format.
string
required
Last update time in ISO 8601 format.
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"merchant_id": "650e8400-e29b-41d4-a716-446655440001",
"customer_id": "650e8400-e29b-41d4-a716-446655440002",
"provider": "bridge",
"status": "active",
"currency": "eur",
"developer_fee": {
"percentage": "0"
},
"deposit_instructions": {
"bank_name": "Example Bank",
"bank_beneficiary_name": "Ada Lovelace",
"iban": "DE89370400440532013000",
"bic": "DEUTDEDBFRA",
"payment_rails": ["sepa", "sepa_instant"]
},
"created_at": "2026-09-22T12:00:00Z",
"updated_at": "2026-09-22T12:00:00Z"
}
{
"error": {
"code": "VALIDATION_FAILED",
"message": "customer is not approved for SEPA virtual accounts",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "CONFLICT",
"message": "existing EUR virtual account has a different developer fee",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
EUR deposit reconciliation
UseGET /v1/virtual-account-deposits or the deposit.completed webhook to reconcile a payment.
For EUR-funded deposits, the response includes:
source_amount: original EUR amount.source_currency:EUR.fx_rate: exchange rate applied to the conversion.amountandcurrency: converted USD amount before Daya deposit fees.settled_amountandsettled_currency: USD amount after Daya deposit fees.customer_amount: USD amount after Daya fees and the configured developer fee.