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

# Размещения

> The publication log of your pools.

Каждая сторис, пост, строка био, пин друзей и рассылка, которые движок опубликовал для ваших пулов, новые первыми. `views` обновляются примерно раз в час. У рассылки есть блок `mass_dm`: `sent` (охват; пусто, пока OnlyFans ещё отправляет), `viewed`, `purchased` у платной и `can_unsend`. `link` содержит итоги трекинг-ссылки, общие для всех публикаций креатива в пуле. У неудачных строк есть `error.code`.


## OpenAPI

````yaml GET /cross-promo/placements
openapi: 3.0.3
info:
  title: OnlyTraffic Studio API
  version: 1.1.0
  description: >-
    External API for OnlyTraffic Studio. Manage and retrieve data about your
    subscribers, CPL campaigns, CPC orders and CPC campaigns.
servers:
  - url: https://studio-api.onlytraffic.com/api/external/v1
security:
  - ApiKeyAuth: []
tags:
  - name: Account
    description: API key holder's wallet, profile, and aggregate state.
  - name: Accounts
    description: OnlyFans accounts attached to the API key holder.
  - name: Agencies
    description: Agency CRUD and image management. All edits stage in moderation.
  - name: CPL
    description: >-
      Cost-per-lead orders: place, list, cancel, manage settings, browse partner
      offers.
  - name: CPC
    description: Cost-per-click orders and creative management.
  - name: RevShare
    description: Revenue-share campaigns and invoices.
  - name: Swaps
    description: Two-sided traffic swap orders and offers.
  - name: Subscribers
    description: Per-fan delivery feed (cursor-paginated).
  - name: Transactions
    description: Per-transaction OF revenue feed (cursor-paginated).
  - name: Cross-promo
    description: Cross-promo pools, creatives and the publication log.
