Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Execute a transaction

Executing a quotation creates the payout transaction. Cashela reserves the quoted amount in your wallet and starts the delivery through the payer you choose.

Endpoint

POST/api/v1/pay-out/transactions/{reference}

{reference} is the quotation reference returned by Create a quotation (your external_identifier). The quotation must be in status ONHOLD and not expired.

Authentication: HTTP Basic with your API key and secret. See Authentication.

Body

FieldTypeRequiredDescription
external_identifierstringYesMust be the same external_identifier as the quotation. Up to 255 characters.
pay_out_payer_idintegerYes, unless you send payer_idPayer that delivers the money. Use an id from the quotation’s payers_available.
payer_idintegerAlternative to pay_out_payer_idSame meaning. Send one of the two.
beneficiaryobjectYes, for a personThe person who receives the money. See below.
receiving_businessobjectYes, for a businessUse instead of beneficiary when the receiver is a business.
credit_party_identifierobjectDepends on the payerAccount details where the money is credited (for example an account number).
senderobjectNoThe person who sends the money.
sending_businessobjectNoUse instead of sender when the sender is a business.
purpose_of_remittancestringNoPurpose of the payout, up to 255 characters.
required_documentsarrayNoDocuments the payer requires, if any.
callback_urlstringNoHTTPS URL where Cashela sends status notifications. Up to 255 characters. It must be a public https:// address.

Beneficiary and account details

Cashela reads these fields from beneficiary:

FieldDescription
first_nameFirst name.
last_nameLast name.
msisdnPhone number. phone is accepted as an alias; if you send both they must be the same number.
emailEmail address.
country_idCashela country ID (the id from Payout countries). It must be the destination country of the quotation.
registration_number, tax_idIdentification numbers, when the corridor requires them.

For receiving_business, send registered_name (the legal name) instead of first_name and last_name, plus the same contact and identification fields.

The fields required in credit_party_identifier and the extra beneficiary fields depend on the payer and the country. They are not returned by the API yet: ask Cashela for the field list of each corridor you will use.

Example

Terminal window
curl -X POST "https://sandbox-api.cashela.com/api/v1/pay-out/transactions/payout-2026-000123" \
-u "$CASHELA_API_KEY:$CASHELA_API_SECRET" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"external_identifier": "payout-2026-000123",
"pay_out_payer_id": 123,
"callback_url": "https://example.com/webhooks/cashela-payout",
"purpose_of_remittance": "family_support",
"sender": { "first_name": "Jane", "last_name": "Example" },
"beneficiary": {
"first_name": "Ana",
"last_name": "Ejemplo",
"msisdn": "+573001234567",
"email": "ana@example.com",
"country_id": 48
},
"credit_party_identifier": {}
}'

Fill credit_party_identifier with the account fields of the corridor.

{
"success": true,
"data": {
"id": "9f2c6a1e-0000-0000-0000-000000000000",
"reference": "payout-2026-000123",
"external_identifier": "payout-2026-000123",
"quotation_reference": "payout-2026-000123",
"status": "PROCESSING",
"transaction_status": "PENDING",
"transaction_message": "Partner PayOut transaction created and funds reserved.",
"idempotency": { "key": "payout-2026-000123", "external_identifier": "payout-2026-000123" },
"transaction_type": "C2C",
"funding": { "source": "main_u_wallet", "currency": "USD", "amount": 103.5 },
"source": { "amount": 100, "currency": "USD", "country_iso_code": "USA" },
"destination": { "amount": 395000, "currency": "COP", "country_iso_code": "COL" },
"fee": { "amount": 3.5, "currency": "USD" },
"rate": 3950,
"payer": { "type": "pay_out_payer", "id": 123, "name": "Example Bank", "currency": "COP", "country": "COL", "service": { "id": 2, "name": "Bank deposit" } },
"callback": { "url": "https://example.com/webhooks/cashela-payout", "last_response": null },
"purpose_of_remittance": "family_support",
"created_at": "2026-10-19T12:05:00+00:00",
"updated_at": "2026-10-19T12:05:00+00:00"
},
"message": "Payout transaction processed successfully."
}

Values are illustrative. The response can include other fields; do not build on fields that are not listed below.

Response fields

FieldDescription
idCashela transaction ID.
referenceTransaction reference. It is the same as the quotation reference.
external_identifierYour ID.
quotation_referenceReference of the quotation executed.
statusTransaction status. See Statuses.
transaction_status, transaction_messageDelivery status and a readable message. When status is FAILED, transaction_message says why.
idempotencyIdempotency key and external_identifier stored with the transaction.
transaction_typeC2C, C2B, B2C or B2B.
fundingWhat was taken from your wallet: currency, amount and payment_status. source is always main_u_wallet (your main wallet).
source, destinationAmounts, currencies and countries.
feeFee and its currency.
rateExchange rate applied.
payerPayer that delivers the money.
callbackYour callback_url and the result of the last notification sent to it.
purpose_of_remittancePurpose you sent.
created_at, updated_atISO 8601 timestamps.

