---
title: "Initiate a payout"
method: POST
path: "/payouts/initiate"
tags: ["Payouts"]
---

# Initiate a payout

`POST /payouts/initiate`

## Request

- Base URL: `https://viral.app/api/v1`
- URL: `https://viral.app/api/v1/payouts/initiate`
- Auth: API key in header `x-api-key`

Stores the finalized payout calculation, engine metadata, and caller-supplied invoice line items for a billing window, and SETTLES that window. Call `POST /payouts/calculate` first and pass the returned `calculation` payload plus `integrityToken` here. The window must be completed, unless you settle and end today: calculate with `windowValidation: "projection"` and `settleToday: true`, then send `allowInProgress: true` with the same `billingPeriodStart` and the calculation's `period.end` (today) as `billingPeriodEnd` — the payout then settles the running period cut to today, and the creator's campaign assignment ends today (a fixed salary is paid pro rata). To pay a completed window and end the assignment after it, send `endAssignment: true` (the running assignment's most recent completed period only). When partial payments were made toward the window (`POST /payouts/partial`), the calculation returns one negative "Already paid" line item per partial; send them back unchanged (a missing or altered one is a 409), every other line item stays yours to customize. `payoutProvider="manual"` (the default) records a payment made outside viral.app; `payoutProvider="talentir"` creates a Talentir payout that waits for approval by a member of your Talentir team in the dashboard.

## Request body

- object
  - `campaignId` string, required: Campaign ID with orgcamp_ prefix
  - `creatorId` string, required: Organization creator ID with orgcre_ prefix
  - `billingPeriodStart` string, date-time, required
  - `billingPeriodEnd` string, date-time, required
  - `lineItems` object[], required
    - `title` string, required
    - `amount` number, required
    - `kind` 'adjustment': Set to "adjustment" for a line whose amount is a percentage of the payout's base (its positive, non-adjustment lines). Send `percent` with it; the amount must equal that percentage of the base, rounded to the currency's minor unit.
    - `percent` number: The adjustment's percentage of the base, -100 to 100 and not 0; a negative value deducts, a positive one adds.
  - `calculation` object, required
    - `period` object, required
      - `index` integer, required
      - `label` string, required
      - `start` string, required
      - `end` string, required
    - `payouts` object, required
      - `total` object, required
        - `amount` number, required
        - `precision` integer, required
        - `currency` string, required
        - `value` number, required
      - `breakdown` object[], required
        - `label` string, required
        - `ruleIds` string[]
        - `ruleName` string, nullable, required
        - `payoutKind` 'flat' | 'rate', required
        - `payoutMode` 'allocation' | 'progressive'
        - `amount` number, required
        - `precision` integer, required
        - `currency` string, required
        - `value` number, required
        - `calculationDetails` object, nullable, required
          - `metricKey` string, required
          - `metricValue` number, required
          - `grain` 'aggregate' | 'per_video' | 'per_platform' | 'per_account'
          - `rawMetricValue` number
          - `metricStartValue` number
          - `metricEndValue` number
          - `eligibleVideoCount` integer
          - `minViewsRequired` integer
          - `conditioned` unknown
          - `creatives` 'once' | 'best' | 'sum': How this row's payouts treat the copies of one creative (the same video posted to several platforms): once, a base payout counts each creative once, on its winner (the copy with the most views); best, a CPM payout or bonus pays only the creative's winner; sum, the per_creative scope: the copies count as one, their views added up on one copy. Absent when the row pays every copy
          - `ratePerUnit` number
          - `perQuantity` integer
          - `mode` 'allocation' | 'progressive'
          - `payoutTiming` 'gains' | 'milestone'
          - `appliedTierIndex` integer
          - `tierBreakdown` union[]
            - union
              - …
          - `maxPayoutApplied` boolean
          - `performanceCapApplied` boolean
          - `baseCapApplied` boolean
          - `earlySettledTopTier` boolean
          - `carriedVideoCount` integer
          - `carriedAmount` number
          - `carriedWindows` object[]
            - `start` string, required
            - `end` string, required
            - `videoCount` integer, required
          - `carriedWaiting` unknown
        - `off` unknown
      - `performanceCap` object
        - `amount` number, required
        - `precision` integer, required
        - `currency` string, required
        - `value` number, required
        - `applied` boolean, required
      - `baseCap` object
        - `amount` number, required
        - `precision` integer, required
        - `currency` string, required
        - `value` number, required
        - `applied` boolean, required
    - `metrics` object, required
      - `facts` object[], required
        - `factName` string, required
        - `metric` 'views' | 'likes' | 'shares' | 'comments' | 'videoCount' | 'engagementRate', required
        - `label` string, required
        - `total` number, required
      - `perVideo` object, nullable, required
        - `metric` 'views' | 'likes' | 'shares' | 'comments' | 'videoCount' | 'engagementRate', required
        - `label` string, required
        - `items` object[], required
          - `id` string, nullable, required
          - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
          - `platformVideoId` string, required
          - `value` number, required
          - `title` string, nullable, required
          - `thumbnailUrl` string, nullable, required
          - `publishedAt` string, nullable, required
          - `accountUsername` string, nullable, required
          - `platformAccountId` string, nullable, required
          - `isCompetitor` boolean, required
          - `contentType` 'video' | 'slideshow', nullable, required: Filter by content types (video, slideshow)
          - `orgAccountId` string, nullable, required: Organization account ID with orgacc_ prefix. Not the same as platform account ID.
          - `payoutAmount` number, nullable, required
          - `payoutCurrency` string, nullable, required
          - `payoutValue` number, nullable, required
          - `creativeCopies` integer: A per-creative payout's row: this video carries its creative, this many copies in all (itself included). On a CPM payout or bonus its value adds up every copy's views; on a base payout it keeps its own views and the creative counts once. The other copies are listed in metrics.mergedCopies
      - `perCategory` object[], nullable, required
        - `category` string, required
        - `metric` 'views' | 'likes' | 'shares' | 'comments' | 'videoCount' | 'engagementRate', required
        - `metricKey` string, required
        - `metricLabel` string, required
        - `items` object[], required
          - `id` string, nullable, required
          - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
          - `platformVideoId` string, required
          - `value` number, required
          - `title` string, nullable, required
          - `thumbnailUrl` string, nullable, required
          - `publishedAt` string, nullable, required
          - `accountUsername` string, nullable, required
          - `platformAccountId` string, nullable, required
          - `isCompetitor` boolean, required
          - `contentType` 'video' | 'slideshow', nullable, required: Filter by content types (video, slideshow)
          - `orgAccountId` string, nullable, required: Organization account ID with orgacc_ prefix. Not the same as platform account ID.
          - `payoutAmount` number, nullable, required
          - `payoutCurrency` string, nullable, required
          - `payoutValue` number, nullable, required
          - `creativeCopies` integer: A per-creative payout's row: this video carries its creative, this many copies in all (itself included). On a CPM payout or bonus its value adds up every copy's views; on a base payout it keeps its own views and the creative counts once. The other copies are listed in metrics.mergedCopies
      - `viewBasis` 'total' | 'organic'
      - `manuallyExcludedVideos` object[]
        - `id` string, nullable, required
        - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
        - `platformVideoId` string, required
        - `value` number, required
        - `title` string, nullable, required
        - `thumbnailUrl` string, nullable, required
        - `publishedAt` string, nullable, required
        - `accountUsername` string, nullable, required
        - `platformAccountId` string, nullable, required
        - `isCompetitor` boolean, required
        - `contentType` 'video' | 'slideshow', nullable, required: Filter by content types (video, slideshow)
        - `orgAccountId` string, nullable, required: Organization account ID with orgacc_ prefix. Not the same as platform account ID.
        - `payoutAmount` number, nullable, required
        - `payoutCurrency` string, nullable, required
        - `payoutValue` number, nullable, required
        - `creativeCopies` integer: A per-creative payout's row: this video carries its creative, this many copies in all (itself included). On a CPM payout or bonus its value adds up every copy's views; on a base payout it keeps its own views and the creative counts once. The other copies are listed in metrics.mergedCopies
        - `ruleIds` string[]
      - `conditionMisses` object[]
        - `category` string, required
        - `ruleIds` string[], required
        - `scope` 'per_video' | 'aggregate', required
        - `items` object[], required
          - `id` string, nullable, required
          - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
          - `platformVideoId` string, required
          - `value` number, required
          - `title` string, nullable, required
          - `thumbnailUrl` string, nullable, required
          - `publishedAt` string, nullable, required
          - `accountUsername` string, nullable, required
          - `platformAccountId` string, nullable, required
          - `isCompetitor` boolean, required
          - `contentType` 'video' | 'slideshow', nullable, required: Filter by content types (video, slideshow)
          - `orgAccountId` string, nullable, required: Organization account ID with orgacc_ prefix. Not the same as platform account ID.
          - `payoutAmount` number, nullable, required
          - `payoutCurrency` string, nullable, required
          - `payoutValue` number, nullable, required
          - `creativeCopies` integer: A per-creative payout's row: this video carries its creative, this many copies in all (itself included). On a CPM payout or bonus its value adds up every copy's views; on a base payout it keeps its own views and the creative counts once. The other copies are listed in metrics.mergedCopies
          - `failed` union[], required
            - union
              - …
          - `wouldEarn` number, nullable
          - `creative` object: Set when a creative payout left this copy out (the group's creatives option): the reason, and the copy that earns instead. failed is empty then: the creative option, not a condition, left the copy out
            - `reason` 'not_best' | 'counted_before' | 'counted_with' | 'bought_out' | 'earlier_period' | 'creative_views', required: Why this copy earned nothing here. not_best: another copy of the creative has more views and is the one a winner-only CPM payout or bonus pays. counted_with: another copy (the winner) counts the creative once in this period. counted_before: the creative was already counted in an earlier period. bought_out: a copy of the creative was paid on its own (a video payout instead of the campaign's pay), which settles the creative for this payout. earlier_period: the creative was first posted in an earlier period and judged there (a per-creative base payout with a Video views condition). creative_views: the copies' combined views (views) fall outside that Video views condition
            - `views` number: This copy's views over the payout's time frame; for creative_views, the creative's combined views
            - `by` object, required: The copy that earns or counts instead: the creative's winner, the copy counted earlier or the bought-out copy; for earlier_period the copy posted in that earlier period, for creative_views the creative's leading copy
              - …
        - `omittedCount` integer, required
        - `failedGates` object[]
          - `condition` union, required
            - object
              - …
            - object
              - …
          - `total` number, required
        - `forfeit` object
          - `amount` number, required
          - `precision` integer, required
          - `currency` string, required
          - `value` number, required
        - `creatives` union: The group lists copies a creative payout did not pay (each item carries creative): the payout's option (once, best or sum, as on calculationDetails.creatives), or true on calculations from before it was recorded
          - unknown
          - 'once' | 'best' | 'sum'
      - `carriedVideos` object[]: Per base payout row, the earlier periods' videos it pays as carried (a missed total videos minimum with a carry), or that wait for a period that reaches the minimum
        - `category` string, required: The breakdown row's label
        - `ruleIds` string[], required
        - `status` 'paid' | 'waiting', required
        - `items` object[], required
          - `id` string, nullable, required
          - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
          - `platformVideoId` string, required
          - `value` number, required
          - `title` string, nullable, required
          - `thumbnailUrl` string, nullable, required
          - `publishedAt` string, nullable, required
          - `accountUsername` string, nullable, required
          - `platformAccountId` string, nullable, required
          - `isCompetitor` boolean, required
          - `contentType` 'video' | 'slideshow', nullable, required: Filter by content types (video, slideshow)
          - `orgAccountId` string, nullable, required: Organization account ID with orgacc_ prefix. Not the same as platform account ID.
          - `payoutAmount` number, nullable, required
          - `payoutCurrency` string, nullable, required
          - `payoutValue` number, nullable, required
          - `creativeCopies` integer: A per-creative payout's row: this video carries its creative, this many copies in all (itself included). On a CPM payout or bonus its value adds up every copy's views; on a base payout it keeps its own views and the creative counts once. The other copies are listed in metrics.mergedCopies
          - `carriedFrom` object, required: The missed period the video was posted in (YYYY-MM-DD)
            - `start` string, required
            - `end` string, required
        - `omittedCount` integer, required
      - `mergedCopies` object[]: Per breakdown row of a per-creative payout, the copies that counted with another copy of their creative (dialog and breakdown calculations only). Not misses: they are paid through that copy
        - `category` string, required: The breakdown row's label
        - `ruleIds` string[], required
        - `pay` 'once' | 'sum', required: once: a base payout counted the creative once, on the into copy (each copy keeps its own views). sum: a CPM payout or bonus added the copies' views up on the into copy
        - `items` object[], required
          - `id` string, nullable, required
          - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
          - `platformVideoId` string, required
          - `value` number, required
          - `title` string, nullable, required
          - `thumbnailUrl` string, nullable, required
          - `publishedAt` string, nullable, required
          - `accountUsername` string, nullable, required
          - `platformAccountId` string, nullable, required
          - `isCompetitor` boolean, required
          - `contentType` 'video' | 'slideshow', nullable, required: Filter by content types (video, slideshow)
          - `orgAccountId` string, nullable, required: Organization account ID with orgacc_ prefix. Not the same as platform account ID.
          - `payoutAmount` number, nullable, required
          - `payoutCurrency` string, nullable, required
          - `payoutValue` number, nullable, required
          - `creativeCopies` integer: A per-creative payout's row: this video carries its creative, this many copies in all (itself included). On a CPM payout or bonus its value adds up every copy's views; on a base payout it keeps its own views and the creative counts once. The other copies are listed in metrics.mergedCopies
          - `into` object, required: The copy the row lists, which this copy counted with
            - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
            - `platformVideoId` string, required
        - `omittedCount` integer, required
      - `conditionTagNames` object
      - `conditionForfeit` object
        - `amount` number, required
        - `precision` integer, required
        - `currency` string, required
        - `value` number, required
      - `videoGates` object[]
        - `ruleId` string, required
        - `required` integer, required
        - `count` integer, required
        - `met` boolean, required
    - `settlement` object
      - `purpose` 'settle' | 'partial', required
      - `calculatedAt` string, required
      - `inProgress` boolean, required
      - `fixedElapsedFactor` number, required
      - `partials` object[], required
        - `payoutId` string, required
        - `amount` integer, required
        - `coveredAmount` integer
        - `paidAt` string, required
      - `separatelyPaidVideos` object[], required
        - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
        - `platformVideoId` string, required
      - `placedVideos` object[]
        - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
        - `platformVideoId` string, required
      - `includedVideos` object[]
        - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
        - `platformVideoId` string, required
      - `carriedVideos` object[]
        - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
        - `platformVideoId` string, required
        - `periodStart` string, required
        - `periodEnd` string, required
        - `ruleId` string
      - `priorCarriedVideos` object[]
        - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
        - `platformVideoId` string, required
      - `carryStops` object[]
        - `ruleId` string, required
        - `periodStart` string, required
      - `timeZone` string: IANA time zone the campaign's periods and dates follow (a period ends at midnight in this zone). Views are still counted per UTC day.
      - `viewsOpenUntil` string
      - `closure` object
        - `kind` 'covered' | 'written_off', required
        - `overpaidAmount` integer, required
        - `writtenOffAmount` integer, required
    - `customRates` boolean
    - `engine` object, required
      - `prorationFactor` number, required
      - `rulesSnapshot` union[], required
        - union
          - object
            - `version` unknown, required
            - `id` string, required
            - `kind` 'fixed', required
            - `name` 'fixed_salary', required
            - `priority` integer, required
            - `payout` object, required
              - …
          - object
            - `version` unknown, required
            - `id` string, required
            - `kind` 'metric', required
            - `name` string, required
            - `priority` integer, required
            - `fact` union, required
              - …
            - `tier` object, required
              - …
            - `payout` union, required
              - …
          - object
            - `version` unknown, required
            - `id` string, required
            - `kind` 'cap', required
            - `name` 'performance_total_cap', required
            - `priority` integer, required
            - `appliesTo` 'performance', required
            - `cap` object, required
              - …
          - object
            - `version` unknown, required
            - `id` string, required
            - `kind` 'cap', required
            - `name` 'base_total_cap', required
            - `priority` integer, required
            - `appliesTo` 'base', required
            - `cap` object, required
              - …
      - `factTraces` object[], required
        - `id` string, required
        - `ruleId` string, nullable, required
        - `ruleName` string, nullable, required
        - `source` 'global' | 'fact', required
        - `factType` 'fixed' | 'metric' | 'snapshot_ratio', required
        - `requirement` object, nullable, required
          - `type` 'metric' | 'snapshot_ratio', required
          - `metric` 'view_gain' | 'like_gain' | 'comment_gain' | 'share_gain' | 'video_count' | 'engagement_rate', required
          - `grain` 'aggregate' | 'per_video' | 'per_platform' | 'per_account', required
          - `aggregation` 'sum' | 'avg' | 'count' | 'min' | 'max', nullable, required
          - `formula` 'engagement_actions_per_view', nullable, required
          - `windowDays` integer, required
          - `publicationScope` 'include_earlier' | 'billing_period_only', required
          - `assignmentPublicationMode` 'assigned_only' | 'include_pre_assignment'
          - `platformFilter` object
            - `include` string[]
            - `exclude` string[]
          - `videoFilter` object
            - `minViews` integer, required
          - `conditions` object
            - `match` 'all' | 'any', required
            - `items` union[], required
              - …
        - `payoutKind` 'flat' | 'rate', required
        - `payoutMode` 'allocation' | 'progressive'
        - `payoutTiming` 'gains' | 'milestone'
        - `tier` object, nullable, required
          - `min` object, required
            - `value` number, required
            - `bound` 'exclusive' | 'inclusive', required
          - `max` object, nullable, required
            - `value` number, required
            - `bound` 'exclusive' | 'inclusive', required
        - `billingWindow` object, required
          - `start` string, required
          - `end` string, required
          - `anchor` 'rolling' | 'fixed', required
          - `timeZone` string, required: IANA time zone the campaign's periods and dates follow (a period ends at midnight in this zone). Views are still counted per UTC day.
        - `factCount` integer, required
        - `requiresProgressiveBaseline` boolean, required
        - `requiresMilestoneFacts` boolean, required
      - `engineTotals` object, required
        - `amount` number, required
        - `precision` integer, required
        - `currency` string, required
        - `value` number, required
      - `engineEvents` object[], required
        - `ruleId` string, nullable
        - `ruleName` string, nullable
        - `ruleIndex` integer
        - `payoutKind` 'flat' | 'rate', required
        - `payoutMode` 'allocation' | 'progressive'
        - `source` 'global' | 'fact', required
        - `factTraceId` string, required
        - `factTrace` object, required
          - `id` string, required
          - `ruleId` string, nullable, required
          - `ruleName` string, nullable, required
          - `source` 'global' | 'fact', required
          - `factType` 'fixed' | 'metric' | 'snapshot_ratio', required
          - `requirement` object, nullable, required
            - `type` 'metric' | 'snapshot_ratio', required
            - `metric` 'view_gain' | 'like_gain' | 'comment_gain' | 'share_gain' | 'video_count' | 'engagement_rate', required
            - `grain` 'aggregate' | 'per_video' | 'per_platform' | 'per_account', required
            - `aggregation` 'sum' | 'avg' | 'count' | 'min' | 'max', nullable, required
            - `formula` 'engagement_actions_per_view', nullable, required
            - `windowDays` integer, required
            - `publicationScope` 'include_earlier' | 'billing_period_only', required
            - `assignmentPublicationMode` 'assigned_only' | 'include_pre_assignment'
            - `platformFilter` object
              - …
            - `videoFilter` object
              - …
            - `conditions` object
              - …
          - `payoutKind` 'flat' | 'rate', required
          - `payoutMode` 'allocation' | 'progressive'
          - `payoutTiming` 'gains' | 'milestone'
          - `tier` object, nullable, required
            - `min` object, required
              - …
            - `max` object, nullable, required
              - …
          - `billingWindow` object, required
            - `start` string, required
            - `end` string, required
            - `anchor` 'rolling' | 'fixed', required
            - `timeZone` string, required: IANA time zone the campaign's periods and dates follow (a period ends at midnight in this zone). Views are still counted per UTC day.
          - `factCount` integer, required
          - `requiresProgressiveBaseline` boolean, required
          - `requiresMilestoneFacts` boolean, required
        - `payout` object, required
          - `amount` number, required
          - `precision` integer, required
          - `currency` string, required
          - `value` number, required
        - `fact` object, required
          - `creatorId` string, required
          - `campaignId` string, required
          - `billingPeriodStart` string, required
          - `billingPeriodEnd` string, required
          - `prorationFactor` number, required
        - `details` object, nullable, required
          - `metricKey` string, required
          - `metricValue` number, required
          - `grain` 'aggregate' | 'per_video' | 'per_platform' | 'per_account'
          - `rawMetricValue` number
          - `metricStartValue` number
          - `metricEndValue` number
          - `eligibleVideoCount` integer
          - `minViewsRequired` integer
          - `conditioned` unknown
          - `creatives` 'once' | 'best' | 'sum': How this row's payouts treat the copies of one creative (the same video posted to several platforms): once, a base payout counts each creative once, on its winner (the copy with the most views); best, a CPM payout or bonus pays only the creative's winner; sum, the per_creative scope: the copies count as one, their views added up on one copy. Absent when the row pays every copy
          - `ratePerUnit` number
          - `perQuantity` integer
          - `mode` 'allocation' | 'progressive'
          - `payoutTiming` 'gains' | 'milestone'
          - `appliedTierIndex` integer
          - `tierBreakdown` union[]
            - union
              - …
          - `maxPayoutApplied` boolean
          - `performanceCapApplied` boolean
          - `baseCapApplied` boolean
          - `earlySettledTopTier` boolean
          - `carriedVideoCount` integer
          - `carriedAmount` number
          - `carriedWindows` object[]
            - `start` string, required
            - `end` string, required
            - `videoCount` integer, required
          - `carriedWaiting` unknown
      - `engineFacts` object[], required
        - `creatorId` string, required
        - `campaignId` string, required
        - `billingPeriodStart` string, required
        - `billingPeriodEnd` string, required
        - `prorationFactor` number, required
        - `interval` 'day' | 'week' | 'month', required
        - `intervalCount` integer, required
        - `fixedElapsedFactor` number
        - `totalViews` number
        - `totalEarnings` number
        - `totalImpressions` number
      - `engineWarnings` string[], required
      - `accountSnapshot` object, required
        - `snapshotVersion` unknown
        - `accounts` object[], required
          - `orgAccountId` string, required: Organization account ID with orgacc_ prefix. Not the same as platform account ID.
          - `platform` 'facebook' | 'instagram' | 'tiktok' | 'youtube' | 'snapchat', required: Social media platform (facebook, instagram, tiktok, youtube, snapchat)
          - `platformAccountId` string, required: Native platform account id
          - `maxVideos` integer, required
          - `hashtagsFilter` string[], nullable
        - `excludedVideosHash` string, required
        - `excludedVideosCount` integer, required
        - `creativeGroups` object
          - `creativeGroupsHash` string, required
          - `creativeGroupsCount` integer, required
  - `integrityToken` string, required: Required integrity token returned by POST /payouts/calculate for this exact calculation payload and billing window. Pass it unchanged.
  - `reference` string: Optional payout reference for reconciliation, invoicing, or external bookkeeping.
  - `notes` string: Optional internal payout notes visible to organization members.
  - `payoutProvider` 'manual' | 'talentir'
  - `allowInProgress` boolean: Settle and end today. The running billing window is cut to today, this payout settles that cut period, and the creator's campaign assignment ends today (a fixed salary is paid pro rata). Requires a calculation made with `purpose: "settle"` and `windowValidation: "projection"`, whose `period.end` is today — send that period here — and no older than 24 hours.
  - `endAssignment` boolean: Pay and end, for a completed window: the creator's campaign assignment ends after this billing period (its last day becomes the period's end), in the same transaction as the payout. Only the running assignment's most recent completed period qualifies, and nothing may be paid or canceled after it — a partial payment toward the running period included. What the creator earned after the period is not paid. `allowInProgress` ends the assignment today on its own.
  - `acknowledgeOpenViews` boolean: Pay a completed period whose views still count. Outside UTC a period ends at midnight in the campaign's time zone, but views are counted per UTC day, so the views of the UTC day the period ends on keep counting until that day is over (the calculation's `settlement.viewsOpenUntil`). Until then the payout is refused with `VIEWS_STILL_OPEN` unless you send `true`; views counted after the payout are not paid.

## Response `200`

OK

- object
  - `success` unknown, required
  - `payoutId` string, required: Payout ID with orgpay_ prefix
  - `providerPayoutId` string, nullable

## Other responses

- `400`: 400
- `401`: 401
- `402`: 402
- `404`: 404
- `408`: 408
- `409`: 409
- `412`: 412
- `422`: 422
- `429`: 429
- `500`: 500
- `502`: 502

---

[API](https://skmtc.dev/viral/apis/viral-app-api.md) · [All operations](https://skmtc.dev/viral/apis/viral-app-api/llms.txt) · [OpenAPI document](https://skmtc.dev/viral/apis/viral-app-api/revisions/31e97fa79ef1?raw)
