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

# Create a payout

> Opens a commission payout for one partner and one period, so your finance stack can assemble a payout end to end over the API. The payout is created empty by default: attach lines with POST /commission-lines using the returned payout id, then render the statement with POST /api/v1/payouts/{id}/statement. Set attachPendingLines to pull in the partner's pending lines for the period instead, the way creating a payout in the app does. Every payout belongs to a batch: pass batchId to put this partner on an existing run alongside others, or leave it out and the payout gets a batch of its own. Either way the id comes back on the payout as batchId. Answers 200 instead of 201 when the partner already had a payout on that batch, returning the one they have.



## OpenAPI

````yaml /openapi.json post /api/v1/payouts
openapi: 3.1.0
info:
  title: Introw API
  version: '2026-05-20'
  description: >-
    Customer-facing API for Introw. Manage partners, delegate commission payout
    operations to your finance software, embed the partner portal in your
    product with pre-authenticated sessions, ingest affiliate conversions, and
    trigger on-demand CRM object syncs.
servers:
  - url: https://api.introw.io
  - url: https://api.staging.introw.io
security:
  - ApiKeyAuth: []
tags:
  - name: Partners
    description: >-
      Read and manage partners for the organisation associated with the
      authenticated API key.
  - name: Payouts
    description: >-
      Read and update commission payouts. Delegate approval, scheduling, and
      payment status to your ERP or accounts-payable stack.
  - name: Commission lines
    description: >-
      Create, read, update, decline, and detach commission line items. Lines can
      live in the pending pool or be attached to a payout.
  - name: Collaboration
    description: >-
      Post comments on partner portals, deals, tasks, form submissions, and
      payouts, with rich text, internal visibility, and thread replies. Comments
      trigger the same notifications, workflows, and CRM note sync as comments
      posted in the app.
  - name: Forms
    description: >-
      Submit Introw forms server-to-server. Register deals, share leads, or file
      any other form submission from your own systems; submissions run the exact
      same automation and acceptance pipeline as portal submissions. Read a
      form's field schema first to discover the field ids, value shapes, and
      allowed values to send.
  - name: Auth
    description: >-
      Create pre-authenticated partner portal sessions. Exchange a visitor email
      for a short-lived, single-use portal URL that you embed in an iframe
      inside your own product: one login, fully branded, no login screen for the
      partner.
  - name: Affiliate
    description: >-
      Ingest affiliate conversions from your backend or directly from the
      browser via affiliate.js. Every conversion is anchored to a signed,
      server-side click token (the first-party `_introw_aff` cookie),
      deduplicated, and mapped onto a campaign form submission, so attribution
      cannot be forged or double-counted.
  - name: CRM
    description: >-
      Trigger on-demand syncs of individual CRM objects. Introw already syncs
      every object automatically about every 15 minutes; use this only when a
      change must be reflected in Introw immediately, e.g. a workflow mutated
      the record and its result must persist in Introw right away.
