UDA Quickstart
This page takes you from an empty project to a live, multi-chain deposit address with webhooks wired up — from POST /v1/uda to a settled transaction in roughly five minutes. Every request runs against the sandbox at https://api.stridge.dev or production at https://api.stridge.com.
Create an account in the
Stridge Dashboard and generate
an API key. Keep it server-side only — every UDA call is authorized
with the X-API-Key header.
Pick a stable owner identifier for the end user (wallet address,
internal user id, or email all work) and a destination where every
deposit should ultimately land.
curl -X POST 'https://api.stridge.com/v1/uda' \
-H 'X-API-Key: '"$STRIDGE_API_KEY"'' \
-H 'Content-Type: application/json' \
-d '{
"accepted_assets": ["USDC", "USDT", "ETH"],
"destination": {
"address": "0x8f4a2c9e1b3d7f5a6c8e0d9b2a4c6e8f0a2c4d6e",
"asset_symbol": "USDC",
"network_id": "9001"
},
"owner": "user_8a7f3c"
}'The response contains the new id and a per-chain
deposit_addresses list. Store both — the id drives every
subsequent lookup, and the addresses are what you show to your user.
{
"id": "31d32b68-e455-42b7-9d39-d2904adbe1b8",
"status": "active",
"owner": "user_8a7f3c",
"deposit_addresses": [
{ "eip155_id": "1", "network_name": "ethereum", "address": "0x3204…f741" },
{ "eip155_id": "56", "network_name": "bsc", "address": "0x3204…f741" },
{ "eip155_id": "8453", "network_name": "base", "address": "0x3204…f741" },
{ "eip155_id": "42161","network_name": "arbitrum", "address": "0x3204…f741" }
]
}Calling POST /v1/uda with the same owner twice returns the
existing record — safe to retry and safe to fan out from idempotent
workers.
Need some deposits to land somewhere other than the default
destination — or accepting Tron assets that can't be routed? Add a
routing_rules array to this request. See Routing rules.
Want the destination to be reusable and rotatable? Replace the inline
triple with destination: { "treasury": "<name>" }, where <name>
is a treasury you created in the dashboard. Rotating the treasury
propagates to every UDA that references it. See
Treasuries.
Pick the chain and token the user wants to deposit in and render the
corresponding deposit_addresses[i].address. The same address works
for every accepted_assets entry on that chain — ERC-20, native
coin, or both.
The recommended UX is a chain picker + "copy" button. Never ask the user to pick the destination chain; that is already locked in when the UDA was created.
In the dashboard, register a webhook subscriber with these event types:
deposit.confirmeduda.settlement.createduda.settlement.completed
Stridge signs every delivery with HMAC SHA-256; see Verify signature for the canonical check.
Send any amount of any accepted_assets to one of the
deposit_addresses. As soon as the transaction is confirmed:
deposit.confirmedfires withto_wallet_category: "uda".uda.settlement.createdfires with the settlement id, source amount, and detectedscenario(same-chain swap, bridge, or swap-and-bridge).uda.settlement.completedfires once the destination tx has landed in the destination token.
See UDA webhook events for the full payload reference.
Any time after a deposit, fetch the canonical settlement record:
curl 'https://api.stridge.com/v1/settlements/bcc2b0c1-f75c-43b2-b1bc-c44437d775f4' \
-H 'X-API-Key: '"$STRIDGE_API_KEY"''The response includes the source deposit tx, the destination settlement tx, the route + provider, and the total fee — useful for reconciliation and support tooling.
If you only have the deposit transaction hash — not the internal
settlement id — look it up with
GET /v1/uda/settlements/by-reference instead. See
List settlements by reference.
What to build next
- Multi-user UDAs — call
POST /v1/udawith each user's id asowner. One UDA per user, forever. - Dashboard reconciliation — poll
GET /v1/uda/{id}/settlementsto hydrate an internal deposit ledger. - Quotes before deposit — use
GET /v1/uda/quoteto show users an expected fee and settlement time before they broadcast.
Common pitfalls
- Hard-coded chain in the UI. A UDA is multi-chain by design —
always read
deposit_addressesrather than assuming a specific network. - Treating the UDA id as the address. The UDA
idis a UUID; the actual on-chain deposit targets are insidedeposit_addresses[].address. - Skipping webhook signature verification. All deliveries are signed; unauthenticated payloads must be rejected.
- Accepting tokens you haven't enabled.
accepted_assetsis a hard filter — tokens outside the list are ignored, not returned.
Next
- UDA webhook events
- Settlements
- API reference —
POST /v1/uda