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

# Create or update a payout

> Create a new payout or update an existing one via external_id. Partners send completed processor settlements (Stripe, Adyen, etc.) with associated invoice payments and refund payments. Returns 201 for new payouts, 200 for updates. Updates are blocked if payout is already reconciled to a bank transaction.



## OpenAPI

````yaml POST /v1/platform/businesses/{business_id}/payouts/
openapi: 3.0.3
info:
  title: Thredfi Accounting Platform API
  version: 1.0.0
  description: >-
    Comprehensive API for accounting, invoice management, open banking, and
    intelligence services.
servers: []
security: []
paths:
  /v1/platform/businesses/{business_id}/payouts/:
    post:
      tags:
        - Payouts
      summary: Create or update a payout
      description: >-
        Create a new payout or update an existing one via external_id. Partners
        send completed processor settlements (Stripe, Adyen, etc.) with
        associated invoice payments and refund payments. Returns 201 for new
        payouts, 200 for updates. Updates are blocked if payout is already
        reconciled to a bank transaction.
      operationId: create_payout
      parameters:
        - in: path
          name: business_id
          schema:
            type: string
            format: uuid
          description: Business UUID (unique identifier for the business)
          required: true
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PayoutCreateRequest'
            examples:
              StripePayoutExample:
                value:
                  external_id: stripe_po_2024_12_20
                  processor: stripe
                  processor_payout_id: po_1OeYZb2eZvKYlo2C6KqhQWxE
                  paid_out_amount_cents: 920000
                  fee_cents: 30000
                  additional_refunds_amount_cents: 0
                  currency: GBP
                  status: paid
                  completed_at: '2024-12-20T14:30:45Z'
                  payment_ids:
                    - 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                    - 4d81d4dd-9d14-5d2b-ad8b-9f6dad4c5g3e
                  refund_payment_ids:
                    - 5e92e5ee-ae25-6e3c-be9c-ag7ebe5d6h4f
                  reference_number: PAYOUT-2024-W51
                  memo: Weekly Stripe settlement
                  metadata:
                    batch_id: w51
                    settlement_period: 2024-12-14_to_2024-12-20
                summary: Stripe Payout Example
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PayoutCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PayoutCreateRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutResponse'
              examples:
                PayoutResponse:
                  value:
                    id: be90c3cc-7d18-4e2d-8e6e-9f5d7e4a5c3b
                    business_id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                    external_id: stripe_po_2024_12_20
                    processor: stripe
                    processor_payout_id: po_1OeYZb2eZvKYlo2C6KqhQWxE
                    paid_out_amount_cents: 920000
                    fee_cents: 30000
                    additional_refunds_amount_cents: 0
                    net_amount_cents: 890000
                    currency: GBP
                    status: paid
                    completed_at: '2024-12-20T14:30:45Z'
                    imported_at: '2024-12-20T15:00:12Z'
                    reference_number: PAYOUT-2024-W51
                    memo: Weekly Stripe settlement
                    metadata:
                      batch_id: w51
                    payment_count: 2
                    refund_payment_count: 1
                    gross_payments_amount_cents: 1000000
                    total_refunds_amount_cents: 50000
                    expected_net_amount_cents: 920000
                    amount_variance_cents: 0
                    payments:
                      - id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                        external_id: stripe_pi_xyz123
                        payment_reference: PAY-2024-0042
                        customer_name: The Red Lion Pub Ltd
                        payment_date: '2024-12-15'
                        total_amount_cents: 450000
                        currency: GBP
                    refund_payments:
                      - id: 5e92e5ee-ae25-6e3c-be9c-ag7ebe5d6h4f
                        external_id: stripe_re_abc456
                        refund_id: 6f03f6ff-bf36-7f4d-cf0d-bh8fcf6e7i5g
                        customer_name: The Red Lion Pub Ltd
                        refunded_amount_cents: 50000
                        completed_at: '2024-12-16T10:00:00Z'
                    reconciliation_status: unreconciled
                    settlement_file_id: null
                    created_at: '2024-12-20T15:00:12Z'
                    updated_at: '2024-12-20T15:00:12Z'
                  summary: Payout Response
          description: ''
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutResponse'
              examples:
                PayoutResponse:
                  value:
                    id: be90c3cc-7d18-4e2d-8e6e-9f5d7e4a5c3b
                    business_id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                    external_id: stripe_po_2024_12_20
                    processor: stripe
                    processor_payout_id: po_1OeYZb2eZvKYlo2C6KqhQWxE
                    paid_out_amount_cents: 920000
                    fee_cents: 30000
                    additional_refunds_amount_cents: 0
                    net_amount_cents: 890000
                    currency: GBP
                    status: paid
                    completed_at: '2024-12-20T14:30:45Z'
                    imported_at: '2024-12-20T15:00:12Z'
                    reference_number: PAYOUT-2024-W51
                    memo: Weekly Stripe settlement
                    metadata:
                      batch_id: w51
                    payment_count: 2
                    refund_payment_count: 1
                    gross_payments_amount_cents: 1000000
                    total_refunds_amount_cents: 50000
                    expected_net_amount_cents: 920000
                    amount_variance_cents: 0
                    payments:
                      - id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                        external_id: stripe_pi_xyz123
                        payment_reference: PAY-2024-0042
                        customer_name: The Red Lion Pub Ltd
                        payment_date: '2024-12-15'
                        total_amount_cents: 450000
                        currency: GBP
                    refund_payments:
                      - id: 5e92e5ee-ae25-6e3c-be9c-ag7ebe5d6h4f
                        external_id: stripe_re_abc456
                        refund_id: 6f03f6ff-bf36-7f4d-cf0d-bh8fcf6e7i5g
                        customer_name: The Red Lion Pub Ltd
                        refunded_amount_cents: 50000
                        completed_at: '2024-12-16T10:00:00Z'
                    reconciliation_status: unreconciled
                    settlement_file_id: null
                    created_at: '2024-12-20T15:00:12Z'
                    updated_at: '2024-12-20T15:00:12Z'
                  summary: Payout Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      security:
        - PartnerJWT: []
        - BusinessScopedJWT: []
        - BasicAuth: []
        - BearerUnscoped: []
        - BearerBusinessScoped: []
