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

# Get apiv1campaign placements



## OpenAPI

````yaml https://backend.aflux.ai/openapi get /api/v1/campaign-placements/{placementId}
openapi: 3.0.3
info:
  title: AdFlux Backend API
  version: v1
servers:
  - url: /
security: []
tags:
  - name: auth
  - name: users
  - name: uploads
  - name: projects
  - name: campaigns
  - name: placements
  - name: billing
  - name: payments
  - name: image-generations
paths:
  /api/v1/campaign-placements/{placementId}:
    get:
      tags:
        - placements
      operationId: placementsGetById
      parameters:
        - in: path
          name: placementId
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignPlacement'
        default:
          $ref: '#/components/responses/DefaultError'
      security:
        - Bearer: []
components:
  schemas:
    CampaignPlacement:
      type: object
      required:
        - id
        - campaignId
        - channelId
        - plannedDate
        - avgReach
        - approvalMode
        - status
        - originalAdCopy
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
          format: uuid
        campaignId:
          type: string
          format: uuid
        channelId:
          type: integer
          format: int64
        channelUsername:
          type: string
          nullable: true
        channelTitle:
          type: string
          nullable: true
        subscribers:
          type: integer
          format: int64
          nullable: true
          description: The channel's subscriber count as measured by the matching parser
        avgReach:
          type: integer
          format: int64
          description: Average views of an ordinary post on this channel
        avgAdReach24h:
          type: integer
          format: int64
          nullable: true
          description: >-
            Average views an ad post collects in its first 24h; null for
            channels with no measured ad posts
        expectedViews:
          type: integer
          format: int64
          nullable: true
          description: >-
            Views one ad post here is expected to reach — avgAdReach24h, or
            avgReach when it was never measured. The same number the campaign's
            expected-views total and the per-deal price cap are computed from.
            Null (never 0) when the channel carries no usable reach at all.
        views:
          type: integer
          format: int64
          nullable: true
          description: >-
            Views this placement's own published post actually collected, as the
            parser measured it — the measured counterpart of expectedViews,
            which is only a forecast from the channel's statistics. Null until
            the post is published and the first snapshot arrives; it then grows
            towards the figure reached ~48h after publication and stops there.
        reactions:
          type: integer
          format: int64
          nullable: true
          description: >-
            Reactions the same post collected, measured in the same snapshot.
            Null until the post is published and a snapshot arrives; there is no
            forecast counterpart for this one.
        clicks:
          type: integer
          format: int64
          nullable: true
          description: >-
            Times a link in this placement's own post was followed. Every link
            in a published post is one of ours, so this is measured directly
            rather than forecast — there is no counterpart to expectedViews
            here. Read next to views: views are the people the post reached,
            clicks are the ones who acted. Null (never 0) while nothing has been
            clicked.
        uniqueClicks:
          type: integer
          format: int64
          nullable: true
          description: >-
            The same clicks counted one per IP, so clicks minus uniqueClicks is
            the readers who came back. Null (never 0) while nothing has been
            clicked.
        plannedDate:
          type: string
          format: date
        managerUsername:
          type: string
          nullable: true
        approvalMode:
          $ref: '#/components/schemas/ApprovalMode'
        status:
          $ref: '#/components/schemas/CampaignPlacementStatus'
        agreedCost:
          $ref: '#/components/schemas/MoneyAmount'
          nullable: true
        agreedDate:
          type: string
          format: date
          nullable: true
        agreedSummary:
          type: string
          nullable: true
        rejectionReason:
          type: string
          nullable: true
        escalationReason:
          type: string
          nullable: true
        escalationUrgency:
          type: string
          nullable: true
        originalAdCopy:
          type: string
          description: >-
            The campaign's own ad copy, carried here so the card can show the
            diff on its own
        proposedAdCopy:
          type: string
          nullable: true
          description: >-
            The manager's variant awaiting a decision; set only while
            AWAITING_CREATIVE_APPROVAL. Ad-copy markup, exactly like
            originalAdCopy: he types plain text into Telegram and the backend
            writes his formatting back into our syntax, so both texts render in
            the same editor and the diff is between two texts of one kind.
        approvedAdCopy:
          type: string
          nullable: true
          description: >-
            The manager's variant once approved — the text actually published
            for this placement, in ad-copy markup like every other ad text
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    ApprovalMode:
      type: string
      enum:
        - OPERATOR
        - USER
    CampaignPlacementStatus:
      type: string
      enum:
        - NEW
        - AWAITING_CONTACT_VERIFICATION
        - IN_PROGRESS
        - AWAITING_CREATIVE_APPROVAL
        - PENDING_APPROVAL
        - APPROVED
        - PAYMENT_PENDING
        - PAYMENT_FAILED
        - PAID
        - AWAITING_POST
        - PUBLISHED
        - VERIFIED
        - COMPLETED
        - REJECTED
        - ESCALATED
        - CANCELLED
        - BREACH
    MoneyAmount:
      type: string
      pattern: ^-?\d+(\.\d{1,6})?$
      example: '125.500000'
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
  responses:
    DefaultError:
      description: Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    Bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT

````