Private Send API
Public API reference for private-send quotes, order creation, and order tracking.
Private Send API
This document describes the public Private Send API for website and external integrations.
All endpoints in this document are published under the following namespace:
/external/private-send/*Base URL
https://back.2aml.com/external/private-sendAuthentication
The Private Send API does not require JWT authentication.
Recommended headers:
Content-Type: application/json
Accept: application/jsonOptional attribution header:
x-fingerprint: fp_browser_or_device_identifierIf x-fingerprint is sent in both the request header and the request body, the body value takes precedence.
General Conventions
- All request amounts must be sent as strings.
- Estimate responses return numeric values together with raw string fields.
- All timestamps are returned as ISO 8601 strings.
orderIdis the canonical identifier for tracking an order.
Integration Flow
Recommended integration sequence:
- Call
GET /currencies. - Call
GET /min-amountorGET /range. - Call
GET /estimated-amount. - Call
GET /validate/address. - Call
POST /orders. - Poll
GET /orders/:orderIduntil a terminal status is reached.
Order Status
| Status | Terminal | Description |
|---|---|---|
awaiting_deposit | No | The order is created and payment instructions are available. |
confirming | No | A deposit has been detected and is awaiting confirmation. |
processing | No | The private-send transfer is being processed. |
sending | No | The outbound transfer is in progress. |
completed | Yes | The order completed successfully. |
failed | Yes | The order failed. |
refunded | Yes | The order was refunded. |
pending_support | Yes | The order requires manual follow-up. |
Order display rules:
- show payment instructions only while
payment !== null - stop polling after a terminal status is returned
- always branch on
status, not on free-text message content
Endpoint Summary
| Method | Path | Purpose |
|---|---|---|
GET | /currencies | List supported private-send currencies and networks |
GET | /min-amount | Return the minimum supported amount for a currency and network |
GET | /range | Return the minimum and maximum supported amounts for a currency and network |
GET | /estimated-amount | Return an estimate for the requested receive amount |
GET | /validate/address | Validate the destination address |
POST | /orders | Create a private-send order |
GET | /orders/:orderId | Get order status by orderId |
1. List Currencies
Returns the supported currency and network combinations for private send.
Endpoint
GET /currenciesQuery Parameters
| Field | Type | Required | Description |
|---|---|---|---|
active | string | No | If true, returns only active assets. |
flow | `'standard' | 'fixed-rate'` | No |
buy | string | No | Optional availability filter. |
sell | string | No | Optional availability filter. |
Example Request
curl --request GET \
--url 'https://back.2aml.com/external/private-send/currencies?active=true'Example Response
[
{
"currency": "usdt",
"network": "trx",
"name": "Tether USD",
"supportsFixedRate": true,
"destinationExtraIdSupported": false,
"destinationExtraIdRequired": false,
"isStable": true,
"isFiat": false,
"tokenContract": null
}
]Response Fields
| Field | Type | Description |
|---|---|---|
currency | string | Asset ticker. |
network | string | Network identifier to use in later requests. |
name | string | Display name. |
supportsFixedRate | boolean | Whether fixed-rate mode is available. |
destinationExtraIdSupported | boolean | Whether a destination extra id can be submitted. |
destinationExtraIdRequired | boolean | Whether a destination extra id is required. |
isStable | boolean | Whether the asset is marked as stable. |
isFiat | boolean | Whether the asset is fiat. |
tokenContract | `string | null` |
2. Get Min Amount
Returns the minimum supported amount for the selected currency and network.
Endpoint
GET /min-amountQuery Parameters
| Field | Type | Required | Description |
|---|---|---|---|
currency | string | Yes | Asset ticker. |
network | string | Yes | Network identifier. |
Example Request
curl --request GET \
--url 'https://back.2aml.com/external/private-send/min-amount?currency=usdt&network=trx'Example Response
{
"currency": "usdt",
"network": "trx",
"flow": "standard",
"minAmount": 10
}3. Get Range
Returns the minimum and maximum supported amounts for the selected currency and network.
Endpoint
GET /rangeQuery Parameters
Same as GET /min-amount.
Example Request
curl --request GET \
--url 'https://back.2aml.com/external/private-send/range?currency=usdt&network=trx'Example Response
{
"currency": "usdt",
"network": "trx",
"flow": "standard",
"minAmount": 10,
"maxAmount": 15000
}maxAmount can be null when no upper bound is returned for the selected currency and network.
4. Get Estimated Amount
Returns the amount that must be paid so the destination receives the requested amount.
Endpoint
GET /estimated-amountQuery Parameters
| Field | Type | Required | Description |
|---|---|---|---|
currency | string | Yes | Asset ticker. |
network | string | Yes | Network identifier. |
toAmount | string | Yes | Destination receive amount. |
Example Request
curl --request GET \
--url 'https://back.2aml.com/external/private-send/estimated-amount?currency=usdt&network=trx&toAmount=250'Example Response
{
"currency": "usdt",
"network": "trx",
"payAmount": 257.35,
"payAmountRaw": "257.35",
"payCurrencyCode": "USDT",
"receiveAmount": 250,
"receiveAmountRaw": "250",
"receiveCurrencyCode": "USDT",
"estimatedFeeAmount": 7.35,
"estimatedFeeAmountRaw": "7.35",
"estimatedFeeCurrencyCode": "USDT",
"rateId": "rate_id_f8a1f4e5c2b84f34",
"validUntil": "2026-05-03T12:45:00.000Z",
"warningMessage": "Estimated private-transfer fee: 7.35 USDT. Recipient receives 250 USDT; sender pays 257.35 USDT in total."
}Response Fields
| Field | Type | Description |
|---|---|---|
currency | string | Asset ticker. |
network | string | Network identifier. |
payAmount | number | Amount to send. |
payAmountRaw | string | Raw string form of payAmount. |
payCurrencyCode | string | Payment currency display code. |
receiveAmount | number | Destination receive amount. |
receiveAmountRaw | string | Raw string form of receiveAmount. |
receiveCurrencyCode | string | Receive currency display code. |
estimatedFeeAmount | number | Estimated fee amount. |
estimatedFeeAmountRaw | string | Raw string form of estimatedFeeAmount. |
estimatedFeeCurrencyCode | string | Fee currency display code. |
rateId | string | Quote identifier for order creation. |
validUntil | string | Quote validity limit. |
warningMessage | `string | null` |
Use rateId from the latest estimate request when creating an order.
Treat rateId as an opaque value.
- preserve it exactly as returned
- do not trim it
- do not parse it
- do not assume a fixed format or length
5. Validate Address
Validates the destination address.
Endpoint
GET /validate/addressQuery Parameters
| Field | Type | Required | Description |
|---|---|---|---|
currency | string | Yes | Asset ticker. |
network | string | No | Optional network hint. |
address | string | Yes | Destination address. |
Example Request
curl --request GET \
--url 'https://back.2aml.com/external/private-send/validate/address?currency=usdt&network=trx&address=TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp'Example Response
{
"valid": true,
"reason": null,
"addressActive": null
}6. Create Order
Creates a private-send order.
Endpoint
POST /ordersRequest Body
| Field | Type | Required | Max Length | Description |
|---|---|---|---|---|
currency | string | Yes | 32 | Asset ticker. |
network | string | Yes | 32 | Network identifier. |
toAmount | string | Yes | 64 | Destination receive amount. |
destinationAddress | string | Yes | 256 | Destination address. |
destinationExtraId | string | No | 128 | Destination memo or tag when required. |
refundAddress | string | No | 256 | Refund address. |
refundExtraId | string | No | 128 | Refund memo or tag. |
rateId | string | No | 256 | Quote identifier returned by GET /estimated-amount. |
fingerprint | string | No | 256 | Optional attribution fingerprint. |
referralCode | string | No | 64 | Optional referral code. |
acceptedTerms | boolean | Yes | - | Must be true. |
Example Request
curl --request POST \
--url 'https://back.2aml.com/external/private-send/orders' \
--header 'Content-Type: application/json' \
--header 'x-fingerprint: fp_8bcafb2f41' \
--data '{
"currency": "usdt",
"network": "trx",
"toAmount": "250",
"destinationAddress": "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp",
"destinationExtraId": "memo-01",
"refundAddress": "TGrefund...",
"refundExtraId": "refund-memo",
"rateId": "rate_id_f8a1f4e5c2b84f34",
"acceptedTerms": true
}'Example Response
{
"orderId": "ORD-20260503-AB12CD34",
"status": "awaiting_deposit",
"message": "Send the exact deposit to the provided payment address.",
"payment": {
"address": "TQzH8abY1fFh6S1J1k3o8mJYw2c4U3mS19",
"extraId": null,
"reference": "PAY-ORD-20260503-AB12CD34",
"qrPayload": "TQzH8abY1fFh6S1J1k3o8mJYw2c4U3mS19",
"qrCodeDataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
},
"steps": {
"awaitingDeposit": "waiting",
"confirming": "waiting",
"processing": "waiting",
"sending": "waiting"
},
"updatedAt": "2026-05-03T12:00:00.000Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
orderId | string | Canonical order identifier. |
status | string | Current order status. |
message | string | Customer-facing status message. |
payment | `object | null` |
steps | object | Progress summary. |
updatedAt | string | Last update timestamp. |
payment.reference is a customer-facing reference value. payment.address and the related QR data must be treated as active only while payment is present in the response.
7. Get Order
Returns the latest customer-facing order status by orderId.
Endpoint
GET /orders/:orderIdExample Request
curl --request GET \
--url 'https://back.2aml.com/external/private-send/orders/ORD-20260503-AB12CD34'Example Response
{
"orderId": "ORD-20260503-AB12CD34",
"status": "processing",
"message": "The private-send transfer is being processed.",
"payment": null,
"steps": {
"awaitingDeposit": "done",
"confirming": "done",
"processing": "waiting",
"sending": "waiting"
},
"updatedAt": "2026-05-03T12:04:00.000Z"
}Pending Support Example
{
"orderId": "ORD-20260503-ZX98YU76",
"status": "pending_support",
"message": "This order cannot continue automatically through the API. Continue from the website support flow with your order ID.",
"payment": null,
"steps": {
"awaitingDeposit": "waiting",
"confirming": "waiting",
"processing": "waiting",
"sending": "waiting"
},
"updatedAt": "2026-05-03T12:05:00.000Z"
}Polling Recommendation
awaiting_deposit: poll every 10 to 20 secondsconfirming: poll every 10 secondsprocessing: poll every 10 secondssending: poll every 10 seconds- terminal states: stop polling
If the order reaches pending_support, show the returned message together with orderId and stop polling.
Error Responses
All errors in this namespace use the following structure:
{
"statusCode": 400,
"timestamp": "2026-05-03T12:10:00.000Z",
"path": "/external/private-send/orders",
"error": {
"message": "Order request is invalid."
}
}error.message can be either a string or an array of strings.
Validation Error Example
{
"statusCode": 400,
"timestamp": "2026-05-03T12:11:00.000Z",
"path": "/external/private-send/orders",
"error": {
"message": [
"acceptedTerms must be a boolean value"
]
}
}Not Found Example
{
"statusCode": 404,
"timestamp": "2026-05-03T12:11:00.000Z",
"path": "/external/private-send/orders/ORD-DOES-NOT-EXIST",
"error": {
"message": "Order not found."
}
}Rate Limit Example
{
"statusCode": 429,
"timestamp": "2026-05-03T12:12:00.000Z",
"path": "/external/private-send/orders",
"error": {
"message": "Too many requests. Please try again shortly."
}
}Temporary Service Error Example
{
"statusCode": 503,
"timestamp": "2026-05-03T12:13:00.000Z",
"path": "/external/private-send/estimated-amount?currency=usdt&network=trx&toAmount=250",
"error": {
"message": "Private Send service is temporarily unavailable."
}
}Reference Schemas
type PrivateSendCurrency = {
currency: string;
network: string;
name: string;
supportsFixedRate: boolean;
destinationExtraIdSupported: boolean;
destinationExtraIdRequired: boolean;
isStable: boolean;
isFiat: boolean;
tokenContract: string | null;
};
type PrivateSendEstimate = {
currency: string;
network: string;
payAmount: number;
payAmountRaw: string;
payCurrencyCode: string;
receiveAmount: number;
receiveAmountRaw: string;
receiveCurrencyCode: string;
estimatedFeeAmount: number;
estimatedFeeAmountRaw: string;
estimatedFeeCurrencyCode: string;
rateId: string;
validUntil: string;
warningMessage: string | null;
};
type PrivateSendOrder = {
orderId: string;
status:
| 'awaiting_deposit'
| 'confirming'
| 'processing'
| 'sending'
| 'completed'
| 'failed'
| 'refunded'
| 'pending_support';
message: string;
payment: {
address: string;
extraId: string | null;
reference: string;
qrPayload: string | null;
qrCodeDataUrl: string | null;
} | null;
steps: {
awaitingDeposit: 'waiting' | 'done';
confirming: 'waiting' | 'done';
processing: 'waiting' | 'done';
sending: 'waiting' | 'done';
};
updatedAt: string;
};
