---
title: "Switch creators to another campaign"
method: POST
path: "/creators/campaigns/switch"
tags: ["Creators"]
---

# Switch creators to another campaign

`POST /creators/campaigns/switch`

## Request

- Base URL: `https://viral.app/api/v1`
- URL: `https://viral.app/api/v1/creators/campaigns/switch`
- Auth: API key in header `x-api-key`

Ends the creators' shared current campaign assignment after the chosen billing period — or on a day inside one, with `endBasis: "today"` or a `custom` `endDate` (that period is cut to the end day and due the day after) — and assigns them to the target campaign starting after it, atomically. All creators must share the same current campaign; the new start must lie after the chosen end. An end on or before the assignment start clears the current assignment entirely instead of ending it.

## Request body

- object
  - `creatorIds` string[], required
  - `campaignId` string, required
  - `endBasis` 'prev' | 'current' | 'next' | 'custom' | 'today', required
  - `endDate` string, date
  - `startBasis` 'prev' | 'current' | 'next' | 'custom' | 'today', required
  - `startDate` string, date
  - `customRates` object: Custom rates for these creators on this campaign, merged per value into any they already have there: their own per-video or CPM rates, bonus amounts, fixed salary, caps or video target, each naming a payout of the campaign spec by id. Values only; the payouts stay the campaign's. Dry-run with POST /campaigns/{id}/custom-rates/validate (mode merge).
    - `videoTarget` integer, nullable: The creator's own video target per cycle, in the campaign's unit (videos or creatives; per-platform campaigns use videoTargetPlatforms). Setting replaces their set (PUT): omitted or null follows the campaign's. Assigning merges: omitted or null keeps what they have, the campaign's own value resets it. A base payout capped at the campaign target is capped at this one instead.
    - `videoTargetPlatforms` object, nullable: For a campaign whose video target counts per platform: the creator's own count per platform (only the campaign's platforms; one left out follows the campaign's), with the same replace and merge rules as videoTarget. E.g. {"tiktok": 20}.
    - `values` object[]: The creator's custom values. A payout left out pays the campaign's value.
      - `id` string, required: The payout's id from the campaign spec: a base payout, a CPM or bonus tier, the fixed salary or the performance cap.
      - `field` 'perVideo' | 'videoCap' | 'amountCap' | 'rate' | 'amount', required: perVideo, videoCap or amountCap on a base payout; rate on a CPM tier; amount on a bonus tier, the fixed salary or the performance cap.
      - `value` number, required: Major units of the campaign currency (a video count for videoCap). 0 switches that payout off for the creator; caps stay above 0.
  - `customRatesPreviewHash` string: The previewHash the custom-rates dry-run (mode merge) returned. When present, custom rates that differ are refused (CUSTOM_RATES_PREVIEW_MISMATCH).

## Response `200`

OK

- object
  - `updated` integer, required

## Other responses

- `400`: 400
- `401`: 401
- `402`: 402
- `404`: 404
- `408`: 408
- `409`: 409
- `429`: 429
- `500`: 500

---

[API](https://skmtc.dev/viral/apis/viral-app-api.md) · [All operations](https://skmtc.dev/viral/apis/viral-app-api/llms.txt) · [OpenAPI document](https://skmtc.dev/viral/apis/viral-app-api/revisions/31e97fa79ef1?raw)