paths:
  /api/v1/payouts:
    post:
      tags:
        - Payouts
      summary: Create a payout
      description: >-
        Opens a commission payout for one partner and one period, so your
        finance stack can assemble a payout end to end over the API. The payout
        is created empty by default: attach lines with POST /commission-lines
        using the returned payout id, then render the statement with POST
        /api/v1/payouts/{id}/statement. Set attachPendingLines to pull in the
        partner's pending lines for the period instead, the way creating a
        payout in the app does. Every payout belongs to a batch: pass batchId to
        put this partner on an existing run alongside others, or leave it out
        and the payout gets a batch of its own. Either way the id comes back on
        the payout as batchId. Answers 200 instead of 201 when the partner
        already had a payout on that batch, returning the one they have.
      operationId: createPayout
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePayoutBody'
            example:
              partnerId: ptn_01HVK6Y8Z8Q7J8J8J8J8J8J8J8
              periodStart: '2026-01-01T00:00:00.000Z'
              periodEnd: '2026-03-31T23:59:59.000Z'
              metadata: |-
                Remittance reference: ACME-Q1-2026
                Bank: paid from our EUR account

                Questions? finance@yourcompany.com
      responses:
        '201':
          description: Payout created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutResponse'
              example:
                data:
                  id: pay_2x7n4q8z0w1a2b3c4d5e6f7g
                  partner:
                    id: ptn_01HVK6Y8Z8Q7J8J8J8J8J8J8J8
                    name: Acme Partners
                  batchId: pbt_9h8g7f6e5d4c3b2a1z0w9v8u
                  periodStart: '2026-01-01T00:00:00.000Z'
                  periodEnd: '2026-03-31T23:59:59.000Z'
                  amount:
                    value: '0.00'
                    currency: USD
                  stage: DRAFT
                  poNumber: null
                  metadata: |-
                    Remittance reference: ACME-Q1-2026
                    Bank: paid from our EUR account

                    Questions? finance@yourcompany.com
                  createdAt: '2026-04-05T09:00:00.000Z'
                  updatedAt: '2026-04-05T09:00:00.000Z'
          headers:
            x-ratelimit-limit-minute:
              description: Maximum number of requests allowed in the current minute.
              schema:
                type: string
            x-ratelimit-remaining-minute:
              description: Number of requests remaining in the current minute.
              schema:
                type: string
            x-introw-credits-limit-month:
              description: >-
                This month's API credit allowance. Absent when the request was
                not metered (for example an authentication failure) or when the
                allowance is unlimited.
              schema:
                type: string
            x-introw-credits-remaining-month:
              description: >-
                API credits left in the current calendar month, after this
                request. `0` on a `402`. Absent when the request was not metered
                or when the allowance is unlimited.
              schema:
                type: string
        '401':
          description: API key is missing, invalid, expired, or revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
          headers:
            x-ratelimit-limit-minute:
              description: Maximum number of requests allowed in the current minute.
              schema:
                type: string
            x-ratelimit-remaining-minute:
              description: Number of requests remaining in the current minute.
              schema:
                type: string
            x-introw-credits-limit-month:
              description: >-
                This month's API credit allowance. Absent when the request was
                not metered (for example an authentication failure) or when the
                allowance is unlimited.
              schema:
                type: string
            x-introw-credits-remaining-month:
              description: >-
                API credits left in the current calendar month, after this
                request. `0` on a `402`. Absent when the request was not metered
                or when the allowance is unlimited.
              schema:
                type: string
        '402':
          description: >-
            Monthly API credit allowance reached. Credits reset at the start of
            the next calendar month.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
          headers:
            x-ratelimit-limit-minute:
              description: Maximum number of requests allowed in the current minute.
              schema:
                type: string
            x-ratelimit-remaining-minute:
              description: Number of requests remaining in the current minute.
              schema:
                type: string
            x-introw-credits-limit-month:
              description: >-
                This month's API credit allowance. Absent when the request was
                not metered (for example an authentication failure) or when the
                allowance is unlimited.
              schema:
                type: string
            x-introw-credits-remaining-month:
              description: >-
                API credits left in the current calendar month, after this
                request. `0` on a `402`. Absent when the request was not metered
                or when the allowance is unlimited.
              schema:
                type: string
            retry-after:
              description: >-
                Seconds until the API credit allowance resets (the start of the
                next calendar month).
              schema:
                type: string
        '403':
          description: API key does not include the commissions:write scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
          headers:
            x-ratelimit-limit-minute:
              description: Maximum number of requests allowed in the current minute.
              schema:
                type: string
            x-ratelimit-remaining-minute:
              description: Number of requests remaining in the current minute.
              schema:
                type: string
            x-introw-credits-limit-month:
              description: >-
                This month's API credit allowance. Absent when the request was
                not metered (for example an authentication failure) or when the
                allowance is unlimited.
              schema:
                type: string
            x-introw-credits-remaining-month:
              description: >-
                API credits left in the current calendar month, after this
                request. `0` on a `402`. Absent when the request was not metered
                or when the allowance is unlimited.
              schema:
                type: string
        '404':
          description: Partner was not found in the authenticated organisation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
          headers:
            x-ratelimit-limit-minute:
              description: Maximum number of requests allowed in the current minute.
              schema:
                type: string
            x-ratelimit-remaining-minute:
              description: Number of requests remaining in the current minute.
              schema:
                type: string
            x-introw-credits-limit-month:
              description: >-
                This month's API credit allowance. Absent when the request was
                not metered (for example an authentication failure) or when the
                allowance is unlimited.
              schema:
                type: string
            x-introw-credits-remaining-month:
              description: >-
                API credits left in the current calendar month, after this
                request. `0` on a `402`. Absent when the request was not metered
                or when the allowance is unlimited.
              schema:
                type: string
        '422':
          description: >-
            Request body failed validation, the period is inverted, or
            commissions are not set up for the organisation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
          headers:
            x-ratelimit-limit-minute:
              description: Maximum number of requests allowed in the current minute.
              schema:
                type: string
            x-ratelimit-remaining-minute:
              description: Number of requests remaining in the current minute.
              schema:
                type: string
            x-introw-credits-limit-month:
              description: >-
                This month's API credit allowance. Absent when the request was
                not metered (for example an authentication failure) or when the
                allowance is unlimited.
              schema:
                type: string
            x-introw-credits-remaining-month:
              description: >-
                API credits left in the current calendar month, after this
                request. `0` on a `402`. Absent when the request was not metered
                or when the allowance is unlimited.
              schema:
                type: string
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
          headers:
            x-ratelimit-limit-minute:
              description: Maximum number of requests allowed in the current minute.
              schema:
                type: string
            x-ratelimit-remaining-minute:
              description: Number of requests remaining in the current minute.
              schema:
                type: string
            x-introw-credits-limit-month:
              description: >-
                This month's API credit allowance. Absent when the request was
                not metered (for example an authentication failure) or when the
                allowance is unlimited.
              schema:
                type: string
            x-introw-credits-remaining-month:
              description: >-
                API credits left in the current calendar month, after this
                request. `0` on a `402`. Absent when the request was not metered
                or when the allowance is unlimited.
              schema:
                type: string
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
          headers:
            x-ratelimit-limit-minute:
              description: Maximum number of requests allowed in the current minute.
              schema:
                type: string
            x-ratelimit-remaining-minute:
              description: Number of requests remaining in the current minute.
              schema:
                type: string
            x-introw-credits-limit-month:
              description: >-
                This month's API credit allowance. Absent when the request was
                not metered (for example an authentication failure) or when the
                allowance is unlimited.
              schema:
                type: string
            x-introw-credits-remaining-month:
              description: >-
                API credits left in the current calendar month, after this
                request. `0` on a `402`. Absent when the request was not metered
                or when the allowance is unlimited.
              schema:
                type: string
