Liquidation Address

Overview

A Liquidation Address is a crypto wallet that automatically converts incoming cryptocurrency (USDC/USDT) to USD and sends it to a pre-configured bank account recipient. This enables seamless crypto-to-fiat off-ramping for your users.

Key Concept: Receive crypto, send USD automatically.

How It Works

sequenceDiagram
    participant Sender
    participant Liquidation Address
    participant Kira
    participant Virtual Account
    participant Recipient Bank

    Note over Sender,Recipient Bank: Crypto Off-Ramp Flow

    Sender->>Liquidation Address: Send USDC/USDT
    Liquidation Address->>Kira: Crypto received
    Kira->>Your Server: Webhook: liquidation.deposit_received

    Note over Kira: Convert crypto to USD

    Kira->>Virtual Account: Debit USD amount
    Virtual Account->>Recipient Bank: Send USD (ACH/WIRE/SWIFT)

    Kira->>Your Server: Webhook: liquidation.payout_processing
    Recipient Bank-->>Kira: Transfer completed
    Kira->>Your Server: Webhook: liquidation.payout_completed

Flow Summary

  1. Sender deposits crypto - USDC or USDT is sent to the liquidation address (blockchain wallet)
  2. Automatic conversion - Crypto is converted to USD at current market rate
  3. USD payout - Funds are sent from the linked virtual account to the configured recipient
  4. Webhook notifications - You're notified at each step of the process

Prerequisites

Before creating a liquidation address:

RequirementDescription
Virtual AccountMust have an active US_BANK virtual account
Account StatusVirtual account must be active
User VerificationUser must be verified (KYC/KYB completed)
RecipientBank account details for USD payouts (ACH, WIRE, or SWIFT)

Note: Liquidation addresses work with both crypto mode and fiat mode virtual accounts.

Supported Configurations

Incoming Crypto

TokenNetworks
USDCSolana, Polygon
USDTPolygon, Tron

Outgoing USD

Transfer TypeDescriptionSpeed
ACHUS domestic, lower fees1-3 business days
WIREUS domestic, fasterSame day - 1 business day
SWIFTInternational3-5 business days

Create Liquidation Address

Creates a liquidation address linked to a virtual account with a configured USD recipient. Multiple liquidation addresses can be created per virtual account, but each bank account can only exist once per VA.

Endpoint

POST /v1/virtual-accounts/{id}/liquidation-address

Headers

HeaderRequiredDescription
AuthorizationYesBearer token from authentication
x-api-keyYesYour API key
Content-TypeYesMust be application/json
idempotency-keyYesUnique identifier to prevent duplicate creation

Path Parameters

ParameterTypeRequiredDescription
idstringYesVirtual account ID (must be US_BANK)

Request Body

{
  "network": "solana",
  "token": "USDC",
  "recipient": {
    "type": "individual",
    "first_name": "Juan",
    "last_name": "Perez",
    "email": "[email protected]",
    "account": {
      "account_type": "ACH",
      "routing_number": "021000021",
      "account_number": "123456789",
      "type": "checking",
      "bank_name": "Chase Bank",
      "bank_address": "123 Main St, New York, NY 10001"
    }
  }
}

Request Fields

Root Fields

FieldTypeRequiredDescription
networkstringYesBlockchain network: solana, polygon, or tron
tokenstringYesStablecoin: USDC or USDT
recipientobjectYesUSD recipient configuration

Recipient Fields

FieldTypeRequiredDescription
recipient.typestringYesindividual or business
recipient.first_namestringYes*First name (required for individual)
recipient.last_namestringYes*Last name (required for individual)
recipient.company_namestringYes*Company name (required for business)
recipient.emailstringYesEmail address
recipient.accountobjectYesBank account details

ACH Account Fields

FieldTypeRequiredDescription
account.account_typestringYesACH
account.routing_numberstringYes9-digit ABA routing number
account.account_numberstringYesBank account number
account.typestringYeschecking or savings
account.bank_namestringYesBank name
account.bank_addressstringYesBank address

