---
title: "Get creator campaign"
method: GET
path: "/v1/creator-campaigns/{campaignId}"
tags: ["Creator Campaigns"]
---

# Get creator campaign

`GET /v1/creator-campaigns/{campaignId}`

## Request

- Base URL: `https://zernio.com/api`
- URL: `https://zernio.com/api/v1/creator-campaigns/{campaignId}`
- Auth: HTTP bearer

Returns the campaign with its budget consumption, participant count and submission counts.

## Path parameters

- `campaignId` string, required

## Response `200`

Campaign

- object
  - `campaign` CreatorCampaign, required
    - `id` string, required
    - `userId` string, required: The workspace billing owner the campaign belongs to.
    - `profileId` string, required: The profile that scopes the campaign: API keys, teammates and webhooks scoped to it reach the campaign.
    - `kind` string, required
    - `name` string, required
    - `brandName` string, required
    - `status` 'draft' | 'active' | 'paused' | 'closed', required: draft until activated; active accepts submissions and accrues; paused stops new submissions; closed is final.
    - `type` 'cpm' | 'per_post' | 'pool', required: Same as economics.type.
    - `currency` string, required
    - `platforms` string[], required
    - `contentRules` string, nullable, required: Free-text rules shown to creators on the join page.
    - `startsAt` string, date-time, nullable, required
    - `endsAt` string, date-time, nullable, required: No new submissions after this time; the campaign closes once every tracking window had its final read.
    - `trackingDays` integer, required: How long each submitted post is tracked.
    - `holdDays` integer, required: Days approved earnings are held before they become payable.
    - `maxPostAgeMinutes` integer, nullable, required: A post older than this many minutes when submitted is refused. Null (the default) accepts any age. Either way, a post published before the campaign started (`startsAt`, or `activatedAt` without one) is refused.
    - `activatedAt` string, date-time, nullable, required: When the campaign was first activated. Without `startsAt`, posts must be published after this moment.
    - `settlement` 'none' | 'external' | 'treasury', required: none: settle records a payout made elsewhere. external: you pay from your own rails on campaign_payout.payable and settle with your reference. treasury: settle moves the money from your Zernio balance to the creator's Stripe account, and the creator sets up payouts from their campaign page.
    - `economics` union, required: How the campaign pays, picked by `type`. Amounts are USD cents. Every type carries `budgetCents`, the most the campaign can pay out in total. Once earnings reach it, the campaign stops accruing and `creator_campaign.budget_exhausted` fires. - `cpm`: `ratePer1kCents` per 1,000 of the counted `metric` (views by default), earned once a post reaches `minViewsToEarn` of it, capped per post by `maxPayoutPerClipCents`. - `per_post`: `perApprovedPostCents` for each approved post, at most `maxPostsPerParticipant` per participant. - `pool`: `budgetCents` is split at close among approved posts by eligible views; a post needs `minViewsToQualify` views to share.
      - CreatorCampaignEconomicsCpm
        - `type` 'cpm', required
        - `metric` 'views' | 'engagements': What the rate pays on. `engagements` counts the `engagementTypes` as each platform reports them, and `minViewsToEarn` then applies to engagements. Fixed once the campaign leaves draft.
        - `engagementTypes` string[]: With `metric: engagements`, the engagements that count. Missing means all four, and sending it on a views campaign answers 400. YouTube reports likes and comments only, Facebook and Threads have no saves, and Pinterest reports saves only.
        - `organicViewsOnly` boolean: Count only organic views: views from ads the creator ran do not earn. Every campaign platform must be YouTube or X, which report ad views per post, or the request answers 400. A post earns nothing until its ad views were first read.
        - `ratePer1kCents` integer, required
        - `minViewsToEarn` integer, required: The count a post must reach before it earns, in the campaign metric (views or engagements).
        - `maxPayoutPerClipCents` integer
        - `budgetCents` integer, required
      - CreatorCampaignEconomicsPerPost
        - `type` 'per_post', required
        - `perApprovedPostCents` integer, required
        - `maxPostsPerParticipant` integer
        - `budgetCents` integer, required
      - CreatorCampaignEconomicsPool
        - `type` 'pool', required
        - `budgetCents` integer, required
        - `minViewsToQualify` integer, required
        - `organicViewsOnly` boolean: Count only organic views: views from ads the creator ran do not earn. Every campaign platform must be YouTube or X, which report ad views per post, or the request answers 400. A post earns nothing until its ad views were first read.
    - `caps` CreatorCampaignCaps, required
      - `maxParticipants` integer: Invites and joins past this count answer 403.
      - `maxSubmissionsPerParticipantPerDay` integer: Posts one participant can submit to this campaign per UTC day, counting every submission whatever its status. The next submit that day answers 409 invalid_resource_state.
      - `maxAccountsPerParticipant` integer: Accounts a participant can use in this campaign. Connecting a new account past it answers 400; only the first accounts connected, up to this count, can submit posts.
      - `maxXReadSpendCents` integer: X campaigns only: what tracking X posts may cost in X reads, in cents. Unset means 5000 ($50). X bills one read per tracked post per UTC day, and you pay it at cost through usage-based billing. When it is spent, open X posts stop counting views and are flagged `x_read_cap`, and new X posts answer 409.
      - `authenticityThreshold` number, required: A submission whose authenticity score falls below this is flagged `low_authenticity`. It is never rejected automatically. Defaults to 40 on create.
    - `branding` CreatorCampaignBranding, required: Branding of the hosted join page, in the connect-link branding shape.
      - `brandName` string
      - `primaryColor` string
      - `logoUrl` string
      - `theme` object
    - `budgetExhaustedAt` string, date-time, nullable, required
    - `closedAt` string, date-time, nullable, required
    - `payableScannedAt` string, date-time, nullable, required: Internal watermark of the payable scan.
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required
    - `hasOpenInvite` boolean, required: True once an open invite link was created. The link itself is returned only when it is created.
    - `consumedCents` integer, required: Budget used so far: earnings accrued, approved or adjusted against the campaign.
    - `participantCount` integer, required
    - `submissionCounts` CampaignSubmissionCounts, required: Number of submissions in each status.
      - `received` integer, required
      - `tracking` integer, required
      - `pending_review` integer, required
      - `approved` integer, required
      - `rejected` integer, required
      - `expired` integer, required
      - `withdrawn` integer, required
    - `payableCents` integer, required: What the campaign's creators can be paid now, summed over every participant's payable balance.