Statuses

statusMeaning
PROCESSINGFunds reserved in your wallet and delivery started.
COMPLETEDThe payout was delivered. The reserved funds are settled.
FAILEDThe payout failed. If funds were reserved, they are released back to your available balance.

Idempotency

A quotation can be executed only once. Sending the same body again returns the existing transaction. Sending a different body for a quotation that was already executed returns 409 A transaction already exists for this quotation with a different execution payload.

Errors

StatusMessageWhat to do
422Validation failed. with errorsFix the fields listed in errors (for example a callback_url that is not public HTTPS).
404Quotation not found.Check the {reference} in the path.
422Quotation has expired.Create a new quotation with a new external_identifier.
422Quotation is not pending execution.The quotation is no longer ONHOLD.
422external_identifier does not match the quotation.Send the quotation’s external_identifier.
422The selected payer is not available for this quotation.Use a payer from payers_available.
404Payer not found.Check pay_out_payer_id.
503PARTNER_PAYOUT_DISBURSEMENT_UNAVAILABLE: Sending payouts is not enabled for this environment yet. Execution refused; no funds were reserved.Pay-Out is not active for your account yet. Nothing was reserved and the quotation is still valid until it expires: retry the same call once Cashela confirms activation.
404Wallet not found for quotation pay currency.You have no active wallet in the source currency.
409A transaction already exists for this quotation ...See Idempotency.

Get a transaction

GET/api/v1/pay-out/transactions/{reference}

Returns the same object as the execute call. {reference} is the transaction reference (your external_identifier). An unknown reference returns 404 Transaction not found for this partner.

Terminal window
curl "https://sandbox-api.cashela.com/api/v1/pay-out/transactions/payout-2026-000123" \
-u "$CASHELA_API_KEY:$CASHELA_API_SECRET" \
-H "Accept: application/json"

Use it to confirm the final status, especially if a notification did not reach you.

Notifications

If you sent a callback_url, Cashela sends a POST to it:

  • right after the execution, with the resulting status, and
  • when the transaction reaches COMPLETED or FAILED.

Each notification carries these headers:

HeaderDescription
X-Cashela-Eventpartner.payout.transaction.updated
X-Cashela-TimestampUnix time (seconds) the signature was computed at.
X-Cashela-NonceUnique value per delivery (UUID).
X-Cashela-Trace-IdCorrelation ID. Quote it to support.
X-Cashela-SignatureHMAC-SHA256 of {timestamp}.{nonce}.{body} with the api_secret of the key that executed the transaction while it is active (or your account’s most recent active key if it was removed).

Verify the signature exactly as for Pay-In notifications: see Verify the signature.

Body:

{
"event": "partner.payout.transaction.updated",
"event_id": "3b6f0c1a-0000-0000-0000-000000000000",
"api_version": "v1",
"created_at": "2026-10-19T12:20:00+00:00",
"data": {
"reference": "payout-2026-000123",
"external_identifier": "payout-2026-000123",
"quotation_reference": "payout-2026-000123",
"status": "COMPLETED",
"transaction_status": "COMPLETED",
"transaction_message": "...",
"funding": { "source": "main_u_wallet", "currency": "USD", "amount": 103.5 },
"source": { "amount": 100, "currency": "USD", "country_iso_code": "USA" },
"destination": { "amount": 395000, "currency": "COP", "country_iso_code": "COL" },
"fee": { "amount": 3.5, "currency": "USD" },
"rate": 3950,
"payer": { "pay_out_payer_id": 123 }
},
"context": { "trace_id": "6f1d2c4e-8b0a-4a57-9c1e-2f3a4b5c6d7e" }
}

Values are illustrative and some fields are omitted. Answer with a 2xx status. Make your handler idempotent: the same transaction can be notified more than once. Treat Get a transaction as the source of truth.

Re-send the notification

POST/api/v1/pay-out/transactions/{reference}/callback

Sends the notification for the current status of the transaction again to its callback_url. No body is needed. This endpoint is limited to 6 requests per minute.

The response contains the transaction (same object as above) and a callback object:

FieldDescription
statusdispatched, failed or skipped.
successtrue if your endpoint answered 2xx.
http_statusStatus your endpoint answered.
reasonWhen skipped: callback_url_not_configured (no HTTPS callback_url) or callback_url_blocked (the URL is not a public address).