Create a payout
Send money from your Meridian balance to a recipient’s wallet or bank account in another country. Meridian converts the currency, routes the payment and notifies you when it settles.
Writing sample. I wrote this for my portfolio. “Meridian” is a fictional payments company, and nothing here comes from any employer’s documentation.
POST /v1/payouts
Before you begin
- You need an access token with the
payouts:writescope. See Authentication. - You need a quote ID for the amount and currency pair. Quotes lock an exchange rate for 60 seconds.
- Your account must have enough available balance in the source currency.
Authentication
Meridian uses the OAuth 2.0 client credentials flow. Send your access token in the Authorization header:
Authorization: Bearer <ACCESS_TOKEN>
Access tokens expire after one hour. Request a new one when you receive a 401 token_expired error.
Headers
| Header | Required | Description |
|---|---|---|
Authorization |
Yes | Bearer followed by your access token. |
Idempotency-Key |
Yes | A unique value, such as a UUID, that identifies this request. If you retry with the same key within 24 hours, Meridian returns the original payout instead of creating a second one. |
Content-Type |
Yes | Must be application/json. |
Always send an idempotency key. Network timeouts happen. Without a key, retrying a request that actually succeeded sends the money twice.
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
quote_id |
string | Yes | The ID of an unexpired quote, for example qt_8Hk2nQ. The quote sets the amounts and exchange rate. |
recipient_id |
string | Yes | The ID of a verified recipient, for example rcp_41Mzx9. |
purpose |
string (enum) | Yes | Why the money is being sent. One of family_support, salary, goods, services. Some corridors require this for compliance. |
reference |
string | No | Up to 35 characters that the recipient sees on their statement. Defaults to your business name. |
metadata |
object | No | Up to 20 key-value pairs for your own use. Meridian stores them but doesn’t act on them. |
Example request
curl https://api.meridian.example/v1/payouts \
-X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Idempotency-Key: 5f0c8a2e-3b7d-4c11-9e2a-6d1f0b7c9a44" \
-H "Content-Type: application/json" \
-d '{
"quote_id": "qt_8Hk2nQ",
"recipient_id": "rcp_41Mzx9",
"purpose": "family_support",
"reference": "September rent"
}'
Example response
Meridian returns 201 Created with the payout object. New payouts start in pending status.
{
"id": "po_7Qe93LmA",
"object": "payout",
"status": "pending",
"source": { "amount": 50000, "currency": "USD" },
"destination": { "amount": 4175000, "currency": "INR" },
"exchange_rate": "83.50",
"fee": { "amount": 199, "currency": "USD" },
"recipient_id": "rcp_41Mzx9",
"purpose": "family_support",
"reference": "September rent",
"created_at": "2026-09-28T10:15:02Z",
"estimated_arrival": "2026-09-28T10:45:00Z"
}
Amounts are integers in the currency’s smallest unit. 50000 USD is $500.00, and 4175000 INR is ₹41,750.00.
Payout statuses
A payout moves through these statuses. Subscribe to the payout.updated webhook instead of polling.
| Status | Meaning | Final? |
|---|---|---|
pending |
Meridian accepted the payout and is running compliance checks. | No |
processing |
The payout is on its way to the recipient’s provider. | No |
completed |
The recipient’s provider confirmed the funds arrived. | Yes |
failed |
The payout couldn’t be delivered. Check failure_code. Meridian returns the funds to your balance. |
Yes |
canceled |
You canceled the payout while it was pending. |
Yes |
Errors
| HTTP status | Error code | What happened | What to do |
|---|---|---|---|
| 400 | quote_expired |
The quote is older than 60 seconds. | Create a new quote and retry with a new idempotency key. |
| 400 | purpose_required |
The destination corridor requires a purpose. |
Add purpose to the request. |
| 401 | token_expired |
Your access token is more than one hour old. | Request a new token and retry. |
| 402 | insufficient_balance |
Your available balance is lower than the source amount plus fees. | Top up your balance, or send a smaller amount. |
| 404 | recipient_not_found |
No verified recipient has this ID. | Check the ID, or create the recipient first. |
| 409 | idempotency_conflict |
You reused an idempotency key with a different request body. | Use a new key for each distinct payout. |
Related
- Integration quickstart: send your first payout
- Retrieve a payout: GET
/v1/payouts/{id} - Cancel a payout: POST
/v1/payouts/{id}/cancel
Why I wrote it this way
- The summary says what happens in the real world (money moves, currency converts), not just “creates a payout object”.
- Prerequisites come first, so developers don’t discover halfway through that they need a quote.
- The idempotency warning explains the consequence (“sends the money twice”), because a consequence changes behaviour and a rule alone doesn’t.
- Every error has a “what to do”. An error table without fixes is just a list of ways to fail.
Thanks! Every doc I ship gets better with feedback, including this one.