paths:
  /cross-promo/placements:
    get:
      tags:
        - Cross-promo
      summary: Placements
      description: The publication log of your pools.
      operationId: getCrossPromoPlacements
      parameters:
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PageSize'
        - name: pool_id
          in: query
          schema:
            type: string
            format: uuid
          description: One pool.
        - name: creative_id
          in: query
          schema:
            type: string
            format: uuid
          description: One creative.
        - name: format
          in: query
          schema:
            type: string
            enum:
              - story
              - post
              - bio
              - friends
              - mass_dm
          description: Filter by format.
        - name: status
          in: query
          schema:
            type: string
            enum:
              - posted
              - removed
              - failed
          description: Filter by status.
        - name: host_of_account_id
          in: query
          schema:
            type: integer
            minimum: 1
          description: Publications by one publisher.
        - name: target_of_account_id
          in: query
          schema:
            type: integer
            minimum: 1
          description: Publications promoting one model.
        - name: since
          in: query
          schema:
            type: string
            format: date-time
          description: Publications from this moment on.
        - $ref: '#/components/parameters/SinceChangedAt'
        - $ref: '#/components/parameters/UntilChangedAt'
        - name: sort
          in: query
          schema:
            type: string
            enum:
              - posted_at_desc
              - posted_at_asc
              - updated_at_desc
            default: posted_at_desc
          description: Sort order.
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/CrossPromoPlacement'
                  pagination:
                    $ref: '#/components/schemas/Pagination'
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: >-
            Server error. Body always reads `{success:false,
            error:"server_error", message:"Server error"}` (no internal details
            leak).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  parameters:
    Page:
      name: page
      in: query
      schema:
        type: integer
        minimum: 1
        default: 1
      description: Page number, 1-indexed.
      example: 1
    PageSize:
      name: page_size
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 50
      description: Items per page. Default 50, max 100.
      example: 50
    SinceChangedAt:
      name: since_changed_at
      in: query
      schema:
        type: integer
        minimum: 0
      description: >-
        Delta-sync filter. Return only rows whose `changed_at` is at or after
        this UNIX timestamp. Pair with `until_changed_at` for a window.
      example: 1738000000
    UntilChangedAt:
      name: until_changed_at
      in: query
      schema:
        type: integer
        minimum: 0
      description: >-
        Delta-sync filter. Return only rows whose `changed_at` is strictly
        before this UNIX timestamp. Useful to lock the upper bound while
        paginating an open delta range.
      example: 1738604800
  schemas:
    CrossPromoPlacement:
      type: object
      properties:
        placement_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        pool:
          type: object
          properties:
            pool_id:
              type: string
              format: uuid
              nullable: true
            name:
              type: string
              nullable: true
        format:
          type: string
          enum:
            - story
            - post
            - bio
            - friends
            - mass_dm
        status:
          type: string
          enum:
            - posted
            - removed
            - failed
          description: >-
            `posted` = live (for a mass message: sent or still sending),
            `removed` = taken down, `failed`.
        host:
          $ref: '#/components/schemas/Account'
        target:
          $ref: '#/components/schemas/Account'
        creative:
          type: object
          nullable: true
          properties:
            creative_id:
              type: string
              format: uuid
            internal_name:
              type: string
        position:
          type: integer
          nullable: true
          description: Friend pin slot.
        views:
          type: integer
          nullable: true
          description: >-
            Views; empty until the first hourly sync. For a mass message the
            fans who opened it.
        mass_dm:
          type: object
          nullable: true
          description: Mass messages only.
          properties:
            sent:
              type: integer
              nullable: true
              description: Fans reached; empty while OnlyFans is still sending.
            viewed:
              type: integer
              nullable: true
            purchased:
              type: integer
              nullable: true
            price_cents:
              type: integer
              nullable: true
            can_unsend:
              type: boolean
        link:
          type: object
          nullable: true
          description: >-
            Posts and mass messages only: the tracking link totals, shared by
            every publication of the creative in the pool. Live figures: they
            keep moving after the row itself stops changing, so they are not
            covered by `since_changed_at`.
          properties:
            clicks:
              type: integer
              nullable: true
            subscribers:
              type: integer
            revenue_cents:
              type: integer
        story:
          type: object
          nullable: true
          description: >-
            Stories only: fans by view, counted about 26 h after publication (a
            viewer who subscribed to the promoted model for the first time while
            the story was live and came through no other campaign). The fields
            stay null until the story is counted.
          properties:
            fans:
              type: integer
              nullable: true
              description: Fans counted for this story; 0 when it brought none.
            revenue_cents:
              type: integer
              nullable: true
              description: >-
                What those fans paid on OnlyFans, in cents, before the platform
                fee. Live.
        error:
          type: object
          nullable: true
          properties:
            code:
              type: string
              description: >-
                Why it failed, for example `host_unavailable`, `list_not_found`,
                `blocked_word`.
            params:
              type: object
        notice:
          type: object
          nullable: true
          properties:
            code:
              type: string
              description: Non-fatal note, for example `unsent_before_next`.
            params:
              type: object
        posted_at:
          type: string
          format: date-time
          nullable: true
        posted_at_ts:
          type: integer
          nullable: true
        removed_at:
          type: string
          format: date-time
          nullable: true
        removed_at_ts:
          type: integer
          nullable: true
        planned_remove_at:
          type: string
          format: date-time
          nullable: true
        planned_remove_at_ts:
          type: integer
          nullable: true
        created_at:
          type: string
          format: date-time
        created_at_ts:
          type: integer
        updated_at:
          type: string
          format: date-time
          nullable: true
        updated_at_ts:
          type: integer
          nullable: true
    Pagination:
      type: object
      description: >-
        Page-based pagination, returned by every list endpoint that isn't a
        cursor feed.
      properties:
        page:
          type: integer
          description: Current page number (1-indexed).
          example: 1
        page_size:
          type: integer
          description: Number of items per page. Default 50, max 100.
          example: 50
        total:
          type: integer
          description: Total number of records matching the filters.
          example: 150
        total_pages:
          type: integer
          description: Total pages available.
          example: 3
        has_next:
          type: boolean
          description: >-
            `true` when `page < total_pages` (i.e. there is at least one more
            page to fetch).
          example: true
    ErrorResponse:
      type: object
      description: Standard error envelope for all 4xx/5xx responses.
      required:
        - success
        - error
        - message
      properties:
        success:
          type: boolean
          enum:
            - false
          description: Always false on error responses.
        error:
          type: string
          description: Stable snake_case machine-readable error code. Branch on this.
          example: validation_failed
        message:
          type: string
          description: >-
            Human-friendly text. For 5xx this is always the literal `Server
            error`. For 4xx an actionable validation/auth message is returned.
        details:
          type: object
          nullable: true
          description: >-
            Optional per-field diagnostic information. On 422 carries `{<field>:
            ["error_code", ...]}`. On 402 (`insufficient_balance`) carries
            `{required, current}`. On 426 (`unpaid_invoices`) carries `{count,
            total, oldest_date_ts}`. Absent on most other errors.
          additionalProperties: true
        retry_after:
          type: integer
          nullable: true
          description: >-
            Seconds until the next request will succeed. Present only on 429
            responses (rate limit). Mirrors the `Retry-After` HTTP header.
    Account:
      type: object
      description: Standard mini-block referencing one of your OnlyFans accounts.
      properties:
        of_account_id:
          type: integer
        username:
          type: string
          nullable: true
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: Your API key from the Studio Dashboard

````