---
title: "Payouts"
description: "5 operations, with parameters and examples."
url: https://docs.fluveo.com/api/payouts/
---

> Index of every page: https://docs.fluveo.com/llms.txt. Integrating Fluveo? Read https://docs.fluveo.com/agents/integrate.md first.

> Too long? This page with code in one language only: https://docs.fluveo.com/api/payouts.curl.md (cURL), https://docs.fluveo.com/api/payouts.node.md (Node.js), https://docs.fluveo.com/api/payouts.python.md (Python), https://docs.fluveo.com/api/payouts.php.md (PHP).

# Payouts

5 operations, with parameters and examples.

A Payout moves money from the store's available balance to its bank account. Fluveo checks how much the store may pay out before it sends a payout, and a payout moves to paid, failed or canceled only once its outcome is known.

Send every request to `https://api.fluveo.com/v1` with your secret key as a Bearer token. This page lists only what Fluveo serves; [the OpenAPI file](https://docs.fluveo.com/openapi.json) holds the same operations.

> **For AI agents:**
>
> Use plain HTTP; install no payments SDK. Send `Authorization: Bearer sk_test_...` and a fresh `Idempotency-Key` on every POST; reuse the same key only when you retry that same POST. Send only the documented parameters.

## Creates a payout

`POST /v1/payouts`

Permission: [`rak_payout_write`](https://docs.fluveo.com/permissions.md#payout).

**Headers**

- `Idempotency-Key` (string, optional): Send a unique key, 1 to 255 characters, on every POST. A retry with the same key and the same body returns the first answer instead of acting twice (with Idempotent-Replayed: true); the same key with another body is refused. Keys are kept 7 days, except on POST /v1/checkout/sessions, POST /v1/checkout/sessions/{session} and POST /v1/webhook_endpoints, where a key holds 24 hours; webhook endpoint keys are also capped at the newest 32 per store and mode. Do not rely on a replay after that window. GET and DELETE ignore it.
- `Fluveo-Version` (enum, optional): Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.

  One of: `2026-05-27.dahlia`.

**Body parameters**

- `amount` (integer, required): Amount in the currency's smallest unit (cents for USD, centavos for BRL): 2000 is 20.00. A positive integer.
- `currency` (string, required): Three-letter ISO code in lowercase, such as usd: the currency the store accepts. Any other currency is refused.
- `description` (string, optional): Free text for your own records.
- `destination` (string, optional): The bank account to pay into, by its id (ba_...): any of the store's own external accounts. Leave it out to pay the store's default bank account. The payout only ever goes to the account it names: if that account is no longer on file before the money leaves, the payout fails with failure_code account_closed (no_account when no account is on file) and the amount goes back to the balance.
- `metadata` (object, optional): Up to 50 key-value pairs of your own, sent as metadata[key]=value: keys of 1 to 40 characters, values up to 500. Keys starting with fluveo_ are reserved. On an update, an empty value removes a key.
- `method` (enum, optional): Only standard. Instant payouts are refused.

  One of: `standard`.
- `statement_descriptor` (string, optional): Text on the store's bank statement for this payout, with none of < > ' ".

Use only the documented body parameters. Send a new `Idempotency-Key` with each new request, and the same key again only to retry that request.

Returns a [`payout`](https://docs.fluveo.com/api/payouts.md#object-payout) object.

**Request**

cURL:

```bash
curl https://api.fluveo.com/v1/payouts \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  --data-urlencode "amount=5000" \
  --data-urlencode "currency=usd"
```

Node.js:

```javascript
const response = await fetch("https://api.fluveo.com/v1/payouts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_test_...",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: new URLSearchParams([["amount","5000"],["currency","usd"]]),
});
console.log(await response.json());
```

Python:

```python
import uuid

import requests

response = requests.post(
    "https://api.fluveo.com/v1/payouts",
    headers={"Authorization": "Bearer sk_test_...", "Idempotency-Key": str(uuid.uuid4())},
    data=[("amount", "5000"), ("currency", "usd")],
)
print(response.json())
```

PHP:

```php
<?php
$ch = curl_init("https://api.fluveo.com/v1/payouts");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer sk_test_...",
        "Idempotency-Key: " . bin2hex(random_bytes(16)),
    ],
    CURLOPT_POSTFIELDS => "amount=5000&currency=usd",
]);
echo curl_exec($ch);
```

*Response (abridged example)*

```json
{
  "amount": 5000,
  "created": 1767225600,
  "currency": "usd",
  "id": "po_123",
  "livemode": false,
  "metadata": {},
  "method": "standard",
  "object": "payout",
  "status": "pending"
}
```

## Lists payout objects, newest first

`GET /v1/payouts`

Permission: [`rak_payout_read`](https://docs.fluveo.com/permissions.md#payout).

**Query parameters**

- `arrival_date` (object, optional): Filter on the expected arrival date, a Unix timestamp: arrival_date=<t> or arrival_date[gt], [gte], [lt], [lte].
- `created` (object, optional): Filter on the creation time, a Unix timestamp: created=<t> for an exact match, or created[gt], created[gte], created[lt], created[lte].
- `destination` (string, optional): Only payouts to this bank account.
- `ending_before` (string, optional): Cursor: the id of the first object of the current page, to get the previous page. Do not send it with starting_after.
- `limit` (integer, optional): How many objects to return, from 1 to 100. Default 10.
- `starting_after` (string, optional): Cursor: the id of the last object of the previous page, to get the next page. Do not send it with ending_before.
- `status` (enum, optional): Only payouts in this status.

  One of: `pending`, `in_transit`, `paid`, `failed`, `canceled`.

**Headers**

- `Fluveo-Version` (enum, optional): Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.

  One of: `2026-05-27.dahlia`.

Returns a list of [`payout`](https://docs.fluveo.com/api/payouts.md#object-payout) objects.

**Request**

cURL:

```bash
curl -G https://api.fluveo.com/v1/payouts \
  -H "Authorization: Bearer sk_test_..." \
  --data-urlencode "status=paid"
```

Node.js:

```javascript
const response = await fetch("https://api.fluveo.com/v1/payouts" + "?" + new URLSearchParams([["status","paid"]]), {
  method: "GET",
  headers: {
    "Authorization": "Bearer sk_test_...",
  },
});
console.log(await response.json());
```

Python:

```python
import requests

response = requests.get(
    "https://api.fluveo.com/v1/payouts",
    headers={"Authorization": "Bearer sk_test_..."},
    params=[("status", "paid")],
)
print(response.json())
```

PHP:

```php
<?php
$ch = curl_init("https://api.fluveo.com/v1/payouts?status=paid");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer sk_test_...",
    ],
]);
echo curl_exec($ch);
```

*Response (abridged example)*

```json
{
  "data": [
    {
      "amount": 5000,
      "created": 1767225600,
      "currency": "usd",
      "id": "po_123",
      "livemode": false,
      "metadata": {},
      "method": "standard",
      "object": "payout",
      "status": "pending"
    }
  ],
  "has_more": false,
  "object": "list",
  "url": "/v1/payouts"
}
```

## Updates a payout

`POST /v1/payouts/{payout}`

Permission: [`rak_payout_write`](https://docs.fluveo.com/permissions.md#payout).

**Path parameters**

- `payout` (string, required): The payout's id.

**Headers**

- `Idempotency-Key` (string, optional): Send a unique key, 1 to 255 characters, on every POST. A retry with the same key and the same body returns the first answer instead of acting twice (with Idempotent-Replayed: true); the same key with another body is refused. Keys are kept 7 days, except on POST /v1/checkout/sessions, POST /v1/checkout/sessions/{session} and POST /v1/webhook_endpoints, where a key holds 24 hours; webhook endpoint keys are also capped at the newest 32 per store and mode. Do not rely on a replay after that window. GET and DELETE ignore it.
- `Fluveo-Version` (enum, optional): Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.

  One of: `2026-05-27.dahlia`.

**Body parameters**

- `metadata` (object, optional): Up to 50 key-value pairs of your own, sent as metadata[key]=value: keys of 1 to 40 characters, values up to 500. Keys starting with fluveo_ are reserved. On an update, an empty value removes a key.

Use only the documented body parameters. Send a new `Idempotency-Key` with each new request, and the same key again only to retry that request.

Returns a [`payout`](https://docs.fluveo.com/api/payouts.md#object-payout) object.

**Request**

cURL:

```bash
curl https://api.fluveo.com/v1/payouts/po_123 \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  --data-urlencode "metadata[batch]=2026-11"
```

Node.js:

```javascript
const response = await fetch("https://api.fluveo.com/v1/payouts/po_123", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_test_...",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: new URLSearchParams([["metadata[batch]","2026-11"]]),
});
console.log(await response.json());
```

Python:

```python
import uuid

import requests

response = requests.post(
    "https://api.fluveo.com/v1/payouts/po_123",
    headers={"Authorization": "Bearer sk_test_...", "Idempotency-Key": str(uuid.uuid4())},
    data=[("metadata[batch]", "2026-11")],
)
print(response.json())
```

PHP:

```php
<?php
$ch = curl_init("https://api.fluveo.com/v1/payouts/po_123");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer sk_test_...",
        "Idempotency-Key: " . bin2hex(random_bytes(16)),
    ],
    CURLOPT_POSTFIELDS => "metadata%5Bbatch%5D=2026-11",
]);
echo curl_exec($ch);
```

*Response (abridged example)*

```json
{
  "amount": 5000,
  "created": 1767225600,
  "currency": "usd",
  "id": "po_123",
  "livemode": false,
  "metadata": {},
  "method": "standard",
  "object": "payout",
  "status": "pending"
}
```

## Retrieves a payout

`GET /v1/payouts/{payout}`

Permission: [`rak_payout_read`](https://docs.fluveo.com/permissions.md#payout).

**Path parameters**

- `payout` (string, required): The payout's id.

**Headers**

- `Fluveo-Version` (enum, optional): Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.

  One of: `2026-05-27.dahlia`.

Returns a [`payout`](https://docs.fluveo.com/api/payouts.md#object-payout) object.

**Request**

cURL:

```bash
curl https://api.fluveo.com/v1/payouts/po_123 \
  -H "Authorization: Bearer sk_test_..."
```

Node.js:

```javascript
const response = await fetch("https://api.fluveo.com/v1/payouts/po_123", {
  method: "GET",
  headers: {
    "Authorization": "Bearer sk_test_...",
  },
});
console.log(await response.json());
```

Python:

```python
import requests

response = requests.get(
    "https://api.fluveo.com/v1/payouts/po_123",
    headers={"Authorization": "Bearer sk_test_..."},
)
print(response.json())
```

PHP:

```php
<?php
$ch = curl_init("https://api.fluveo.com/v1/payouts/po_123");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer sk_test_...",
    ],
]);
echo curl_exec($ch);
```

*Response (abridged example)*

```json
{
  "amount": 5000,
  "created": 1767225600,
  "currency": "usd",
  "id": "po_123",
  "livemode": false,
  "metadata": {},
  "method": "standard",
  "object": "payout",
  "status": "pending"
}
```

## Cancels a payout

`POST /v1/payouts/{payout}/cancel`

Permission: [`rak_payout_write`](https://docs.fluveo.com/permissions.md#payout).

**Path parameters**

- `payout` (string, required): The payout's id.

**Headers**

- `Idempotency-Key` (string, optional): Send a unique key, 1 to 255 characters, on every POST. A retry with the same key and the same body returns the first answer instead of acting twice (with Idempotent-Replayed: true); the same key with another body is refused. Keys are kept 7 days, except on POST /v1/checkout/sessions, POST /v1/checkout/sessions/{session} and POST /v1/webhook_endpoints, where a key holds 24 hours; webhook endpoint keys are also capped at the newest 32 per store and mode. Do not rely on a replay after that window. GET and DELETE ignore it.
- `Fluveo-Version` (enum, optional): Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.

  One of: `2026-05-27.dahlia`.

Use only the documented body parameters. Send a new `Idempotency-Key` with each new request, and the same key again only to retry that request.

Returns a [`payout`](https://docs.fluveo.com/api/payouts.md#object-payout) object.

**Request**

cURL:

```bash
curl -X POST https://api.fluveo.com/v1/payouts/po_123/cancel \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: $(uuidgen)"
```

Node.js:

```javascript
const response = await fetch("https://api.fluveo.com/v1/payouts/po_123/cancel", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_test_...",
    "Idempotency-Key": crypto.randomUUID(),
  },
});
console.log(await response.json());
```

Python:

```python
import uuid

import requests

response = requests.post(
    "https://api.fluveo.com/v1/payouts/po_123/cancel",
    headers={"Authorization": "Bearer sk_test_...", "Idempotency-Key": str(uuid.uuid4())},
)
print(response.json())
```

PHP:

```php
<?php
$ch = curl_init("https://api.fluveo.com/v1/payouts/po_123/cancel");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer sk_test_...",
        "Idempotency-Key: " . bin2hex(random_bytes(16)),
    ],
    CURLOPT_POSTFIELDS => "",
]);
echo curl_exec($ch);
```

*Response (abridged example)*

```json
{
  "amount": 5000,
  "created": 1767225600,
  "currency": "usd",
  "id": "po_123",
  "livemode": false,
  "metadata": {},
  "method": "standard",
  "object": "payout",
  "status": "pending"
}
```

## The payout object

Ids start with `po_`.

**Attributes**

- `amount` (integer)
- `application_fee` (string, nullable)
- `application_fee_amount` (integer, nullable)
- `arrival_date` (integer)
- `automatic` (boolean)
- `balance_transaction` (string, nullable, expandable): An id by default; send `expand[]=balance_transaction` to get the full balance_transaction object.
- `created` (integer)
- `currency` (string)
- `description` (string, nullable)
- `destination` (string, nullable)
- `failure_balance_transaction` (string, nullable, expandable): An id by default; send `expand[]=failure_balance_transaction` to get the full balance_transaction object.
- `failure_code` (string, nullable)
- `failure_message` (string, nullable)
- `id` (string)
- `livemode` (boolean)
- `metadata` (object, nullable)
- `method` (string)
- `object` (enum): One of: `payout`.
- `original_payout` (string, nullable, expandable): An id by default; send `expand[]=original_payout` to get the full payout object.
- `payout_method` (string, nullable)
- `reconciliation_status` (enum): One of: `completed`, `in_progress`, `not_applicable`.
- `reversed_by` (string, nullable, expandable): An id by default; send `expand[]=reversed_by` to get the full payout object.
- `source_type` (string)
- `statement_descriptor` (string, nullable)
- `status` (string)
- `trace_id` (object, nullable)
- `type` (enum): One of: `bank_account`, `card`.
