Every request on this page goes to https://api.stridge.com/v1 with a sandbox key. Replace sk_sbx_... with your own key.
Sign in to the Stridge dashboard. If your workspace is already live, switch to the sandbox from the workspace menu at the top of the sidebar (Environments → Sandbox). Then choose Developer → API Keys → Create API key. Give the key the Universal addresses scope, or Full access, and copy the secret. It starts with sk_sbx_.
Owners and developers can create sandbox keys, and you can reveal a sandbox key's secret again later. Keep it on your server anyway: anyone holding it can act in your sandbox.
Still in the sandbox, open Developer → Webhooks and choose Create endpoint. Subscribe it to at least:
deposit.confirmeduda.settlement.createduda.settlement.completed
The URL must use https and resolve to a public host: localhost, private addresses, and literal private IPs are refused. To receive events on your laptop, use a tunnel that gives you a public https URL.
Copy the endpoint's signing secret when the dialog shows it: you need it to verify deliveries, and it is shown only once. Webhook endpoints belong to one environment, so an endpoint you add in the sandbox receives only sandbox events.
A Universal Deposit Address (UDA) gives one customer a deposit address on every supported network and settles whatever arrives to one destination. Create one exactly as you would in live. This one settles every deposit to USDC on Base.
curl -X POST 'https://api.stridge.com/v1/uda' \
-H 'X-API-Key: sk_sbx_...' \
-H 'Content-Type: application/json' \
-d '{
"owner": "user_8a7f3c",
"accepted_assets": ["USDC", "USDT"],
"destination": {
"network_id": "8453",
"asset_symbol": "USDC",
"address": "0x8f4a2c9e1b3d7f5a6c8e0d9b2a4c6e8f0a2c4d6e"
}
}'It answers 201 with the UDA. It lists a deposit address on each simulated network, and every object in it carries "livemode": false:
{
"livemode": false,
"id": "31d32b68-e455-42b7-9d39-d2904adbe1b8",
"status": "active",
"owner": "user_8a7f3c",
"deposit_addresses": [
{
"livemode": false,
"network_id": "60",
"eip155_id": "1",
"network_name": "ethereum",
"address": "0x3204a1c9e1b3d7f5a6c8e0d9b2a4c6e8f0a2f741",
"accepted_assets": [
{ "livemode": false, "symbol": "USDC", "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "decimals": 6, "logo": "…" },
{ "livemode": false, "symbol": "USDT", "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "decimals": 6, "logo": "…" }
]
}
]
}The response is shortened to one network here. Note the id: you pass it to the test helper next.
Ask the sandbox to send 25 USDC to the UDA on Ethereum. The test helper puts a transfer on the simulated chain, and Stridge picks it up exactly as it would a real payment.
amountis in base units: 25 USDC at 6 decimals is25000000.assetnames a token by its contract address, as listed indeposit_addresses[].accepted_assets.- Every test helper call needs an
Idempotency-Keyheader. Use a fresh value for each new simulation.
curl -X POST 'https://api.stridge.com/v1/test_helpers/uda/deposits' \
-H 'X-API-Key: sk_sbx_...' \
-H 'Idempotency-Key: 5f0c7e1a-quickstart-1' \
-H 'Content-Type: application/json' \
-d '{
"uda_id": "31d32b68-e455-42b7-9d39-d2904adbe1b8",
"network_id": "60",
"asset": { "token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
"amount": "25000000"
}'The helper answers 201 at once with a simulation, the record of what you asked for and what came of it:
{
"success": true,
"message": "success",
"data": {
"id": "019a1b2c-3d4e-7f60-8a9b-0c1d2e3f4a5b",
"object": "simulation",
"environment_id": "3f2c1d9e-8a47-4b6e-9c11-2d5e7f8a9b04",
"livemode": false,
"kind": "uda_deposit",
"preset": null,
"request": {
"uda_id": "31d32b68-e455-42b7-9d39-d2904adbe1b8",
"network_id": "60",
"asset": { "token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
"amount": "25000000",
"settlement": "success"
},
"state": "running",
"chain": { "network_id": "60", "hash": "0x9c1e…4b7a" },
"caused": [],
"epoch": 2,
"error": null,
"outcome": null,
"created_at": "2026-10-25T09:46:50Z",
"updated_at": "2026-10-25T09:46:50Z"
}
}Read the simulation back with wait=completed. The request holds until the settlement finishes or timeout_ms passes (at most 30 seconds), then answers with whatever state the simulation reached.
curl 'https://api.stridge.com/v1/test_helpers/simulations/019a1b2c-3d4e-7f60-8a9b-0c1d2e3f4a5b?wait=completed&timeout_ms=30000' \
-H 'X-API-Key: sk_sbx_...'When it completes, caused lists every Stridge object the deposit produced, with its status and the last webhook event it sent. Keep the settlement id: it is what you look up with GET /v1/uda/settlements/{id}.
{
"state": "completed",
"caused": [
{ "livemode": false, "object": "deposit", "id": "bcc2b0c1-f75c-43b2-b1bc-c44437d775f4", "status": "confirmed", "event_type": "deposit.confirmed" },
{ "livemode": false, "object": "settlement", "id": "6a1f0c2b-3e94-4d1e-9b3c-5f2a8d4e1a6f", "status": "completed", "event_type": "uda.settlement.completed" },
{ "livemode": false, "object": "routing", "id": "9b3c6d1e-5f2a-4b7c-8d4e-1a6f0c2b3e94", "status": "completed", "event_type": null }
],
"outcome": null
}You can also watch the simulation under Developer → Simulations in the dashboard.
Your endpoint receives deposit.confirmed, then uda.settlement.created, then uda.settlement.completed, with the same payloads live sends. The envelope says the event came from the sandbox:
{
"id": "7401d9c7-e29d-4374-8952-af40f05168b7",
"version": "v1",
"type": "deposit.confirmed",
"time": "2026-10-25T09:46:54Z",
"livemode": false,
"environment_id": "3f2c1d9e-8a47-4b6e-9c11-2d5e7f8a9b04",
"reset_epoch": 2,
"payload": {
"id": "bcc2b0c1-f75c-43b2-b1bc-c44437d775f4",
"owner": "user_8a7f3c",
"asset": "USDC",
"network_id": "60",
"network_symbol": "ethereum",
"tx_id": "0x9c1e…4b7a",
"to_wallet_category": "uda",
"scanner_url": "https://sandbox-explorer.stridge.com/60/tx/0x9c1e…4b7a?in=acme"
}
}The payload is shortened here; the full payloads are in UDA webhook events. Verify each delivery's signature exactly as you will in live (see Verify signature), and open scanner_url to see the transaction in the sandbox explorer.