Create Quotation
Create Quotation
Before initiating a payout transaction, create a quotation to lock in the exchange rate and view the total cost including fees. Quotations are valid for up to 60 minutes, giving your users time to review and confirm the transaction details.
Overview
The quotation endpoint:
- Calculates the exact amount the recipient will receive
- Locks the FX rate for up to 60 minutes
- Shows all applicable fees transparently
- Returns available payer networks for the destination
Important: A valid quotation ID is required when creating a payout transaction. The locked rate from the quotation will be applied to the actual transfer.
Endpoint
POST /api/v1/pay-out/create-quotationAuthentication: Basic Auth (Business Key + Business Secret)
Base URLs:
- Sandbox:
https://sandbox-api.cashela.com - Production:
https://api.cashela.com
Required Headers
Authorization: Basic <base64_encoded_credentials>Content-Type: application/jsonAccept: application/jsonIdempotency-Key: <uuid-v4>Request Parameters
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
external_identifier | string | Yes | Your unique reference for this quotation. Used for idempotency and reconciliation. Max 255 characters. |
mode | string | Yes | Calculation mode: SOURCE_AMOUNT (you specify how much to send) or DESTINATION_AMOUNT (you specify how much recipient gets). |
transaction_type | string | Yes | Transaction type: C2C (Customer to Customer), B2C (Business to Customer), B2B (Business to Business). |
service_id | integer | Yes | Payout service identifier. See Get Services for available services. |
source | object | Yes | Source details: currency, country, and amount. |
source.currency | string | Yes | ISO 3-letter currency code (e.g., USD, EUR). |
source.country_iso_code | string | Yes | ISO 3-letter country code of source (e.g., USA). |
source.amount | number | Conditional | Amount to send. Required when mode is SOURCE_AMOUNT. |
destination | object | Yes | Destination details: currency, country, and amount. |
destination.currency | string | Yes | ISO 3-letter currency code (e.g., MXN, BRL). |
destination.country_iso_code | string | Yes | ISO 3-letter country code of destination (e.g., MEX, BRA). |
destination.amount | number | Conditional | Amount recipient will receive. Required when mode is DESTINATION_AMOUNT. |
Calculation Modes
SOURCE_AMOUNT: Specify how much you want to send, and the API calculates how much the recipient will receive after fees and FX conversion.
DESTINATION_AMOUNT: Specify how much the recipient should receive, and the API calculates how much you need to send including fees.
Example Requests
Send a Fixed Source Amount (SOURCE_AMOUNT)
Use this when the sender wants to pay exactly $1,000 USD:
curl -X POST "https://api.cashela.com/api/v1/pay-out/create-quotation" \ -H "Authorization: Basic $(echo -n 'your_business_key:your_business_secret' | base64)" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "Idempotency-Key: a1b2c3d4-e5f6-7890-abcd-ef1234567890" \ -d '{ "external_identifier": "PAYOUT-2025-00123", "mode": "SOURCE_AMOUNT", "transaction_type": "C2C", "service_id": 2, "source": { "currency": "USD", "country_iso_code": "USA", "amount": 1000.00 }, "destination": { "currency": "BRL", "country_iso_code": "BRA", "amount": null } }'Deliver a Fixed Destination Amount (DESTINATION_AMOUNT)
Use this when the recipient needs exactly 5,000 BRL:
curl -X POST "https://api.cashela.com/api/v1/pay-out/create-quotation" \ -H "Authorization: Basic $(echo -n 'your_business_key:your_business_secret' | base64)" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "Idempotency-Key: b2c3d4e5-f6a7-8901-bcde-f23456789012" \ -d '{ "external_identifier": "PAYOUT-2025-00124", "mode": "DESTINATION_AMOUNT", "transaction_type": "C2C", "service_id": 2, "source": { "currency": "USD", "country_iso_code": "USA", "amount": null }, "destination": { "currency": "BRL", "country_iso_code": "BRA", "amount": 5000.00 } }'Response Format
Success Response (201 Created)
{ "success": true, "data": { "id": "qtn_01HJ3KBCD8E9F0G1H2I3J4K5L6", "reference": "CSH-QTN-20250202-00001234", "external_identifier": "PAYOUT-2025-00123", "mode": "SOURCE_AMOUNT", "transaction_type": "C2C", "source": { "amount": 1000.00, "currency": "USD", "country_iso_code": "USA" }, "destination": { "amount": 5416.96, "currency": "BRL", "country_iso_code": "BRA" }, "sent_amount": { "amount": 1000.00, "currency": "USD" }, "wholesale_fx_rate": 5.41696, "retail_fx_rate": 5.35, "fee": { "amount": 15.00, "currency": "USD", "breakdown": { "transfer_fee": 10.00, "fx_markup": 5.00 } }, "total_cost": { "amount": 1015.00, "currency": "USD" }, "creation_date": "2025-02-02T12:56:04.000Z", "expiration_date": "2025-02-02T13:56:04.000Z", "status": "ONHOLD", "payers_available": [ { "id": 45, "name": "BANCO SANTANDER BRASIL S.A", "code": "santander_br", "currency": "BRL", "country": "BRA", "service": { "id": 2, "name": "BankAccount" }, "estimated_delivery": "1-2 business days", "minimum_amount": 10.00, "maximum_amount": 50000.00 }, { "id": 46, "name": "BANCO DO BRASIL S.A", "code": "bb_br", "currency": "BRL", "country": "BRA", "service": { "id": 2, "name": "BankAccount" }, "estimated_delivery": "1-2 business days", "minimum_amount": 10.00, "maximum_amount": 50000.00 } ] }, "message": "Quotation created successfully"}Response Parameters
| Field | Type | Description |
|---|---|---|
id | string | Unique quotation ID. Use this when creating the payout transaction. |
reference | string | Cashela system reference for support and reconciliation. |
external_identifier | string | Your provided reference echoed back. |
mode | string | Calculation mode used (SOURCE_AMOUNT or DESTINATION_AMOUNT). |
transaction_type | string | Transaction type (C2C, B2C, B2B). |
source | object | Source amount, currency, and country. |
destination | object | Destination amount (calculated if SOURCE_AMOUNT mode), currency, and country. |
sent_amount | object | Total amount debited from your account (includes fees). |
wholesale_fx_rate | number | Wholesale/mid-market exchange rate. |
retail_fx_rate | number | Rate applied to this transaction (may include markup). |
fee | object | Fee amount and breakdown. |
fee.breakdown | object | Itemized fee components (transfer fee, FX markup, etc.). |
total_cost | object | Total amount including fees in source currency. |
creation_date | string | ISO 8601 timestamp when quotation was created. |
expiration_date | string | ISO 8601 timestamp when quotation expires. Rate is locked until this time. |
status | string | Quotation status: ONHOLD (active), USED (transaction created), EXPIRED. |
payers_available | array | List of available payout providers for this corridor. |
payers_available[].id | integer | Payer ID to use when creating transaction. |
payers_available[].name | string | Payer/bank display name. |
payers_available[].code | string | Unique payer code. |
payers_available[].estimated_delivery | string | Expected delivery time. |
payers_available[].minimum_amount | number | Minimum transfer amount. |
payers_available[].maximum_amount | number | Maximum transfer amount. |
Quotation Status Lifecycle
| Status | Description | Next Steps |
|---|---|---|
ONHOLD | Active quotation with locked rate | Create transaction before expiration |
USED | Transaction created using this quotation | Monitor transaction status |
EXPIRED | Rate lock expired | Create new quotation |
Rate Locking Rules
- Lock Duration: 60 minutes from creation
- Rate Guarantee: The locked rate is applied to your transaction if created before expiration
- One-Time Use: Each quotation can only be used for one transaction
- Balance Check: Quotation creation verifies you have sufficient balance
Best Practice: Display the
expiration_dateto users with a countdown timer. Prompt them to refresh the quotation if they take too long to confirm.
Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | INVALID_INPUT | Malformed request or invalid JSON |
| 401 | UNAUTHORIZED | Invalid API credentials |
| 403 | FORBIDDEN | IP not allowlisted |
| 403 | INSUFFICIENT_FUNDS | Account balance too low |
| 404 | SERVICE_NOT_FOUND | Invalid service_id |
| 404 | CORRIDOR_NOT_AVAILABLE | Source/destination corridor not supported |
| 422 | AMOUNT_BELOW_MINIMUM | Amount below minimum for this corridor |
| 422 | AMOUNT_ABOVE_MAXIMUM | Amount exceeds maximum for this corridor |
| 422 | CURRENCY_MISMATCH | Invalid currency for the specified country |
| 429 | RATE_LIMITED | Too many requests |
Best Practices
- Always display rates and fees to users before they confirm
- Show expiration countdown so users know how long the rate is valid
- Handle expired quotations gracefully by creating a new one
- Store the quotation ID to create the transaction later
- Check payers_available to show users which delivery methods are available
Next Steps
After creating a quotation, use the returned id to Create Transaction with the beneficiary details.
Related Documentation
- Get Services – Query available payout services
- Get Countries – View supported destinations
- Get Payers – Explore payer networks
- Create Transaction – Execute the payout
- FX & Rate Locking – Understanding rate behavior