> ## Documentation Index
> Fetch the complete documentation index at: https://docs.privy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Execute a payout

> Convert crypto from a wallet to fiat and settle it to a bank account

A payout converts crypto from a wallet and settles it to a [registered bank account](/financial-flows/transfers/fiat-payouts/register-bank-account) in a single call.

## Supported assets and chains

Pass `source.asset` as one of [Privy's well-known assets](/wallets/actions/transfer/overview#well-known-assets). The asset value differs by chain: Tempo uses `usdc_e` and `usdt0`, not `usdc` and `usdt`.

| Chain | `source.chain` | Supported `source.asset` |
| - | - | - |
| Tempo | `tempo` | `ousd`, `usdc_e`, `usdt0` |
| Ethereum | `ethereum` | `ousd`, `usdc`, `usdt`, `usdb`, `eurc` |
| Base | `base` | `ousd`, `usdc`, `usdb`, `eurc` |
| Arbitrum | `arbitrum` | `usdc` |
| Optimism | `optimism` | `usdc` |
| Polygon | `polygon` | `usdc` |
| Solana | `solana` | `ousd`, `usdc`, `usdt`, `usdb`, `eurc` |

<Warning>
  On Polygon, pay out `usdc` rather than `usdc_e`. Privy's `usdc_e` on Polygon is PoS-bridged USDC,
  which the provider does not accept, so a payout naming it is rejected.
</Warning>

## Payment rails

By default, a payout settles over the standard rail for the destination account's type. To settle over a different rail, pass `destination.payment_rail`. The rail must be one the destination account supports.

| Account type | Default rail | Supported `payment_rail` |
| - | - | - |
| `us` | `ach` | `ach`, `ach_same_day`, `wire`, `fednow` |
| `gb` | `faster_payments` | `faster_payments` |
| `iban` | `sepa` | `sepa` |
| `pix` | `pix` | `pix` |
| `swift` | `wire` | `wire` |

<Warning>
  FedNow payouts are waitlisted. Reach out to [sales@privy.io](mailto:sales@privy.io) to request
  access.
</Warning>

<View title="NodeJS" icon="node-js">
  Use the `create` method from the `payout().fiat()` service on `wallets()`.

  ```ts {skip-check} theme={"system"}
  import {PrivyClient} from '@privy-io/node';

  const privy = new PrivyClient({
    appId: process.env.PRIVY_APP_ID!,
    appSecret: process.env.PRIVY_APP_SECRET!
  });

  const payout = await privy
    .wallets()
    .payout()
    .fiat()
    .create('<wallet-id>', {
      source: {
        asset: 'usdc_e',
        chain: 'tempo',
        amount: '100.00'
      },
      destination: {
        fiat_account_id: '<fiat-account-id>',
        payment_rail: 'ach_same_day' // optional, defaults to the account's standard rail
      }
    });

  // payout.id is the wallet action ID to track
  ```
</View>

<View title="REST API" icon="terminal">
  To pay out from a wallet, make a `POST` request to:

  ```bash theme={"system"}
  https://api.privy.io/v1/wallets/{wallet_id}/payout/fiat
  ```

  See the [API reference](/api-reference/wallets/payout/create) for the full request and response schema.

  In the body of the request, include the following fields:

  <ParamField body="source" type="object" required>
    The crypto to offramp.

    <Expandable title="properties" defaultOpen>
      <ParamField body="source.asset" type="string" required>
        Asset to offramp. See [supported assets and chains](#supported-assets-and-chains).
      </ParamField>

      <ParamField body="source.chain" type="string" required>
        Chain the asset is held on. Must match the wallet's `chain_type`. See [supported assets and
        chains](#supported-assets-and-chains).
      </ParamField>

      <ParamField body="source.amount" type="string" required>
        Amount to offramp, as a decimal string in the asset's standard units, such as `"100.00"`.
      </ParamField>
    </Expandable>
  </ParamField>

  <ParamField body="destination" type="object" required>
    Where the fiat settles.

    <Expandable title="properties" defaultOpen>
      <ParamField body="destination.fiat_account_id" type="string" required>
        ID of a registered bank account. The account's currency determines the fiat currency the
        payout settles in.
      </ParamField>

      <ParamField body="destination.payment_rail" type="'ach' | 'ach_same_day' | 'wire' | 'fednow' | 'sepa' | 'faster_payments' | 'pix'">
        Rail to settle the payout over. Must be one the destination account supports. Defaults to the
        account type's standard rail, such as `ach` for `us` accounts. See [payment
        rails](#payment-rails).
      </ParamField>
    </Expandable>
  </ParamField>

  <Warning>
    Payouts are not yet a [policy](/controls/policies/overview) method. Because the policy engine
    denies any method a policy does not explicitly allow, attaching a policy that only covers other
    methods, such as `transfer`, blocks payouts from that wallet.
  </Warning>

  <Info>
    Pass a `privy-idempotency-key` header to make retries safe. If the wallet has an owner, the
    request also requires an [authorization signature](/api-reference/authorization-signatures).
  </Info>

  Below is a sample cURL command for this request:

  ```bash theme={"system"}
  curl --request POST https://api.privy.io/v1/wallets/{wallet_id}/payout/fiat \
    -u "<your-privy-app-id>:<your-privy-app-secret>" \
    -H "privy-app-id: <your-privy-app-id>" \
    -H 'Content-Type: application/json' \
    -H 'privy-idempotency-key: <your-idempotency-key>' \
    -d '{
      "source": {
        "asset": "usdc_e",
        "chain": "tempo",
        "amount": "100.00"
      },
      "destination": {
        "fiat_account_id": "fa_3ad996de-e827-4d2e-99fc-799838520453",
        "payment_rail": "ach_same_day"
      }
    }'
  ```

  A successful response is a pending payout wallet action:

  <ResponseField name="id" type="string">
    ID of the wallet action. Use this to track the payout.
  </ResponseField>

  <ResponseField name="type" type="'payout'">
    Type of the wallet action.
  </ResponseField>

  <ResponseField name="status" type="'pending' | 'succeeded' | 'rejected' | 'failed'">
    Current status of the payout.
  </ResponseField>

  <ResponseField name="provider" type="'bridge'">
    Provider settling the payout.
  </ResponseField>

  <ResponseField name="environment" type="'production' | 'sandbox'">
    Provider environment the payout runs against.
  </ResponseField>

  <ResponseField name="source" type="object">
    The `asset`, `chain`, and `amount` being offramped.
  </ResponseField>

  <ResponseField name="destination" type="object">
    The `fiat_account_id` the payout settles to.
  </ResponseField>

  ```json theme={"system"}
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "wallet_id": "fmfdj6yqly31huorjqzq38zc",
    "type": "payout",
    "status": "pending",
    "provider": "bridge",
    "environment": "sandbox",
    "source": {
      "asset": "usdc_e",
      "chain": "tempo",
      "amount": "100.00"
    },
    "destination": {
      "fiat_account_id": "fa_3ad996de-e827-4d2e-99fc-799838520453"
    },
    "created_at": "2026-08-03T12:00:00Z"
  }
  ```
</View>

## Next steps

<CardGroup cols={2}>
  <Card title="Track a payout" icon="webhook" href="/financial-flows/transfers/fiat-payouts/track-payouts">
    Follow a payout from on-chain transfer to bank settlement
  </Card>

  <Card title="Wallet actions" icon="bolt" href="/wallets/actions/overview">
    Learn how wallet actions are authorized and executed
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.