WIRE Account Fields

FieldTypeRequiredDescription
account.account_typestringYesWIRE
account.routing_numberstringYes9-digit ABA routing number
account.account_numberstringYesBank account number
account.typestringYeschecking or savings
account.bank_namestringYesBank name
account.bank_addressstringYesBank address
account.swift_codestringNoSWIFT/BIC code (optional)

SWIFT Account Fields

FieldTypeRequiredDescription
account.account_typestringYesSWIFT
account.swift_codestringYesSWIFT/BIC code (8 or 11 characters)
account.account_numberstringYesAccount number or IBAN
account.bank_namestringYesBank name
account.bank_addressstringYesBank address
account.countrystringYesRecipient country

Example: Create ACH Liquidation Address

curl -X POST https://api.balampay.com/v1/virtual-accounts/550e8400-e29b-41d4-a716-446655440001/liquidation-address \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "idempotency-key: liq-$(uuidgen)" \
  -d '{
    "network": "solana",
    "token": "USDC",
    "recipient": {
      "type": "individual",
      "first_name": "Juan",
      "last_name": "Perez",
      "email": "[email protected]",
      "account": {
        "account_type": "ACH",
        "routing_number": "021000021",
        "account_number": "123456789",
        "type": "checking",
        "bank_name": "Chase Bank",
        "bank_address": "123 Main St, New York, NY 10001"
      }
    }
  }'

Response

{
  "id": "liq_550e8400-e29b-41d4-a716-446655440050",
  "virtual_account_id": "550e8400-e29b-41d4-a716-446655440001",
  "status": "active",
  "network": "solana",
  "token": "USDC",
  "address": "7tQJvFk8XZoaVRjLGcBdqN3hJq8VqBvGpPQy8R9xYwZ1",
  "recipient": {
    "id": "rec_550e8400-e29b-41d4-a716-446655440060",
    "type": "individual",
    "name": "Juan Perez",
    "account_type": "ACH",
    "bank_name": "Chase Bank",
    "account_number_last4": "6789"
  },
  "created_at": "2024-01-15T10:30:00Z"
}

Response Fields

FieldTypeDescription
idstringLiquidation address ID
virtual_account_idstringLinked virtual account ID
statusstringStatus: active, inactive
networkstringBlockchain network
tokenstringAccepted stablecoin
addressstringBlockchain wallet address to receive crypto
recipientobjectConfigured USD recipient (masked)
recipient.idstringRecipient ID
recipient.typestringindividual or business
recipient.namestringRecipient name
recipient.account_typestringACH, WIRE, or SWIFT
recipient.bank_namestringBank name
recipient.account_number_last4stringLast 4 digits of account
created_atstringISO 8601 timestamp

Example: Create WIRE Liquidation Address (Business)

curl -X POST https://api.balampay.com/v1/virtual-accounts/550e8400-e29b-41d4-a716-446655440001/liquidation-address \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "idempotency-key: liq-$(uuidgen)" \
  -d '{
    "network": "polygon",
    "token": "USDC",
    "recipient": {
      "type": "business",
      "company_name": "Acme Corp",
      "email": "[email protected]",
      "account": {
        "account_type": "WIRE",
        "routing_number": "021000021",
        "account_number": "987654321",
        "type": "checking",
        "bank_name": "Bank of America",
        "bank_address": "456 Wall St, New York, NY 10005"
      }
    }
  }'

Example: Create SWIFT Liquidation Address (International)

curl -X POST https://api.balampay.com/v1/virtual-accounts/550e8400-e29b-41d4-a716-446655440001/liquidation-address \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "idempotency-key: liq-$(uuidgen)" \
  -d '{
    "network": "tron",
    "token": "USDT",
    "recipient": {
      "type": "individual",
      "first_name": "Maria",
      "last_name": "Garcia",
      "email": "[email protected]",
      "account": {
        "account_type": "SWIFT",
        "swift_code": "DEUTDEFF",
        "account_number": "DE89370400440532013000",
        "bank_name": "Deutsche Bank",
        "bank_address": "Taunusanlage 12, 60325 Frankfurt, Germany",
        "country": "Germany"
      }
    }
  }'

