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

# Execute a batch of payouts

> Lock and execute N payouts that share a source currency, in one call.

Batched [`POST /rfq/execute`](/api-reference/payouts/execute). Rows share `fromCurrency`. Partial failure is per-row — walk `data.rows`, retry `retryable: true`.

<Info>**Scope** `payouts:write` · rate-limited</Info>

## Headers

<ParamField header="Authorization" type="string" required>
  API key.
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Optional envelope-level dedup. Per-row dedup uses `items[].idempotency_key`.
</ParamField>

## Request body

<Info>
  **Batch is exact-output by design.** Each row's `targetAmount` is what the recipient receives; the engine sizes the source spend. `items[].amount` is accepted on the wire but informational only — `targetAmount` drives quoting.
</Info>

<Tabs>
  <Tab title="Fiat-to-fiat / Onramp">
    <ParamField body="fromCurrency" type="string" required>Shared source currency.</ParamField>
    <ParamField body="onrampProtocol" type="string" required>Opaque onramp route token. Pins every row to the same onramp route.</ParamField>
    <ParamField body="userPaymentMethodId" type="string" required>Shared funding source.</ParamField>

    <ParamField body="items" type="object[]" required>
      Non-empty array of payouts.

      <Expandable title="items[]">
        <ParamField body="toCurrency" type="string" required>Destination currency.</ParamField>
        <ParamField body="targetAmount" type="number" required>Destination amount the recipient receives. Must be `> 0`.</ParamField>
        <ParamField body="recipientId" type="string" required>Recipient UUID.</ParamField>
        <ParamField body="amount" type="number">Informational source amount. Accepted but not used for sizing — `targetAmount` drives quoting.</ParamField>
        <ParamField body="recipientPaymentMethodId" type="string">Recipient PM UUID.</ParamField>
        <ParamField body="offrampProvider" type="string">Offramp routing hint.</ParamField>
        <ParamField body="routeProtocol" type="string">Per-row opaque route token.</ParamField>
        <ParamField body="paymentPurpose" type="string">Per-row classification.</ParamField>
        <ParamField body="reference" type="string">Per-row free-text reference.</ParamField>
        <ParamField body="idempotencyKey" type="string">Per-row dedup key — retry just this row.</ParamField>
      </Expandable>
    </ParamField>
  </Tab>

  <Tab title="Stablecoin-to-fiat">
    <ParamField body="fromCurrency" type="string" required>Stablecoin ticker (e.g. `USDC`).</ParamField>
    <ParamField body="onrampProtocol" type="string" required>Required at the top level even for S2F (handler-level constraint).</ParamField>
    <ParamField body="userPaymentMethodId" type="string" required>Required at the top level even for S2F (handler-level constraint).</ParamField>
    <ParamField body="walletAddresses" type="object">Per-chain source wallet — `{"polygon": "0x…", "arbitrum": "0x…"}`.</ParamField>

    <ParamField body="items" type="object[]" required>
      Non-empty array of payouts. Same `items[]` shape as the other tab.
    </ParamField>
  </Tab>
</Tabs>

## Response

Always `{ "success": true, "data": { "rows": [...], "items": [...] } }`. Use `rows` — `items` is a deprecation alias.

<ResponseField name="rows" type="object[]">
  One entry per input row, in the same order.

  <Expandable title="rows[]">
    <ResponseField name="idx" type="integer">Zero-based input index.</ResponseField>
    <ResponseField name="status" type="string">`accepted` or `failed`.</ResponseField>
    <ResponseField name="transactionId" type="string">Present when `accepted`.</ResponseField>
    <ResponseField name="quoteId" type="string">Echoed for correlation.</ResponseField>
    <ResponseField name="errorCode" type="string">Present when `failed`.</ResponseField>
    <ResponseField name="retryable" type="boolean">When `true`, re-fire just this row with the same `idempotencyKey`.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="items" type="object[]">
  Deprecation alias for `rows`. Same shape, same order, same contents — kept for one major-version of backward compatibility. New code should read `rows`.
</ResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "success": true,
    "data": {
      "rows": [
        { "idx": 0, "status": "accepted", "transactionId": "8b1a4c1d-…", "quoteId": "4c2b7e8f-…" },
        { "idx": 1, "status": "failed", "errorCode": "RECIPIENT_NOT_FOUND", "retryable": false },
        { "idx": 2, "status": "accepted", "transactionId": "4f9e5f15-…", "quoteId": "1c84203c-…" }
      ]
    }
  }
  ```
</ResponseExample>

HTTP status is `200` even when some rows fail — `data.rows[].status` is the source of truth.
