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

# Send a Payout

> Confirms an open quote: the total of the quote (`total_debited_usd`) is debited from the balance of the rail
(`payout_sepa` for SEPA, `others` for ACH) and the payout is created with status `pending` (HTTP `202`). It is then sent to the bank asynchronously:
follow it with the `payout.*` webhooks or `GET /payouts/{code}`. The `code` of the payout is the `quote_code`.

**`reference` is required** and unique per partner account: 1 to 100 characters among letters, digits and
`- _ . : /` (for example your order ID). Sending the same `quote_code` with the same `reference` again returns
the payout already created with HTTP `200`, and nothing is debited twice. A `reference` already used by
another payout returns `422 VALIDATION_ERROR`.

If the quote has expired when the payout is sent to the bank, KemyCard requests a new quote automatically.
If the amount received would be more than 1% lower than the accepted quote, the payout fails and is refunded.




## OpenAPI

````yaml POST /payouts
openapi: 3.1.0
info:
  title: KemyCard API
  version: '1.0'
  description: >
    KemyCard API allows you to issue virtual and physical cards, manage KYC/POA
    verification,

    create crypto wallets, virtual bank accounts, purchase gift cards and send
    payouts to bank accounts (SEPA Instant

    in EUR, ACH in USD to the United States).


    Access depends on your plan (see [Plans and
    Pricing](/getting-started/plans)). The free Découverte plan gives

    access to virtual cards with the KYC and POA endpoints and to payouts (SEPA
    and ACH), within monthly limits (25 cards

    created and 5,000 USD loaded on cards per calendar month, 5,000 USD of
    payouts per calendar month), 30 requests

    per minute per API key, 2 allowed IP addresses and 1 active webhook
    endpoint. Starter, Business and Premium give access to every product with no
    monthly limit,

    100 requests per minute per API key, 10 allowed IP addresses and 10 active
    webhook endpoints.


    Plan errors: `402 PLAN_UPGRADE_REQUIRED` (product not included in your
    plan), `403 PLAN_LIMIT_REACHED`

    (limit of your plan reached). While one of your ops balances is negative,
    every request other than `GET`

    returns `403 ACCOUNT_SUSPENDED_NEGATIVE_BALANCE`.
  contact:
    name: KemyCard API Support
    email: hi@kemycard.com
servers:
  - url: https://api.kemycard.com/v1
    description: Production
security:
  - BearerAuth: []
tags:
  - name: Customers
    description: Manage your customers
  - name: Card Products
    description: Browse the card product catalog
  - name: Cards
    description: Issue and manage cards
  - name: KYC
    description: Identity verification
  - name: POA
    description: Proof of address verification
  - name: Wallets
    description: Crypto wallets
  - name: Virtual Accounts
    description: Virtual bank accounts
  - name: Gift Cards
    description: Gift card catalog and purchases
  - name: Payouts
    description: >
      Payouts to bank accounts: SEPA Instant in EUR (paid from your Payout SEPA
      balance) and ACH in USD to bank

      accounts in the United States (paid from your Ops Others balance)
  - name: Balance
    description: Operational balances and transaction history
  - name: Webhooks
    description: Webhook endpoints and delivery management
paths:
  /payouts:
    post:
      tags:
        - Payouts
      summary: Send a payout
      description: >
        Confirms an open quote: the total of the quote (`total_debited_usd`) is
        debited from the balance of the rail

        (`payout_sepa` for SEPA, `others` for ACH) and the payout is created
        with status `pending` (HTTP `202`). It is then sent to the bank
        asynchronously:

        follow it with the `payout.*` webhooks or `GET /payouts/{code}`. The
        `code` of the payout is the `quote_code`.


        **`reference` is required** and unique per partner account: 1 to 100
        characters among letters, digits and

        `- _ . : /` (for example your order ID). Sending the same `quote_code`
        with the same `reference` again returns

        the payout already created with HTTP `200`, and nothing is debited
        twice. A `reference` already used by

        another payout returns `422 VALIDATION_ERROR`.


        If the quote has expired when the payout is sent to the bank, KemyCard
        requests a new quote automatically.

        If the amount received would be more than 1% lower than the accepted
        quote, the payout fails and is refunded.
      operationId: createPayout
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePayoutRequest'
      responses:
        '200':
          description: >-
            Same `quote_code` and `reference` sent again — the payout already
            created is returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutSuccessResponse'
        '202':
          description: Payout accepted (status `pending`), balance debited
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutSuccessResponse'
        '400':
          description: >
            `INSUFFICIENT_BALANCE`: the balance of the rail (Payout SEPA for
            SEPA, Ops Others for ACH) does not cover

            the total (`details`: `required`, `balance_type`, and `available`
            when known). `OPERATION_FAILED`: payouts are temporarily
            unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: >-
            `PLAN_LIMIT_REACHED` (Découverte monthly limit), `FORBIDDEN`
            (customer not active) or `ACCOUNT_SUSPENDED_NEGATIVE_BALANCE`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          description: >
            Validation error: missing field, invalid `reference`
            (`details.field`), `reference` already used by another

            payout (`details.reference`, `details.payout_code`), quote expired
            or no longer open (request a new quote),

            or customer not verified.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: VALIDATION_ERROR
                  message: This reference is already used by another payout.
                  details:
                    reference: order-1001
                    payout_code: 0199e3a1-7c2b-7d40-9a51-3f6e2b8c4d10
