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

# Start CPL Campaign

> Find Offers **Start**: you start delivering traffic to a client's CPL offer. Same fields, limits and messages as the Start modal on the Find Offers page. Runs one campaign start at a time per account.

Returns the created order as one `/api/marketer/cpl/orders` row (`is_client_offer` = `true`).

**Errors** (`status: "error"`, HTTP 200):

- `422` `Please fill in all campaign fields` when a field is missing or out of range.
- `422` Limit messages, the same as the cabinet: you already run a campaign on this offer, your order on this model is pending the client's trial review, or all your CPL campaign slots are taken.
- `429` Another campaign start is still running. Wait a few seconds and try again (one campaign start at a time per account).
- `403` Access denied: missing / unknown key, or the account is not an active partner.
- `429` Rate limit exceeded (30 writes per minute per key, see the `Retry-After` header).
- `503` Service is temporarily unavailable: the platform did not answer in time. The action may still have been applied, check the matching read endpoint before repeating it.

Same as **Start** on the Find Offers page: you start delivering traffic to a client's CPL offer. The created order comes back as a [`/api/marketer/cpl/orders`](/docs/partners/api/cpl-orders) row with `is_client_offer` `true` and `client_offer_id` set.

## Fields

| Field           | Description                                                                                                                                            |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `offer_id`      | Client offer id from Find Offers (the `client_offer_id` on orders)                                                                                     |
| `collaboration` | Payout format: `per_subscription`, `per_messages`, `per_first_purchase` or `per_paid_subscription`. The offer must pay for it and not block it for you |
| `source`        | Traffic source slug, the same values the Start form offers (e.g. `telegram`, `instagram`, `tiktok`, `reddit`, `x`)                                     |
| `campaign_type` | `link` (default) or `free_trial`                                                                                                                       |
| `speed`         | Subscribers per day you plan to deliver, at least 1                                                                                                    |

## Errors

| Message                                                                     | Meaning                                                                                                               |
| --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Please fill in all campaign fields`                                        | A field is missing, `collaboration` / `campaign_type` is not one of the allowed values, or `speed` is below 1 (`422`) |
| `You already run a campaign on this offer. …`                               | Per-offer limit (`422`)                                                                                               |
| `Your order on this model is pending the client's trial review. …`          | Wait for the trial result (`422`)                                                                                     |
| `… of your CPL campaign slots are taken …`                                  | Total campaign limit reached (`422`)                                                                                  |
| `Another campaign start is still running. Wait a few seconds and try again` | One start at a time per account (`429`), retry after a few seconds                                                    |


## OpenAPI