List Liquidation Addresses

Retrieves all liquidation addresses for a virtual account.

Endpoint

GET /v1/virtual-accounts/{id}/liquidation-address

Headers

HeaderRequiredDescription
AuthorizationYesBearer token from authentication
x-api-keyYesYour API key

Path Parameters

ParameterTypeRequiredDescription
idstringYesVirtual account ID

Example Request

curl -X GET https://api.balampay.com/v1/virtual-accounts/550e8400-e29b-41d4-a716-446655440001/liquidation-address \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-api-key: YOUR_API_KEY"

Response

Returns an array of liquidation addresses.

[
  {
    "id": "liq_550e8400-e29b-41d4-a716-446655440050",
    "virtual_account_id": "550e8400-e29b-41d4-a716-446655440001",
    "status": "active",
    "network": "solana",
    "token": "USDC",
    "address": "7tQJvFk8XZoaVRjLGcBdqN3hJq8VqBvGpPQy8R9xYwZ1",
    "recipient": {
      "id": "rec_550e8400-e29b-41d4-a716-446655440060",
      "type": "individual",
      "name": "Juan Perez",
      "account_type": "ACH",
      "bank_name": "Chase Bank",
      "account_number_last4": "6789"
    },
    "wallet": {
      "id": "770e8400-e29b-41d4-a716-446655440002",
      "address": "7tQJvFk8XZoaVRjLGcBdqN3hJq8VqBvGpPQy8R9xYwZ1",
      "network": "solana"
    },
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-20T14:00:00Z"
  }
]

Get Liquidation Address by ID

Retrieves a specific liquidation address by its ID.

Endpoint

GET /v1/virtual-accounts/{id}/liquidation-address/{addressId}

Path Parameters

ParameterTypeRequiredDescription
idstringYesVirtual account ID
addressIdstringYesLiquidation address ID (with or without liq_ prefix)

Example Request

curl -X GET https://api.balampay.com/v1/virtual-accounts/550e8400-e29b-41d4-a716-446655440001/liquidation-address/liq_550e8400-e29b-41d4-a716-446655440050 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-api-key: YOUR_API_KEY"

Response

{
  "id": "liq_550e8400-e29b-41d4-a716-446655440050",
  "virtual_account_id": "550e8400-e29b-41d4-a716-446655440001",
  "status": "active",
  "network": "solana",
  "token": "USDC",
  "address": "7tQJvFk8XZoaVRjLGcBdqN3hJq8VqBvGpPQy8R9xYwZ1",
  "recipient": {
    "id": "rec_550e8400-e29b-41d4-a716-446655440060",
    "type": "individual",
    "name": "Juan Perez",
    "account_type": "ACH",
    "bank_name": "Chase Bank",
    "account_number_last4": "6789"
  },
  "wallet": {
    "id": "770e8400-e29b-41d4-a716-446655440002",
    "address": "7tQJvFk8XZoaVRjLGcBdqN3hJq8VqBvGpPQy8R9xYwZ1",
    "network": "solana"
  },
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-01-20T14:00:00Z"
}

Response Fields

FieldTypeDescription
walletobjectCrypto wallet details
wallet.idstringWallet ID
wallet.addressstringBlockchain wallet address
wallet.networkstringBlockchain network

Webhooks

Receive real-time notifications for liquidation events.

liquidation.deposit_received

Sent when crypto is received at the liquidation address.

{
  "event": "liquidation.deposit_received",
  "data": {
    "liquidation_id": "liq_550e8400-e29b-41d4-a716-446655440050",
    "virtual_account_id": "550e8400-e29b-41d4-a716-446655440001",
    "deposit_id": "ldep_550e8400-e29b-41d4-a716-446655440070",
    "network": "solana",
    "token": "USDC",
    "amount": "1000.00",
    "tx_hash": "5KYmFMZ3qvX7h8sN...",
    "sender_address": "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",
    "usd_amount": "1000.00",
    "created_at": "2024-01-15T14:30:00Z"
  }
}

