Decaf
Contents

API reference/Claim links: pay a phone number or email

Claim links: pay a phone number or email

Send to someone with no bank account, no wallet and no Decaf account. Funds are held until the recipient opens the link, verifies their number and chooses how to receive from the methods that work in their country. The payout moves from awaiting_claim to claimed to succeeded; unclaimed links return to your balance. The receivability check tells you before sending whether a person in that country can be paid.

Create a payout

POST/payouts

One transfer to one recipient on one channel. Pass a saved recipient_id or an inline recipient. Either source_amount or destination_amount. quote_id is optional; without it the payout is priced at execution.

Parameters

  • Idempotency-Keyheaderstringoptional
FieldTyperequiredNotes
recipient_idstringoptional
recipientInlineRecipientoptional
channelstringrequired
quote_idstringoptional
source_amountAmountoptionalDecimal string. Up to two decimals for fiat, six for USDC.
destination_amountAmountoptionalDecimal string. Up to two decimals for fiat, six for USDC.
referencestringoptional
memostringoptionalTravels with the payment where the rail supports it.
messagestringoptionalClaim links only. Shown to the recipient.

Request

{
  "recipient_id": "rcp_9d1a",
  "channel": "spei_mxn",
  "quote_id": "qt_5m2n",
  "source_amount": "1000.00",
  "reference": "INV-2026-0912",
  "memo": "Freight, week 37"
}

Response 201

{
  "id": "po_1b7e",
  "status": "submitted",
  "channel": "spei_mxn",
  "recipient_id": "rcp_9d1a",
  "source_amount": "1000.00",
  "source_currency": "USDC",
  "destination_amount": "16865.35",
  "destination_currency": "MXN",
  "rate": "16.86535",
  "fees": {
    "provider": "0.50",
    "decaf": "5.00",
    "total": "5.50",
    "currency": "USDC"
  },
  "reference": "INV-2026-0912",
  "estimated_arrival": "2026-09-16T15:20:00Z",
  "provider_reference": null,
  "attempts": 1,
  "created_at": "2026-09-16T15:01:12Z"
}

Errors: 400 validation_error, channel_unavailable, amount_out_of_range; 402 insufficient_balance; 409 idempotency_conflict; 410 quote_expired

Examples: Create a payout

curl -X POST https://sandbox.api.decaf.so/v1/payouts \
  -H "Authorization: Bearer $DECAF_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"recipient_id":"rcp_9d1a","channel":"spei_mxn","quote_id":"qt_5m2n","source_amount":"1000.00","reference":"INV-2026-0912","memo":"Freight, week 37"}'

Check whether a phone or email can receive

GET/recipients/check

Says before sending whether a person in that country can receive, and by which methods.

Parameters

  • typequeryenum: phone, emailrequired
  • numberquerystringoptional
  • addressquerystringoptional

Response 200

{
  "receivable": true,
  "country": "MX",
  "methods": [
    "spei_bank",
    "decaf_wallet"
  ],
  "kyc_required_for": [
    "spei_bank"
  ]
}

Get access

Build against the sandbox this week.

Tell us the corridors you need and the recipients you pay. Sandbox keys are issued by a person.