components:
  schemas:
    PayoutCreateRequest:
      type: object
      description: |-
        Serializer for creating or updating payouts
        All amounts in cents (integers)
      properties:
        external_id:
          type: string
          minLength: 1
          description: Partner's unique payout ID (idempotency key)
          maxLength: 255
        processor:
          enum:
            - stripe
            - paypal
            - square
            - adyen
            - worldpay
            - sage_pay
            - klarna
            - other
          type: string
          x-spec-enum-id: 2e3f3dccc08fb43f
          description: |-
            Payment processor (stripe, adyen, paypal, etc.)

            * `stripe` - Stripe
            * `paypal` - PayPal
            * `square` - Square
            * `adyen` - Adyen
            * `worldpay` - Worldpay
            * `sage_pay` - Sage Pay
            * `klarna` - Klarna
            * `other` - Other
        processor_payout_id:
          type: string
          description: Processor's payout ID reference
          maxLength: 255
        paid_out_amount_cents:
          type: integer
          description: >-
            Net payout amount in cents (can be negative if refunds exceed
            payments)
        fee_cents:
          type: integer
          minimum: 0
          description: Processor fee charged in cents (must be >= 0)
        additional_refunds_amount_cents:
          type: integer
          minimum: 0
          default: 0
          description: >-
            Additional refunds not tied to specific RefundPayment records in
            cents
        currency:
          enum:
            - EUR
            - GBP
            - USD
            - SEK
            - NOK
            - DKK
            - ISK
            - MYR
            - SGD
          type: string
          x-spec-enum-id: afe366a2ba7f6cae
          description: |-
            Payout currency (ISO 4217)

            * `EUR` - EUR
            * `GBP` - GBP
            * `USD` - USD
            * `SEK` - SEK
            * `NOK` - NOK
            * `DKK` - DKK
            * `ISK` - ISK
            * `MYR` - MYR
            * `SGD` - SGD
        status:
          enum:
            - pending
            - processing
            - paid
            - failed
            - cancelled
          type: string
          x-spec-enum-id: c671b6dd1cffeef4
          description: |-
            Payout status (must be 'paid')

            * `pending` - Pending
            * `processing` - Processing
            * `paid` - Paid
            * `failed` - Failed
            * `cancelled` - Cancelled
        completed_at:
          type: string
          format: date-time
          description: When payout was completed (ISO 8601)
        payment_ids:
          type: array
          items:
            type: string
            format: uuid
          description: List of Payment UUIDs included in this payout
        refund_payment_ids:
          type: array
          items:
            type: string
            format: uuid
          description: List of RefundPayment UUIDs included in this payout
        reference_number:
          type: string
          description: User-visible payout reference number
          maxLength: 100
        memo:
          type: string
          description: Internal memo or notes
        metadata:
          description: Custom metadata (max 1KB JSON object)
      required:
        - completed_at
        - currency
        - external_id
        - fee_cents
        - paid_out_amount_cents
        - processor
        - status
    PayoutResponse:
      type: object
      description: |-
        Full payout serializer for detail views and create responses
        Includes all computed fields and expanded payment/refund arrays
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        business_id:
          type: string
          format: uuid
          readOnly: true
        external_id:
          type: string
          maxLength: 255
        processor:
          enum:
            - stripe
            - paypal
            - square
            - adyen
            - worldpay
            - sage_pay
            - klarna
            - other
            - ''
          type: string
          description: |-
            * `stripe` - Stripe
            * `paypal` - PayPal
            * `square` - Square
            * `adyen` - Adyen
            * `worldpay` - Worldpay
            * `sage_pay` - Sage Pay
            * `klarna` - Klarna
            * `other` - Other
          x-spec-enum-id: 2e3f3dccc08fb43f
        processor_payout_id:
          type: string
          maxLength: 255
        paid_out_amount_cents:
          type: integer
          maximum: 9223372036854776000
          minimum: -9223372036854776000
          format: int64
          description: Net payout amount in cents (can be negative)
        fee_cents:
          type: integer
          maximum: 9223372036854776000
          minimum: 0
          format: int64
        additional_refunds_amount_cents:
          type: integer
          maximum: 9223372036854776000
          minimum: 0
          format: int64
          description: Additional refunds not tied to specific RefundPayment records
        net_amount_cents:
          type: integer
          readOnly: true
          description: 'Net amount: paid_out_amount - fee'
        currency:
          enum:
            - EUR
            - GBP
            - USD
            - SEK
            - NOK
            - DKK
            - ISK
            - MYR
            - SGD
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
        status:
          enum:
            - pending
            - processing
            - paid
            - failed
            - cancelled
          type: string
          description: |-
            * `pending` - Pending
            * `processing` - Processing
            * `paid` - Paid
            * `failed` - Failed
            * `cancelled` - Cancelled
          x-spec-enum-id: c671b6dd1cffeef4
        completed_at:
          type: string
          format: date-time
          nullable: true
        imported_at:
          type: string
          format: date-time
          readOnly: true
        reference_number:
          type: string
          maxLength: 100
        memo:
          type: string
        metadata: {}
        payment_count:
          type: integer
          description: Number of payments in this payout
          readOnly: true
        refund_payment_count:
          type: integer
          description: Number of refund payments in this payout
          readOnly: true
        gross_payments_amount_cents:
          type: integer
          description: Total amount of invoice payments before refunds
          readOnly: true
        total_refunds_amount_cents:
          type: integer
          description: Total amount of refund payments in cents
          readOnly: true
        expected_net_amount_cents:
          type: integer
          description: 'Expected net: payments - refunds - additional_refunds - fees'
          readOnly: true
        amount_variance_cents:
          type: integer
          description: Difference between reported and expected net (for debugging)
          readOnly: true
        payments:
          type: array
          items: {}
          description: Expanded payment details
          readOnly: true
        refund_payments:
          type: array
          items: {}
          description: Expanded refund payment details
          readOnly: true
        reconciliation_status:
          enum:
            - unreconciled
            - partially_reconciled
            - fully_reconciled
          type: string
          x-spec-enum-id: 0d688bdcecae9270
          readOnly: true
          description: |-
            Reconciliation state

            * `unreconciled` - Unreconciled
            * `partially_reconciled` - Partially Reconciled
            * `fully_reconciled` - Fully Reconciled
        settlement_file_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
          description: Settlement file UUID if attached
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
        - amount_variance_cents
        - business_id
        - created_at
        - expected_net_amount_cents
        - gross_payments_amount_cents
        - id
        - imported_at
        - net_amount_cents
        - paid_out_amount_cents
        - payment_count
        - payments
        - processor
        - processor_payout_id
        - reconciliation_status
        - refund_payment_count
        - refund_payments
        - settlement_file_id
        - total_refunds_amount_cents
        - updated_at
    ValidationErrorResponse:
      type: object
      description: Validation error response with field-specific errors
      properties:
        error_code:
          type: string
          description: Error code (e.g., 'validation_error')
        message:
          type: string
          nullable: true
          description: Human-readable error message
        detail:
          type: object
          additionalProperties: {}
          description: Contains field_errors and additional context
        request_id:
          type: string
          description: Request ID for tracing
      required:
        - detail
        - error_code
        - message
    ErrorResponse:
      type: object
      description: Standard error response format
      properties:
        error_code:
          type: string
          description: Error code for programmatic handling
        message:
          type: string
          nullable: true
          description: Human-readable error message
        detail:
          type: object
          additionalProperties: {}
          description: Additional error details including field_errors and debug info
        request_id:
          type: string
          description: Request ID for tracing
      required:
        - error_code
        - message
  securitySchemes:
    PartnerJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Partner-level JWT token (unscoped). Token payload includes `partner_id`.
        Business access is validated via partner ownership. Format: `Bearer
        <your-jwt-token>`


        **Use this for**: Multi-business operations where the business_id is
        specified in the URL and partner has access to multiple businesses.
    BusinessScopedJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Business-scoped JWT token. Token payload includes `business_id` to
        automatically scope requests. Format: `Bearer <your-jwt-token>`


        **Use this for**: Business-specific operations where the business
        context is embedded in the token.
    BasicAuth:
      type: http
      scheme: basic
      description: >-
        Basic authentication for OAuth2 token endpoint. Use partner_uuid:api_key
        as username:password. Example: Authorization: Basic
        base64(partner_uuid:api_key)
    BearerUnscoped:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Partner (unscoped) JWT Bearer token. Obtain via POST
        /v1/platform/oauth2/token with Basic auth (partner_uuid:api_key). Use
        header: Authorization: Bearer {access_token}
    BearerBusinessScoped:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Business-scoped JWT Bearer token. Obtain via POST
        /v1/platform/{business_id}/oauth2/token/ using a partner Bearer token.
        Only valid for endpoints whose URL contains that business_id.

````