liquidation.payout_processing

Sent when the USD payout is being processed.

{
  "event": "liquidation.payout_processing",
  "data": {
    "liquidation_id": "liq_550e8400-e29b-41d4-a716-446655440050",
    "virtual_account_id": "550e8400-e29b-41d4-a716-446655440001",
    "deposit_id": "ldep_550e8400-e29b-41d4-a716-446655440070",
    "payout_id": "lpo_550e8400-e29b-41d4-a716-446655440080",
    "recipient_id": "rec_550e8400-e29b-41d4-a716-446655440060",
    "amount": "1000.00",
    "fees": {
      "total_fees": 15
    },
    "recipient_amount": "985.00",
    "status": "processing",
    "created_at": "2024-01-15T14:31:00Z"
  }
}

liquidation.payout_completed

Sent when USD has been successfully sent to the recipient.

{
  "event": "liquidation.payout_completed",
  "data": {
    "liquidation_id": "liq_550e8400-e29b-41d4-a716-446655440050",
    "virtual_account_id": "550e8400-e29b-41d4-a716-446655440001",
    "deposit_id": "ldep_550e8400-e29b-41d4-a716-446655440070",
    "payout_id": "lpo_550e8400-e29b-41d4-a716-446655440080",
    "recipient_id": "rec_550e8400-e29b-41d4-a716-446655440060",
    "amount": "1000.00",
    "fees": {
      "total_fees": 15
    },
    "recipient_amount": "985.00",
    "status": "completed",
    "completed_at": "2024-01-17T10:15:00Z"
  }
}

liquidation.payout_failed

Sent when a USD payout fails.

{
  "event": "liquidation.payout_failed",
  "data": {
    "liquidation_id": "liq_550e8400-e29b-41d4-a716-446655440050",
    "virtual_account_id": "550e8400-e29b-41d4-a716-446655440001",
    "deposit_id": "ldep_550e8400-e29b-41d4-a716-446655440070",
    "payout_id": "lpo_550e8400-e29b-41d4-a716-446655440080",
    "amount": "1000.00",
    "reason": "recipient_bank_rejected",
    "message": "Recipient bank rejected the transfer",
    "created_at": "2024-01-15T14:35:00Z"
  }
}

Complete Integration Flow

Step-by-Step Implementation

sequenceDiagram
    participant Your App
    participant Kira API
    participant Blockchain
    participant Your User

    Note over Your App,Your User: Setup Phase

    Your App->>Kira API: POST /v1/virtual-accounts (US_BANK)
    Kira API-->>Your App: Virtual Account created

    Your App->>Kira API: POST /v1/virtual-accounts/{id}/liquidation-address
    Kira API-->>Your App: Liquidation Address + Crypto Wallet

    Your App->>Your User: Display crypto wallet address

    Note over Your App,Your User: Operation Phase

    Your User->>Blockchain: Send USDC/USDT to wallet
    Blockchain->>Kira API: Crypto received
    Kira API->>Your App: Webhook: liquidation.deposit_received

    Note over Kira API: Convert & Send USD

    Kira API->>Your App: Webhook: liquidation.payout_processing
    Kira API->>Your App: Webhook: liquidation.payout_completed

    Your App->>Your User: Notify: USD sent to bank

Code Example

// 1. Create virtual account
const virtualAccount = await fetch(
  'https://api.balampay.com/v1/virtual-accounts',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'x-api-key': apiKey,
      'Content-Type': 'application/json',
      'idempotency-key': crypto.randomUUID()
    },
    body: JSON.stringify({
      user_id: userId,
      type: 'US_BANK',
      bank: 'portage'
    })
  }
).then(r => r.json());

// 2. Wait for virtual account to be active...