````yaml api/openapi-partners.json POST /api/marketer/cpl/campaigns/start
openapi: 3.0.2
info:
  title: OnlyTraffic Marketer API
  version: 2.1.0
  description: >-
    Partner (marketer) API for OnlyTraffic.


    **Authentication:** pass your API key in the `Authorization` header
    (`Authorization: your-api-key` or `Authorization: Bearer your-api-key`).
    Create keys in the partner cabinet: Tools -> API
    (https://partners.onlytraffic.com/tools/api). Up to 5 named keys per
    account, each **Full** or **Read-only**, with an optional expiry. Keys start
    with `ot_partners_` and are shown once, at creation. Read-only keys cannot
    call the `POST` endpoints (`error_code` 403, message `This API key is
    read-only`). An older legacy key keeps working with full access until you
    delete it on the same page.


    **Pagination:** all list endpoints accept `offset` (default 0) and `limit`
    (default 50, max 1000) as query parameters or JSON body fields.


    **Dates:** every timestamp field has two variants — an ISO 8601 string
    (`*_at`) and a Unix timestamp integer (`*_at_ts` / `*_ts`).


    **Writes:** a Full-access key reads and writes. Write endpoints are `POST`
    with a JSON body, accept public ids only (`revc_…`, `cplo_…`) and answer
    with the updated object in `data`. Rate limit: 120 requests per minute for
    reads, 30 per minute for writes, per account (shared by all its keys).
servers:
  - url: https://partners.onlytraffic.com
security: []
tags:
  - name: RevShare
    description: RevShare campaigns and financial data
  - name: CPL
    description: Cost-Per-Lead orders placed against your offers
  - name: CPC
    description: Cost-Per-Click orders and the category catalog
  - name: Subscribers
    description: Fans acquired through your campaigns
  - name: Stats
    description: Dashboard-style statistics widgets (fans, income, conversion)
  - name: Write
    description: >-
      Write API: start / stop / update campaigns and accept / reject / stop CPL
      orders (same key, same rules as the cabinet)
paths:
  /api/marketer/cpl/campaigns/start:
    post:
      tags:
        - Write
      summary: Start a CPL campaign on a client offer
      description: >-
        Find Offers **Start**: you start delivering traffic to a client's CPL
        offer. Same fields, limits and messages as the Start modal on the Find
        Offers page. Runs one campaign start at a time per account.


        Returns the created order as one `/api/marketer/cpl/orders` row
        (`is_client_offer` = `true`).


        **Errors** (`status: "error"`, HTTP 200):


        - `422` `Please fill in all campaign fields` when a field is missing or
        out of range.

        - `422` Limit messages, the same as the cabinet: you already run a
        campaign on this offer, your order on this model is pending the client's
        trial review, or all your CPL campaign slots are taken.

        - `429` Another campaign start is still running. Wait a few seconds and
        try again (one campaign start at a time per account).

        - `403` Access denied: missing / unknown key, or the account is not an
        active partner.

        - `429` Rate limit exceeded (30 writes per minute per key, see the
        `Retry-After` header).

        - `503` Service is temporarily unavailable: the platform did not answer
        in time. The action may still have been applied, check the matching read
        endpoint before repeating it.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - offer_id
                - collaboration
                - source
                - campaign_type
                - speed
              properties:
                offer_id:
                  type: integer
                  description: >-
                    Client offer id from Find Offers (`client_offer_id` on
                    orders).
                collaboration:
                  type: string
                  enum:
                    - per_subscription
                    - per_messages
                    - per_first_purchase
                    - per_paid_subscription
                  description: >-
                    Payout format you deliver on. Must be one the offer pays for
                    and does not block for you.
                source:
                  type: string
                  description: >-
                    Traffic source slug, the same values the Start form offers
                    (for example `telegram`, `instagram`, `tiktok`, `reddit`,
                    `x`).
                campaign_type:
                  type: string
                  enum:
                    - link
                    - free_trial
                  default: link
                  description: '`link` = campaign link, `free_trial` = free trial link.'
                speed:
                  type: integer
                  minimum: 1
                  description: Subscribers per day you plan to deliver.
            example:
              offer_id: 512
              collaboration: per_subscription
              source: telegram
              campaign_type: link
              speed: 20
      responses:
        '200':
          description: Success (check `status`; errors are also HTTP 200)
          content:
            application/json:
              schema:
                oneOf:
                  - title: Success
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - success
                      message:
                        type: string
                        description: Confirmation text from the platform, when present.
                      data:
                        $ref: '#/components/schemas/CplOrder'
                  - $ref: '#/components/schemas/ErrorResponse'
              examples:
                success:
                  summary: Success
                  value:
                    status: success
                    data:
                      order_id: cplo_abc123
                      offer_id: 0
                      client_offer_id: 512
                      is_client_offer: true
                      of_account_id: 456789
                      of_username: modelname
                      url: https://onlyfans.com/modelname/c1
                      source: Telegram
                      quantity_ordered: 100
                      quantity_delivered: 67
                      price_per_subscriber: 2.5
                      total_earned: 167.5
                      status: accepted
                      onlyfans_account:
                        name: Model Name
                        username: modelname
                        about: About text
                        tags:
                          - brunette
                        avatar:
                          original: https://cdn.example.com/avatar.jpg
                          thumbnail: https://cdn.example.com/avatar_thumb.jpg
                          thumbnail_640: https://cdn.example.com/avatar_640.jpg
                        demo_content: []
                        regular_price: 9.99
                        promotions: []
                        blocked_countries: []
                        subscribers_count: 3400
                        likes_count: 87000
                        posts_count: 560
                        photos_count: 420
                        videos_count: 140
                        performer_top: 5
                      auto_renewal:
                        enabled: true
                        quantity: 100
                        max_price: 3
                        next_price: 2.5
                        can_renew: false
                      created_at: '2024-01-15T08:00:00+00:00'
                      created_at_ts: 1705305600
                      changed_at: '2024-06-01T12:00:00+00:00'
                      changed_at_ts: 1717243200
                      completed_at: null
                      completed_at_ts: null
                error:
                  summary: Error
                  value:
                    status: error
                    error_code: 422
                    message: Please fill in all campaign fields
      security:
        - api_key: []
components:
  schemas:
    CplOrder:
      type: object
      properties:
        order_id:
          type: string
          description: CPL order public id (prefix `cplo_`).
        offer_id:
          type: integer
          description: Partner offer id. `0` for client-offer orders.
        client_offer_id:
          type: integer
          nullable: true
          description: >-
            Client offer id for client-offer orders; `null` for partner-offer
            orders.
        is_client_offer:
          type: boolean
          description: '`true` when the order was placed against a client offer.'
        of_account_id:
          type: integer
        of_username:
          type: string
        url:
          type: string
          format: uri
          nullable: true
          description: >-
            Promotion URL (OnlyFans campaign/trial link). Available once the
            order has been accepted; `null` otherwise.
        source:
          type: string
          nullable: true
          description: >-
            Traffic source (from the running campaign, falling back to the
            offer). `null` until the order is accepted.
        quantity_ordered:
          type: integer
        quantity_delivered:
          type: integer
          description: >-
            Delivered actions counted against the order's target action
            (subscriptions, messages, purchases, or paid subscriptions).
        price_per_subscriber:
          type: number
        total_earned:
          type: number
          description: >-
            billable × price_per_subscriber, where billable = min(ordered,
            delivered), or all delivered actions when the order is open-ended
            (quantity = 0).
        status:
          type: string
          enum:
            - waiting
            - accepted
            - rejected
            - completed
            - cancelled
            - paused
        onlyfans_account:
          $ref: '#/components/schemas/OnlyfansAccount'
        auto_renewal:
          type: object
          properties:
            enabled:
              type: boolean
            quantity:
              type: integer
              description: Repeat quantity when order completes.
            max_price:
              type: number
              description: Maximum payout per subscriber you may charge on a renewal.
            next_price:
              type: number
              description: >-
                Your payout per subscriber for the next cycle, resolved from the
                offer price steps for the repeat quantity.
            can_renew:
              type: boolean
              description: >-
                Whether the renewal will actually go through: client account
                active, offer available, price within the cap and enough balance
                for the next cycle.
        created_at:
          type: string
          format: date-time
        created_at_ts:
          type: integer
        changed_at:
          type: string
          format: date-time
        changed_at_ts:
          type: integer
        completed_at:
          type: string
          format: date-time
          nullable: true
        completed_at_ts:
          type: integer
          nullable: true
    ErrorResponse:
      title: Error
      type: object
      properties:
        status:
          type: string
          enum:
            - error
        message:
          type: string
          description: Human-readable error description.
        error_code:
          type: integer
          description: >-
            403: access denied (missing / unknown / expired / revoked key, or
            the account is not an active partner: `Error! Access denied`; a
            Read-only key calling a write endpoint: `This API key is
            read-only`). 404: not found. 422: bad request params (message says
            what is wrong). 429: rate limit exceeded (a `Retry-After` header is
            set) or another campaign start is still running. 500: server error.
            503: the platform did not answer a write in time, retry later.
    OnlyfansAccount:
      type: object
      description: Cached snapshot of the OnlyFans model profile.
      properties:
        name:
          type: string
        username:
          type: string
        about:
          type: string
        tags:
          type: array
          items:
            type: string
        avatar:
          type: object
          properties:
            original:
              type: string
              format: uri
            thumbnail:
              type: string
              format: uri
            thumbnail_640:
              type: string
              format: uri
        demo_content:
          type: array
          description: >-
            Model's demo photos/videos. Empty for finished campaigns and for
            completed/rejected CPL orders.
          items:
            type: object
            properties:
              type:
                type: string
                enum:
                  - photo
                  - video
              url:
                type: string
                format: uri
              thumbnail:
                type: string
                format: uri
        regular_price:
          type: number
        promotions:
          type: array
        blocked_countries:
          type: array
          items:
            type: string
        subscribers_count:
          type: integer
        likes_count:
          type: integer
        posts_count:
          type: integer
        photos_count:
          type: integer
        videos_count:
          type: integer
        performer_top:
          type: number
          description: Top percentage among all performers (e.g. 5 = top 5%).
  securitySchemes:
    api_key:
      type: apiKey
      name: Authorization
      in: header
      description: >-
        API key from the partner cabinet, Tools -> API
        (https://partners.onlytraffic.com/tools/api): up to 5 named keys per
        account, each Full or Read-only, `ot_partners_` prefix, shown once at
        creation. Raw value or `Bearer` form. Read-only keys cannot call the
        `POST` endpoints (403 `This API key is read-only`); expired or revoked
        keys get 403 `Error! Access denied`.

````