components:
  schemas:
    CreatePayoutRequest:
      type: object
      required:
        - quote_code
        - reference
      properties:
        quote_code:
          type: string
          format: uuid
          description: The `quote_code` of an open quote
        reference:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[A-Za-z0-9_\-.:/]{1,100}$
          description: >
            Your own reference, unique per partner account (for example your
            order ID): 1 to 100 characters among

            letters, digits and `- _ . : /`. It makes the call safe to retry.
          example: order-1001
    PayoutSuccessResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          $ref: '#/components/schemas/Payout'
        meta:
          $ref: '#/components/schemas/Meta'
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              description: >
                Error code, for example `AUTHENTICATION_REQUIRED`,
                `AUTHENTICATION_FAILED`, `ACCOUNT_RESTRICTED`,

                `IP_NOT_ALLOWED`, `PLAN_UPGRADE_REQUIRED`, `PLAN_LIMIT_REACHED`,
                `ACCOUNT_SUSPENDED_NEGATIVE_BALANCE`,

                `INSUFFICIENT_BALANCE`, `OPERATION_FAILED`, `FORBIDDEN`,
                `RESOURCE_NOT_FOUND`, `VALIDATION_ERROR`,

                `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`, `wrong_api_host`. See
                [Error Handling](/guides/error-handling).
              example: VALIDATION_ERROR
            message:
              type: string
              example: Missing required fields.
            details:
              type: object
              nullable: true
        meta:
          $ref: '#/components/schemas/Meta'
    Payout:
      type: object
      properties:
        code:
          type: string
          format: uuid
          description: Payout code (same value as the `quote_code` it was created from)
        reference:
          type: string
          description: Your reference
          example: order-1001
        rail:
          type: string
          enum:
            - sepa
            - ach
          description: >-
            `sepa` (beneficiary with `rail` `sepa`) or `ach` (beneficiary in the
            United States)
          example: sepa
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
            - refunded
          description: >
            `pending`: accepted, balance debited, not yet sent to the bank.
            `processing`: sent to the bank.

            `completed`: credited to the beneficiary's bank. `failed`: the bank
            transfer could not be completed.

            `refunded`: the amount and the fee have been credited back to the
            balance that paid the payout.
          example: pending
        customer_code:
          type: string
          format: uuid
        beneficiary:
          $ref: '#/components/schemas/PayoutBeneficiarySummary'
        amount_usd:
          type: number
          example: 100
        fee_usd:
          type: number
          example: 7
        total_debited_usd:
          type: number
          description: Amount + fee, debited from the balance given by `balance_type`
          example: 107
        received_amount:
          type: number
          nullable: true
          description: >-
            Amount sent to the beneficiary, in `received_currency` (updated if
            the quote was renewed when sending)
          example: 86
        received_currency:
          type: string
          enum:
            - EUR
            - USD
          description: '`EUR` for SEPA, `USD` for ACH (no currency conversion)'
          example: EUR
        amount_eur:
          type: number
          nullable: true
          description: >-
            Amount in EUR sent to the beneficiary (updated if the quote was
            renewed when sending). `null` for ACH.
          example: 86
        exchange_rate:
          type: number
          nullable: true
          description: '`amount_eur` / `amount_usd`. `null` for ACH.'
          example: 0.86
        balance_type:
          type: string
          enum:
            - payout_sepa
            - others
          description: >-
            Balance that paid the payout: `payout_sepa` (Payout SEPA) for SEPA,
            `others` (Ops Others) for ACH
          example: payout_sepa
        failure_reason:
          type: string
          nullable: true
          description: Set when the status is `failed` or `refunded`, `null` otherwise
          example: null
        created_at:
          type: string
          format: date-time
        confirmed_at:
          type: string
          format: date-time
          nullable: true
          description: When you confirmed the quote with `POST /payouts`
        sent_at:
          type: string
          format: date-time
          nullable: true
          description: When the payout was sent to the bank
        completed_at:
          type: string
          format: date-time
          nullable: true
        refunded_at:
          type: string
          format: date-time
          nullable: true
    Meta:
      type: object
      properties:
        request_id:
          type: string
          example: a4f8e2c1b3d97056
        mode:
          type: string
          enum:
            - test
            - live
          example: test
        timestamp:
          type: string
          format: date-time
    PayoutBeneficiarySummary:
      type: object
      properties:
        code:
          type: string
          format: uuid
        name:
          type: string
          example: JANE DOE
        iban_masked:
          type: string
          description: SEPA payouts only
          example: DE89 **** 3000
        account_number_masked:
          type: string
          description: ACH payouts only. Last 4 digits of the US account number.
          example: '**** 9012'
        routing_number:
          type: string
          description: ACH payouts only
          example: '021000021'
        bank_name:
          type: string
          example: Test Bank
        country:
          type: string
          description: Country of the bank account (`US` for ACH)
          example: DE
  responses:
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: RESOURCE_NOT_FOUND
              message: Resource not found.
              details: null
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: API key (sk_test_... or sk_live_...)

````

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