// 3. Create liquidation address
const liquidationAddress = await fetch(
  `https://api.balampay.com/v1/virtual-accounts/${virtualAccount.id}/liquidation-address`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'x-api-key': apiKey,
      'Content-Type': 'application/json',
      'idempotency-key': crypto.randomUUID()
    },
    body: JSON.stringify({
      network: 'solana',
      token: 'USDC',
      recipient: {
        type: 'individual',
        first_name: 'Juan',
        last_name: 'Perez',
        email: '[email protected]',
        account: {
          account_type: 'ACH',
          routing_number: '021000021',
          account_number: '123456789',
          type: 'checking',
          bank_name: 'Chase Bank',
          bank_address: '123 Main St, New York, NY 10001'
        }
      }
    })
  }
).then(r => r.json());

// 4. Display wallet address to user
console.log(`Send USDC to: ${liquidationAddress.address}`);
console.log(`Network: ${liquidationAddress.network}`);

// 5. Handle webhooks
app.post('/webhooks/kira', (req, res) => {
  const event = req.body;

  switch (event.event) {
    case 'liquidation.deposit_received':
      console.log(`Received ${event.data.amount} ${event.data.token}`);
      console.log(`TX: ${event.data.tx_hash}`);
      // Notify user that crypto was received
      break;

    case 'liquidation.payout_processing':
      console.log(`Processing USD payout: ${event.data.recipient_amount}`);
      break;

    case 'liquidation.payout_completed':
      console.log(`USD sent to recipient: ${event.data.recipient_amount}`);
      // Notify user that USD was sent
      break;

    case 'liquidation.payout_failed':
      console.log(`Payout failed: ${event.data.reason}`);
      // Handle failure, contact support
      break;
  }

  res.status(200).send('OK');
});

Error Responses

Virtual Account Not Found

Status: 404 Not Found

{
  "code": "not_found",
  "message": "Virtual account not found: 550e8400-e29b-41d4-a716-446655440001"
}

Virtual Account Not US_BANK

Status: 400 Bad Request

{
  "code": "validation_error",
  "message": "Liquidation address is only supported for US_BANK virtual accounts"
}

Virtual Account Not Active

Status: 400 Bad Request

{
  "code": "validation_error",
  "message": "Virtual account must be active to create liquidation address"
}

Bank Account Already Has Liquidation Address

Status: 409 Conflict

{
  "code": "conflict",
  "message": "A liquidation address with this bank account already exists for this virtual account"
}

Invalid Network/Token Combination

Status: 400 Bad Request

{
  "code": "validation_error",
  "message": "Invalid network/token combination. USDT is not supported on Solana"
}

Liquidation Address Not Found

Status: 404 Not Found

{
  "code": "not_found",
  "message": "Liquidation address not found for this virtual account"
}

Fees

Fees are deducted from each liquidation payout:

Crypto Received:         1,000.00 USDC
USD Conversion:          $1,000.00 USD

Fees:
  Platform Fee:          $10.00
  Transfer Fee (ACH):    $5.00
─────────────────────────────────────
Total Fees:              $15.00
Recipient Receives:      $985.00 USD

Note: Fee structure varies by transfer type (ACH/WIRE/SWIFT) and client configuration.


Best Practices

  1. Verify virtual account is active - Wait for virtual_account.created webhook before creating liquidation address
  2. Store the wallet address - Save address to display to users for deposits
  3. Display network clearly - Show users which network to use (wrong network = lost funds)
  4. Handle webhooks idempotently - Process each event only once using deposit_id
  5. Monitor for failures - Set up alerts for liquidation.payout_failed events
  6. Validate recipient details - Ensure bank account information is accurate before creation

Network-Specific Wallet Addresses

NetworkAddress FormatExample
SolanaBase58, 32-44 chars7tQJvFk8XZoaVRjLGcBdqN3hJq8VqBvGpPQy8R9xYwZ1
Polygon0x + 40 hex chars0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1
TronT + 33 Base58 charsTJYeasupSvU7VwSS8rUVDxKwsrmhnzKPJd

Support