## Other responses

- `400`: Invalid request
- `401`: Missing or invalid API key. `code` is `missing_credentials` when no Authorization header was sent and `invalid_credentials` when the key is unknown, revoked or expired.
- `403`: Refused. Code `feature_not_available`: creator campaigns run on usage-based billing and the workspace that owns the campaign is not on it yet ("Creator campaigns require usage-based billing..."; contact support to switch), or the campaign reached `caps.maxParticipants` (invites and joins only). Code `insufficient_permissions`: a restricted API key without the `creator_campaigns` resource group.
- `404`: The campaign, participant or submission does not exist, belongs to another team, or sits in a profile this key cannot reach (code `resource_not_found`).

## Changes

- **2026-10-30** `c319eb5d95b6`: 2 info
  - added the optional property `campaign/economics/oneOf[subschema #1: CPM]/organicViewsOnly` to the response with the `200` status
  - added the optional property `campaign/economics/oneOf[subschema #3: Pool]/organicViewsOnly` to the response with the `200` status
- **2026-10-30** `172499a6a5e9`: 2 info
  - added the optional property `campaign/economics/oneOf[subschema #1: CPM]/engagementTypes` to the response with the `200` status
  - added the optional property `campaign/economics/oneOf[subschema #1: CPM]/metric` to the response with the `200` status
- **2026-10-29** `dbfaa35515ac`: 1 breaking, 4 warning, 3 info
  - the response property `campaign/maxPostAgeMinutes` became nullable for the status `200`
  - added the new `facebook` enum value to the `campaign/platforms/items/` response property for the response status `200`
  - added the new `pinterest` enum value to the `campaign/platforms/items/` response property for the response status `200`
  - added the new `threads` enum value to the `campaign/platforms/items/` response property for the response status `200`
  - …4 more
- **2026-10-28** `8f2c44dd7550`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/creator-campaigns/:campaignId/get.md)

---

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