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
- Sender deposits crypto - USDC or USDT is sent to the liquidation address (blockchain wallet)
- Automatic conversion - Crypto is converted to USD at current market rate
- USD payout - Funds are sent from the linked virtual account to the configured recipient
- Webhook notifications - You're notified at each step of the process
Prerequisites
Before creating a liquidation address:
| Requirement | Description |
|---|---|
| Virtual Account | Must have an active US_BANK virtual account |
| Account Status | Virtual account must be active |
| User Verification | User must be verified (KYC/KYB completed) |
| Recipient | Bank 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
| Token | Networks |
|---|---|
| USDC | Solana, Polygon |
| USDT | Polygon, Tron |
Outgoing USD
| Transfer Type | Description | Speed |
|---|---|---|
| ACH | US domestic, lower fees | 1-3 business days |
| WIRE | US domestic, faster | Same day - 1 business day |
| SWIFT | International | 3-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
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token from authentication |
x-api-key | Yes | Your API key |
Content-Type | Yes | Must be application/json |
idempotency-key | Yes | Unique identifier to prevent duplicate creation |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Virtual 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
| Field | Type | Required | Description |
|---|---|---|---|
network | string | Yes | Blockchain network: solana, polygon, or tron |
token | string | Yes | Stablecoin: USDC or USDT |
recipient | object | Yes | USD recipient configuration |
Recipient Fields
| Field | Type | Required | Description |
|---|---|---|---|
recipient.type | string | Yes | individual or business |
recipient.first_name | string | Yes* | First name (required for individual) |
recipient.last_name | string | Yes* | Last name (required for individual) |
recipient.company_name | string | Yes* | Company name (required for business) |
recipient.email | string | Yes | Email address |
recipient.account | object | Yes | Bank account details |
ACH Account Fields
| Field | Type | Required | Description |
|---|---|---|---|
account.account_type | string | Yes | ACH |
account.routing_number | string | Yes | 9-digit ABA routing number |
account.account_number | string | Yes | Bank account number |
account.type | string | Yes | checking or savings |
account.bank_name | string | Yes | Bank name |
account.bank_address | string | Yes | Bank address |
WIRE Account Fields
| Field | Type | Required | Description |
|---|---|---|---|
account.account_type | string | Yes | WIRE |
account.routing_number | string | Yes | 9-digit ABA routing number |
account.account_number | string | Yes | Bank account number |
account.type | string | Yes | checking or savings |
account.bank_name | string | Yes | Bank name |
account.bank_address | string | Yes | Bank address |
account.swift_code | string | No | SWIFT/BIC code (optional) |
SWIFT Account Fields
| Field | Type | Required | Description |
|---|---|---|---|
account.account_type | string | Yes | SWIFT |
account.swift_code | string | Yes | SWIFT/BIC code (8 or 11 characters) |
account.account_number | string | Yes | Account number or IBAN |
account.bank_name | string | Yes | Bank name |
account.bank_address | string | Yes | Bank address |
account.country | string | Yes | Recipient 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
| Field | Type | Description |
|---|---|---|
id | string | Liquidation address ID |
virtual_account_id | string | Linked virtual account ID |
status | string | Status: active, inactive |
network | string | Blockchain network |
token | string | Accepted stablecoin |
address | string | Blockchain wallet address to receive crypto |
recipient | object | Configured USD recipient (masked) |
recipient.id | string | Recipient ID |
recipient.type | string | individual or business |
recipient.name | string | Recipient name |
recipient.account_type | string | ACH, WIRE, or SWIFT |
recipient.bank_name | string | Bank name |
recipient.account_number_last4 | string | Last 4 digits of account |
created_at | string | ISO 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
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token from authentication |
x-api-key | Yes | Your API key |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Virtual 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
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Virtual account ID |
addressId | string | Yes | Liquidation 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
| Field | Type | Description |
|---|---|---|
wallet | object | Crypto wallet details |
wallet.id | string | Wallet ID |
wallet.address | string | Blockchain wallet address |
wallet.network | string | Blockchain 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
- Verify virtual account is active - Wait for
virtual_account.createdwebhook before creating liquidation address - Store the wallet address - Save
addressto display to users for deposits - Display network clearly - Show users which network to use (wrong network = lost funds)
- Handle webhooks idempotently - Process each event only once using
deposit_id - Monitor for failures - Set up alerts for
liquidation.payout_failedevents - Validate recipient details - Ensure bank account information is accurate before creation
Network-Specific Wallet Addresses
| Network | Address Format | Example |
|---|---|---|
| Solana | Base58, 32-44 chars | 7tQJvFk8XZoaVRjLGcBdqN3hJq8VqBvGpPQy8R9xYwZ1 |
| Polygon | 0x + 40 hex chars | 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1 |
| Tron | T + 33 Base58 chars | TJYeasupSvU7VwSS8rUVDxKwsrmhnzKPJd |
Support
- Email: [email protected]
- Virtual Accounts Guide: virtual-accounts.md
- Payouts Guide: payouts.md
- Webhooks Guide: webhooks.md
Updated about 14 hours ago
