API Reference
Most integrations never call the API directly — the SDK does it for you. This reference is for server-side work: minting a user's deposit address from your backend, or reconciling deposits against your own records.
depositOS runs the API. There is nothing to deploy and no keys to manage beyond your own.
Base URL
https://api-deposit-os.gizmolab.io
Authentication
Every endpoint requires your app's API key from the portal, sent as an x-api-key header.
x-api-key: dos_live_…
Requests without a valid key return 401. Upstream provider keys live on the depositOS
API and are never exposed — your key identifies your app, nothing more.
POST /addresses
Returns this user's deposit address for a route. The address is stored, so calling this repeatedly returns the same address; a new one is minted only on first use, or if the stored address stops being valid upstream.
Request
POST /addresses
x-api-key: dos_live_…
Content-Type: application/json
{
"userId": "your-user-123",
"originChainId": 137,
"originCurrency": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
"destinationChainId": 8453,
"destinationCurrency": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"recipient": "0xYourTreasury",
"refundTo": "0xUserWallet",
"amount": "10000000"
}
| Field | Type | Description |
|---|---|---|
| userId | string | Your stable id for the end user. Same id + same route → same address. |
| originChainId | number | Chain the user sends from. |
| originCurrency | string | Token address on the origin chain. |
| destinationChainId | number | Chain the funds land on. |
| destinationCurrency | string | Token address on the destination chain. |
| recipient | string | Final recipient on the destination chain. |
| refundTo | string | Where a failed deposit is refunded. Must be an address on the origin chain's network — a Solana deposit refunds to a Solana address. |
| amount | string | Base units. Only used to price the route; the address itself accepts any amount. |
Response
{
"depositAddress": "0x882785654700d9afcabe231e36b3801f43e9ca3f",
"requestId": "0x…",
"originChainId": 137,
"addressType": "open",
"reused": true,
"persisted": true,
"currencyOut": { "amountFormatted": "9.969622", "currency": { "symbol": "USDC", "decimals": 6 } },
"timeEstimate": 12
}
| Field | Description |
|---|---|
| depositAddress | Where the user sends funds. Show this, and its QR code. |
| reused | true when the address was already stored for this user; false on first mint. |
| addressType | Always "open" — reusable, variable amount. |
| persisted | false would mean the address could not be stored and won't be stable. |
| currencyOut | Live pricing for the amount you passed. Indicative only. |
The address is identified by (app, userId, originChainId, originCurrency, destinationChainId, destinationCurrency, recipient, refundTo). Change any of those — a
different recipient, a different source token — and you get a different address.
Errors: 400 on invalid input, 401 without a key, 502 when the route cannot be priced
(for example, a token that doesn't exist on that chain).
GET /rail/requests
Every deposit made to an address. Track by address, never by requestId — each deposit
to a reusable address creates a new request, so the requestId returned at mint time
only ever describes the first one.
GET /rail/requests?depositAddress=0x8827…&includeChildRequests=true&limit=1&sortBy=createdAt&sortDirection=desc
x-api-key: dos_live_…
| Parameter | Description |
|---|---|
| depositAddress | The address to track. |
| includeChildRequests | true to include follow-on requests from a regenerated quote. |
| startTimestamp | Epoch seconds. Only return deposits started after this time. |
| limit, sortBy, sortDirection | sortBy=createdAt&sortDirection=desc&limit=1 gives the latest deposit. |
{ "requests": [{ "id": "0x…", "status": "success", "createdAt": "2026-07-10T09:55:19.595Z", "depositAddress": "0x8827…" }] }
status is one of pending, depositing, success, refund, failure. An empty
requests array means no deposit has landed yet — that's the normal "waiting" state, not
an error.
Use startTimestamp when you show a returning user their address. Without it, an address
that already carries a completed deposit will immediately report success for that old
deposit.
POST /events
The SDK posts lifecycle events here automatically when you set config.apiKey. You rarely
need to call it yourself. See Events.