Fund endpoints let an organization withdraw funds, query withdrawal status and fees, and read its available USDT and USDC balances.
All Fund API prefix:
/v2/funds
All endpoints use HMAC-SHA256 authentication with Date, Digest when the request has a body, and Authorization with keyId. For a GET request with query parameters, the signed request path must include the complete query string. See Chapter 4: Authorization and Security Mechanisms.
| Permission | Endpoints |
|---|---|
fund.withdraw | POST /v2/funds/withdraw, GET /v2/funds/withdraw/status, GET /v2/funds/withdraw/fees, GET /v2/funds/balances |
IP whitelist: API keys that include
fund.withdrawmust be configured with a non-empty IP whitelist when created or updated in the merchant dashboard.
request_id is optional when creating a withdrawal:
- When omitted, Infini generates the withdrawal request ID and preserves the existing withdrawal behavior. Separate caller retries without a shared ID are not idempotent.
- When supplied, it must be a UUID and is used as the idempotency key.
- When the same merchant retries with the same
request_id, the API returns the previously created withdrawal information withis_duplicate: true. - Use one
request_idfor exactly one logical withdrawal. Do not reuse it for a different amount, chain, token, or destination address.
After gateway authentication, application responses use the standard code / message / data envelope. Business success is indicated by code === 0; a non-zero code indicates an error and message carries the details. Some downstream business failures can be returned with HTTP 200, a non-zero code, and data: null.
HMAC or gateway validation failures can be rejected before the request reaches the application and may return a gateway response such as {"message":"client request can't be validated"} instead of the application envelope. Clients should check the HTTP status first, then check code whenever the envelope is present.
POST /v2/funds/withdraw
Creates a withdrawal from the authenticated organization to an external wallet.
- Required permission:
fund.withdraw
| Field | Type | Required | Description |
|---|---|---|---|
| request_id | string (UUID) | No | Idempotency key. When omitted, Infini generates one |
| chain | string | Yes | Public chain name, for example ETHEREUM or ARBITRUM |
| token_type | string | Yes | Token type, for example USDT or USDC |
| amount | string | Yes | Positive decimal amount. Digits after the sixth decimal place are truncated without rounding; the resulting amount must be at least 1 and greater than the withdrawal fee |
| wallet_address | string | Yes | Destination address valid for the selected chain |
| note | string | No | Optional withdrawal note |
Use GET /v2/funds/withdraw/fees as the current source of truth for enabled chain/token pairs and their fees. Chain and token names in examples are uppercase.
{
"request_id": "e94b4e88-36c2-4550-907e-839742cf5fae",
"chain": "ETHEREUM",
"token_type": "USDT",
"amount": "10.00",
"wallet_address": "0x5f716e5775b18409917e2a2f0762d29d6c385cb0",
"note": "Treasury withdrawal"
}{
"code": 0,
"message": "",
"data": {
"request_id": "e94b4e88-36c2-4550-907e-839742cf5fae",
"status": "pending",
"is_duplicate": false
}
}For an idempotent retry, data.is_duplicate is true and data.status is the existing withdrawal's current status.
GET /v2/funds/withdraw/status?request_id={request_id}
Returns the current state and amounts for a withdrawal owned by the authenticated organization.
- Required permission:
fund.withdraw - The HMAC signing path must include
?request_id={request_id}.
| Field | Type | Required | Description |
|---|---|---|---|
| request_id | string (UUID) | Yes | Withdrawal request ID |
{
"code": 0,
"message": "",
"data": {
"request_id": "e94b4e88-36c2-4550-907e-839742cf5fae",
"status": "completed",
"amount": "11",
"fee": "0.1",
"actual_amount": "10.9",
"transaction_hash": "0xabc123",
"chain": "ETHEREUM",
"token_type": "USDT"
}
}| Field | Type | Description |
|---|---|---|
| request_id | string | Withdrawal request ID |
| status | string | Current withdrawal status |
| amount | string | Original withdrawal amount |
| fee | string | Withdrawal fee denominated in token_type |
| actual_amount | string | On-chain amount after the fee |
| transaction_hash | string | On-chain transaction hash; empty before submission |
| chain | string | Public chain name |
| token_type | string | Token type |
| Status | Description |
|---|---|
pending | Withdrawal created and waiting for submission or review |
processing | Transaction submitted and waiting for confirmation |
completed | Withdrawal completed |
failed | Withdrawal failed |
GET /v2/funds/withdraw/fees
Returns currently enabled public chain/token pairs and their fees. Fees are dynamic; clients should query this endpoint instead of hard-coding a fee table.
- Required permission:
fund.withdraw
{
"code": 0,
"message": "",
"data": {
"fees": [
{
"chain": "ARBITRUM",
"token_type": "USDC",
"withdraw_fee": "0.5"
},
{
"chain": "ETHEREUM",
"token_type": "USDT",
"withdraw_fee": "2"
}
]
}
}Each withdraw_fee is denominated in the corresponding token_type.
GET /v2/funds/balances
Returns only the authenticated organization's USDT and USDC AVAILABLE_BALANCE values.
- Required permission:
fund.withdraw
{
"code": 0,
"message": "",
"data": {
"available_balance_usdt": "120.50",
"available_balance_usdc": "75.25"
}
}When the organization has no balance entry for one of the tokens, its value is returned as "0".