Create a sandbox deposit
curl --request POST \
--url https://api.sandbox.daya.co/v1/sandbox/deposits \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"funding_account_id": "<string>",
"funding_account_scope": "<string>",
"currency": "<string>",
"amount": "<string>",
"scenario": "<string>",
"payout_scenario": "<string>"
}
'import requests
url = "https://api.sandbox.daya.co/v1/sandbox/deposits"
payload = {
"funding_account_id": "<string>",
"funding_account_scope": "<string>",
"currency": "<string>",
"amount": "<string>",
"scenario": "<string>",
"payout_scenario": "<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({
funding_account_id: '<string>',
funding_account_scope: '<string>',
currency: '<string>',
amount: '<string>',
scenario: '<string>',
payout_scenario: '<string>'
})
};
fetch('https://api.sandbox.daya.co/v1/sandbox/deposits', 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.sandbox.daya.co/v1/sandbox/deposits",
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([
'funding_account_id' => '<string>',
'funding_account_scope' => '<string>',
'currency' => '<string>',
'amount' => '<string>',
'scenario' => '<string>',
'payout_scenario' => '<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.sandbox.daya.co/v1/sandbox/deposits"
payload := strings.NewReader("{\n \"funding_account_id\": \"<string>\",\n \"funding_account_scope\": \"<string>\",\n \"currency\": \"<string>\",\n \"amount\": \"<string>\",\n \"scenario\": \"<string>\",\n \"payout_scenario\": \"<string>\"\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.sandbox.daya.co/v1/sandbox/deposits")
.header("X-Api-Key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"funding_account_id\": \"<string>\",\n \"funding_account_scope\": \"<string>\",\n \"currency\": \"<string>\",\n \"amount\": \"<string>\",\n \"scenario\": \"<string>\",\n \"payout_scenario\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.daya.co/v1/sandbox/deposits")
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 \"funding_account_id\": \"<string>\",\n \"funding_account_scope\": \"<string>\",\n \"currency\": \"<string>\",\n \"amount\": \"<string>\",\n \"scenario\": \"<string>\",\n \"payout_scenario\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyDeposits
Create a sandbox deposit
Simulate a deposit into a customer or merchant funding account in sandbox
POST
/
v1
/
sandbox
/
deposits
Create a sandbox deposit
curl --request POST \
--url https://api.sandbox.daya.co/v1/sandbox/deposits \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"funding_account_id": "<string>",
"funding_account_scope": "<string>",
"currency": "<string>",
"amount": "<string>",
"scenario": "<string>",
"payout_scenario": "<string>"
}
'import requests
url = "https://api.sandbox.daya.co/v1/sandbox/deposits"
payload = {
"funding_account_id": "<string>",
"funding_account_scope": "<string>",
"currency": "<string>",
"amount": "<string>",
"scenario": "<string>",
"payout_scenario": "<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({
funding_account_id: '<string>',
funding_account_scope: '<string>',
currency: '<string>',
amount: '<string>',
scenario: '<string>',
payout_scenario: '<string>'
})
};
fetch('https://api.sandbox.daya.co/v1/sandbox/deposits', 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.sandbox.daya.co/v1/sandbox/deposits",
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([
'funding_account_id' => '<string>',
'funding_account_scope' => '<string>',
'currency' => '<string>',
'amount' => '<string>',
'scenario' => '<string>',
'payout_scenario' => '<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.sandbox.daya.co/v1/sandbox/deposits"
payload := strings.NewReader("{\n \"funding_account_id\": \"<string>\",\n \"funding_account_scope\": \"<string>\",\n \"currency\": \"<string>\",\n \"amount\": \"<string>\",\n \"scenario\": \"<string>\",\n \"payout_scenario\": \"<string>\"\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.sandbox.daya.co/v1/sandbox/deposits")
.header("X-Api-Key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"funding_account_id\": \"<string>\",\n \"funding_account_scope\": \"<string>\",\n \"currency\": \"<string>\",\n \"amount\": \"<string>\",\n \"scenario\": \"<string>\",\n \"payout_scenario\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.daya.co/v1/sandbox/deposits")
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 \"funding_account_id\": \"<string>\",\n \"funding_account_scope\": \"<string>\",\n \"currency\": \"<string>\",\n \"amount\": \"<string>\",\n \"scenario\": \"<string>\",\n \"payout_scenario\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyOverview
This sandbox-only endpoint creates a mock deposit for an existing customer or merchant funding account. Setfunding_account_scope to tell Daya which kind of funding account the ID belongs to. Daya uses only the selected account store; it does not search customer and merchant funding accounts for a match.
CUSTOMER(default): Runs the simulated deposit through the customer funding-account settlement and webhook flow.MERCHANT: Creates a merchant funding deposit. Includecurrency: NGNandamountto credit a specific amount towithdrawal_balance_ngn. Includecurrency: USDand an optionalamountto creditwithdrawal_balance_usd. Omitting both preserves the legacy 10 USD simulation.
- Deposit creation
- Settlement to internal balance, onchain payout, or NGN payout
- Webhook dispatch
scenario to trigger a specific sandbox lifecycle outcome. Use scenarios when you need to confirm your app handles specific deposit states without waiting for the sandbox processor to produce them naturally.
For a customer funding account, create the receive instruction with /v1/funding-accounts, then pass its id. For merchant funding, call GET /v1/merchant/funding, pass data.id, and set funding_account_scope to MERCHANT.
This endpoint is available only in sandbox. Calls outside sandbox return
403.For end-to-end guidance (recommended flow, what to validate, and common flagging scenarios), see Sandbox testing.
Authentication
string
required
Your merchant API key
string
Required when
funding_account_scope is MERCHANT. Use a unique value for each simulated deposit and reuse the same value when retrying that request. Retries with the same value resume the original deposit instead of crediting the merchant balance again.Request Body
string
required
Funding account ID to simulate a deposit for. For customer funding, use the
id returned by /v1/funding-accounts. For merchant funding, use data.id from GET /v1/merchant/funding.Example: 6b0e8400-e29b-41d4-a716-446655440000string
default:"CUSTOMER"
Selects the funding account kind. Allowed values are
CUSTOMER and MERCHANT. Omit this field for existing customer funding-account simulations.string
Merchant funding simulations only. Allowed values are
NGN and USD. NGN credits withdrawal_balance_ngn; USD credits withdrawal_balance_usd. Omit this field to preserve the legacy USD simulation.string
Merchant funding simulations only. A positive decimal amount in the selected currency. Required when
currency is NGN; optional for USD, which defaults to 10 when omitted. NGN supports at most two decimal places and USD supports at most six.string
Optional sandbox lifecycle outcome to trigger.Allowed values:
DEFAULTPROCESSINGCOMPLETEDREQUIRES_REVIEWFAILED
string
Optional linked payout outcome for customer funding accounts. Allowed values are
DEFAULT, PROCESSING, SETTLED, and FAILED. This field is not supported when funding_account_scope is MERCHANT.Request Examples
curl --request POST \
--url https://api.sandbox.daya.co/v1/sandbox/deposits \
--header 'X-Api-Key: YOUR_SANDBOX_KEY' \
--header 'Content-Type: application/json' \
--data '{
"funding_account_id": "6b0e8400-e29b-41d4-a716-446655440000"
}'
curl --request POST \
--url https://api.sandbox.daya.co/v1/sandbox/deposits \
--header 'X-Api-Key: YOUR_SANDBOX_KEY' \
--header 'Content-Type: application/json' \
--data '{
"funding_account_id": "6b0e8400-e29b-41d4-a716-446655440000",
"scenario": "COMPLETED"
}'
curl --request POST \
--url https://api.sandbox.daya.co/v1/sandbox/deposits \
--header 'X-Api-Key: YOUR_SANDBOX_KEY' \
--header 'Content-Type: application/json' \
--data '{
"funding_account_id": "6b0e8400-e29b-41d4-a716-446655440000",
"scenario": "REQUIRES_REVIEW"
}'
curl --request POST \
--url https://api.sandbox.daya.co/v1/sandbox/deposits \
--header 'X-Api-Key: YOUR_SANDBOX_KEY' \
--header 'X-Idempotency-Key: merchant-deposit-test-001' \
--header 'Content-Type: application/json' \
--data '{
"funding_account_id": "750e8400-e29b-41d4-a716-446655440000",
"funding_account_scope": "MERCHANT",
"scenario": "COMPLETED"
}'
curl --request POST \
--url https://api.sandbox.daya.co/v1/sandbox/deposits \
--header 'X-Api-Key: YOUR_SANDBOX_KEY' \
--header 'X-Idempotency-Key: merchant-ngn-deposit-test-001' \
--header 'Content-Type: application/json' \
--data '{
"funding_account_id": "750e8400-e29b-41d4-a716-446655440000",
"funding_account_scope": "MERCHANT",
"currency": "NGN",
"amount": "10000",
"scenario": "COMPLETED"
}'
Response
Returns a confirmation message and the simulated deposit status. For customer funding accounts, use/v1/deposits and webhook events to track the deposit.
message: Human-readable status messagedeposit_id: Created deposit IDstatus: Current deposit statusscenario: Scenario that was applied, if provided
{
"message": "Sandbox deposit created for processing.",
"deposit_id": "4b4a0f1f-f1dc-4f4c-a77d-3f4ebc8b4f42",
"status": "COMPLETED",
"scenario": "COMPLETED"
}
Customer funding lifecycle outcomes
Usescenario to test the state machine in your integration:
| Scenario | Expected webhook path | Use this to test |
|---|---|---|
PROCESSING | deposit.received → deposit.processing | In-progress UI and retry-safe polling |
COMPLETED | deposit.received → deposit.completed | Crediting/final success logic |
REQUIRES_REVIEW | deposit.received → deposit.requires_review | Review/hold states |
FAILED | deposit.received → deposit.failed | Failure messaging and recovery |
Scenario outcomes are for testing a specific lifecycle state in sandbox.
PROCESSING and COMPLETED still use the funding account’s active settlement destination, so the funding account must include any required rate_id, destination wallet, or destination bank details. To test the production-like settlement processor and any natural intermediate states, omit scenario.Merchant funding outcomes
Merchant funding simulations do not use the customer settlement destination orpayout_scenario. An NGN simulation directly credits the merchant’s NGN withdrawal balance and requires an active sandbox NGN merchant funding account.
| Scenario | Returned status | Merchant balance |
|---|---|---|
Omitted or DEFAULT | SETTLED | Credits the requested merchant amount and currency; defaults to 10 USD when both are omitted |
PROCESSING | PENDING | No credit |
COMPLETED | SETTLED | Credits the requested merchant amount and currency; defaults to 10 USD when both are omitted |
REQUIRES_REVIEW | FLAGGED | No credit |
FAILED | FAILED | No credit |
Error Responses
This endpoint may return:400: Invalid request401: Unauthorized403: Not available outside sandbox404: Funding account not found500: Internal server error
Next Steps
Get merchant funding
Get the merchant funding account ID and Base address
Webhooks Overview
Verify your webhook handling with sandbox events
Sandbox testing
Recommended end-to-end sandbox flow + common flagging scenarios