Swap

A Swap converts funds between different currencies within your own wallets. For example, converting USD in your USD wallet to EUR in your EUR wallet. The conversion happens immediately upon quote acceptance.

Overview

  1. Create a SWAP Quote — Lock in the exchange rate and fees
  2. Accept the Quote — Conversion happens immediately
  3. Webhook Notification — Receive confirmation of the completed swap

Swaps do not require an external beneficiary. Funds move between your own wallets.


Step 1: Create a SWAP Quote

Create a quote with quote_type: "SWAP". The source and target currencies must be different.

Endpoint

POST /api/v1/client/quotes

Authentication

http
x-api-key: <your-api-key>x-timestamp: <rfc3339-timestamp>x-signature: <hmac-sha256-signature>

Request Body

json
{  "source_currency": "USD",  "target_currency": "EUR",  "source_amount": "1000.00",  "quote_type": "SWAP",  "tz": "UTC",  "narration": "Convert USD to EUR",  "origin_reference": "SWAP-2026-001",  "on_behalf_of": "660e8400-e29b-41d4-a716-446655440001"}

Required Parameters

ParameterTypeDescription
source_currencystringCurrency to convert from (e.g., "USD")
target_currencystringCurrency to convert to (must differ from source, e.g., "EUR")
source_amountstringAmount to convert (decimal string)
quote_typestring"SWAP"
tzstringTimezone (IANA format)
origin_referencestringYour unique reference (max 40 chars)
on_behalf_ofstring (UUID)Customer ID

Optional Parameters

ParameterTypeDescription
narrationstringDescription for the swap

Success Response (201 Created)

json
{  "quote_id": "swap1234-e89b-12d3-a456-426614174000",  "source": {    "currency": "USD",    "amount": "1000.00"  },  "target": {    "currency": "EUR",    "amount": "920.00"  },  "exchange_rate": "0.92",  "fees": {    "processing_fee": "5.00",    "deposit_fee": "0.00",    "payout_fee": "0.00",    "total_fees": "5.00",    "fee_currency": "USD"  },  "total_payable": "1005.00",  "valid_until": "2026-03-16T15:40:53Z",  "quote_status": "CREATED",  "type": "SWAP"}

No beneficiary_id required. A self-beneficiary is automatically created for swaps.


Step 2: Accept the Quote

Accept the quote to execute the swap. The conversion is processed immediately — funds are deducted from your source currency wallet and credited to your target currency wallet.

Endpoint

POST /api/v1/client/quotes/{id}/accept

Authentication

http
x-api-key: <your-api-key>x-timestamp: <rfc3339-timestamp>x-signature: <hmac-sha256-signature>

Success Response (200 OK)

json
{  "quote_id": "swap1234-e89b-12d3-a456-426614174000",  "transaction_id": "txn56789-e21b-43d2-b456-426614174111",  "transaction_reference": "TXN-SWAP-78901",  "total_payable": "1005.00",  "timeline": {    "created_at": "2026-03-16T15:10:53Z",    "accepted_at": "2026-03-16T15:12:30Z"  },  "status": "PROCESSING"}

No payment instructions are returned for swaps. The conversion uses your existing wallet balance.


Step 3: Webhook Notification

You'll receive a transaction webhook when the swap completes:

json
{  "event_type": "transaction",  "transaction_id": "txn56789-e21b-43d2-b456-426614174111",  "transaction_type": "EXCHANGE",  "status": "COMPLETED",  "reference": "TXN-SWAP-78901",  "user_id": "660e8400-e29b-41d4-a716-446655440001",  "created_at": "2026-03-16T15:10:53Z",  "timestamp": "2026-03-16T15:12:45Z",  "source_currency": "USD",  "source_amount": "1000.00",  "target_currency": "EUR",  "target_amount": "920.00",  "amount_with_fees": "1005.00",  "fee": "5.00",  "fee_currency": "USD",  "exchange_rate": "0.92",  "sender": {    "email": "user@example.com",    "account_name": "Your Business"  },  "recipient": {    "email": "user@example.com",    "account_name": "Your Business"  }}

