{
  "openapi": "3.0.4",
  "info": {
    "title": "Launchpoint Public API",
    "version": "1.0.0",
    "description": "**Private preview.** The Launchpoint Public API is in private preview and available only to trusted partners we work with directly. Access is not self-serve. Email hi@launchpointhq.com to ask about access.\n\nREST API for Launchpoint brands and agencies. Use an API key in the `x-api-key` header to authenticate.\n\n## Requirements\n- Public API access must be enabled for the company. During private preview, access is limited to trusted partners.\n- Create and manage API keys in Dashboard \u2192 Settings \u2192 Developer.\n\n## Creator privacy\n- Responses never include creator email addresses. Creator phone numbers are null when no number is stored or the workspace does not have access to creator contact details.\n\n## Rate limits\n- Default: **100 requests per minute** per API key.\n- Approved partner accounts: **400 requests per minute**.\n- Every response includes `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`. Requests over the limit return `429`.\n\n## Errors\n- Errors use `{ \"error\": \"<message>\" }` with the matching HTTP status. Some endpoints also include a `code`.\n\n## Timestamps\n- Timestamps are Unix timestamps in milliseconds unless a field says otherwise.\n\n## Pagination\n- Most list endpoints accept `page` and `limit` and return `{ data, page, total }`. Some also return `totalPages`.\n- `scope=company` is the default. A parent agency key can pass `scope=agency` on supported routes to include its own data and linked brands."
  },
  "servers": [
    {
      "url": "https://dashboard.launchpointhq.com/api/v1",
      "description": "Live API server"
    }
  ],
  "tags": [
    {
      "name": "Deals",
      "description": "Public creator opportunities across Launchpoint"
    },
    {
      "name": "Programs",
      "description": "Programs and campaign management"
    },
    {
      "name": "Posts",
      "description": "Posts and social content"
    },
    {
      "name": "Analytics",
      "description": "KPIs and performance metrics"
    },
    {
      "name": "Payouts",
      "description": "Payouts, balances, and pending creator funds"
    },
    {
      "name": "Contracts",
      "description": "Contracts and creator agreements"
    },
    {
      "name": "Creators",
      "description": "Creator profiles and metrics"
    },
    {
      "name": "Applications",
      "description": "Creator applications to Canvas programs"
    },
    {
      "name": "Messages",
      "description": "Read and send creator messages"
    },
    {
      "name": "Onboarding",
      "description": "Creator onboarding: status, messages, and proof review"
    },
    {
      "name": "Media review",
      "description": "Review the media creators send before they post: queue, status, approve, and reject"
    }
  ],
  "components": {
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key created in Dashboard \u2192 Settings \u2192 Developer"
      }
    },
    "parameters": {
      "ScopeParam": {
        "in": "query",
        "name": "scope",
        "required": false,
        "schema": {
          "type": "string",
          "enum": [
            "company",
            "agency"
          ],
          "default": "company"
        },
        "description": "Choose the data scope. `company` (default) limits results to the API key company's data. `agency` includes the parent agency and its linked brands. `scope=agency` requires a parent agency key; other keys receive `403`."
      },
      "CreatorHandleParam": {
        "in": "query",
        "name": "creatorHandle",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Limit results to creators who have a linked social account with exactly this handle, in any letter case. A leading `@` is ignored. A handle that no visible creator linked returns an empty result. Use it when you know the handle but not the `creatorId`."
      }
    },
    "schemas": {
      "PostPlatform": {
        "type": "string",
        "enum": [
          "tiktok",
          "instagram",
          "youtube",
          "facebook",
          "snapchat"
        ]
      },
      "AudienceDistribution": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "percentage": {
            "type": "number"
          }
        }
      },
      "InstagramAudience": {
        "type": "object",
        "properties": {
          "basis": {
            "type": "string",
            "enum": [
              "reached",
              "engaged",
              "followers"
            ]
          },
          "sampleSize": {
            "type": "integer",
            "nullable": true,
            "description": "Number of people behind the country distribution, or null when the source has percentages without counts"
          },
          "countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AudienceDistribution"
            }
          },
          "ages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AudienceDistribution"
            }
          },
          "genders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AudienceDistribution"
            }
          },
          "cities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AudienceDistribution"
            }
          }
        }
      },
      "CreatorAudienceBlock": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "available",
              "no_data"
            ]
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "unsupported_platform",
              "no_data_marker",
              "never_fetched"
            ]
          },
          "countriesReason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "unsupported_platform",
              "no_data_marker",
              "never_fetched"
            ]
          },
          "usAudiencePercentage": {
            "type": "number",
            "nullable": true,
            "description": "US audience percentage from the monthly country refresh only; null does not mean zero. A saved no-data marker can return 0; that does not prove the US share is zero."
          },
          "sampleSize": {
            "type": "integer",
            "nullable": true,
            "description": "Number of people behind the returned country distribution, or null when the saved source has percentages without counts"
          },
          "countries": {
            "type": "array",
            "description": "Country distribution from the monthly country refresh when available, or the Instagram account's own country split when no monthly geo row exists.",
            "items": {
              "$ref": "#/components/schemas/AudienceDistribution"
            }
          },
          "ages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AudienceDistribution"
            }
          },
          "genders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AudienceDistribution"
            }
          },
          "cities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AudienceDistribution"
            }
          },
          "demographicsBasis": {
            "type": "string",
            "nullable": true,
            "enum": [
              "reached",
              "followers"
            ]
          },
          "instagramAudiences": {
            "type": "array",
            "description": "Separate Instagram populations reported by Meta: people reached, people who engaged, and followers. These are different sets of people and should not be added together.",
            "items": {
              "$ref": "#/components/schemas/InstagramAudience"
            }
          }
        }
      },
      "CreatorAudienceAccount": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string"
          },
          "handle": {
            "type": "string",
            "nullable": true
          },
          "lastUpdatedAt": {
            "type": "integer",
            "nullable": true,
            "description": "Unix timestamp in milliseconds; audience data may be up to about 30 days old"
          },
          "audience": {
            "$ref": "#/components/schemas/CreatorAudienceBlock"
          }
        }
      },
      "CreatorConversation": {
        "type": "object",
        "required": [
          "id",
          "programId",
          "creatorId",
          "creatorName",
          "unreadCount",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "programId": {
            "type": "string",
            "format": "uuid"
          },
          "creatorId": {
            "type": "string",
            "description": "Opaque creator id returned by the public API"
          },
          "creatorName": {
            "type": "string"
          },
          "lastMessageAt": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "lastMessagePreview": {
            "type": "string",
            "nullable": true
          },
          "lastMessageDirection": {
            "type": "string",
            "enum": [
              "outbound",
              "inbound"
            ],
            "nullable": true
          },
          "unreadCount": {
            "type": "integer"
          },
          "creatorLastReadAt": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdAt": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "CreatorMessage": {
        "type": "object",
        "required": [
          "id",
          "conversationId",
          "direction",
          "body",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "conversationId": {
            "type": "string",
            "format": "uuid"
          },
          "direction": {
            "type": "string",
            "enum": [
              "outbound",
              "inbound"
            ],
            "description": "outbound means sent by the workspace; inbound means sent by the creator"
          },
          "body": {
            "type": "string"
          },
          "createdAt": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "CreatorDeal": {
        "type": "object",
        "required": [
          "id",
          "name",
          "description",
          "brandName",
          "brandIconUrl",
          "url",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Stable Launchpoint deal ID."
          },
          "name": {
            "type": "string",
            "description": "Campaign display name."
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Public deal description, or null when not supplied. Treat this value as text, not trusted HTML."
          },
          "brandName": {
            "type": "string",
            "nullable": true
          },
          "brandIconUrl": {
            "type": "string",
            "nullable": true
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Public deal landing page. Show this link on your deal card. No Launchpoint account is needed to view it. It has links to open the selected deal in the app, download the iPhone app, or continue on web."
          },
          "createdAt": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Unix timestamp in milliseconds, or null when unavailable."
          },
          "updatedAt": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Unix timestamp in milliseconds, or null when unavailable."
          }
        }
      },
      "OnboardingProof": {
        "type": "object",
        "required": [
          "id",
          "type",
          "programId",
          "creatorId",
          "account",
          "requirement",
          "media",
          "status",
          "rejectionComments",
          "submittedAt",
          "reviewedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "account_requirement",
              "warm_up"
            ],
            "description": "`account_requirement`: a screenshot or screen recording for a custom account requirement of the program. `warm_up`: a screen recording of the creator's warmed-up feed."
          },
          "programId": {
            "type": "string",
            "format": "uuid"
          },
          "creatorId": {
            "type": "string",
            "description": "Opaque creator id, the same as in `/creators`"
          },
          "account": {
            "type": "object",
            "required": [
              "platform",
              "username"
            ],
            "properties": {
              "platform": {
                "type": "string",
                "description": "Platform of the creator account the proof is for"
              },
              "username": {
                "type": "string",
                "nullable": true,
                "description": "Null while creator details are locked for the workspace"
              }
            }
          },
          "requirement": {
            "type": "object",
            "required": [
              "id",
              "label",
              "instructions",
              "searchTerms"
            ],
            "properties": {
              "id": {
                "type": "string",
                "nullable": true,
                "description": "Custom requirement id. Null for a warm-up proof."
              },
              "label": {
                "type": "string",
                "nullable": true,
                "description": "Requirement name. `Account warm-up` for a warm-up proof."
              },
              "instructions": {
                "type": "string",
                "nullable": true,
                "description": "What the creator was asked to show. For a warm-up proof, the program's warm-up instructions for the platform."
              },
              "searchTerms": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Warm-up niches the feed should show. Empty for an account requirement."
              }
            }
          },
          "media": {
            "type": "object",
            "required": [
              "kind",
              "mediaUrl",
              "thumbnailUrl"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "image",
                  "video"
                ]
              },
              "mediaUrl": {
                "type": "string",
                "nullable": true,
                "description": "Link that downloads the proof file. Null unless media links are turned on for your workspace (email hi@launchpointhq.com). The link does not expire; do not share it."
              },
              "thumbnailUrl": {
                "type": "string",
                "nullable": true,
                "description": "Preview image link. Null unless media links are turned on for your workspace."
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_review",
              "approved",
              "rejected"
            ]
          },
          "rejectionComments": {
            "type": "string",
            "nullable": true,
            "description": "The message the creator saw when the proof was rejected"
          },
          "submittedAt": {
            "type": "integer",
            "format": "int64"
          },
          "reviewedAt": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        }
      },
      "MediaReviewItem": {
        "type": "object",
        "required": [
          "id",
          "programId",
          "creatorId",
          "revisionId",
          "media",
          "status",
          "rejectionComments",
          "submittedAt",
          "reviewedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "programId": {
            "type": "string",
            "format": "uuid"
          },
          "creatorId": {
            "type": "string",
            "description": "Opaque creator id, the same as in `/creators`"
          },
          "revisionId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "The newest revision of the media. Send it back with a decision so that the decision fails if the creator sent a newer revision after you read this one."
          },
          "media": {
            "type": "object",
            "required": [
              "kind",
              "mediaUrl",
              "thumbnailUrl",
              "carouselMediaUrls"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "video",
                  "carousel"
                ]
              },
              "mediaUrl": {
                "type": "string",
                "nullable": true,
                "description": "Link that downloads the video file. Null unless media links are turned on for your workspace (email hi@launchpointhq.com). The link does not expire; do not share it."
              },
              "thumbnailUrl": {
                "type": "string",
                "nullable": true,
                "description": "Link to the preview image. Null under the same rule as `mediaUrl`."
              },
              "carouselMediaUrls": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Links to the images of a carousel. Empty for a video, and empty under the same rule as `mediaUrl`."
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_review",
              "approved",
              "rejected",
              "not_reviewable"
            ],
            "description": "`pending_review`: the media is in your review queue, so approve and reject can act on it. `not_reviewable`: the media has no decision and is not in your queue, for example while the managing agency has not passed it. Only a read of one item returns it."
          },
          "rejectionComments": {
            "type": "string",
            "nullable": true,
            "description": "The message the creator got. Null unless the status is `rejected`."
          },
          "submittedAt": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "When the creator sent the newest revision, in Unix milliseconds"
          },
          "reviewedAt": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "When the media was approved or rejected, in Unix milliseconds"
          }
        }
      },
      "PostPayment": {
        "type": "object",
        "description": "Where the post's pay stands. `paid` means the money reached the creator's Launchpoint balance, not that the creator withdrew it. Amounts are whole cents.",
        "required": [
          "state"
        ],
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "paid",
              "pending",
              "excluded",
              "credit_missing",
              "clawed_back",
              "paid_off_platform",
              "unknown"
            ],
            "description": "`paid`: credits cover the pay owed. `pending`: pay is owed (or zero so far) and has not reached the creator. `excluded`: the post was removed from the program; see `exclusion`. `credit_missing`: brand money was spent for the post but the creator credit is missing; contact Launchpoint. `clawed_back`: the creator was credited, then the credit was taken back. `paid_off_platform`: the brand marked the pay as sent outside Launchpoint. `unknown`: the post is not visible to this API key or does not exist (lookup only)."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD"
            ]
          },
          "earnedCents": {
            "type": "integer",
            "description": "Pay owed now on the post's own pay lines"
          },
          "billedCents": {
            "type": "integer",
            "description": "Pay billed on an invoice that is not void"
          },
          "creditedCents": {
            "type": "integer",
            "description": "Money added to the creator's Launchpoint balance for this post, after any clawback"
          },
          "invoiceIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Invoices that bill this post"
          },
          "lastCreditedAt": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Time of the latest credit, in Unix milliseconds"
          }
        }
      },
      "PostExclusion": {
        "type": "object",
        "description": "The record kept when a post is removed from a program. It stays after the post itself is deleted.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "excludedAt": {
            "type": "integer",
            "format": "int64",
            "description": "Unix milliseconds"
          },
          "disposition": {
            "type": "string",
            "enum": [
              "excluded",
              "unlinked"
            ],
            "description": "`excluded`: removed from pay for good. `unlinked`: removed from the program; the platform post can be imported again under a new id."
          },
          "source": {
            "type": "string",
            "enum": [
              "dashboard",
              "api",
              "creator_removal",
              "trial_reel_variant",
              "relink",
              "import_cleanup",
              "script",
              "backfill"
            ],
            "description": "Where the removal was made. `backfill`: recorded later by Launchpoint; the original surface is not known."
          },
          "actorWorkspaceId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "The workspace that removed the post; null for Launchpoint jobs"
          },
          "message": {
            "type": "string",
            "nullable": true,
            "description": "The text sent to the creator; null when the creator was not told"
          },
          "pendingCentsRemoved": {
            "type": "integer",
            "nullable": true,
            "description": "Pay owed and not credited when the post was removed; null when not recorded"
          }
        }
      }
    }
  },
  "security": [
    {
      "apiKeyAuth": []
    }
  ],
  "paths": {
    "/deals": {
      "get": {
        "tags": [
          "Deals"
        ],
        "operationId": "listCreatorDeals",
        "summary": "List creator deals",
        "description": "List public creator opportunities across Launchpoint for a jobs board or creator app. This catalog is platform-wide, not limited to the API key company. It includes only public, active campaigns that accept submissions and have not been deleted. Private, unlisted, paused, closed, and deleted deals are excluded.\n\nUse each item\u2019s `url` for the details action. It opens a public landing page before signup, with app, iPhone download, and web links. After installation or signup, a new creator must return to that page and open the deal again; automatic return through app installation is not supported.\n\nThis is not a personalized eligibility or pay feed. Launchpoint checks eligibility and shows current terms when the creator applies. The feed does not return creator identities, private budgets, or sourcing rewards.\n\nThe only query parameters are `page` and `limit`. Unsupported parameters, including `scope` and creator filters, return `400`. Results are ordered by stable deal ID. Fetch successive pages through `totalPages` to read the full catalog. Paging reads live state, so changes during a crawl can move rows between pages. Deduplicate by `id` and replace your cached catalog after each complete refresh.",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagination page number"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Items to return per page"
          }
        ],
        "responses": {
          "200": {
            "description": "Creator deals returned successfully. An empty catalog has data: [], total: 0, and totalPages: 0.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in this window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Window reset time in Unix seconds.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "page",
                    "total",
                    "totalPages"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CreatorDeal"
                      }
                    },
                    "page": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "total": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "totalPages": {
                      "type": "integer",
                      "minimum": 0
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "11111111-1111-4111-8111-111111111111",
                      "name": "Daily routine videos",
                      "description": "Create videos about your daily routine.",
                      "brandName": "Example brand",
                      "brandIconUrl": null,
                      "url": "https://dashboard.launchpointhq.com/creator-deals/11111111-1111-4111-8111-111111111111",
                      "createdAt": 1788220800000,
                      "updatedAt": null
                    }
                  ],
                  "page": 1,
                  "total": 1,
                  "totalPages": 1
                }
              }
            }
          },
          "400": {
            "description": "Invalid pagination or unsupported query parameter.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in this window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Window reset time in Unix seconds.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked API key.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in this window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Window reset time in Unix seconds.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API access is disabled for the workspace.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in this window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Window reset time in Unix seconds.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API key rate limit exceeded. Retry after the Retry-After header value in seconds.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in this window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Window reset time in Unix seconds.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Launchpoint could not complete the request.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in this window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Window reset time in Unix seconds.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/pay-structures": {
      "get": {
        "tags": [
          "Payouts"
        ],
        "summary": "Browse creator pay structures",
        "description": "Get the pay terms for each visible creator and program.\n\nThis endpoint includes offer-level cash terms and active Canvas payscales. `baseRateCents` contains cash entries only. Manual and Shopify entries are returned separately in `nonCashBaseRateEntries` with their `valueCents`; a product seed is not cash. `platformRatios: null` means there is no platform split. In the Canvas `assigned` block, `assignment: \"explicit\"` means the creator really resolves to that payscale group. `assignment: \"campaign_default\"` covers both a creator who was never assigned and a creator whose assigned group no longer exists; `assignedAt` is epoch milliseconds for an explicit assignment and is null for `campaign_default`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagination page number"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Items to return per page"
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results to one opaque creator ID"
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "programId",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Narrow results to one program"
          }
        ],
        "responses": {
          "200": {
            "description": "Pay structures returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "creatorId": {
                            "type": "string"
                          },
                          "creatorName": {
                            "type": "string"
                          },
                          "programId": {
                            "type": "string"
                          },
                          "programName": {
                            "type": "string"
                          },
                          "contractId": {
                            "type": "string",
                            "nullable": true
                          },
                          "createdAt": {
                            "type": "integer",
                            "description": "Unix timestamp in milliseconds"
                          },
                          "updatedAt": {
                            "type": "integer",
                            "description": "Unix timestamp in milliseconds"
                          },
                          "money": {
                            "type": "object",
                            "properties": {
                              "payModelKind": {
                                "type": "string",
                                "nullable": true,
                                "description": "The offer pricing kind, or `canvas_payscale` for a creator on Canvas"
                              },
                              "baseRateCents": {
                                "type": "integer",
                                "description": "Cash base-rate entries only, in the smallest currency unit"
                              },
                              "nonCashBaseRateEntries": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "currency": {
                                      "type": "string",
                                      "enum": [
                                        "manual",
                                        "shopify"
                                      ]
                                    },
                                    "name": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "valueCents": {
                                      "type": "integer",
                                      "description": "Declared non-cash value; not included in baseRateCents"
                                    }
                                  }
                                }
                              },
                              "cpmCents": {
                                "type": "integer",
                                "nullable": true
                              },
                              "cpcCents": {
                                "type": "integer",
                                "nullable": true
                              },
                              "viewCap": {
                                "type": "integer",
                                "nullable": true
                              },
                              "minViewThreshold": {
                                "type": "integer",
                                "nullable": true
                              },
                              "maxCpmEarnableCents": {
                                "type": "integer",
                                "nullable": true
                              },
                              "maxTotalEarnableCents": {
                                "type": "integer",
                                "nullable": true
                              },
                              "platformRatios": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": {
                                  "type": "number"
                                },
                                "description": "Platform split ratios. Null means no split."
                              }
                            }
                          },
                          "canvas": {
                            "nullable": true,
                            "oneOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "assigned": {
                                    "nullable": true,
                                    "oneOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "type": "string"
                                          },
                                          "label": {
                                            "type": "string"
                                          },
                                          "isDefault": {
                                            "type": "boolean"
                                          },
                                          "isTrial": {
                                            "type": "boolean"
                                          },
                                          "assignment": {
                                            "type": "string",
                                            "enum": [
                                              "explicit",
                                              "campaign_default"
                                            ],
                                            "description": "`explicit` means the creator resolves to this payscale group. `campaign_default` means the creator was never assigned to a group or the assigned group no longer exists."
                                          },
                                          "assignedAt": {
                                            "type": "integer",
                                            "nullable": true,
                                            "description": "Unix timestamp in milliseconds for an explicit assignment; null when `assignment` is `campaign_default`."
                                          }
                                        }
                                      }
                                    ]
                                  },
                                  "contentRules": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "type": "string"
                                        },
                                        "label": {
                                          "type": "string"
                                        },
                                        "matcher": {
                                          "type": "object",
                                          "properties": {
                                            "kind": {
                                              "type": "string",
                                              "enum": [
                                                "content",
                                                "lifetime_views"
                                              ]
                                            },
                                            "description": {
                                              "type": "string"
                                            },
                                            "thresholdViews": {
                                              "type": "integer"
                                            }
                                          }
                                        },
                                        "pay": {
                                          "type": "object",
                                          "properties": {
                                            "payoutType": {
                                              "type": "string",
                                              "enum": [
                                                "view_bonus",
                                                "cpm",
                                                "flat_fee"
                                              ]
                                            },
                                            "platformPayoutMode": {
                                              "type": "string",
                                              "enum": [
                                                "per_post",
                                                "highest_platform"
                                              ]
                                            },
                                            "viewTrackingDays": {
                                              "type": "integer"
                                            },
                                            "trialCutoff": {
                                              "type": "object",
                                              "properties": {
                                                "views": {
                                                  "type": "integer"
                                                },
                                                "posts": {
                                                  "type": "integer"
                                                },
                                                "days": {
                                                  "type": "integer"
                                                },
                                                "enabled": {
                                                  "type": "boolean"
                                                }
                                              }
                                            },
                                            "perCreatorCap": {
                                              "type": "object",
                                              "properties": {
                                                "enabled": {
                                                  "type": "boolean"
                                                },
                                                "capCents": {
                                                  "type": "integer"
                                                },
                                                "periodDays": {
                                                  "type": "integer"
                                                }
                                              }
                                            },
                                            "inactivityCutoff": {
                                              "type": "object",
                                              "properties": {
                                                "enabled": {
                                                  "type": "boolean"
                                                },
                                                "days": {
                                                  "type": "integer"
                                                }
                                              }
                                            },
                                            "baseRateDisabled": {
                                              "type": "boolean"
                                            },
                                            "tiers": {
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "viewsThreshold": {
                                                    "type": "integer"
                                                  },
                                                  "bonusCents": {
                                                    "type": "integer"
                                                  }
                                                }
                                              }
                                            },
                                            "cpmCents": {
                                              "type": "integer"
                                            },
                                            "minViews": {
                                              "type": "integer"
                                            },
                                            "maxViews": {
                                              "type": "integer"
                                            },
                                            "flatFeeCents": {
                                              "type": "integer"
                                            },
                                            "amountCents": {
                                              "type": "integer"
                                            },
                                            "flatFee": {
                                              "type": "object",
                                              "properties": {
                                                "enabled": {
                                                  "type": "boolean"
                                                },
                                                "flatFeeCents": {
                                                  "type": "integer"
                                                },
                                                "minViews": {
                                                  "type": "integer"
                                                }
                                              }
                                            },
                                            "monthlyInput": {
                                              "type": "object",
                                              "properties": {
                                                "budgetCents": {
                                                  "type": "integer"
                                                },
                                                "postsPerMonth": {
                                                  "type": "integer"
                                                },
                                                "videosPerMonth": {
                                                  "type": "integer"
                                                }
                                              }
                                            },
                                            "perPlatform": {
                                              "type": "object",
                                              "additionalProperties": {
                                                "type": "object",
                                                "properties": {
                                                  "payoutType": {
                                                    "type": "string",
                                                    "enum": [
                                                      "excluded",
                                                      "view_bonus",
                                                      "cpm",
                                                      "flat_fee"
                                                    ]
                                                  },
                                                  "excluded": {
                                                    "type": "boolean"
                                                  },
                                                  "flatFeeCents": {
                                                    "type": "integer"
                                                  },
                                                  "tiers": {
                                                    "type": "array",
                                                    "items": {
                                                      "type": "object",
                                                      "properties": {
                                                        "viewsThreshold": {
                                                          "type": "integer"
                                                        },
                                                        "bonusCents": {
                                                          "type": "integer"
                                                        }
                                                      }
                                                    }
                                                  },
                                                  "cpmCents": {
                                                    "type": "integer"
                                                  },
                                                  "minViews": {
                                                    "type": "integer"
                                                  },
                                                  "maxViews": {
                                                    "type": "integer"
                                                  },
                                                  "flatFee": {
                                                    "type": "object"
                                                  },
                                                  "amountCents": {
                                                    "type": "integer"
                                                  },
                                                  "monthlyInput": {
                                                    "type": "object"
                                                  },
                                                  "baseRateDisabled": {
                                                    "type": "boolean"
                                                  }
                                                }
                                              }
                                            }
                                          }
                                        }
                                      }
                                    }
                                  },
                                  "fallbackPay": {
                                    "nullable": true,
                                    "description": "The pay config used when content matches no rule. This can be null for a non-default payscale group with no fallback configured; null means the creator has no fallback pay yet.",
                                    "type": "object",
                                    "properties": {
                                      "payoutType": {
                                        "type": "string",
                                        "enum": [
                                          "view_bonus",
                                          "cpm",
                                          "flat_fee"
                                        ]
                                      },
                                      "platformPayoutMode": {
                                        "type": "string",
                                        "enum": [
                                          "per_post",
                                          "highest_platform"
                                        ]
                                      },
                                      "viewTrackingDays": {
                                        "type": "integer"
                                      },
                                      "trialCutoff": {
                                        "type": "object",
                                        "properties": {
                                          "views": {
                                            "type": "integer"
                                          },
                                          "posts": {
                                            "type": "integer"
                                          },
                                          "days": {
                                            "type": "integer"
                                          },
                                          "enabled": {
                                            "type": "boolean"
                                          }
                                        }
                                      },
                                      "perCreatorCap": {
                                        "type": "object",
                                        "properties": {
                                          "enabled": {
                                            "type": "boolean"
                                          },
                                          "capCents": {
                                            "type": "integer"
                                          },
                                          "periodDays": {
                                            "type": "integer"
                                          }
                                        }
                                      },
                                      "inactivityCutoff": {
                                        "type": "object",
                                        "properties": {
                                          "enabled": {
                                            "type": "boolean"
                                          },
                                          "days": {
                                            "type": "integer"
                                          }
                                        }
                                      },
                                      "baseRateDisabled": {
                                        "type": "boolean"
                                      },
                                      "tiers": {
                                        "type": "array",
                                        "items": {
                                          "type": "object",
                                          "properties": {
                                            "viewsThreshold": {
                                              "type": "integer"
                                            },
                                            "bonusCents": {
                                              "type": "integer"
                                            }
                                          }
                                        }
                                      },
                                      "cpmCents": {
                                        "type": "integer"
                                      },
                                      "minViews": {
                                        "type": "integer"
                                      },
                                      "maxViews": {
                                        "type": "integer"
                                      },
                                      "flatFeeCents": {
                                        "type": "integer"
                                      },
                                      "amountCents": {
                                        "type": "integer"
                                      },
                                      "flatFee": {
                                        "type": "object",
                                        "properties": {
                                          "enabled": {
                                            "type": "boolean"
                                          },
                                          "flatFeeCents": {
                                            "type": "integer"
                                          },
                                          "minViews": {
                                            "type": "integer"
                                          }
                                        }
                                      },
                                      "monthlyInput": {
                                        "type": "object",
                                        "properties": {
                                          "budgetCents": {
                                            "type": "integer"
                                          },
                                          "postsPerMonth": {
                                            "type": "integer"
                                          },
                                          "videosPerMonth": {
                                            "type": "integer"
                                          }
                                        }
                                      },
                                      "perPlatform": {
                                        "type": "object",
                                        "additionalProperties": {
                                          "type": "object",
                                          "properties": {
                                            "payoutType": {
                                              "type": "string",
                                              "enum": [
                                                "excluded",
                                                "view_bonus",
                                                "cpm",
                                                "flat_fee"
                                              ]
                                            },
                                            "excluded": {
                                              "type": "boolean"
                                            },
                                            "flatFeeCents": {
                                              "type": "integer"
                                            },
                                            "tiers": {
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "viewsThreshold": {
                                                    "type": "integer"
                                                  },
                                                  "bonusCents": {
                                                    "type": "integer"
                                                  }
                                                }
                                              }
                                            },
                                            "cpmCents": {
                                              "type": "integer"
                                            },
                                            "minViews": {
                                              "type": "integer"
                                            },
                                            "maxViews": {
                                              "type": "integer"
                                            },
                                            "flatFee": {
                                              "type": "object"
                                            },
                                            "amountCents": {
                                              "type": "integer"
                                            },
                                            "monthlyInput": {
                                              "type": "object"
                                            },
                                            "baseRateDisabled": {
                                              "type": "boolean"
                                            }
                                          }
                                        }
                                      }
                                    }
                                  },
                                  "maxVideosPerWeek": {
                                    "type": "integer",
                                    "nullable": true
                                  }
                                }
                              }
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "creatorId": "crt_demo_creator_7x2",
                      "creatorName": "Demo Creator",
                      "programId": "00000000-0000-4000-8000-000000000101",
                      "programName": "Spring Launch",
                      "contractId": "00000000-0000-4000-8000-000000000102",
                      "createdAt": 1786003200000,
                      "updatedAt": 1786089600000,
                      "money": {
                        "payModelKind": "post",
                        "baseRateCents": 7500,
                        "nonCashBaseRateEntries": [
                          {
                            "currency": "manual",
                            "name": "Product sample",
                            "valueCents": 2500
                          }
                        ],
                        "cpmCents": 400,
                        "cpcCents": 25,
                        "viewCap": 100000,
                        "minViewThreshold": 1000,
                        "maxCpmEarnableCents": 50000,
                        "maxTotalEarnableCents": 100000,
                        "platformRatios": {
                          "instagram": 0.6,
                          "tiktok": 0.4
                        }
                      },
                      "canvas": null
                    },
                    {
                      "creatorId": "crt_demo_creator_9k4",
                      "creatorName": "Sample Creator",
                      "programId": "00000000-0000-4000-8000-000000000103",
                      "programName": "Always-On Video Program",
                      "contractId": null,
                      "createdAt": 1785916800000,
                      "updatedAt": 1786089600000,
                      "money": {
                        "payModelKind": "canvas_payscale",
                        "baseRateCents": 0,
                        "nonCashBaseRateEntries": [],
                        "cpmCents": null,
                        "cpcCents": null,
                        "viewCap": null,
                        "minViewThreshold": null,
                        "maxCpmEarnableCents": null,
                        "maxTotalEarnableCents": null,
                        "platformRatios": null
                      },
                      "canvas": {
                        "assigned": {
                          "id": "scale-growth",
                          "label": "Growth",
                          "isDefault": false,
                          "isTrial": false,
                          "assignment": "explicit",
                          "assignedAt": 1786003200000
                        },
                        "contentRules": [
                          {
                            "id": "rule-talking-head",
                            "label": "Talking head",
                            "matcher": {
                              "kind": "content",
                              "description": "Creator speaks directly to camera"
                            },
                            "pay": {
                              "payoutType": "view_bonus",
                              "platformPayoutMode": "per_post",
                              "viewTrackingDays": 30,
                              "trialCutoff": {
                                "views": 10000,
                                "posts": 10,
                                "days": 14,
                                "enabled": true
                              },
                              "perCreatorCap": {
                                "enabled": true,
                                "capCents": 150000,
                                "periodDays": 30
                              },
                              "inactivityCutoff": {
                                "enabled": true,
                                "days": 30
                              },
                              "baseRateDisabled": false,
                              "tiers": [
                                {
                                  "viewsThreshold": 1000,
                                  "bonusCents": 2000
                                },
                                {
                                  "viewsThreshold": 10000,
                                  "bonusCents": 10000
                                },
                                {
                                  "viewsThreshold": 50000,
                                  "bonusCents": 30000
                                }
                              ],
                              "flatFeeCents": 0
                            }
                          }
                        ],
                        "fallbackPay": {
                          "payoutType": "view_bonus",
                          "platformPayoutMode": "per_post",
                          "viewTrackingDays": 30,
                          "trialCutoff": {
                            "views": 10000,
                            "posts": 10,
                            "days": 14,
                            "enabled": true
                          },
                          "perCreatorCap": {
                            "enabled": true,
                            "capCents": 150000,
                            "periodDays": 30
                          },
                          "inactivityCutoff": {
                            "enabled": true,
                            "days": 30
                          },
                          "baseRateDisabled": false,
                          "tiers": [
                            {
                              "viewsThreshold": 1000,
                              "bonusCents": 2000
                            },
                            {
                              "viewsThreshold": 10000,
                              "bonusCents": 10000
                            },
                            {
                              "viewsThreshold": 50000,
                              "bonusCents": 30000
                            }
                          ],
                          "flatFeeCents": 0
                        },
                        "maxVideosPerWeek": 5
                      }
                    }
                  ],
                  "page": 1,
                  "total": 2,
                  "totalPages": 1
                }
              }
            }
          },
          "400": {
            "description": "Invalid creator ID or query parameter"
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "403": {
            "description": "The requested scope is not allowed"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    },
    "/creators/{id}/audience": {
      "get": {
        "tags": [
          "Creators"
        ],
        "summary": "View creator audience demographics",
        "description": "Get saved audience demographics for each linked social account of a visible creator.\n\nPercentages use a `0` to `100` scale, including `usAudiencePercentage`. Audience data can be up to about 30 days old; `lastUpdatedAt` is a Unix timestamp in milliseconds for the newest data in that account block. `countries` comes from the monthly country refresh when available and falls back to the Instagram account's own country split otherwise. `usAudiencePercentage` is populated only from the monthly country refresh, so null does not mean the US share is zero. A saved no-data marker can return `0`; that does not prove the US share is zero. `reason` is set only when the entire audience block has no data. When country data is missing but age, gender, or city data exists, `countriesReason` describes the missing country data instead.\n\nThe `instagramAudiences` entries expose separate populations Meta reports: people reached, people who engaged, and followers. These are different sets of people, so do not add them together.\n\nThe possible no-data reasons are `unsupported_platform`, `no_data_marker`, and `never_fetched`. A creator the API key cannot see returns `404`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Opaque creator ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Audience demographics returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "creatorId": {
                      "type": "string"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CreatorAudienceAccount"
                      }
                    }
                  }
                },
                "example": {
                  "creatorId": "crt_demo_creator_7x2",
                  "data": [
                    {
                      "platform": "instagram",
                      "handle": "demo_creator",
                      "lastUpdatedAt": 1786089600000,
                      "audience": {
                        "status": "available",
                        "reason": null,
                        "countriesReason": null,
                        "usAudiencePercentage": 72,
                        "countries": [
                          {
                            "label": "US",
                            "percentage": 72
                          },
                          {
                            "label": "GB",
                            "percentage": 18
                          },
                          {
                            "label": "CA",
                            "percentage": 10
                          }
                        ],
                        "ages": [
                          {
                            "label": "25-34",
                            "percentage": 48.5
                          }
                        ],
                        "genders": [
                          {
                            "label": "female",
                            "percentage": 61.2
                          }
                        ],
                        "cities": [
                          {
                            "label": "New York",
                            "percentage": 12.4
                          }
                        ],
                        "demographicsBasis": "reached",
                        "sampleSize": 2500,
                        "instagramAudiences": [
                          {
                            "basis": "reached",
                            "sampleSize": 2500,
                            "countries": [
                              {
                                "label": "US",
                                "percentage": 72
                              },
                              {
                                "label": "GB",
                                "percentage": 18
                              },
                              {
                                "label": "CA",
                                "percentage": 10
                              }
                            ],
                            "ages": [
                              {
                                "label": "25-34",
                                "percentage": 48.5
                              }
                            ],
                            "genders": [
                              {
                                "label": "female",
                                "percentage": 61.2
                              }
                            ],
                            "cities": [
                              {
                                "label": "New York",
                                "percentage": 12.4
                              }
                            ]
                          },
                          {
                            "basis": "engaged",
                            "sampleSize": 840,
                            "countries": [
                              {
                                "label": "US",
                                "percentage": 68
                              },
                              {
                                "label": "GB",
                                "percentage": 22
                              },
                              {
                                "label": "CA",
                                "percentage": 10
                              }
                            ],
                            "ages": [
                              {
                                "label": "25-34",
                                "percentage": 52.1
                              }
                            ],
                            "genders": [
                              {
                                "label": "female",
                                "percentage": 58.7
                              }
                            ],
                            "cities": [
                              {
                                "label": "New York",
                                "percentage": 14.1
                              }
                            ]
                          },
                          {
                            "basis": "followers",
                            "sampleSize": 3100,
                            "countries": [
                              {
                                "label": "US",
                                "percentage": 70
                              },
                              {
                                "label": "GB",
                                "percentage": 20
                              },
                              {
                                "label": "CA",
                                "percentage": 10
                              }
                            ],
                            "ages": [
                              {
                                "label": "25-34",
                                "percentage": 47.9
                              }
                            ],
                            "genders": [
                              {
                                "label": "female",
                                "percentage": 62.4
                              }
                            ],
                            "cities": [
                              {
                                "label": "New York",
                                "percentage": 11.8
                              }
                            ]
                          }
                        ]
                      }
                    },
                    {
                      "platform": "tiktok",
                      "handle": null,
                      "lastUpdatedAt": 1786003200000,
                      "audience": {
                        "status": "no_data",
                        "reason": "no_data_marker",
                        "countriesReason": "no_data_marker",
                        "usAudiencePercentage": null,
                        "countries": [],
                        "ages": [],
                        "genders": [],
                        "cities": [],
                        "demographicsBasis": null,
                        "sampleSize": null,
                        "instagramAudiences": []
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Creator ID is invalid"
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "403": {
            "description": "The requested scope is not allowed"
          },
          "404": {
            "description": "Creator was not found or is not visible to this API key"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    },
    "/creators/{id}/feed": {
      "get": {
        "tags": [
          "Creators"
        ],
        "summary": "List a creator's feed",
        "description": "List one visible creator's public posts, newest first, on the social accounts the creator uses on your programs. The list combines the creator's feed, as Launchpoint last read it, with the Launchpoint campaign posts on your programs. A post that is both appears once, as the campaign post.\n\nThis endpoint returns stored data only and never starts a new read. Each read keeps the account's most recent posts, so how far back the feed goes depends on how often the account was read. `accounts[].feedReadAt` is when each account's feed was last read; `null` means it was not read yet. Stories are not included.\n\nThe counts of each post are one reading, taken at `metricsRecordedAt`. `paidPartnershipLabel` is the platform's own label and nothing more: a sponsored post that the creator did not label reads as `false`.\n\n`fromDate` and `toDate` filter by posting day in America/New_York, as `GET /posts` does. A creator the API key cannot see returns `404`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Opaque creator ID"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "in": "query",
            "name": "platform",
            "schema": {
              "type": "string",
              "enum": [
                "tiktok",
                "instagram",
                "youtube",
                "facebook",
                "snapchat"
              ]
            }
          },
          {
            "in": "query",
            "name": "fromDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "First posting day, `YYYY-MM-DD`."
          },
          {
            "in": "query",
            "name": "toDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Last posting day, `YYYY-MM-DD`."
          }
        ],
        "responses": {
          "200": {
            "description": "Feed returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "creatorId": {
                      "type": "string"
                    },
                    "accounts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "platform": {
                            "type": "string"
                          },
                          "handle": {
                            "type": "string",
                            "nullable": true
                          },
                          "feedReadAt": {
                            "type": "integer",
                            "nullable": true,
                            "description": "When this account's feed was last read, Unix time in milliseconds."
                          }
                        }
                      }
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "platform": {
                            "type": "string",
                            "enum": [
                              "tiktok",
                              "instagram",
                              "youtube",
                              "facebook",
                              "snapchat"
                            ]
                          },
                          "handle": {
                            "type": "string",
                            "nullable": true,
                            "description": "Account handle. `null` while creator access is locked (wallet balance under the minimum)."
                          },
                          "platformPostId": {
                            "type": "string",
                            "description": "The platform's own id for the post. It does not change; use it to match the same post across calls."
                          },
                          "url": {
                            "type": "string",
                            "nullable": true
                          },
                          "uploadedAt": {
                            "type": "integer",
                            "nullable": true,
                            "description": "When the post went live, Unix time in milliseconds."
                          },
                          "caption": {
                            "type": "string",
                            "nullable": true
                          },
                          "mediaType": {
                            "type": "string",
                            "enum": [
                              "video",
                              "image"
                            ],
                            "nullable": true,
                            "description": "`null` when the read did not report it."
                          },
                          "durationSeconds": {
                            "type": "number",
                            "nullable": true
                          },
                          "views": {
                            "type": "integer",
                            "nullable": true,
                            "description": "`null` when the read did not report the count. A missing count is never returned as `0`."
                          },
                          "likes": {
                            "type": "integer",
                            "nullable": true
                          },
                          "comments": {
                            "type": "integer",
                            "nullable": true
                          },
                          "shares": {
                            "type": "integer",
                            "nullable": true
                          },
                          "bookmarks": {
                            "type": "integer",
                            "nullable": true
                          },
                          "metricsRecordedAt": {
                            "type": "integer",
                            "nullable": true,
                            "description": "When these counts were read, Unix time in milliseconds. The counts are one reading, not a history."
                          },
                          "paidPartnershipLabel": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "The platform's own paid-partnership (ad) label. `true`: the post shows the label. `false`: the read reported no label. `null`: no read has reported the field yet. A sponsored post that the creator did not label reads as `false`."
                          },
                          "launchpointCampaign": {
                            "type": "object",
                            "nullable": true,
                            "description": "Set when the post is a Launchpoint campaign post on one of your programs; otherwise `null`.",
                            "properties": {
                              "programId": {
                                "type": "string"
                              },
                              "postId": {
                                "type": "string",
                                "description": "Use with `GET /posts/{id}` for payment and contract details."
                              }
                            }
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "creatorId": "crt_demo_creator_7x2",
                  "accounts": [
                    {
                      "platform": "tiktok",
                      "handle": "demo_creator",
                      "feedReadAt": 1792407806006
                    }
                  ],
                  "data": [
                    {
                      "platform": "tiktok",
                      "handle": "demo_creator",
                      "platformPostId": "7698835017320959246",
                      "url": "https://www.tiktok.com/@demo_creator/video/7698835017320959246",
                      "uploadedAt": 1792544400000,
                      "caption": "The best side hustle yet",
                      "mediaType": "video",
                      "durationSeconds": 50,
                      "views": 17800,
                      "likes": 612,
                      "comments": 24,
                      "shares": 11,
                      "bookmarks": 40,
                      "metricsRecordedAt": 1792548698699,
                      "paidPartnershipLabel": true,
                      "launchpointCampaign": {
                        "programId": "32ea539c-a42e-4158-b68a-11649446e80f",
                        "postId": "157cc1c1-75e1-40ed-86cb-6083165b2a9c"
                      }
                    },
                    {
                      "platform": "tiktok",
                      "handle": "demo_creator",
                      "platformPostId": "7697012345678901234",
                      "url": "https://www.tiktok.com/@demo_creator/video/7697012345678901234",
                      "uploadedAt": 1792200000000,
                      "caption": "Morning routine",
                      "mediaType": "video",
                      "durationSeconds": 31,
                      "views": 9400,
                      "likes": 380,
                      "comments": 12,
                      "shares": 4,
                      "bookmarks": null,
                      "metricsRecordedAt": 1792407806006,
                      "paidPartnershipLabel": false,
                      "launchpointCampaign": null
                    }
                  ],
                  "page": 1,
                  "total": 2,
                  "totalPages": 1
                }
              }
            }
          },
          "400": {
            "description": "Creator ID or a query parameter is invalid, or fromDate is after toDate"
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "403": {
            "description": "The requested scope is not allowed"
          },
          "404": {
            "description": "Creator was not found or is not visible to this API key"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    },
    "/programs": {
      "get": {
        "tags": [
          "Programs"
        ],
        "summary": "Browse programs",
        "description": "Get your company's programs with pagination and filters.\n\nPrograms are campaigns or marketing initiatives that creators take part in.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagination page number"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Items to return per page"
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "active",
                "paused",
                "completed",
                "archived"
              ]
            },
            "description": "Narrow programs by status"
          },
          {
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string"
            },
            "description": "Find programs by name"
          }
        ],
        "responses": {
          "200": {
            "description": "Programs returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "createdAt": {
                            "type": "integer"
                          },
                          "updatedAt": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "429": {
            "description": "Request rate limit exceeded"
          }
        }
      }
    },
    "/posts": {
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "Browse posts",
        "description": "Get social media posts with detailed filters.\n\nFilter posts by program, platform, creator, date range, and more. Each row includes direct links, thumbnails, stable creator IDs, cross-post group IDs, current metrics, metric availability, and the current UTC day's view change.\n\nEach post includes `adCode`, the saved, verified or submitted code in plain text, and `adCodeStatus`, its stored status (`verified` or `submitted`). `submitted` means the campaign collects codes without checking them. Both fields are `null` when no verified or submitted, unexpired code is stored. A code without an expiry remains available. This read does not request a new code from the creator or platform. Posts without a code remain in the response, under the same campaign visibility rules.\n\nPlatform copies of one source video remain separate rows because their links and metrics differ. Copies share `crossPostGroupId` so callers can group or de-duplicate them.\n\nAgency accounts can pass `scope=agency` to return posts from the parent agency and every subaccount in one request.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 25,
              "maximum": 500
            }
          },
          {
            "in": "query",
            "name": "program",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Narrow results by program IDs (multiple allowed)"
          },
          {
            "in": "query",
            "name": "platform",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/PostPlatform"
              }
            },
            "description": "Narrow results by platforms (multiple allowed)"
          },
          {
            "in": "query",
            "name": "creator",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Narrow results by creator IDs (multiple allowed)"
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "fromDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Include posts from this date (YYYY-MM-DD)"
          },
          {
            "in": "query",
            "name": "toDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Include posts through this date (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "Posts returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "creatorId": {
                            "type": "string",
                            "description": "Client-stable encrypted creator ID"
                          },
                          "adCode": {
                            "type": "string",
                            "nullable": true,
                            "description": "Saved, verified or submitted ad code in plain text, or null when no verified or submitted, unexpired code is stored. Codes without an expiry remain available. Fetching the post does not request a new code.",
                            "example": "example-ad-code"
                          },
                          "adCodeStatus": {
                            "type": "string",
                            "enum": [
                              "verified",
                              "submitted"
                            ],
                            "nullable": true,
                            "description": "Stored status of the code: verified, or submitted when the campaign collects codes without checking them. Null when no code is returned."
                          },
                          "crossPostGroupId": {
                            "type": "string",
                            "description": "Shared by platform copies of the same source video"
                          },
                          "title": {
                            "type": "string"
                          },
                          "platform": {
                            "$ref": "#/components/schemas/PostPlatform"
                          },
                          "url": {
                            "type": "string",
                            "description": "Direct URL for this platform post; an empty string means no URL is stored"
                          },
                          "thumbnail": {
                            "type": "string",
                            "description": "Thumbnail URL; an empty string means no thumbnail is stored"
                          },
                          "metricsAvailable": {
                            "type": "boolean",
                            "description": "False when the post has no stored metric snapshot; use this to distinguish missing data from a stored zero"
                          },
                          "metricsRecordedAt": {
                            "type": "integer",
                            "format": "int64",
                            "nullable": true,
                            "description": "Unix timestamp in milliseconds for the latest metric snapshot, or null when metrics are unavailable"
                          },
                          "views": {
                            "type": "integer"
                          },
                          "likes": {
                            "type": "integer"
                          },
                          "comments": {
                            "type": "integer"
                          },
                          "shares": {
                            "type": "integer"
                          },
                          "earnings": {
                            "type": "number",
                            "description": "Dollars credited to the creator for this post (`payment.creditedCents / 100`)"
                          },
                          "paid": {
                            "type": "boolean",
                            "description": "True when any credit exists for this post. Use `payment.state` instead."
                          },
                          "contractorName": {
                            "type": "string"
                          },
                          "uploadedAt": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Unix timestamp in milliseconds"
                          },
                          "deltaFromPrevDay": {
                            "type": "object",
                            "description": "Signed change from the last snapshot before the current UTC day. A lower latest count produces a negative value. This is zero when no new snapshot was recorded today or when no earlier snapshot exists; the first stored total is a baseline, not views proven to have arrived today.",
                            "properties": {
                              "views": {
                                "type": "integer"
                              }
                            }
                          },
                          "payment": {
                            "$ref": "#/components/schemas/PostPayment"
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/posts/{id}": {
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "View post details",
        "description": "Get full details for one post/video.\n\nThe response includes metrics, engagement data, payment status, and related contract/program information.\n\n`adCode` is the saved, verified or submitted code in plain text, and `adCodeStatus` is its stored status (`verified` or `submitted`). `submitted` means the campaign collects codes without checking them. Both fields are `null` when no verified or submitted, unexpired code is stored. A code without an expiry remains available. This read does not request a new code from the creator or platform. The fields use the same campaign visibility rules as the post.\n\n`description` is the post's caption. For an Instagram post on an account connected to Launchpoint, each metrics read replaces it with the current caption, so an edit by the creator appears after the next read. `descriptionFetchedAt` is the time of the read that returned it.\n\n`account` is the social account that published the post.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the post"
          }
        ],
        "responses": {
          "200": {
            "description": "Post details returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string",
                          "description": "The post's caption"
                        },
                        "adCode": {
                          "type": "string",
                          "nullable": true,
                          "description": "Saved, verified or submitted ad code in plain text, or null when no verified or submitted, unexpired code is stored. Codes without an expiry remain available. Fetching the post does not request a new code.",
                          "example": "example-ad-code"
                        },
                        "adCodeStatus": {
                          "type": "string",
                          "enum": [
                            "verified",
                            "submitted"
                          ],
                          "nullable": true,
                          "description": "Stored status of the code: verified, or submitted when the campaign collects codes without checking them. Null when no code is returned."
                        },
                        "descriptionFetchedAt": {
                          "type": "integer",
                          "format": "int64",
                          "nullable": true,
                          "description": "When the caption in `description` was read from the platform, in Unix milliseconds. Null when no read has stored it yet."
                        },
                        "platform": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "thumbnail": {
                          "type": "string"
                        },
                        "mediaUrl": {
                          "type": "string",
                          "nullable": true,
                          "description": "Link that downloads the post's video or image file. Null unless media links are turned on for your workspace (email hi@launchpointhq.com). The link does not expire; do not share it. Also null when Launchpoint has no stored copy of the file."
                        },
                        "creator": {
                          "type": "string",
                          "description": "Social handle"
                        },
                        "account": {
                          "type": "object",
                          "description": "The social account that published the post",
                          "properties": {
                            "handle": {
                              "type": "string"
                            },
                            "bio": {
                              "type": "string",
                              "nullable": true
                            },
                            "avatarUrl": {
                              "type": "string",
                              "nullable": true
                            },
                            "profileFetchedAt": {
                              "type": "integer",
                              "format": "int64",
                              "nullable": true,
                              "description": "When the account's profile, including `bio` and `avatarUrl`, was last read from the platform, in Unix milliseconds"
                            }
                          }
                        },
                        "uploadedAt": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "type": "integer"
                        },
                        "views": {
                          "type": "integer"
                        },
                        "likes": {
                          "type": "integer"
                        },
                        "comments": {
                          "type": "integer"
                        },
                        "shares": {
                          "type": "integer"
                        },
                        "bookmarks": {
                          "type": "integer"
                        },
                        "engagementRate": {
                          "type": "string",
                          "description": "Percentage represented as a string"
                        },
                        "earnings": {
                          "type": "number",
                          "description": "Dollars credited to the creator for this post (`payment.creditedCents / 100`)"
                        },
                        "paid": {
                          "type": "boolean",
                          "description": "True when any credit exists for this post. Use `payment.state` instead."
                        },
                        "lastPaidAt": {
                          "type": "integer",
                          "format": "int64",
                          "nullable": true,
                          "description": "Same as `payment.lastCreditedAt`"
                        },
                        "lastSyncedAt": {
                          "type": "integer",
                          "nullable": true,
                          "description": "When the post's metrics were last read. This is not the caption read time; see `descriptionFetchedAt`."
                        },
                        "contract": {
                          "type": "object",
                          "nullable": true,
                          "description": "Contract details, or null if the post creator has no offer-level contract.",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "contractorName": {
                              "type": "string"
                            },
                            "contractorId": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string"
                            },
                            "isGhostHandle": {
                              "type": "boolean"
                            }
                          }
                        },
                        "program": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string"
                            }
                          }
                        },
                        "creatorInfo": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "profileImageUrl": {
                              "type": "string"
                            }
                          }
                        },
                        "awardedBonuses": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "bonusAmount": {
                          "type": "number"
                        },
                        "payment": {
                          "$ref": "#/components/schemas/PostPayment"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Post ID is invalid"
          },
          "404": {
            "description": "No post was found"
          }
        }
      }
    },
    "/posts/{id}/payments": {
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "List a post's money events",
        "description": "Get the money events behind the post's `payment.state`, oldest first. Works for a post that was removed after its rows were deleted.\n\nEvent kinds:\n- `earned`: the pay owed now on one pay line.\n- `billed`: the pay line on an invoice.\n- `charged` and `refunded`: brand money spent from, or given back to, the creator's reserve. Shown only when your workspace funded the reserve.\n- `credited`: money added to the creator's Launchpoint balance. A clawback is a negative credit.\n- `excluded`: the post was removed; `amountCents` is the pending pay removed.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID of the post"
          }
        ],
        "responses": {
          "200": {
            "description": "Payment state and events",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "postId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "payment": {
                          "$ref": "#/components/schemas/PostPayment"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Stable: `<kind>:<source row id>`"
                              },
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "earned",
                                  "billed",
                                  "charged",
                                  "refunded",
                                  "credited",
                                  "excluded"
                                ]
                              },
                              "occurredAt": {
                                "type": "integer",
                                "format": "int64",
                                "description": "Unix milliseconds"
                              },
                              "amountCents": {
                                "type": "integer",
                                "nullable": true
                              },
                              "currency": {
                                "type": "string",
                                "enum": [
                                  "USD"
                                ]
                              },
                              "invoiceId": {
                                "type": "string",
                                "format": "uuid",
                                "nullable": true
                              },
                              "releaseId": {
                                "type": "string",
                                "format": "uuid",
                                "nullable": true,
                                "description": "The payout run that made a credit"
                              },
                              "fundingWorkspaceId": {
                                "type": "string",
                                "format": "uuid",
                                "nullable": true
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Post not found, or not visible to this API key"
          }
        }
      }
    },
    "/posts/{id}/metrics-history": {
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "View post metrics history",
        "description": "Get daily historical metrics for one post/video.\n\nSee how views, likes, comments, and other metrics changed over time.\n",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the post"
          },
          {
            "in": "query",
            "name": "days",
            "schema": {
              "type": "integer",
              "default": 30
            },
            "description": "History length in days (0 for all)"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 500
            },
            "description": "Maximum data points to return"
          }
        ],
        "responses": {
          "200": {
            "description": "Metrics history returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "postId": {
                          "type": "string"
                        },
                        "history": {
                          "type": "array",
                          "description": "Daily snapshots ordered from oldest to newest",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string",
                                "description": "Date formatted as YYYY-MM-DD"
                              },
                              "timestamp": {
                                "type": "integer",
                                "nullable": true
                              },
                              "views": {
                                "type": "integer",
                                "description": "Views recorded on this date"
                              },
                              "likes": {
                                "type": "integer"
                              },
                              "comments": {
                                "type": "integer"
                              },
                              "shares": {
                                "type": "integer"
                              },
                              "bookmarks": {
                                "type": "integer"
                              },
                              "engagementRate": {
                                "type": "string"
                              },
                              "viewsDelta": {
                                "type": "integer",
                                "description": "Change since the previous day"
                              },
                              "likesDelta": {
                                "type": "integer"
                              },
                              "commentsDelta": {
                                "type": "integer"
                              },
                              "sharesDelta": {
                                "type": "integer"
                              },
                              "bookmarksDelta": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "growth": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "viewsGrowth": {
                              "type": "string",
                              "description": "Growth percentage for the period"
                            },
                            "likesGrowth": {
                              "type": "string"
                            },
                            "commentsGrowth": {
                              "type": "string"
                            },
                            "sharesGrowth": {
                              "type": "string"
                            },
                            "bookmarksGrowth": {
                              "type": "string"
                            },
                            "periodDays": {
                              "type": "integer"
                            },
                            "totalDaysTracked": {
                              "type": "integer"
                            }
                          }
                        },
                        "totalDataPoints": {
                          "type": "integer"
                        },
                        "periodDays": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Post ID is invalid"
          },
          "404": {
            "description": "No post was found"
          }
        }
      }
    },
    "/posts/{id}/insights": {
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "View post insights",
        "description": "Get the latest stored Instagram performance and Reel watch metrics for one post.\n\n`insights.status` and `insights.reason` are paired: `available` with `reason: null` means a post snapshot exists; `no_data` with `reason: never_fetched` means no post snapshot exists; and `no_data` with `reason: unsupported_platform` means the post is not Instagram.\n\n`creatorAudience` is account-level audience data for the account that published the post. Its handle follows the same PII lock as the creator audience endpoint. It is not the geography of people who watched this video: Meta does not expose per-post country data at any access level. Instagram audience entries describe separate populations reported by Meta and should not be added together. Non-Instagram posts return `no_data` with `reason: unsupported_platform` instead of invented metrics.\n",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the post"
          }
        ],
        "responses": {
          "200": {
            "description": "Post insights returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "platform": {
                          "type": "string"
                        },
                        "insights": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "available",
                                "no_data"
                              ]
                            },
                            "reason": {
                              "type": "string",
                              "nullable": true,
                              "enum": [
                                "never_fetched",
                                "unsupported_platform"
                              ]
                            },
                            "updatedAt": {
                              "type": "integer",
                              "nullable": true,
                              "description": "Unix timestamp in milliseconds for the stored post snapshot"
                            },
                            "views": {
                              "type": "number",
                              "nullable": true
                            },
                            "reach": {
                              "type": "number",
                              "nullable": true
                            },
                            "likes": {
                              "type": "number",
                              "nullable": true
                            },
                            "comments": {
                              "type": "number",
                              "nullable": true
                            },
                            "shares": {
                              "type": "number",
                              "nullable": true
                            },
                            "saves": {
                              "type": "number",
                              "nullable": true
                            },
                            "totalInteractions": {
                              "type": "number",
                              "nullable": true
                            },
                            "profileVisits": {
                              "type": "number",
                              "nullable": true
                            },
                            "follows": {
                              "type": "number",
                              "nullable": true
                            },
                            "totalWatchTimeMs": {
                              "type": "number",
                              "nullable": true
                            },
                            "avgWatchTimeMs": {
                              "type": "number",
                              "nullable": true
                            },
                            "skipRate": {
                              "type": "number",
                              "nullable": true,
                              "description": "Percentage from 0 to 100"
                            },
                            "engagementRate": {
                              "type": "number",
                              "nullable": true,
                              "description": "Percentage from 0 to 100"
                            }
                          }
                        },
                        "creatorAudience": {
                          "$ref": "#/components/schemas/CreatorAudienceAccount"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "post_demo_4k9",
                    "platform": "instagram",
                    "insights": {
                      "status": "available",
                      "reason": null,
                      "updatedAt": 1786089600000,
                      "views": 128450,
                      "reach": 102300,
                      "likes": 8420,
                      "comments": 312,
                      "shares": 486,
                      "saves": 1190,
                      "totalInteractions": 10408,
                      "profileVisits": 2180,
                      "follows": 347,
                      "totalWatchTimeMs": 184520000,
                      "avgWatchTimeMs": 14360,
                      "skipRate": 31.4,
                      "engagementRate": 8.1
                    },
                    "creatorAudience": {
                      "platform": "instagram",
                      "handle": "demo_creator",
                      "lastUpdatedAt": 1786089600000,
                      "audience": {
                        "status": "available",
                        "reason": null,
                        "countriesReason": null,
                        "usAudiencePercentage": 72,
                        "countries": [
                          {
                            "label": "US",
                            "percentage": 72
                          },
                          {
                            "label": "GB",
                            "percentage": 18
                          },
                          {
                            "label": "CA",
                            "percentage": 10
                          }
                        ],
                        "ages": [
                          {
                            "label": "25-34",
                            "percentage": 48.5
                          }
                        ],
                        "genders": [
                          {
                            "label": "female",
                            "percentage": 61.2
                          }
                        ],
                        "cities": [
                          {
                            "label": "New York",
                            "percentage": 12.4
                          }
                        ],
                        "demographicsBasis": "reached",
                        "sampleSize": 2500,
                        "instagramAudiences": [
                          {
                            "basis": "reached",
                            "sampleSize": 2500,
                            "countries": [
                              {
                                "label": "US",
                                "percentage": 72
                              },
                              {
                                "label": "GB",
                                "percentage": 18
                              },
                              {
                                "label": "CA",
                                "percentage": 10
                              }
                            ],
                            "ages": [
                              {
                                "label": "25-34",
                                "percentage": 48.5
                              }
                            ],
                            "genders": [
                              {
                                "label": "female",
                                "percentage": 61.2
                              }
                            ],
                            "cities": [
                              {
                                "label": "New York",
                                "percentage": 12.4
                              }
                            ]
                          },
                          {
                            "basis": "engaged",
                            "sampleSize": 840,
                            "countries": [
                              {
                                "label": "US",
                                "percentage": 68
                              },
                              {
                                "label": "GB",
                                "percentage": 22
                              },
                              {
                                "label": "CA",
                                "percentage": 10
                              }
                            ],
                            "ages": [
                              {
                                "label": "25-34",
                                "percentage": 52.1
                              }
                            ],
                            "genders": [
                              {
                                "label": "female",
                                "percentage": 58.7
                              }
                            ],
                            "cities": [
                              {
                                "label": "New York",
                                "percentage": 14.1
                              }
                            ]
                          },
                          {
                            "basis": "followers",
                            "sampleSize": 3100,
                            "countries": [
                              {
                                "label": "US",
                                "percentage": 70
                              },
                              {
                                "label": "GB",
                                "percentage": 20
                              },
                              {
                                "label": "CA",
                                "percentage": 10
                              }
                            ],
                            "ages": [
                              {
                                "label": "25-34",
                                "percentage": 47.9
                              }
                            ],
                            "genders": [
                              {
                                "label": "female",
                                "percentage": 62.4
                              }
                            ],
                            "cities": [
                              {
                                "label": "New York",
                                "percentage": 11.8
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Post ID is invalid"
          },
          "404": {
            "description": "No post was found"
          }
        }
      }
    },
    "/posts/{id}/analysis": {
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "View post analysis",
        "description": "Get the media analysis for one post: the storyboard scenes the analyzer wrote plus retention data.\n\n`analysisStatus` is the state of the post's latest non-fingerprint analysis: `none` when the post has never been analyzed, `pending`, `failed`, or `complete`. `storyboard` is `null` until a complete analysis with scenes exists.\n\n`retention.organic` follows the post insights contract: `status` and `reason` are paired \u2014 `available` with `reason: null` means an Instagram snapshot exists; `no_data` with `never_fetched` means none was stored; `no_data` with `unsupported_platform` means the post is not Instagram.\n\n`retention.paid` sums the post's video paid metrics across all of its boosts: `impressions`, three-second views, and watch-through quartile counters (`videoP25Views` \u2026 `videoP100Views`), plus `hookRatePct` (three-second views \u00f7 impressions) and `completionRatePct` (completes \u00f7 impressions), both as percentages from 0 to 100. Paid metrics are video-level, so every crossposted sibling post of one video reports the same paid block. `no_data` with reason `no_paid_metrics` means the video has no reported paid metrics.\n",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the post"
          }
        ],
        "responses": {
          "200": {
            "description": "Post analysis returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "analysisStatus": {
                          "type": "string",
                          "enum": [
                            "none",
                            "pending",
                            "failed",
                            "complete"
                          ]
                        },
                        "analyzedAt": {
                          "type": "integer",
                          "nullable": true,
                          "description": "Unix timestamp in milliseconds of the latest analysis update"
                        },
                        "durationSeconds": {
                          "type": "number",
                          "nullable": true
                        },
                        "storyboard": {
                          "type": "array",
                          "nullable": true,
                          "items": {
                            "type": "object",
                            "properties": {
                              "startMs": {
                                "type": "number"
                              },
                              "endMs": {
                                "type": "number"
                              },
                              "description": {
                                "type": "string"
                              },
                              "transcript": {
                                "type": "string",
                                "nullable": true
                              },
                              "textOnScreen": {
                                "type": "string",
                                "nullable": true
                              },
                              "sellsProduct": {
                                "type": "boolean",
                                "nullable": true,
                                "description": "Present on newer analyses; null on older artifacts"
                              }
                            }
                          }
                        },
                        "retention": {
                          "type": "object",
                          "properties": {
                            "organic": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "available",
                                    "no_data"
                                  ]
                                },
                                "reason": {
                                  "type": "string",
                                  "nullable": true,
                                  "enum": [
                                    "never_fetched",
                                    "unsupported_platform"
                                  ]
                                },
                                "durationSeconds": {
                                  "type": "number",
                                  "nullable": true
                                },
                                "hookRatePct": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Share still watching at 3s, percentage from 0 to 100 (1 \u2212 reels skip rate)"
                                },
                                "skipRatePct": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Percentage from 0 to 100"
                                },
                                "avgWatchTimeMs": {
                                  "type": "number",
                                  "nullable": true
                                },
                                "totalWatchTimeMs": {
                                  "type": "number",
                                  "nullable": true
                                },
                                "updatedAt": {
                                  "type": "integer",
                                  "nullable": true,
                                  "description": "Unix timestamp in milliseconds for the stored post snapshot"
                                }
                              }
                            },
                            "paid": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "available",
                                    "no_data"
                                  ]
                                },
                                "reason": {
                                  "type": "string",
                                  "nullable": true,
                                  "enum": [
                                    "no_paid_metrics"
                                  ]
                                },
                                "daysLive": {
                                  "type": "integer",
                                  "nullable": true,
                                  "description": "Distinct days with a reported paid row"
                                },
                                "throughDate": {
                                  "type": "string",
                                  "nullable": true,
                                  "description": "Most recent reported day, YYYY-MM-DD"
                                },
                                "impressions": {
                                  "type": "number",
                                  "nullable": true
                                },
                                "video3sViews": {
                                  "type": "number",
                                  "nullable": true
                                },
                                "videoP25Views": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Views that reached 25% of the video"
                                },
                                "videoP50Views": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Views that reached 50% of the video"
                                },
                                "videoP75Views": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Views that reached 75% of the video"
                                },
                                "videoP100Views": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Views that reached 100% of the video"
                                },
                                "hookRatePct": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Three-second views \u00f7 impressions, percentage from 0 to 100"
                                },
                                "completionRatePct": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Completes \u00f7 impressions, percentage from 0 to 100"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "post_demo_4k9",
                    "analysisStatus": "complete",
                    "analyzedAt": 1786183200000,
                    "durationSeconds": 14.2,
                    "storyboard": [
                      {
                        "startMs": 0,
                        "endMs": 6400,
                        "description": "A person reacts in surprise to the product on a kitchen counter.",
                        "transcript": "Wait, this actually works?",
                        "textOnScreen": null,
                        "sellsProduct": true
                      },
                      {
                        "startMs": 6400,
                        "endMs": 14200,
                        "description": "Close-up demo of the product with a price overlay.",
                        "transcript": null,
                        "textOnScreen": "Only $19",
                        "sellsProduct": true
                      }
                    ],
                    "retention": {
                      "organic": {
                        "status": "available",
                        "reason": null,
                        "durationSeconds": 14.2,
                        "hookRatePct": 68.6,
                        "skipRatePct": 31.4,
                        "avgWatchTimeMs": 14360,
                        "totalWatchTimeMs": 184520000,
                        "updatedAt": 1786089600000
                      },
                      "paid": {
                        "status": "available",
                        "reason": null,
                        "daysLive": 12,
                        "throughDate": "2026-09-18",
                        "impressions": 245000,
                        "video3sViews": 121000,
                        "videoP25Views": 88000,
                        "videoP50Views": 54000,
                        "videoP75Views": 31000,
                        "videoP100Views": 19000,
                        "hookRatePct": 49.4,
                        "completionRatePct": 7.8
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Post not found or not visible to the API key's scope"
          }
        }
      }
    },
    "/posts/{id}/exclude": {
      "post": {
        "tags": [
          "Posts"
        ],
        "summary": "Exclude a post from earnings",
        "description": "Exclude a post in a canvas program from creator earnings. This is permanent. The exclusion covers the post's whole video, including its cross-posts on other platforms (same `crossPostGroupId`). The video stops counting in pay and analytics, its pending pay is removed, and it is not tracked again. Afterwards the posts are no longer returned by `/posts`.\n\nWith a `message`, the creator is told that the video will not be paid, and why. Without one, the creator is not told.\n\nThe request is refused with `409` and a `code` when real pay already reached the creator or a paid ad uses the video. `paid: false` in `/posts` does not guarantee that the exclusion is allowed.\n\nWith `?dryRun=true`, the request runs the same checks and changes nothing. It answers `200` with `{ id, excluded: false, dryRun: true, canExclude, blockedBy, crossPostIds, pendingCentsToRemove }`. A refusal is `canExclude: false` with its code in `blockedBy`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID of the post"
          },
          {
            "in": "query",
            "name": "dryRun",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "With `true`, run every check and roll back. Nothing is excluded, recorded, or sent."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "Optional. Shown to the creator."
                  },
                  "reason": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "deprecated": true,
                    "description": "Earlier name for `message`. Send one of the two, not both."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Post excluded, or the dry-run result",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": [
                        "id",
                        "excluded",
                        "creatorNotified"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "excluded": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        },
                        "creatorNotified": {
                          "type": "boolean",
                          "description": "True when a reason was sent to the creator"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "title": "Dry run",
                      "required": [
                        "id",
                        "excluded",
                        "dryRun",
                        "canExclude"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "excluded": {
                          "type": "boolean",
                          "enum": [
                            false
                          ]
                        },
                        "dryRun": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        },
                        "canExclude": {
                          "type": "boolean"
                        },
                        "blockedBy": {
                          "type": "string",
                          "nullable": true,
                          "description": "The refusal code, for example `already_paid`, `payout_processing`, or `has_paid_ads`"
                        },
                        "crossPostIds": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "description": "Every post the exclusion would remove"
                        },
                        "pendingCentsToRemove": {
                          "type": "integer"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid post id or message, both `message` and `reason` sent, or the post is not in a canvas program"
          },
          "403": {
            "description": "The program is read-only for this API key"
          },
          "404": {
            "description": "Post not found or already excluded"
          },
          "409": {
            "description": "Refused to protect money already paid. `code` is one of `already_paid`, `payout_processing`, `paid_off_platform`, `has_paid_ads`, `has_platform_fee`, `manual_payout_in_progress`, `removal_in_progress`."
          }
        }
      }
    },
    "/posts/lookup": {
      "post": {
        "tags": [
          "Posts"
        ],
        "summary": "Look up posts by id",
        "description": "Get one answer for each of up to 1,000 post ids, in request order. Duplicate ids are answered once.\n\n- A post in a visible program has the `GET /posts` item shape, `payment`, and `exclusion: null`.\n- A post that was removed from a visible program has a short shape with `payment.state: \"excluded\"` and its `exclusion` record, even after the post was deleted.\n- Any other id returns `{ \"id\", \"payment\": { \"state\": \"unknown\" } }`. Unknown means the post is not visible to this API key or does not exist; the two cases are not told apart.\n\nOne request uses one rate-limit slot.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "postIds"
                ],
                "properties": {
                  "postIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 1000,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One entry for each distinct id",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "payment"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "program": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              }
                            },
                            "description": "Removed posts only"
                          },
                          "creatorId": {
                            "type": "string"
                          },
                          "crossPostGroupId": {
                            "type": "string",
                            "nullable": true
                          },
                          "platform": {
                            "type": "string",
                            "nullable": true
                          },
                          "url": {
                            "type": "string"
                          },
                          "uploadedAt": {
                            "type": "integer",
                            "format": "int64"
                          },
                          "payment": {
                            "$ref": "#/components/schemas/PostPayment"
                          },
                          "exclusion": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/PostExclusion"
                              }
                            ],
                            "nullable": true
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing `postIds`, more than 1,000 ids, or an id that is not a UUID"
          }
        }
      }
    },
    "/posts/export": {
      "post": {
        "tags": [
          "Posts"
        ],
        "summary": "Download posts as CSV",
        "description": "Create and download a CSV file containing posts.\n\nThe response streams all post data, including metrics, as CSV.\n",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filters": {
                    "type": "object",
                    "description": "Uses the same filters as GET /posts",
                    "properties": {
                      "program": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "platform": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/PostPlatform"
                        }
                      },
                      "creator": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "creatorHandle": {
                        "type": "string",
                        "description": "A creator's exact social handle, with or without a leading `@`."
                      },
                      "fromDate": {
                        "type": "string",
                        "format": "date"
                      },
                      "toDate": {
                        "type": "string",
                        "format": "date"
                      },
                      "scope": {
                        "type": "string",
                        "enum": [
                          "company",
                          "agency"
                        ]
                      }
                    }
                  },
                  "selectedIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Post IDs to export. When provided, these override filters; an empty array returns a header-only CSV."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "CSV stream",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                },
                "description": "attachment; filename=\"posts-export.csv\""
              }
            }
          }
        }
      }
    },
    "/analytics/kpis": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "View key KPIs",
        "description": "Get key performance indicators grouped by status.\n\nThe response includes:\n- Programs (by status: active, draft, paused, etc.)\n- Contracts (by status: active, pending, completed, etc.)\n- Posts (total, views, engagement, paid/unpaid)\n- Creators (total, with active contracts)\n\nAgency accounts can pass `scope=agency` to calculate KPIs across the\nparent agency and every subaccount.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          }
        ],
        "responses": {
          "200": {
            "description": "KPIs returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "programs": {
                          "type": "object",
                          "properties": {
                            "total": {
                              "type": "integer"
                            },
                            "active": {
                              "type": "integer"
                            },
                            "draft": {
                              "type": "integer"
                            },
                            "paused": {
                              "type": "integer"
                            },
                            "completed": {
                              "type": "integer"
                            },
                            "archived": {
                              "type": "integer"
                            }
                          }
                        },
                        "contracts": {
                          "type": "object",
                          "properties": {
                            "total": {
                              "type": "integer"
                            },
                            "active": {
                              "type": "integer"
                            },
                            "pending": {
                              "type": "integer"
                            },
                            "completed": {
                              "type": "integer"
                            },
                            "declined": {
                              "type": "integer"
                            },
                            "cancelled": {
                              "type": "integer"
                            },
                            "expired": {
                              "type": "integer"
                            }
                          }
                        },
                        "posts": {
                          "type": "object",
                          "properties": {
                            "total": {
                              "type": "integer"
                            },
                            "totalViews": {
                              "type": "integer"
                            },
                            "totalLikes": {
                              "type": "integer"
                            },
                            "totalComments": {
                              "type": "integer"
                            },
                            "totalShares": {
                              "type": "integer"
                            },
                            "paid": {
                              "type": "integer"
                            },
                            "unpaid": {
                              "type": "integer"
                            }
                          }
                        },
                        "creators": {
                          "type": "object",
                          "properties": {
                            "total": {
                              "type": "integer"
                            },
                            "withActiveContracts": {
                              "type": "integer"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/analytics/leaderboard": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "View a program leaderboard",
        "description": "Return an all-time creator leaderboard and program totals without paging through every post.\n\nProvide the program ID in `program`. Every creator in the program is returned in descending order by current total views. Creator sub-profiles are folded into one client-stable root creator ID.\n\n`totalPosts` counts platform post rows, so cross-posted copies count separately. `totalSourceVideos` counts distinct source videos and can be used for de-duplicated totals.\n\nThe normal analytics read model refreshes at :10 and :40 each hour, so its totals can trail a new metric scrape by about 30 minutes. Posts outside that read model fall back to their latest stored metric snapshot.\n\nAgency accounts can pass `scope=agency` to access a program owned by the parent agency or one of its linked brands.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "program",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Program ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Program leaderboard returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "programId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "summary": {
                          "type": "object",
                          "properties": {
                            "uniqueCreators": {
                              "type": "integer"
                            },
                            "totalViews": {
                              "type": "integer",
                              "format": "int64"
                            },
                            "totalPosts": {
                              "type": "integer",
                              "description": "Number of platform post rows; cross-posted copies count separately"
                            },
                            "totalSourceVideos": {
                              "type": "integer",
                              "description": "Number of distinct source videos after grouping cross-posted copies"
                            }
                          }
                        },
                        "topCreators": {
                          "type": "array",
                          "description": "Every program creator in descending order by total views",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Client-stable encrypted root creator ID"
                              },
                              "name": {
                                "type": "string"
                              },
                              "totalViews": {
                                "type": "integer",
                                "format": "int64"
                              },
                              "totalPosts": {
                                "type": "integer",
                                "description": "Number of platform post rows for this creator"
                              },
                              "totalSourceVideos": {
                                "type": "integer",
                                "description": "Number of distinct source videos for this creator"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Program ID is missing, invalid, or conflicts with the alias"
          },
          "404": {
            "description": "No visible program was found"
          }
        }
      }
    },
    "/analytics/videos": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Browse tracked videos and analytics",
        "description": "Get tracked videos/posts with analytics and filters.\n\nEach video includes engagement metrics, sorting, and detailed statistics.\n\nAgency accounts can pass `scope=agency` to combine tracked videos from the\nparent agency and every subaccount.\n\nUse `attribution=gained` to get what each post gained in the dates. Posts with no activity are left out, so a day's rows sum to the day's total on `GET /analytics/overview`. `minViews` and `paid` use lifetime totals and return `400` with `attribution=gained`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 100
            }
          },
          {
            "in": "query",
            "name": "sortBy",
            "schema": {
              "type": "string",
              "enum": [
                "uploadedAt",
                "views",
                "likes",
                "engagement"
              ],
              "default": "uploadedAt"
            },
            "description": "Sort results by field"
          },
          {
            "in": "query",
            "name": "sortOrder",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          },
          {
            "in": "query",
            "name": "program",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "in": "query",
            "name": "platform",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/PostPlatform"
              }
            }
          },
          {
            "in": "query",
            "name": "creator",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "fromDate",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "in": "query",
            "name": "toDate",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "in": "query",
            "name": "minViews",
            "schema": {
              "type": "integer"
            },
            "description": "Minimum views to include"
          },
          {
            "in": "query",
            "name": "paid",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false",
                "all"
              ],
              "default": "all"
            }
          },
          {
            "name": "attribution",
            "in": "query",
            "required": false,
            "description": "Decides what the dates select and what `views` means. `published` selects posts by New York publish day and returns their current lifetime totals. `gained` selects New York days and returns views gained on those days across every tracked post, as on the dashboard Performance chart. With `gained`, `fromDate` and `toDate` are required, a range covers at most 366 days, and money fields are left out.",
            "schema": {
              "type": "string",
              "enum": [
                "published",
                "gained"
              ],
              "default": "published"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tracked videos returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "attribution": {
                      "type": "string",
                      "enum": [
                        "published",
                        "gained"
                      ],
                      "description": "The attribution of this response."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "platform": {
                            "type": "string"
                          },
                          "views": {
                            "type": "integer"
                          },
                          "likes": {
                            "type": "integer"
                          },
                          "comments": {
                            "type": "integer"
                          },
                          "shares": {
                            "type": "integer"
                          },
                          "bookmarks": {
                            "type": "integer"
                          },
                          "engagementRate": {
                            "type": "number"
                          },
                          "totalEngagement": {
                            "type": "integer"
                          },
                          "earnings": {
                            "type": "number"
                          },
                          "cpm": {
                            "type": "number",
                            "nullable": true,
                            "description": "Cost per 1,000 views: creator earnings divided by views, times 1,000, in dollars. Null when there are no views or no money paid yet."
                          },
                          "paid": {
                            "type": "boolean"
                          },
                          "contractorName": {
                            "type": "string"
                          },
                          "uploadedAt": {
                            "type": "integer"
                          },
                          "crossPostGroupId": {
                            "type": "string",
                            "description": "Only with `attribution=gained`. Platform copies of one source video share it."
                          },
                          "programId": {
                            "type": "string",
                            "description": "Only with `attribution=gained`."
                          },
                          "url": {
                            "type": "string",
                            "description": "Only with `attribution=gained`."
                          },
                          "creatorId": {
                            "type": "string",
                            "description": "Only with `attribution=gained`."
                          },
                          "totalViews": {
                            "type": "integer",
                            "description": "Only with `attribution=gained`. The post's total at the end of the dates."
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "totalVideos": {
                          "type": "integer"
                        },
                        "totalViews": {
                          "type": "integer"
                        },
                        "totalLikes": {
                          "type": "integer"
                        },
                        "totalComments": {
                          "type": "integer"
                        },
                        "totalShares": {
                          "type": "integer"
                        },
                        "totalBookmarks": {
                          "type": "integer"
                        },
                        "totalEngagement": {
                          "type": "integer"
                        },
                        "averageEngagementRate": {
                          "type": "number"
                        },
                        "totalEarnings": {
                          "type": "number"
                        },
                        "cpm": {
                          "type": "number",
                          "nullable": true,
                          "description": "Cost per 1,000 views: creator earnings divided by views, times 1,000, in dollars. Null when there are no views or no money paid yet."
                        },
                        "paidVideos": {
                          "type": "integer"
                        },
                        "unpaidVideos": {
                          "type": "integer"
                        },
                        "platformBreakdown": {
                          "type": "object"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/analytics/accounts": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Browse tracked accounts",
        "description": "Get tracked social media accounts with aggregated analytics.\n\nPosts are grouped by social handle and platform, with metrics for each account.\n\nAgency accounts can pass `scope=agency` to combine accounts from the\nparent agency and every subaccount.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 100
            }
          },
          {
            "in": "query",
            "name": "platform",
            "schema": {
              "$ref": "#/components/schemas/PostPlatform"
            },
            "description": "Narrow results to a platform"
          },
          {
            "in": "query",
            "name": "programId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results to a program"
          },
          {
            "in": "query",
            "name": "sortBy",
            "schema": {
              "type": "string",
              "enum": [
                "totalViews",
                "totalPosts",
                "engagementRate",
                "creator"
              ],
              "default": "totalViews"
            }
          },
          {
            "in": "query",
            "name": "sortOrder",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tracked accounts returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "handle": {
                            "type": "string"
                          },
                          "platform": {
                            "type": "string"
                          },
                          "contractorId": {
                            "type": "string"
                          },
                          "contractorName": {
                            "type": "string"
                          },
                          "isGhostHandle": {
                            "type": "boolean"
                          },
                          "totalPosts": {
                            "type": "integer"
                          },
                          "totalViews": {
                            "type": "integer"
                          },
                          "totalLikes": {
                            "type": "integer"
                          },
                          "totalComments": {
                            "type": "integer"
                          },
                          "totalShares": {
                            "type": "integer"
                          },
                          "totalBookmarks": {
                            "type": "integer"
                          },
                          "totalEngagement": {
                            "type": "integer"
                          },
                          "totalEarnings": {
                            "type": "number"
                          },
                          "cpm": {
                            "type": "number",
                            "nullable": true,
                            "description": "Cost per 1,000 views: creator earnings divided by views, times 1,000, in dollars. Null when there are no views or no money paid yet."
                          },
                          "paidPosts": {
                            "type": "integer"
                          },
                          "unpaidPosts": {
                            "type": "integer"
                          },
                          "engagementRate": {
                            "type": "number"
                          },
                          "averageViewsPerPost": {
                            "type": "integer"
                          },
                          "averageEngagementPerPost": {
                            "type": "integer"
                          },
                          "contracts": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "programs": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "contractCount": {
                            "type": "integer"
                          },
                          "programCount": {
                            "type": "integer"
                          },
                          "firstPostDate": {
                            "type": "integer"
                          },
                          "lastPostDate": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "totalAccounts": {
                          "type": "integer"
                        },
                        "totalPosts": {
                          "type": "integer"
                        },
                        "totalViews": {
                          "type": "integer"
                        },
                        "totalLikes": {
                          "type": "integer"
                        },
                        "totalEngagement": {
                          "type": "integer"
                        },
                        "averageEngagementRate": {
                          "type": "number"
                        },
                        "totalEarnings": {
                          "type": "number"
                        },
                        "cpm": {
                          "type": "number",
                          "nullable": true,
                          "description": "Cost per 1,000 views: creator earnings divided by views, times 1,000, in dollars. Null when there are no views or no money paid yet."
                        },
                        "platformBreakdown": {
                          "type": "object"
                        },
                        "ghostHandles": {
                          "type": "integer"
                        },
                        "realHandles": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/analytics/overview": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "View analytics overview",
        "description": "Get analytics with filtering support.\n\nLike the /overall page in the web app, this endpoint returns:\n- Summary metrics\n- Top performing posts\n- Top performing creators\n- Platform breakdown\n\nWhen `fromDate` and/or `toDate` are provided, `summary` follows the same\nactivity attribution model as the dashboard Performance Overview chart:\n- daily deltas from post `daily` stats\n- first-stat totals attributed back to the upload date\n- posts without daily stats attributed to their upload date\n\n`snapshotSummary`, `topPosts`, `topCreators`, and `platformBreakdown`\nstay as upload-date snapshot views, matching the `/overall` page tables.\n\nAgency accounts can pass `scope=agency` to calculate the overview across\nthe parent agency and every subaccount.\n\nUse `attribution=gained` to get the numbers on the dashboard Performance chart. A day is a New York calendar day. The current day is partial, and a late first read of a post changes an earlier day. Metrics history uses UTC days, so its `viewsDelta` sum can differ.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "programId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow analytics to a program"
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow analytics to a creator"
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "platform",
            "schema": {
              "$ref": "#/components/schemas/PostPlatform"
            },
            "description": "Narrow analytics to a platform"
          },
          {
            "in": "query",
            "name": "fromDate",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "in": "query",
            "name": "toDate",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "attribution",
            "in": "query",
            "required": false,
            "description": "Decides what the dates select and what `views` means. `published` selects posts by New York publish day and returns their current lifetime totals. `gained` selects New York days and returns views gained on those days across every tracked post, as on the dashboard Performance chart. With `gained`, `fromDate` and `toDate` are required, a range covers at most 366 days, and money fields are left out. On this route `gained` also leaves out `topPosts`; use `GET /analytics/videos` with `attribution=gained&sortBy=views`.",
            "schema": {
              "type": "string",
              "enum": [
                "published",
                "gained"
              ],
              "default": "published"
            }
          },
          {
            "name": "groupBy",
            "in": "query",
            "required": false,
            "description": "With `attribution=gained`, adds `data.daily`: one row per New York day.",
            "schema": {
              "type": "string",
              "enum": [
                "day"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Analytics overview returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "attribution": {
                      "type": "string",
                      "enum": [
                        "published",
                        "gained"
                      ],
                      "description": "The attribution of this response."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "summary": {
                          "type": "object",
                          "properties": {
                            "totalPosts": {
                              "type": "integer"
                            },
                            "totalViews": {
                              "type": "integer"
                            },
                            "totalLikes": {
                              "type": "integer"
                            },
                            "totalComments": {
                              "type": "integer"
                            },
                            "totalShares": {
                              "type": "integer"
                            },
                            "totalBookmarks": {
                              "type": "integer"
                            },
                            "totalEarnings": {
                              "type": "number"
                            },
                            "cpm": {
                              "type": "number",
                              "nullable": true,
                              "description": "Cost per 1,000 views: creator earnings divided by views, times 1,000, in dollars. Null when there are no views or no money paid yet."
                            },
                            "engagementRate": {
                              "type": "number"
                            },
                            "totalContracts": {
                              "type": "integer"
                            },
                            "activeContracts": {
                              "type": "integer"
                            },
                            "uniqueCreators": {
                              "type": "integer"
                            }
                          }
                        },
                        "snapshotSummary": {
                          "type": "object",
                          "description": "Legacy snapshot totals by upload date for the same filters",
                          "properties": {
                            "totalPosts": {
                              "type": "integer"
                            },
                            "totalViews": {
                              "type": "integer"
                            },
                            "totalLikes": {
                              "type": "integer"
                            },
                            "totalComments": {
                              "type": "integer"
                            },
                            "totalShares": {
                              "type": "integer"
                            },
                            "totalBookmarks": {
                              "type": "integer"
                            },
                            "totalEarnings": {
                              "type": "number"
                            },
                            "cpm": {
                              "type": "number",
                              "nullable": true,
                              "description": "Cost per 1,000 views: creator earnings divided by views, times 1,000, in dollars. Null when there are no views or no money paid yet."
                            },
                            "engagementRate": {
                              "type": "number"
                            },
                            "uniqueCreators": {
                              "type": "integer"
                            }
                          }
                        },
                        "topPosts": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          },
                          "description": "Top 10 posts by snapshot views among posts uploaded in the selected range"
                        },
                        "topCreators": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          },
                          "description": "Top 10 creators by snapshot views among posts uploaded in the selected range"
                        },
                        "platformBreakdown": {
                          "type": "object",
                          "description": "Snapshot metrics by platform for posts uploaded in the selected range"
                        },
                        "daily": {
                          "type": "array",
                          "description": "Only with `attribution=gained` and `groupBy=day`. Each row has the views gained on that day and the posts published that day.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string",
                                "format": "date"
                              },
                              "views": {
                                "type": "integer"
                              },
                              "likes": {
                                "type": "integer"
                              },
                              "comments": {
                                "type": "integer"
                              },
                              "shares": {
                                "type": "integer"
                              },
                              "bookmarks": {
                                "type": "integer"
                              },
                              "posts": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/analytics/recruitment": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "View daily recruitment outreach analytics",
        "description": "Get daily totals for sent recruitment invites and candidate responses.\n\nDates are grouped by UTC day in `YYYY-MM-DD` format.\n\nAgency accounts can pass `scope=agency` to combine recruitment outreach\nfrom the parent agency and every subaccount.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "fromDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Beginning date in YYYY-MM-DD format (UTC). Defaults to 29 days before `toDate`."
          },
          {
            "in": "query",
            "name": "toDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Ending date in YYYY-MM-DD format (UTC). Defaults to today."
          }
        ],
        "responses": {
          "200": {
            "description": "Recruitment analytics returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "summary": {
                          "type": "object",
                          "properties": {
                            "totalInvitesSent": {
                              "type": "integer"
                            },
                            "totalResponsesReceived": {
                              "type": "integer"
                            },
                            "responseRate": {
                              "type": "number",
                              "description": "Responses divided by invites sent and shown as a percentage"
                            }
                          }
                        },
                        "daily": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string",
                                "description": "UTC date bucket formatted as YYYY-MM-DD"
                              },
                              "invitesSent": {
                                "type": "integer"
                              },
                              "responsesReceived": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "filters": {
                          "type": "object",
                          "properties": {
                            "fromDate": {
                              "type": "string",
                              "format": "date"
                            },
                            "toDate": {
                              "type": "string",
                              "format": "date"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Date range or format is invalid"
          }
        }
      }
    },
    "/analytics/comment-dms": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Report the comment-to-DM funnel",
        "description": "Comment-to-DM attribution for each visible program: how many leads opted in, how many got the first DM, and how many tapped the DM link.\n\nEvery row has the same fields. A field the chosen grouping does not use is `null`. Group the report with `groupBy`:\n\n- `program` (default): one row per program.\n- `account`: one row per program and creator account that sent the DMs.\n- `post`: one row per program, creator account, and the post the lead commented on. `postId` is the id used by `GET /posts` when the post is tracked; otherwise it is `null`. A lead who DMed the keyword directly has no post, so that row has a `null` `platformPostId`.\n- `day`: one row per day.\n\nEach event counts on its own day in America/New_York, the same rule as the dashboard DMs sent and DM clicks tiles: an opt-in on the day the conversation opened, a DM on the day it was sent, a tap on the day of the tap. `fromDate` and `toDate` apply to those days, so a tap can fall in a range that does not include its DM.\n\nTaps on links sent by Launchpoint's earlier comment automations (before 2026-09-27) are included and belong to their post. Opt-ins and sends from that period were not stored.\n\nSort with `sortBy` and `sortOrder` (default `desc`). `sortBy` defaults to `date` for `groupBy=day` and to `linkClicks` otherwise; `sortBy=date` works only with `groupBy=day`. Ties keep a stable order, so pages do not shift between reads. `summary` sums every row in the report, not only the current page.\n\nEach row and `summary` have `linkClicksByCountry`: the link taps per country, most taps first. Launchpoint finds the country from the IP address of the tap. With `groupBy=post` this gives the taps per video per country. `country` is `null` when it is not known, which is true for every tap made before this field was added. The API does not return IP addresses.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagination page number"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Rows to return per page"
          },
          {
            "in": "query",
            "name": "programId",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Narrow the report to one program"
          },
          {
            "in": "query",
            "name": "groupBy",
            "schema": {
              "type": "string",
              "enum": [
                "program",
                "account",
                "post",
                "day"
              ],
              "default": "program"
            },
            "description": "How to group the rows"
          },
          {
            "in": "query",
            "name": "sortBy",
            "schema": {
              "type": "string",
              "enum": [
                "linkClicks",
                "uniqueClickers",
                "dmsSent",
                "optIns",
                "date"
              ]
            },
            "description": "Field to sort rows by. Defaults to `date` for groupBy=day and `linkClicks` otherwise. `date` needs groupBy=day"
          },
          {
            "in": "query",
            "name": "sortOrder",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "in": "query",
            "name": "fromDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Count events on or after this day (YYYY-MM-DD, America/New_York)"
          },
          {
            "in": "query",
            "name": "toDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Count events on or before this day (YYYY-MM-DD, America/New_York)"
          }
        ],
        "responses": {
          "200": {
            "description": "Comment-to-DM funnel returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "Every row has every field. Grouping keys the chosen `groupBy` does not use are null.",
                        "properties": {
                          "programId": {
                            "type": "string",
                            "nullable": true,
                            "description": "Program id (groupBy=program, account, or post)"
                          },
                          "programName": {
                            "type": "string",
                            "nullable": true,
                            "description": "Program name (groupBy=program, account, or post)"
                          },
                          "handle": {
                            "type": "string",
                            "nullable": true,
                            "description": "Creator account handle (groupBy=account or post). For Facebook this is the numeric profile id"
                          },
                          "platform": {
                            "type": "string",
                            "nullable": true,
                            "description": "instagram or facebook (groupBy=account or post)"
                          },
                          "creatorId": {
                            "type": "string",
                            "nullable": true,
                            "description": "Opaque creator id, the same as GET /creators (groupBy=account or post)"
                          },
                          "platformPostId": {
                            "type": "string",
                            "nullable": true,
                            "description": "The platform's id for the post the lead commented on (groupBy=post)"
                          },
                          "postId": {
                            "type": "string",
                            "nullable": true,
                            "description": "The GET /posts id when the post is tracked, else null (groupBy=post)"
                          },
                          "postUrl": {
                            "type": "string",
                            "nullable": true,
                            "description": "The tracked post's link, else null (groupBy=post)"
                          },
                          "date": {
                            "type": "string",
                            "format": "date",
                            "nullable": true,
                            "description": "America/New_York day (groupBy=day)"
                          },
                          "optIns": {
                            "type": "integer",
                            "description": "Leads who opted in: a keyword comment or a keyword DM that opened a conversation"
                          },
                          "dmsSent": {
                            "type": "integer",
                            "description": "Conversations whose first DM went out. Follow-up DMs are not counted"
                          },
                          "linkClicks": {
                            "type": "integer",
                            "description": "Taps on the DM link by a person; link previews and prefetches are not counted"
                          },
                          "uniqueClickers": {
                            "type": "integer",
                            "description": "Conversations (people) with at least one link tap"
                          },
                          "linkClicksByCountry": {
                            "type": "array",
                            "description": "Link taps per country, most taps first; ties in country code order with null last. The linkClicks values add up to linkClicks",
                            "items": {
                              "type": "object",
                              "properties": {
                                "country": {
                                  "type": "string",
                                  "nullable": true,
                                  "description": "Two-letter ISO 3166-1 country code from the IP address of the tap, or null when it is not known"
                                },
                                "linkClicks": {
                                  "type": "integer",
                                  "description": "Taps from this country"
                                }
                              },
                              "required": [
                                "country",
                                "linkClicks"
                              ]
                            }
                          }
                        },
                        "required": [
                          "programId",
                          "programName",
                          "handle",
                          "platform",
                          "creatorId",
                          "platformPostId",
                          "postId",
                          "postUrl",
                          "date",
                          "optIns",
                          "dmsSent",
                          "linkClicks",
                          "uniqueClickers",
                          "linkClicksByCountry"
                        ]
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    },
                    "groupBy": {
                      "type": "string",
                      "enum": [
                        "program",
                        "account",
                        "post",
                        "day"
                      ]
                    },
                    "fromDate": {
                      "type": "string",
                      "format": "date",
                      "nullable": true
                    },
                    "toDate": {
                      "type": "string",
                      "format": "date",
                      "nullable": true
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "optIns": {
                          "type": "integer",
                          "description": "Leads who opted in: a keyword comment or a keyword DM that opened a conversation"
                        },
                        "dmsSent": {
                          "type": "integer",
                          "description": "Conversations whose first DM went out. Follow-up DMs are not counted"
                        },
                        "linkClicks": {
                          "type": "integer",
                          "description": "Taps on the DM link by a person; link previews and prefetches are not counted"
                        },
                        "uniqueClickers": {
                          "type": "integer",
                          "description": "Conversations (people) with at least one link tap"
                        },
                        "linkClicksByCountry": {
                          "type": "array",
                          "description": "Link taps per country, most taps first; ties in country code order with null last. The linkClicks values add up to linkClicks",
                          "items": {
                            "type": "object",
                            "properties": {
                              "country": {
                                "type": "string",
                                "nullable": true,
                                "description": "Two-letter ISO 3166-1 country code from the IP address of the tap, or null when it is not known"
                              },
                              "linkClicks": {
                                "type": "integer",
                                "description": "Taps from this country"
                              }
                            },
                            "required": [
                              "country",
                              "linkClicks"
                            ]
                          }
                        }
                      }
                    },
                    "sortBy": {
                      "type": "string",
                      "enum": [
                        "linkClicks",
                        "uniqueClickers",
                        "dmsSent",
                        "optIns",
                        "date"
                      ]
                    },
                    "sortOrder": {
                      "type": "string",
                      "enum": [
                        "asc",
                        "desc"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid filters, such as fromDate after toDate, an unknown groupBy or sortBy, or sortBy=date without groupBy=day"
          },
          "401": {
            "description": "API key is invalid or missing"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    },
    "/programs/{id}/invite": {
      "post": {
        "tags": [
          "Programs"
        ],
        "summary": "Create a program invite link",
        "description": "Create a shareable invite link for a program.\n\nCreators can join the program directly through this link.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the program"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "expiresInDays": {
                    "type": "integer",
                    "description": "Days before the link expires (null for never, max 90)",
                    "example": 14,
                    "nullable": true
                  },
                  "maxUses": {
                    "type": "integer",
                    "description": "Maximum link uses (null for unlimited)",
                    "example": 50,
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Invite link was created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "link": {
                      "type": "string",
                      "description": "Complete invite URL"
                    },
                    "token": {
                      "type": "string",
                      "description": "Token for the invite"
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "maxUses": {
                      "type": "integer",
                      "nullable": true
                    },
                    "programId": {
                      "type": "string"
                    },
                    "programName": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request is invalid"
          },
          "404": {
            "description": "No program was found"
          }
        }
      }
    },
    "/programs/{id}/creators/{creatorId}/discord-channel": {
      "put": {
        "tags": [
          "Creators"
        ],
        "summary": "Link a Discord channel to a creator",
        "description": "Make a Discord text channel that you created the creator's space on this program's Discord server. Launchpoint then sends that creator's drafts and notices there.\n\nUse this when your own flow creates each creator's channel and creator channel creation is turned off in the program's Discord settings. It replaces the creator's earlier space for this program; it does not delete that space.\n\nThe channel must be a text or announcement channel in the program's server, and the Launchpoint bot must be able to see it and post in it. A thread is not accepted. This route does not give the creator access to the channel.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The program id"
          },
          {
            "in": "path",
            "name": "creatorId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The creator `id` from `GET /creators`"
          },
          {
            "$ref": "#/components/parameters/ScopeParam"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "channelId"
                ],
                "properties": {
                  "channelId": {
                    "type": "string",
                    "description": "The Discord text channel id",
                    "example": "1200000000000000002"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Channel linked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "programId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "creatorId": {
                      "type": "string"
                    },
                    "channelId": {
                      "type": "string"
                    },
                    "channelName": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, creator id, or channel id"
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "403": {
            "description": "The program is read-only for this API key"
          },
          "404": {
            "description": "Program not found, the creator is not an approved creator in this program, or the channel was not found as a text or announcement channel in the program's server"
          },
          "409": {
            "description": "The program has no connected Discord server, the channel is linked to another creator, or the Launchpoint bot cannot post in the channel"
          },
          "429": {
            "description": "Request rate limit exceeded"
          }
        }
      }
    },
    "/payouts": {
      "get": {
        "tags": [
          "Payouts"
        ],
        "summary": "View wallet activity",
        "description": "Read-only view of your company's wallet ledger entries.\n\nThe ledger lists wallet credits and debits, including:\n- Payouts to creators\n- Adjustments\n- Refunds\n\n**Note:** The API does not support executing payouts for security reasons.\n",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results to a creator"
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "contractId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results to a contract"
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "confirmed",
                "pending",
                "failed"
              ]
            },
            "description": "Narrow results by transaction status"
          },
          {
            "in": "query",
            "name": "reason",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results by description (e.g., \"payout\", \"adjustment\")"
          },
          {
            "in": "query",
            "name": "fromDate",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "in": "query",
            "name": "toDate",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Wallet activity returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "amount": {
                            "type": "number",
                            "description": "Transaction amount in dollars (negative values are debits)"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "credit",
                              "debit"
                            ],
                            "description": "Type of transaction"
                          },
                          "balanceAfter": {
                            "type": "number",
                            "nullable": true,
                            "description": "Wallet balance after the transaction (in dollars)"
                          },
                          "description": {
                            "type": "string",
                            "description": "Description of the transaction (e.g., \"Payout to creator\")"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "confirmed",
                              "pending",
                              "failed"
                            ]
                          },
                          "contractId": {
                            "type": "string",
                            "nullable": true
                          },
                          "creatorId": {
                            "type": "string",
                            "nullable": true
                          },
                          "creatorName": {
                            "type": "string",
                            "nullable": true
                          },
                          "creatorProfileImageUrl": {
                            "type": "string",
                            "nullable": true
                          },
                          "programId": {
                            "type": "string",
                            "nullable": true
                          },
                          "createdAt": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "totalCredits": {
                          "type": "number",
                          "description": "Total credits in dollars"
                        },
                        "totalDebits": {
                          "type": "number",
                          "description": "Total debits in dollars (absolute value)"
                        },
                        "confirmedCount": {
                          "type": "integer"
                        },
                        "pendingCount": {
                          "type": "integer"
                        },
                        "failedCount": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payouts/stats": {
      "get": {
        "tags": [
          "Payouts"
        ],
        "summary": "View payout wallet statistics",
        "description": "Read-only summary of your company's payout wallet balances and lifetime activity.\n\nThese are the same metrics shown on the payouts dashboard:\n- **Available balance** \u2014 funds ready to pay creators\n- **Pending balance** \u2014 incoming top-ups still processing\n- **Total owed** \u2014 calculated amount owed across active contracts\n- **Lifetime deposits** \u2014 total confirmed wallet top-ups\n- **Lifetime paid out** \u2014 total confirmed payouts to creators\n\nAll amounts are in USD dollars.\n",
        "responses": {
          "200": {
            "description": "Payout statistics returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "availableBalance": {
                      "type": "number",
                      "description": "Available wallet balance, in dollars"
                    },
                    "pendingBalance": {
                      "type": "number",
                      "description": "Pending top-up balance, in dollars"
                    },
                    "totalOwed": {
                      "type": "number",
                      "description": "Total owed to creators across active contracts, in dollars"
                    },
                    "lifetimeDeposits": {
                      "type": "number",
                      "description": "Confirmed wallet deposits over time, in dollars"
                    },
                    "lifetimePaidOut": {
                      "type": "number",
                      "description": "Confirmed payouts to creators over time, in dollars"
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "usd"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API key is invalid or missing"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "500": {
            "description": "Server error"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          }
        ]
      }
    },
    "/payouts/spend": {
      "get": {
        "tags": [
          "Payouts"
        ],
        "summary": "Report creator spend per program",
        "description": "Creator money for each visible program, using the same definition as the campaign pages in the dashboard.\n\n`spend` is money sent to creators through Launchpoint (`paid`), money the brand paid creators directly (`paidOffPlatform`), and money still held for creators (`awaiting` is past its pay date, `tracking` is still inside its view window). Every field is returned in dollars and in cents.\n\nThis is different from `GET /payouts`, which lists money that left your own wallet. For an agency, a linked brand's wallet can fund the same creators, so summing the wallet ledger by program understates what creators earned. Use this endpoint for per-program spend reports.\n\n`fromDate` and `toDate` pick posts by their publish day, the same rule as the dashboard date picker, not the day money moved. Rows are sorted by spend, and `summary` sums every program in the report, not only the current page.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagination page number"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Programs to return per page"
          },
          {
            "in": "query",
            "name": "programId",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Narrow the report to one program"
          },
          {
            "in": "query",
            "name": "fromDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Count posts published on or after this day (YYYY-MM-DD)"
          },
          {
            "in": "query",
            "name": "toDate",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Count posts published on or before this day (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "Program spend returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "programId": {
                            "type": "string"
                          },
                          "programName": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "draft",
                              "active",
                              "paused",
                              "completed",
                              "archived"
                            ]
                          },
                          "currency": {
                            "type": "string",
                            "enum": [
                              "usd"
                            ]
                          },
                          "spend": {
                            "type": "number",
                            "description": "paid + paidOffPlatform + awaiting + tracking, in dollars"
                          },
                          "spendCents": {
                            "type": "integer",
                            "description": "paid + paidOffPlatform + awaiting + tracking, in cents"
                          },
                          "paid": {
                            "type": "number",
                            "description": "Money sent to creators through Launchpoint, in dollars"
                          },
                          "paidCents": {
                            "type": "integer",
                            "description": "Money sent to creators through Launchpoint, in cents"
                          },
                          "paidOffPlatform": {
                            "type": "number",
                            "description": "Money the brand paid creators directly, outside Launchpoint, in dollars"
                          },
                          "paidOffPlatformCents": {
                            "type": "integer",
                            "description": "Money the brand paid creators directly, outside Launchpoint, in cents"
                          },
                          "awaiting": {
                            "type": "number",
                            "description": "Money held for creators that is past its pay date, in dollars"
                          },
                          "awaitingCents": {
                            "type": "integer",
                            "description": "Money held for creators that is past its pay date, in cents"
                          },
                          "tracking": {
                            "type": "number",
                            "description": "Money held for creators that is still inside its view-tracking window, in dollars"
                          },
                          "trackingCents": {
                            "type": "integer",
                            "description": "Money held for creators that is still inside its view-tracking window, in cents"
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    },
                    "fromDate": {
                      "type": "string",
                      "nullable": true
                    },
                    "toDate": {
                      "type": "string",
                      "nullable": true
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "programCount": {
                          "type": "integer",
                          "description": "Programs in the whole report, not only this page"
                        },
                        "currency": {
                          "type": "string",
                          "enum": [
                            "usd"
                          ]
                        },
                        "spend": {
                          "type": "number",
                          "description": "paid + paidOffPlatform + awaiting + tracking, in dollars"
                        },
                        "spendCents": {
                          "type": "integer",
                          "description": "paid + paidOffPlatform + awaiting + tracking, in cents"
                        },
                        "paid": {
                          "type": "number",
                          "description": "Money sent to creators through Launchpoint, in dollars"
                        },
                        "paidCents": {
                          "type": "integer",
                          "description": "Money sent to creators through Launchpoint, in cents"
                        },
                        "paidOffPlatform": {
                          "type": "number",
                          "description": "Money the brand paid creators directly, outside Launchpoint, in dollars"
                        },
                        "paidOffPlatformCents": {
                          "type": "integer",
                          "description": "Money the brand paid creators directly, outside Launchpoint, in cents"
                        },
                        "awaiting": {
                          "type": "number",
                          "description": "Money held for creators that is past its pay date, in dollars"
                        },
                        "awaitingCents": {
                          "type": "integer",
                          "description": "Money held for creators that is past its pay date, in cents"
                        },
                        "tracking": {
                          "type": "number",
                          "description": "Money held for creators that is still inside its view-tracking window, in dollars"
                        },
                        "trackingCents": {
                          "type": "integer",
                          "description": "Money held for creators that is still inside its view-tracking window, in cents"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid filters, such as fromDate after toDate"
          },
          "401": {
            "description": "API key is invalid or missing"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    },
    "/payouts/pending": {
      "get": {
        "tags": [
          "Payouts"
        ],
        "summary": "View pending payouts",
        "description": "Get money currently held for creators in the payout reserve.\n\nThis is money already held for payment, not every unpaid creator amount or a complete list of pay terms. Use `/pay-structures` for creator and program pay terms.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 100
            }
          },
          {
            "in": "query",
            "name": "programId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results to a program"
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results to a creator"
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "minAmount",
            "schema": {
              "type": "number",
              "minimum": 0,
              "multipleOf": 0.01
            },
            "description": "Minimum payout in dollars, with at most two decimal places"
          },
          {
            "in": "query",
            "name": "sortBy",
            "schema": {
              "type": "string",
              "enum": [
                "amount",
                "dueDate",
                "creator"
              ],
              "default": "amount"
            }
          },
          {
            "in": "query",
            "name": "sortOrder",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pending payouts returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "contractId": {
                            "type": "string",
                            "nullable": true,
                            "description": "Offer-level contract ID, or null when the pending reserve has no contract row"
                          },
                          "contractName": {
                            "type": "string"
                          },
                          "amount": {
                            "type": "number",
                            "description": "Amount, in dollars"
                          },
                          "amountCents": {
                            "type": "integer"
                          },
                          "originalAmount": {
                            "type": "number",
                            "description": "Amount before the pro-rata adjustment"
                          },
                          "originalAmountCents": {
                            "type": "integer"
                          },
                          "currency": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "overdue",
                              "due",
                              "upcoming"
                            ]
                          },
                          "dueDate": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "isOverdue": {
                            "type": "boolean"
                          },
                          "isDue": {
                            "type": "boolean"
                          },
                          "programId": {
                            "type": "string",
                            "nullable": true
                          },
                          "programName": {
                            "type": "string",
                            "nullable": true
                          },
                          "creatorId": {
                            "type": "string"
                          },
                          "creatorName": {
                            "type": "string"
                          },
                          "creatorProfileImageUrl": {
                            "type": "string",
                            "nullable": true
                          },
                          "hasStripeAccount": {
                            "type": "boolean"
                          },
                          "deliveredPosts": {
                            "type": "integer"
                          },
                          "requiredPosts": {
                            "type": "integer"
                          },
                          "deliveryPercentage": {
                            "type": "number"
                          },
                          "totalViews": {
                            "type": "integer"
                          },
                          "isProRata": {
                            "type": "boolean"
                          },
                          "paymentComponents": {
                            "type": "array",
                            "items": {
                              "type": "object"
                            }
                          },
                          "paymentStructure": {
                            "type": "object",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "totalPending": {
                          "type": "integer"
                        },
                        "totalAmount": {
                          "type": "number"
                        },
                        "totalAmountCents": {
                          "type": "integer"
                        },
                        "overdueCount": {
                          "type": "integer"
                        },
                        "dueCount": {
                          "type": "integer"
                        },
                        "upcomingCount": {
                          "type": "integer"
                        },
                        "readyToPay": {
                          "type": "integer"
                        },
                        "needsSetup": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/creators": {
      "get": {
        "tags": [
          "Creators"
        ],
        "summary": "Browse creators",
        "description": "Get creators associated with your company, along with a contract status map for each campaign.\nUse this to see which creators are active across your campaigns. Each creator has a\n`phone` number, which is `null` when no number is on file or while your creator access is locked.\nCreator email addresses are never returned.\n\nThe `campaigns` array lists every program a creator is or was contracted under,\nalong with its contract status. A creator's top-level `status` is `\"active\"` when they\nhave at least one active contract; otherwise, it is `\"inactive\"`.\n\nEach campaign lists `enhancementOptIns`: the creator's accounts opted into that\nprogram's enhancements, trial reels (`trialReels`) or comment-to-DM (`commentDm`).\nA brand turns an enhancement on for a program; the creator then opts in per account.\nAn account opted into both has two entries. An opt-out removes the entry.\n\nGhost-handle contracts are excluded.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagination page number"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Results to return per page"
          },
          {
            "in": "query",
            "name": "programId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results to creators contracted in this program"
          },
          {
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string"
            },
            "description": "Find approved creators by part of their name or of a social handle assigned to a visible program. A leading `@` is ignored. To find a creator who is not approved yet, use `search` on `GET /applications`."
          }
        ],
        "responses": {
          "200": {
            "description": "Creators returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "User ID for the creator"
                          },
                          "name": {
                            "type": "string"
                          },
                          "phone": {
                            "type": "string",
                            "nullable": true,
                            "description": "Creator phone number. `null` when no number is on file, and `null` for every creator while creator access is locked (wallet balance under the minimum)."
                          },
                          "profileImageUrl": {
                            "type": "string",
                            "nullable": true
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "inactive"
                            ],
                            "description": "`\"active\"` when the creator has at least one active contract"
                          },
                          "niches": {
                            "type": "array",
                            "description": "Niches the creator picked in the Launchpoint app, oldest pick first. Self-reported, not inferred from content. Empty when the creator picked none.",
                            "items": {
                              "type": "object",
                              "required": [
                                "code",
                                "name"
                              ],
                              "properties": {
                                "code": {
                                  "type": "string",
                                  "enum": [
                                    "sports",
                                    "health_fitness",
                                    "beauty",
                                    "collectibles",
                                    "education_learning",
                                    "entertainment_media",
                                    "family",
                                    "fashion",
                                    "finance_commerce",
                                    "food_drink",
                                    "gaming",
                                    "lifestyle_utilities",
                                    "music",
                                    "photo_video",
                                    "side_hustle_business",
                                    "social_communication",
                                    "technology",
                                    "travel_local",
                                    "other"
                                  ],
                                  "description": "Stable niche key to match on. New codes can be added; existing codes do not change. A niche the creator typed in is `other`."
                                },
                                "name": {
                                  "type": "string",
                                  "description": "English display name, such as `Health & Fitness`. For a typed-in niche, the creator's own text."
                                }
                              }
                            },
                            "example": [
                              {
                                "code": "health_fitness",
                                "name": "Health & Fitness"
                              },
                              {
                                "code": "gaming",
                                "name": "Gaming"
                              }
                            ]
                          },
                          "campaigns": {
                            "type": "array",
                            "description": "Contract status for each campaign/program",
                            "items": {
                              "type": "object",
                              "properties": {
                                "programId": {
                                  "type": "string"
                                },
                                "programName": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "contractId": {
                                  "type": "string"
                                },
                                "joinedAt": {
                                  "type": "integer",
                                  "nullable": true,
                                  "description": "When the creator joined this program: their first approval on it, the date the dashboard shows as \"Joined\". Unix milliseconds, an absolute UTC instant, so compare it directly with a post's `uploadedAt`. `null` when the creator has no approval record."
                                },
                                "contractStatus": {
                                  "type": "string",
                                  "enum": [
                                    "pending",
                                    "active",
                                    "completed",
                                    "declined",
                                    "cancelled"
                                  ]
                                },
                                "handles": {
                                  "type": "array",
                                  "description": "Social handles linked to this contract",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "platform": {
                                        "type": "string"
                                      },
                                      "handle": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                },
                                "enhancementOptIns": {
                                  "type": "array",
                                  "description": "The creator's accounts opted into an enhancement on this program, oldest first",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "enhancement": {
                                        "type": "string",
                                        "enum": [
                                          "trialReels",
                                          "commentDm"
                                        ]
                                      },
                                      "platform": {
                                        "type": "string",
                                        "description": "Platform of the opted-in account, such as `instagram` or `facebook`"
                                      },
                                      "handle": {
                                        "type": "string",
                                        "description": "Handle of the opted-in account. Facebook Pages return the Page id."
                                      },
                                      "optedInAt": {
                                        "type": "integer",
                                        "description": "When the creator opted in, in Unix milliseconds"
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/creators/collections": {
      "get": {
        "tags": [
          "Creators"
        ],
        "summary": "Browse creator collections",
        "description": "Get the creator collections (saved account groups) for the\nauthenticated company.\n",
        "responses": {
          "200": {
            "description": "Creator collections returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "color": {
                            "type": "string",
                            "nullable": true
                          },
                          "creatorCount": {
                            "type": "integer"
                          },
                          "creatorIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "429": {
            "description": "Request rate limit exceeded"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          }
        ]
      },
      "post": {
        "tags": [
          "Creators"
        ],
        "summary": "Create a creator collection",
        "description": "Create a collection that your workspace owns. Add creators with `POST /creators/collections/{id}/creators`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Collection created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "name"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "403": {
            "description": "The API key is limited to one campaign. Collections belong to the workspace."
          },
          "409": {
            "description": "Your workspace already has a collection with this name"
          }
        }
      }
    },
    "/creators/collections/{id}": {
      "patch": {
        "tags": [
          "Creators"
        ],
        "summary": "Rename a creator collection",
        "description": "Rename a collection that your workspace owns.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The collection id from `GET /creators/collections`"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Collection renamed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "name"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "403": {
            "description": "The API key is limited to one campaign. Collections belong to the workspace."
          },
          "404": {
            "description": "Collection not found, or this API key cannot change it"
          },
          "409": {
            "description": "Your workspace already has a collection with this name"
          }
        }
      },
      "delete": {
        "tags": [
          "Creators"
        ],
        "summary": "Delete a creator collection",
        "description": "Delete a collection that your workspace owns. Its creators leave the collection; they are not moved to another one and nothing else about them changes.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The collection id from `GET /creators/collections`"
          }
        ],
        "responses": {
          "200": {
            "description": "Collection deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "403": {
            "description": "The API key is limited to one campaign. Collections belong to the workspace."
          },
          "404": {
            "description": "Collection not found, or this API key cannot change it"
          }
        }
      }
    },
    "/creators/collections/{id}/creators": {
      "post": {
        "tags": [
          "Creators"
        ],
        "summary": "Add creators to a collection",
        "description": "Add creators by the `id` that `GET /creators` returns. A creator already in the collection is counted in `skipped`.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The collection id from `GET /creators/collections`"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "creatorIds"
                ],
                "properties": {
                  "creatorIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 1000,
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Creators added",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "added": {
                      "type": "integer"
                    },
                    "skipped": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or creator id"
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "403": {
            "description": "The API key is limited to one campaign, or an agency key named a creator who is neither linked to the agency nor on a campaign it can see"
          },
          "404": {
            "description": "Collection not found, or this API key cannot change it"
          }
        }
      },
      "delete": {
        "tags": [
          "Creators"
        ],
        "summary": "Remove creators from a collection",
        "description": "Remove creators named in repeated `creatorId` query parameters. This request has no body.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The collection id from `GET /creators/collections`"
          },
          {
            "in": "query",
            "name": "creatorId",
            "required": true,
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 1000,
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "A creator `id` from `GET /creators`. Repeat the parameter for each creator."
          }
        ],
        "responses": {
          "200": {
            "description": "Creators removed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "removed": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or creator id"
          },
          "401": {
            "description": "Unauthorized - API key is invalid"
          },
          "429": {
            "description": "Request rate limit exceeded"
          },
          "403": {
            "description": "The API key is limited to one campaign. Collections belong to the workspace."
          },
          "404": {
            "description": "Collection not found, or this API key cannot change it"
          }
        }
      }
    },
    "/applications": {
      "get": {
        "tags": [
          "Applications"
        ],
        "summary": "Browse creator applications",
        "description": "Get creator applications to your Canvas programs, with each application's approval status.\n\nAn application is a creator's current enrollment in a Canvas program together with the campaign-level approval decision. `status` is `pending` while the application waits for review, `approved` once the creator is accepted, and `rejected` when the creator is turned down. A creator who joined before approvals existed is returned as `approved` with `decidedAt: null`.\n\nBrief-based programs approve creators per brief and are not listed here.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagination page number"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Results to return per page"
          },
          {
            "in": "query",
            "name": "programId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results to applications for this program"
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            },
            "description": "Narrow results to one creator, using the opaque `id` returned by `/creators`"
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string"
            },
            "description": "Find applications by part of the creator's name or of a handle on a social account the creator linked. A leading `@` is ignored. This also finds applicants who are not approved yet, which `GET /creators` does not list."
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "approved",
                "rejected"
              ]
            },
            "description": "Narrow results to one application status"
          }
        ],
        "responses": {
          "200": {
            "description": "Applications returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Stable application id"
                          },
                          "programId": {
                            "type": "string"
                          },
                          "programName": {
                            "type": "string",
                            "nullable": true
                          },
                          "creatorId": {
                            "type": "string",
                            "description": "Opaque creator id, the same value `/creators` returns"
                          },
                          "creatorName": {
                            "type": "string"
                          },
                          "creatorProfileImageUrl": {
                            "type": "string",
                            "nullable": true
                          },
                          "handles": {
                            "type": "array",
                            "description": "Social handles linked to the creator",
                            "items": {
                              "type": "object",
                              "properties": {
                                "platform": {
                                  "type": "string"
                                },
                                "handle": {
                                  "type": "string"
                                }
                              }
                            }
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "approved",
                              "rejected"
                            ]
                          },
                          "submittedAt": {
                            "type": "integer",
                            "description": "When the creator applied, in Unix milliseconds. Uses the application media time, or the enrollment time when no media was sent."
                          },
                          "decidedAt": {
                            "type": "integer",
                            "nullable": true,
                            "description": "When the application was approved or rejected, in Unix milliseconds. `null` while pending."
                          },
                          "applicationVideoUrl": {
                            "type": "string",
                            "nullable": true,
                            "description": "Video the creator sent with the application, if any"
                          },
                          "applicationThumbnailUrl": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/conversations": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "List creator conversations",
        "description": "List conversations for one visible program. Reading this endpoint does not change message read receipts. Creator ids are the opaque ids returned by `/creators`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "programId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            },
            "description": "Optional opaque creator id"
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Conversations returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "page",
                    "total",
                    "totalPages"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CreatorConversation"
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid program, creator, or paging value"
          },
          "404": {
            "description": "Program not found"
          }
        }
      }
    },
    "/conversations/{id}/messages": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "Read conversation messages",
        "description": "Read a newest-first message page. This does not mark the conversation read or change either side's read receipt.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Conversation id"
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            },
            "description": "Opaque nextCursor from the previous page"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Messages returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "nextCursor",
                    "creatorLastReadAt"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CreatorMessage"
                      }
                    },
                    "nextCursor": {
                      "type": "string",
                      "nullable": true
                    },
                    "creatorLastReadAt": {
                      "type": "integer",
                      "format": "int64",
                      "nullable": true,
                      "description": "When the creator last opened the conversation"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid conversation id, cursor, or limit"
          },
          "404": {
            "description": "Conversation not found"
          }
        }
      }
    },
    "/messages": {
      "post": {
        "tags": [
          "Messages"
        ],
        "summary": "Send a creator message",
        "description": "Send a real message from the workspace to a creator and notify them. The program must be writable, the creator must be part of it, and the creator must not be blocked. Pass a stable clientMessageId UUID to make retries idempotent.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "programId",
                  "creatorId",
                  "body"
                ],
                "properties": {
                  "programId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "creatorId": {
                    "type": "string",
                    "description": "Opaque creator id returned by `/creators`"
                  },
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4000
                  },
                  "clientMessageId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Optional stable idempotency id for safe retries"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message stored and creator notification attempted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "conversationId",
                    "message"
                  ],
                  "properties": {
                    "conversationId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "message": {
                      "$ref": "#/components/schemas/CreatorMessage"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid creator, program, message, or idempotency id"
          },
          "403": {
            "description": "Program is read-only, creator details are locked, or the creator is blocked"
          },
          "404": {
            "description": "Program or creator relationship not found"
          },
          "409": {
            "description": "clientMessageId was already used for a different message"
          }
        }
      }
    },
    "/onboarding": {
      "get": {
        "tags": [
          "Onboarding"
        ],
        "summary": "List creators in onboarding",
        "description": "List the creators in one program who still have onboarding work, the same list as the dashboard's Onboarding tasks: creators with a proof waiting for review first, then creators still getting ready.\n\nThe list includes approved creators who still have an open slot. A creator with no linked account is listed only when the program requires specific platforms; check other creators with `GET /onboarding/{creatorId}`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "programId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            },
            "description": "Optional opaque creator id"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Creators returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "page",
                    "total",
                    "totalPages"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "programId",
                          "creatorId",
                          "status",
                          "pendingProofCount",
                          "lastActivityAt"
                        ],
                        "properties": {
                          "programId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "creatorId": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "waiting_for_review",
                              "getting_ready"
                            ],
                            "description": "`waiting_for_review`: a proof waits for your decision. `getting_ready`: the creator still has to do something. `ready`: nothing is left (detail only)."
                          },
                          "pendingProofCount": {
                            "type": "integer",
                            "description": "Proofs waiting for your decision"
                          },
                          "lastActivityAt": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Newest proof submission or account link"
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid program, creator, or paging value"
          },
          "404": {
            "description": "Program not found"
          }
        }
      }
    },
    "/onboarding/{creatorId}": {
      "get": {
        "tags": [
          "Onboarding"
        ],
        "summary": "Get a creator's onboarding",
        "description": "Everything one approved creator still needs in a program, as the dashboard's Onboarding task shows it. It also answers for a creator with no linked account or no proof.\n\nApproving a proof meets one requirement. Onboarding is finished when nothing is left: `status` is `ready`. `status` matches the dashboard: a creator in the Onboarding list has its status there; any other creator is `ready`, or `getting_ready` while they still cannot post (for example, no linked account).",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "creatorId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Opaque creator id returned by `/creators`"
          },
          {
            "in": "query",
            "name": "programId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Creator onboarding returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "programId",
                    "creatorId",
                    "status",
                    "canPost",
                    "pendingProofCount",
                    "requiredPlatforms",
                    "missingPlatforms",
                    "warmUp",
                    "accounts",
                    "requirementsWithoutAccount",
                    "checklist"
                  ],
                  "properties": {
                    "programId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "creatorId": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "waiting_for_review",
                        "getting_ready",
                        "ready"
                      ],
                      "description": "`waiting_for_review`: a proof waits for your decision. `getting_ready`: the creator still has to do something. `ready`: nothing is left (detail only)."
                    },
                    "canPost": {
                      "type": "boolean",
                      "description": "The creator may post in the program now"
                    },
                    "pendingProofCount": {
                      "type": "integer"
                    },
                    "requiredPlatforms": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Platforms the program requires an account on"
                    },
                    "missingPlatforms": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Required platforms without a ready account"
                    },
                    "warmUp": {
                      "type": "object",
                      "required": [
                        "required",
                        "status"
                      ],
                      "properties": {
                        "required": {
                          "type": "boolean"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "unavailable",
                            "not_required",
                            "waiting_for_account",
                            "not_started",
                            "in_progress",
                            "pending_review",
                            "rejected",
                            "complete"
                          ]
                        }
                      }
                    },
                    "accounts": {
                      "type": "array",
                      "description": "The creator's accounts linked to the program",
                      "items": {
                        "type": "object",
                        "required": [
                          "platform",
                          "username",
                          "met",
                          "requirements"
                        ],
                        "properties": {
                          "platform": {
                            "type": "string"
                          },
                          "username": {
                            "type": "string",
                            "nullable": true,
                            "description": "Null while creator details are locked for the workspace"
                          },
                          "met": {
                            "type": "boolean",
                            "description": "Every requirement on this account is met"
                          },
                          "requirements": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "id",
                                "type",
                                "label",
                                "instructions",
                                "status",
                                "unmetReason",
                                "rejectionComments",
                                "pendingProofId"
                              ],
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "type": {
                                  "type": "string",
                                  "enum": [
                                    "account_requirement",
                                    "warm_up"
                                  ]
                                },
                                "label": {
                                  "type": "string"
                                },
                                "instructions": {
                                  "type": "string"
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "met",
                                    "not_applicable",
                                    "unmet",
                                    "checking",
                                    "pending_review",
                                    "rejected"
                                  ]
                                },
                                "unmetReason": {
                                  "type": "string",
                                  "nullable": true,
                                  "description": "Why an automatic check is unmet, for example `bio_link_missing`"
                                },
                                "rejectionComments": {
                                  "type": "string",
                                  "nullable": true,
                                  "description": "Your message on the latest rejected proof"
                                },
                                "pendingProofId": {
                                  "type": "string",
                                  "format": "uuid",
                                  "nullable": true,
                                  "description": "Set while a proof waits. Approve or reject it with the onboarding proof endpoints."
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    "requirementsWithoutAccount": {
                      "type": "array",
                      "description": "Custom requirements the creator cannot meet yet because no linked account is on their platforms",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "label",
                          "instructions",
                          "platforms"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "instructions": {
                            "type": "string"
                          },
                          "platforms": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    },
                    "checklist": {
                      "type": "array",
                      "description": "The program's onboarding checklist items for the creator",
                      "items": {
                        "type": "object",
                        "required": [
                          "label",
                          "platform",
                          "result",
                          "manual"
                        ],
                        "properties": {
                          "label": {
                            "type": "string"
                          },
                          "platform": {
                            "type": "string",
                            "nullable": true
                          },
                          "result": {
                            "type": "string",
                            "enum": [
                              "met",
                              "unmet",
                              "unknown"
                            ]
                          },
                          "manual": {
                            "type": "boolean",
                            "description": "Your team ticks it in the dashboard"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid program or creator id"
          },
          "403": {
            "description": "The program is read-only for this API key"
          },
          "404": {
            "description": "Program not found, or the creator is not approved in the program"
          }
        }
      }
    },
    "/onboarding/{creatorId}/messages": {
      "post": {
        "tags": [
          "Onboarding"
        ],
        "summary": "Send an onboarding message",
        "description": "Send the creator a message about their onboarding, for example to ask them to link Instagram and send a proof. The creator gets it as onboarding feedback in the app, by push, and in Discord. Nothing else changes.\n\nWhile a proof from the creator waits for review, the message is not sent and the request returns `409` with `code: proofs_waiting`. Approve or reject the proof instead; a rejection carries its own message to the creator.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "creatorId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Opaque creator id returned by `/creators`"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "programId",
                  "message"
                ],
                "properties": {
                  "programId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "Shown to the creator. Say what to do next."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message sent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "programId",
                    "creatorId",
                    "sent"
                  ],
                  "properties": {
                    "programId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "creatorId": {
                      "type": "string"
                    },
                    "sent": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid program, creator, or message"
          },
          "403": {
            "description": "The program is read-only for this API key"
          },
          "404": {
            "description": "Program not found, or the creator is not approved in the program"
          },
          "502": {
            "description": "The message reached no channel. The body includes a `code`; try again."
          },
          "409": {
            "description": "`code: proofs_waiting`: a proof waits for your decision; nothing was sent"
          }
        }
      }
    },
    "/onboarding/proofs": {
      "get": {
        "tags": [
          "Onboarding"
        ],
        "summary": "List onboarding proofs",
        "description": "List the onboarding proofs creators sent in one visible program, newest first. A creator sends a proof for each custom account requirement of the program (for example, a screenshot of their audience countries) and, when the program requires it, a screen recording of their warmed-up feed. `pending_review` lists only proofs that approve or reject can act on.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "programId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "pending_review",
                "approved",
                "rejected"
              ],
              "default": "pending_review"
            }
          },
          {
            "in": "query",
            "name": "type",
            "schema": {
              "type": "string",
              "enum": [
                "account_requirement",
                "warm_up"
              ]
            },
            "description": "Optional. Both types when absent."
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            },
            "description": "Optional opaque creator id"
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Proofs returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "page",
                    "total",
                    "totalPages"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/OnboardingProof"
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid program, status, type, creator, or paging value"
          },
          "404": {
            "description": "Program not found"
          }
        }
      }
    },
    "/onboarding/proofs/{id}/approve": {
      "post": {
        "tags": [
          "Onboarding"
        ],
        "summary": "Approve an onboarding proof",
        "description": "Approve one pending proof in a writable program. For an account requirement, the requirement counts as met for that creator account. For a warm-up proof, the account counts as warmed up. Approving meets one requirement; check `GET /onboarding/{creatorId}` for the creator's overall status. The proof id selects the type. No request body.\n\nRepeating the decision a proof already has returns the proof as it stands, so retries are safe. The opposite decision, or a decision another reviewer made first, returns `409` with `code: proof_already_reviewed`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID of the onboarding proof"
          }
        ],
        "responses": {
          "200": {
            "description": "Proof approved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "type",
                    "status",
                    "rejectionComments",
                    "reviewedAt"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "account_requirement",
                        "warm_up"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "approved",
                        "rejected"
                      ]
                    },
                    "rejectionComments": {
                      "type": "string",
                      "nullable": true
                    },
                    "reviewedAt": {
                      "type": "integer",
                      "format": "int64"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid proof id or message"
          },
          "403": {
            "description": "The program is read-only for this API key"
          },
          "404": {
            "description": "Proof not found, or no longer reviewable because its account left the program"
          },
          "409": {
            "description": "`code: proof_already_reviewed`: the proof already has the other decision"
          }
        }
      }
    },
    "/onboarding/proofs/{id}/reject": {
      "post": {
        "tags": [
          "Onboarding"
        ],
        "summary": "Reject an onboarding proof",
        "description": "Reject one pending proof in a writable program. The creator gets a notification, sees your message, and can send a new proof.\n\nRepeating the decision a proof already has returns the proof as it stands, so retries are safe. The opposite decision, or a decision another reviewer made first, returns `409` with `code: proof_already_reviewed`. A repeated reject keeps the first message.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID of the onboarding proof"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "message"
                ],
                "properties": {
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "Shown to the creator. Say what to fix."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Proof rejected and creator notified",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "type",
                    "status",
                    "rejectionComments",
                    "reviewedAt"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "account_requirement",
                        "warm_up"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "approved",
                        "rejected"
                      ]
                    },
                    "rejectionComments": {
                      "type": "string",
                      "nullable": true
                    },
                    "reviewedAt": {
                      "type": "integer",
                      "format": "int64"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid proof id or message"
          },
          "403": {
            "description": "The program is read-only for this API key"
          },
          "404": {
            "description": "Proof not found, or no longer reviewable because its account left the program"
          },
          "409": {
            "description": "`code: proof_already_reviewed`: the proof already has the other decision"
          }
        }
      }
    },
    "/media": {
      "get": {
        "tags": [
          "Media review"
        ],
        "summary": "List media for review",
        "description": "List the media creators sent for review in one visible program, before they post it. This is the Media queue of the dashboard's Tasks page. `pending_review` lists only media that approve or reject can act on, in the dashboard's order.\n\nA post that is already live is not in this list. To stop pay on a live post, use `POST /posts/{id}/exclude`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "programId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "pending_review",
                "approved",
                "rejected"
              ],
              "default": "pending_review"
            }
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            },
            "description": "Optional opaque creator id"
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Media returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "page",
                    "total",
                    "totalPages"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MediaReviewItem"
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid program, status, creator, or paging value"
          },
          "404": {
            "description": "Program not found"
          }
        }
      }
    },
    "/media/{id}": {
      "get": {
        "tags": [
          "Media review"
        ],
        "summary": "Get one media item",
        "description": "Get one media item and its current review status.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID of the media"
          }
        ],
        "responses": {
          "200": {
            "description": "Media returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/MediaReviewItem"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid media id"
          },
          "404": {
            "description": "Media not found"
          }
        }
      }
    },
    "/media/{id}/approve": {
      "post": {
        "tags": [
          "Media review"
        ],
        "summary": "Approve media",
        "description": "Approve one media item in your review queue. This is the brand's decision, the same as Approve in the dashboard: the creator is told and can post.\n\nRepeating the decision the media already has returns the media as it stands, so retries are safe. The opposite decision returns `409` with `code: media_already_reviewed`. Media outside your review queue returns `409` with `code: media_not_reviewable`.\n\nOnly a brand API key can decide. An agency API key gets `403` with `code: agency_key_not_supported`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID of the media"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "revisionId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Optional. The `revisionId` you reviewed. The decision fails with `409` and `code: media_newer_revision` when the creator has sent a newer revision."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Media approved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/MediaReviewItem"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid media id or revision id"
          },
          "402": {
            "description": "`code: budget_exceeded`: the approval would exceed the program budget"
          },
          "403": {
            "description": "The program is read-only for this API key, or `code: agency_key_not_supported`"
          },
          "404": {
            "description": "Media not found"
          },
          "409": {
            "description": "`code: media_already_reviewed`, `media_not_reviewable`, or `media_newer_revision`"
          },
          "422": {
            "description": "`code: missing_task_compensation` or `payout_prerequisite_failed`: the program's pay setup blocks the approval"
          }
        }
      }
    },
    "/media/{id}/reject": {
      "post": {
        "tags": [
          "Media review"
        ],
        "summary": "Reject media",
        "description": "Reject one media item in your review queue. The creator gets a notification, sees your message, and can send a new revision.\n\nRepeating the decision the media already has returns the media as it stands, so retries are safe. The opposite decision returns `409` with `code: media_already_reviewed`. Media outside your review queue returns `409` with `code: media_not_reviewable`.\n\nOnly a brand API key can decide. An agency API key gets `403` with `code: agency_key_not_supported`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID of the media"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "message"
                ],
                "properties": {
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "Shown to the creator. Say what to fix."
                  },
                  "revisionId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Optional. The `revisionId` you reviewed. The decision fails with `409` and `code: media_newer_revision` when the creator has sent a newer revision."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Media rejected and creator notified",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/MediaReviewItem"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid media id, message, or revision id"
          },
          "403": {
            "description": "The program is read-only for this API key, or `code: agency_key_not_supported`"
          },
          "404": {
            "description": "Media not found"
          },
          "409": {
            "description": "`code: media_already_reviewed`, `media_not_reviewable`, or `media_newer_revision`"
          }
        }
      }
    },
    "/contracts": {
      "get": {
        "tags": [
          "Contracts"
        ],
        "summary": "Browse contracts",
        "description": "Get offer-level creator contract metadata with sensitive payment details hidden.\n\nContracts describe the relationship between your company and creators, but this endpoint does not include Canvas weekly pay, task-level terms, or every pay term. Use `/pay-structures` for creator and program pay terms.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScopeParam"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 25
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string"
            },
            "description": "Narrow by status (pending, active, completed, declined, cancelled)"
          },
          {
            "in": "query",
            "name": "programId",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "creatorId",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/CreatorHandleParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Contracts returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "contractorId": {
                            "type": "string"
                          },
                          "contractorName": {
                            "type": "string"
                          },
                          "programId": {
                            "type": "string"
                          },
                          "contractName": {
                            "type": "string"
                          },
                          "position": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "contractType": {
                            "type": "string"
                          },
                          "paymentType": {
                            "type": "string",
                            "nullable": true
                          },
                          "paymentSchedule": {
                            "type": "string",
                            "nullable": true
                          },
                          "socialProfiles": {
                            "type": "array",
                            "items": {
                              "type": "object"
                            }
                          },
                          "platform": {
                            "type": "string"
                          },
                          "handle": {
                            "type": "string"
                          },
                          "isGhostHandle": {
                            "type": "boolean"
                          },
                          "createdAt": {
                            "type": "integer"
                          },
                          "updatedAt": {
                            "type": "integer"
                          },
                          "startsAt": {
                            "type": "integer"
                          },
                          "expiresAt": {
                            "type": "integer",
                            "nullable": true,
                            "description": "Contract end time in Unix milliseconds, or null if the contract is ongoing."
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
