Initiate Fiat Payout

Send fiat currency from your wallet to an external bank account.

POST /v1/payouts/fiat

Headers

Header Required Description
X-Api-Key Yes Your API key
X-Idempotency-Key Yes Unique key to prevent duplicate payouts
Content-Type Yes application/json

Request Body

Common Fields

Field Type Required Description
amount number Yes Amount to send. Must meet the per-currency minimum (see below).
currency string Yes Fiat currency: USD, EUR, or GBP
countryCode string Yes Destination country (ISO 3166-1 alpha-2, e.g. US, GB)
bankName string Yes Name of the destination bank
accountNumber string Yes Bank account IBAN or local account number (e.g. UK 8-digit number)
bankCode string Yes Bank identifier. Interpreted by destination: ACH routing number for USDUS, UK sort code for GBPGB, SWIFT/BIC otherwise.
beneficiaryType string Yes BUSINESS or INDIVIDUAL
streetAddress string Yes Beneficiary street address
city string Yes Beneficiary city
postalCode string Yes Beneficiary postal code
reference string No Payment reference (max 30 chars, alphanumeric with spaces, commas, periods, and hyphens)
paymentPurpose string No Purpose of payment
paymentPurposeAttachmentId string No Id of a file previously uploaded via POST /v1/files. Use the data.id returned by that endpoint verbatim (e.g. file_3f1e0a7c-5b2d-4f9c-8a31-90c8b1f4e2a7). The file must belong to your account.
beneficiaryRelationship string Conditional Relationship to the beneficiary. Required when currency is USD. One of: EMPLOYEE, CONTRACTOR, VENDOR, SUBSIDIARY, MERCHANT, CUSTOMER, LANDLORD, FAMILY, OTHER.

Individual Beneficiary Fields

Required when beneficiaryType is INDIVIDUAL:

Field Type Required Description
firstName string Conditional Beneficiary first name
lastName string Conditional Beneficiary last name

Business Beneficiary Fields

Required when beneficiaryType is BUSINESS:

Field Type Required Description
businessName string Conditional Business legal name

Minimum Amounts

Currency Minimum
USD 100
GBP 30
EUR 30

Requests below the minimum for the selected currency are rejected with 400 Bad Request and a message of the form Minimum payout amount for <CURRENCY> is <amount>.

Routing by Destination

The API automatically routes the payout based on the currency and destination country:

Currency Destination Method bankCode used as accountNumber used as
USD US ACH Routing number Account number
USD Non-US SWIFT SWIFT/BIC code IBAN
EUR Any SEPA/SWIFT SWIFT/BIC code IBAN
GBP GB FPS UK sort code UK 8-digit account number
GBP Non-GB SWIFT SWIFT/BIC code IBAN

Bank Detail Validation

Before the payout is submitted, the bank details are verified. If the details fail validation, the request is rejected with 400 Bad Request before any funds move:

{
  "status": false,
  "message": "Invalid bank details.",
  "errors": ["Invalid IBAN checksum", "BIC not recognised"]
}

Example Request (Individual, USD to US)

curl -X POST "https://api.esca.finance/v1/payouts/fiat" \
  -H "X-Api-Key: your_api_key_here" \
  -H "X-Idempotency-Key: payout-660e8400-e29b-41d4-a716-446655440001" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 500,
    "currency": "USD",
    "countryCode": "US",
    "bankName": "Chase Bank",
    "accountNumber": "0123456789",
    "bankCode": "021000021",
    "beneficiaryType": "INDIVIDUAL",
    "firstName": "John",
    "lastName": "Doe",
    "streetAddress": "123 Main St",
    "city": "New York",
    "postalCode": "10001",
    "reference": "INV-2026-001",
    "paymentPurpose": "Supplier payment",
    "beneficiaryRelationship": "VENDOR"
  }'

Attaching a Payment Purpose Document

To accompany a payout with supporting documentation (e.g. an invoice or contract), upload the file first via POST /v1/files, then reference the returned id on the payout:

# 1. Upload the file
curl -X POST "https://api.esca.finance/v1/files" \
  -H "X-Api-Key: your_api_key_here" \
  -F "file=@invoice.pdf"
# → { "data": { "id": "file_3f1e0a7c-5b2d-4f9c-8a31-90c8b1f4e2a7" } }

# 2. Initiate the payout, referencing the file
curl -X POST "https://api.esca.finance/v1/payouts/fiat" \
  -H "X-Api-Key: your_api_key_here" \
  -H "X-Idempotency-Key: payout-880e8400-e29b-41d4-a716-446655440003" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 500,
    "currency": "USD",
    "countryCode": "US",
    "bankName": "Chase Bank",
    "accountNumber": "0123456789",
    "bankCode": "021000021",
    "beneficiaryType": "BUSINESS",
    "businessName": "Acme Corp",
    "streetAddress": "123 Main St",
    "city": "New York",
    "postalCode": "10001",
    "paymentPurpose": "Supplier payment for invoice 2026-001",
    "paymentPurposeAttachmentId": "file_3f1e0a7c-5b2d-4f9c-8a31-90c8b1f4e2a7",
    "beneficiaryRelationship": "VENDOR"
  }'

The id may only be referenced by the same account that uploaded the file — using a file id that belongs to a different account returns 400 Bad Request.

Example Request (Business, GBP to UK)

curl -X POST "https://api.esca.finance/v1/payouts/fiat" \
  -H "X-Api-Key: your_api_key_here" \
  -H "X-Idempotency-Key: payout-770e8400-e29b-41d4-a716-446655440002" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1000,
    "currency": "GBP",
    "countryCode": "GB",
    "bankName": "Barclays",
    "accountNumber": "20015555",
    "bankCode": "200000",
    "beneficiaryType": "BUSINESS",
    "businessName": "Acme Corp",
    "streetAddress": "456 High St",
    "city": "London",
    "postalCode": "EC1A 1BB"
  }'

Example Response

{
  "status": true,
  "message": "Payout initiated successfully",
  "data": {
    "payoutId": "f7a8b9c0-d1e2-3456-abcd-ef7890123456",
    "type": "fiat",
    "currency": "USD",
    "amount": 500,
    "fee": 5.00,
    "status": "PROCESSING",
    "bankName": "Chase Bank",
    "bankAccountNumber": "0123456789",
    "firstName": "John",
    "lastName": "Doe"
  }
}

For business beneficiaries, the response includes businessName instead of firstName/lastName.

Error Responses

Status Description
400 Invalid request, unsupported country, or bank details that fail upstream validation (response includes an errors array — see Bank Detail Validation)
401 Invalid or expired API key
409 Duplicate request (idempotency conflict)
429 Rate limit exceeded
500 Payout failed