Note that sender and recipient are the same user, since funds move between your own wallets.


Preview Exchange Rates

Before creating a swap quote, you can preview estimated rates and fees using the Exchange Rates API:

GET /api/v1/client/exchange-rates

This is optional — actual rates are locked when the quote is created. See Exchange Rates API for details.


Example: Complete Swap Flow

cURL

Step 1: Create swap quote

bash
curl -X POST https://api.transfaar.com/api/v1/client/quotes \  -H "Content-Type: application/json" \  -H "x-api-key: your-api-key" \  -H "x-timestamp: 2026-03-16T10:30:00Z" \  -H "x-signature: your-hmac-signature" \  -d '{    "source_currency": "USD",    "target_currency": "EUR",    "source_amount": "1000.00",    "quote_type": "SWAP",    "tz": "UTC",    "narration": "Convert USD to EUR",    "origin_reference": "SWAP-2026-001",    "on_behalf_of": "660e8400-e29b-41d4-a716-446655440001"  }'

Step 2: Accept the quote

bash
curl -X POST https://api.transfaar.com/api/v1/client/quotes/swap1234-e89b-12d3-a456-426614174000/accept \  -H "Content-Type: application/json" \  -H "x-api-key: your-api-key" \  -H "x-timestamp: 2026-03-16T10:31:00Z" \  -H "x-signature: your-hmac-signature"

HTTP

Step 1: Create swap quote

http
POST /api/v1/client/quotes HTTP/1.1Host: api.transfaar.comx-api-key: your-api-keyx-timestamp: 2026-03-16T10:30:00Zx-signature: your-hmac-signatureContent-Type: application/json
{  "source_currency": "USD",  "target_currency": "EUR",  "source_amount": "1000.00",  "quote_type": "SWAP",  "tz": "UTC",  "origin_reference": "SWAP-2026-001",  "on_behalf_of": "660e8400-e29b-41d4-a716-446655440001"}

Step 2: Accept the quote

http
POST /api/v1/client/quotes/swap1234-e89b-12d3-a456-426614174000/accept HTTP/1.1Host: api.transfaar.comx-api-key: your-api-keyx-timestamp: 2026-03-16T10:31:00Zx-signature: your-hmac-signatureContent-Type: application/json

JavaScript

javascript
async function processSwap(apiKey, secretKey, swapData) {  // Step 1: Create swap quote  const quote = await apiCall('POST', '/api/v1/client/quotes', apiKey, secretKey, {    source_currency: swapData.fromCurrency,    target_currency: swapData.toCurrency,    source_amount: swapData.amount,    quote_type: 'SWAP',    tz: 'UTC',    narration: swapData.narration,    origin_reference: swapData.reference,    on_behalf_of: swapData.customerId  });
  console.log(`Rate: ${quote.exchange_rate}, You'll receive: ${quote.target.amount} ${quote.target.currency}`);  console.log(`Fees: ${quote.fees.total_fees} ${quote.fees.fee_currency}, Total: ${quote.total_payable}`);
  // Step 2: Accept the quote — conversion happens immediately  const result = await apiCall('POST', `/api/v1/client/quotes/${quote.quote_id}/accept`, apiKey, secretKey);
  return {    transactionId: result.transaction_id,    transactionReference: result.transaction_reference,    status: result.status  };}

Requirements

  • Wallet Balance — You must have sufficient balance in the source currency wallet to cover the amount plus fees.
  • Different Currencies — Source and target currencies must be different (e.g., USD to EUR). For same-currency operations, use a Transfer or Withdrawal.
  • Wallets for Both Currencies — You must have wallets for both the source and target currencies.

Best Practices

  1. Preview Rates First — Use the Exchange Rates API to show estimated rates to users before committing to a swap.
  2. Accept Promptly — Quotes expire after ~30 minutes. Accept before the valid_until timestamp to lock in the displayed rate.
  3. Check Balance — Verify sufficient balance in the source wallet before creating the quote.
  4. Unique Origin References — Each origin_reference must be unique to prevent duplicate swaps.
  5. Track via Webhooks — Use webhooks for real-time confirmation rather than polling.