components:
  schemas:
    CreatePayoutBody:
      type: object
      properties:
        partnerId:
          type: string
          minLength: 1
          description: Introw partner the payout is for.
        periodStart:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          description: Start of the commission period the payout covers.
        periodEnd:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          description: >-
            End of the commission period the payout covers. Must be on or after
            periodStart.
        batchId:
          description: >-
            Existing batch to open this payout on, so several partners share one
            payout run. The batch is one period by definition, so it dates the
            payout and periodStart/periodEnd are ignored. When omitted, the
            payout gets a batch of its own. A partner already on the batch
            returns their existing payout instead of a second one.
          type: string
          minLength: 1
        stage:
          description: >-
            Stage to open the payout in. Defaults to DRAFT, which is where the
            app creates one.
          type: string
          enum:
            - DRAFT
            - PENDING_REVIEW
            - PENDING_INVOICE
            - APPROVED
            - SCHEDULED
            - PENDING_PAYMENT
            - PAID
            - DECLINED
            - POSTPONED
            - BLOCKED
            - FAILED
        poNumber:
          description: Partner purchase order number.
          anyOf:
            - type: string
            - type: 'null'
        metadata:
          description: >-
            Free-text block printed on the commission statement PDF, below the
            commission table.
          anyOf:
            - type: string
              maxLength: 2000
            - type: 'null'
        attachPendingLines:
          description: >-
            Attach the partner's pending commission lines whose period overlaps
            this one, the way creating a payout in the app does. Defaults to
            false, so the payout opens empty and you attach lines yourself with
            POST /commission-lines.
          type: boolean
      required:
        - partnerId
        - periodStart
        - periodEnd
      additionalProperties: false
    PayoutResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            id:
              type: string
              description: Introw payout identifier.
            partner:
              type: object
              properties:
                id:
                  type: string
                  description: Introw partner identifier.
                name:
                  type: string
                  description: Partner display name.
              required:
                - id
                - name
              additionalProperties: false
            batchId:
              anyOf:
                - type: string
                - type: 'null'
              description: >-
                Identifier of the payout batch this payout belongs to, when
                assigned.
            periodStart:
              type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
              description: Start of the commission period covered by this payout.
            periodEnd:
              type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
              description: End of the commission period covered by this payout.
            amount:
              type: object
              properties:
                value:
                  type: string
                  description: Decimal amount as a string, e.g. "1250.00".
                currency:
                  type: string
                  description: ISO 4217 currency code, e.g. "USD".
              required:
                - value
                - currency
              additionalProperties: false
            stage:
              type: string
              enum:
                - DRAFT
                - PENDING_REVIEW
                - PENDING_INVOICE
                - APPROVED
                - SCHEDULED
                - PENDING_PAYMENT
                - PAID
                - DECLINED
                - POSTPONED
                - BLOCKED
                - FAILED
            poNumber:
              anyOf:
                - type: string
                - type: 'null'
              description: Partner purchase order number, when provided.
            metadata:
              anyOf:
                - type: string
                - type: 'null'
              description: >-
                Free-text block printed on the commission statement PDF. Null
                when none is set.
            createdAt:
              type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
              description: ISO 8601 timestamp for when the payout was created.
            updatedAt:
              type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
              description: ISO 8601 timestamp for when the payout was last updated.
          required:
            - id
            - partner
            - batchId
            - periodStart
            - periodEnd
            - amount
            - stage
            - poNumber
            - metadata
            - createdAt
            - updatedAt
          additionalProperties: false
      required:
        - data
      additionalProperties: false
    PublicApiError:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: Stable machine-readable error code.
            message:
              type: string
              description: Human-readable error message.
            details:
              description: Optional structured details for validation and debugging.
          required:
            - code
            - message
          additionalProperties: false
      required:
        - error
      additionalProperties: false
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: Introw API key shown once when the credential is created.

````