---
title: "Create a paid-clipping campaign (Pro plan or above)"
method: POST
path: "/api/v1/campaigns"
---

# Create a paid-clipping campaign (Pro plan or above)

`POST /api/v1/campaigns`

## Request

- Base URL: `https://everpop.app`
- URL: `https://everpop.app/api/v1/campaigns`
- Auth: HTTP bearer

## Request body

- object
  - `name` string, required
  - `sourceVideoId` string: The sponsor's footage in the user's library; posts published from its clips attach automatically.
  - `sourceUrl` string, uri: Link to the brief (stored, never fetched).
  - `cpmCents` integer
  - `budgetCents` integer
  - `deadline` string, date-time
  - `notes` string
  - `brief` object: Structured brief rules enforced on every attach.

## Response `200`

The created campaign.

- CampaignEnvelope
  - `ok` unknown, required
  - `data` object, required
    - `campaign` Campaign, required: A campaign row as stored.
      - `id` string, required: The id /api/v1/campaigns/{id}/attach and /proof take.
      - `userId` string, required: The owner (the calling account).
      - `name` string, required
      - `sourceUrl` string, nullable, required: Link to the sponsor's brief — stored, never fetched.
      - `sourceVideoId` string, nullable, required: The sponsor's footage in the user's library; posts published from its clips attach automatically.
      - `platformRule` string, required
      - `cpmCents` integer, nullable, required
      - `budgetCents` integer, nullable, required
      - `deadline` string, date-time, nullable, required
      - `notes` string, nullable, required: Free-text notes, or the stored form of structured brief rules (read brief / briefLines on GET /api/v1/campaigns instead).
      - `status` 'ACTIVE' | 'COMPLETED', required
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required

## Other responses

- `401`: The API key did not authenticate. code=key_missing: no Authorization: Bearer epk_... header. code=key_invalid: the key is unknown or revoked. code=key_expired: the key passed its expiry; the user creates a new one in Dashboard → API.
- `402`: Subscription required, or reason=plan.
- `403`: code=scope (also reason=scope): the API key is read-only and this is a write. code=suspended: the account is suspended. Endpoint-specific refusals document their own reason.
- `404`: sourceVideoId is not in the user's library.
- `422`: The body did not validate, the brief could not be read, or both brief and notes were sent.
- `429`: Too many requests. code=rate_limited: the per-minute limit; wait Retry-After (60) seconds. code=quota_exhausted (with used, limit, resetsAt, retryable: false): the monthly allowance is used up; Retry-After is the seconds until resetsAt — tell the user rather than wait. code=queue_capacity (retryable: true): the render queue is full; retry after Retry-After (180).

---

[API](https://skmtc.dev/everpop/apis/everpop-api.md) · [All operations](https://skmtc.dev/everpop/apis/everpop-api/llms.txt) · [OpenAPI document](https://skmtc.dev/everpop/apis/everpop-api/revisions/1a9fb20867f5?raw)
