Docs

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-send

Authentication

The Private Send API does not require JWT authentication.

Recommended headers:

Content-Type: application/json
Accept: application/json

Optional attribution header:

x-fingerprint: fp_browser_or_device_identifier

If 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.
  • orderId is the canonical identifier for tracking an order.

Integration Flow

Recommended integration sequence:

  1. Call GET /currencies.
  2. Call GET /min-amount or GET /range.
  3. Call GET /estimated-amount.
  4. Call GET /validate/address.
  5. Call POST /orders.
  6. Poll GET /orders/:orderId until a terminal status is reached.

Order Status

StatusTerminalDescription
awaiting_depositNoThe order is created and payment instructions are available.
confirmingNoA deposit has been detected and is awaiting confirmation.
processingNoThe private-send transfer is being processed.
sendingNoThe outbound transfer is in progress.
completedYesThe order completed successfully.
failedYesThe order failed.
refundedYesThe order was refunded.
pending_supportYesThe 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

MethodPathPurpose
GET/currenciesList supported private-send currencies and networks
GET/min-amountReturn the minimum supported amount for a currency and network
GET/rangeReturn the minimum and maximum supported amounts for a currency and network
GET/estimated-amountReturn an estimate for the requested receive amount
GET/validate/addressValidate the destination address
POST/ordersCreate a private-send order
GET/orders/:orderIdGet order status by orderId

1. List Currencies

Returns the supported currency and network combinations for private send.

Endpoint

GET /currencies

Query Parameters

FieldTypeRequiredDescription
activestringNoIf true, returns only active assets.
flow`'standard''fixed-rate'`No
buystringNoOptional availability filter.
sellstringNoOptional 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

FieldTypeDescription
currencystringAsset ticker.
networkstringNetwork identifier to use in later requests.
namestringDisplay name.
supportsFixedRatebooleanWhether fixed-rate mode is available.
destinationExtraIdSupportedbooleanWhether a destination extra id can be submitted.
destinationExtraIdRequiredbooleanWhether a destination extra id is required.
isStablebooleanWhether the asset is marked as stable.
isFiatbooleanWhether the asset is fiat.
tokenContract`stringnull`

2. Get Min Amount

Returns the minimum supported amount for the selected currency and network.

Endpoint

GET /min-amount

Query Parameters

FieldTypeRequiredDescription
currencystringYesAsset ticker.
networkstringYesNetwork 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 /range

Query 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-amount

Query Parameters

FieldTypeRequiredDescription
currencystringYesAsset ticker.
networkstringYesNetwork identifier.
toAmountstringYesDestination 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

FieldTypeDescription
currencystringAsset ticker.
networkstringNetwork identifier.
payAmountnumberAmount to send.
payAmountRawstringRaw string form of payAmount.
payCurrencyCodestringPayment currency display code.
receiveAmountnumberDestination receive amount.
receiveAmountRawstringRaw string form of receiveAmount.
receiveCurrencyCodestringReceive currency display code.
estimatedFeeAmountnumberEstimated fee amount.
estimatedFeeAmountRawstringRaw string form of estimatedFeeAmount.
estimatedFeeCurrencyCodestringFee currency display code.
rateIdstringQuote identifier for order creation.
validUntilstringQuote validity limit.
warningMessage`stringnull`

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/address

Query Parameters

FieldTypeRequiredDescription
currencystringYesAsset ticker.
networkstringNoOptional network hint.
addressstringYesDestination 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 /orders

Request Body

FieldTypeRequiredMax LengthDescription
currencystringYes32Asset ticker.
networkstringYes32Network identifier.
toAmountstringYes64Destination receive amount.
destinationAddressstringYes256Destination address.
destinationExtraIdstringNo128Destination memo or tag when required.
refundAddressstringNo256Refund address.
refundExtraIdstringNo128Refund memo or tag.
rateIdstringNo256Quote identifier returned by GET /estimated-amount.
fingerprintstringNo256Optional attribution fingerprint.
referralCodestringNo64Optional referral code.
acceptedTermsbooleanYes-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

FieldTypeDescription
orderIdstringCanonical order identifier.
statusstringCurrent order status.
messagestringCustomer-facing status message.
payment`objectnull`
stepsobjectProgress summary.
updatedAtstringLast 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/:orderId

Example 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 seconds
  • confirming: poll every 10 seconds
  • processing: poll every 10 seconds
  • sending: 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;
};
2AML2AML

2AML is a technology and integration platform for digital asset workflows, built to provide clear service flows, transaction visibility, and support tools.

© 2026 2AML. All rights reserved. Use of this platform is subject to our Terms of Service.

Trustpilot