> ## 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.

# Post apiv1campaigns



## OpenAPI

````yaml https://backend.aflux.ai/openapi post /api/v1/campaigns
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/campaigns:
    post:
      tags:
        - campaigns
      operationId: campaignsCreate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCampaignRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Campaign'
        default:
          $ref: '#/components/responses/DefaultError'
      security:
        - Bearer: []
components:
  schemas:
    CreateCampaignRequest:
      type: object
      required:
        - idempotencyKey
        - matchToken
        - projectId
        - name
        - destinationUrl
        - adCopy
        - platform
        - distributionType
        - mediaAssetIds
        - budget
        - startsAt
        - endsAt
        - dailyDistribution
        - approvalMode
      properties:
        idempotencyKey:
          type: string
          format: uuid
        matchToken:
          type: string
        projectId:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 255
        destinationUrl:
          type: string
          minLength: 1
          maxLength: 2048
          description: >-
            Where the ad sends the reader. May carry placeholders that are
            substituted per placement, so the advertiser's own analytics can
            tell campaigns and channels apart under the parameter names his
            reporting already reads: `{campaign}` becomes the campaign's uuid,
            `{channel}` the handle of the channel that published the post (no
            `@`, lower case), `{platform}` the platform in lower case. They may
            sit anywhere in the URL, query string or path alike, including a bot
            deeplink payload — `https://t.me/mybot?start={campaign}-{channel}`.
            Names are case-insensitive and are stored lowercased, so the value
            returned by the API may differ from the one sent in exactly that
            way. Any OTHER `{name}` is rejected with a 400: an unknown
            placeholder cannot be filled in and would reach the published post
            as literal text. Deliberately NOT validated as a URI — a URL
            carrying a placeholder is not a well-formed one. Example:
            `https://mysite.com/landing?utm_campaign={campaign}&utm_source={channel}`
        adCopy:
          type: string
          maxLength: 8000
          description: >-
            The ad text as markup, written exactly as ValidateAdCopyRequest.text
            describes it. Create applies the very same rules POST
            /api/v1/campaigns/ad-copy/validate applies, so a text that validates
            is a text that creates and there is no second verdict to discover
            here. Two of those rules decide most refusals: the text must carry
            at least one {these words are the link}, and it must contain no web
            address at all beyond one on the advertiser's own domain — the
            destination is attached to the {...} per placement and never written
            into the text. A refusal is a 400 whose message lists every problem
            with the span of the markup it occupies. The cap here is a bound on
            request size, an order of magnitude above any text that could pass
            the 700-character visible limit.
        platform:
          $ref: '#/components/schemas/CampaignPlatform'
        objective:
          $ref: '#/components/schemas/CampaignObjective'
          nullable: true
        distributionType:
          $ref: '#/components/schemas/CampaignDistributionType'
        mediaAssetIds:
          type: array
          minItems: 1
          maxItems: 3
          items:
            type: string
            format: uuid
        budget:
          $ref: '#/components/schemas/MoneyAmount'
        startsAt:
          type: string
          format: date
        endsAt:
          type: string
          format: date
        dailyDistribution:
          type: array
          items:
            $ref: '#/components/schemas/DailyDistributionItem'
        approvalMode:
          $ref: '#/components/schemas/ApprovalMode'
        creativeChangesAllowed:
          type: boolean
          nullable: true
          description: >-
            Whether a channel manager may propose his own wording of the ad text
            (a human then approves or rejects it). Absent defaults to true, so
            deals are not lost over trivial edits.
        excludedChannelIds:
          type: array
          nullable: true
          items:
            type: integer
            format: int64
          description: >-
            Channels from the previewed match set the advertiser struck off
            while approving the list. They become neither placements nor part of
            the queue behind them, so the campaign can never come back to one of
            them later. Ids that are not in the previewed set are ignored.
            Rejected with 400 only if nothing at all is left after the
            strike-outs.
    Campaign:
      type: object
      required:
        - id
        - projectId
        - name
        - destinationUrl
        - adCopy
        - platform
        - distributionType
        - mediaAssets
        - budget
        - startsAt
        - endsAt
        - dailyDistribution
        - approvalMode
        - creativeChangesAllowed
        - status
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
          format: uuid
        projectId:
          type: string
          format: uuid
        name:
          type: string
        destinationUrl:
          type: string
          description: >-
            As stored, which is as it was sent except that the names of any
            known placeholders (see CreateCampaignRequest.destinationUrl) have
            been lowercased. Placeholders are never substituted here: what each
            one becomes depends on the placement, and this is the campaign.
        adCopy:
          type: string
        platform:
          $ref: '#/components/schemas/CampaignPlatform'
        objective:
          $ref: '#/components/schemas/CampaignObjective'
          nullable: true
        distributionType:
          $ref: '#/components/schemas/CampaignDistributionType'
        mediaAssets:
          type: array
          items:
            $ref: '#/components/schemas/AssetRef'
        budget:
          $ref: '#/components/schemas/MoneyAmount'
        startsAt:
          type: string
          format: date
        endsAt:
          type: string
          format: date
        dailyDistribution:
          type: array
          items:
            $ref: '#/components/schemas/DailyDistributionItem'
        approvalMode:
          $ref: '#/components/schemas/ApprovalMode'
        creativeChangesAllowed:
          type: boolean
        status:
          $ref: '#/components/schemas/CampaignStatus'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    CampaignPlatform:
      type: string
      enum:
        - TELEGRAM
    CampaignObjective:
      type: string
      enum:
        - AWARENESS
        - TRAFFIC
        - CONVERSIONS
        - APP_INSTALLS
    CampaignDistributionType:
      type: string
      enum:
        - RECOMMENDED
        - MANUAL
    MoneyAmount:
      type: string
      pattern: ^-?\d+(\.\d{1,6})?$
      example: '125.500000'
    DailyDistributionItem:
      type: object
      required:
        - date
        - amount
      properties:
        date:
          type: string
          format: date
        amount:
          $ref: '#/components/schemas/MoneyAmount'
    ApprovalMode:
      type: string
      enum:
        - OPERATOR
        - USER
    AssetRef:
      type: object
      required:
        - assetId
        - publicUrl
      properties:
        assetId:
          type: string
          format: uuid
        publicUrl:
          type: string
    CampaignStatus:
      type: string
      enum:
        - ACTIVE
        - COMPLETED
        - ARCHIVED
    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

````