---
title: "End a campaign"
method: POST
path: "/campaigns/{id}/end"
tags: ["Creators"]
---

# End a campaign

`POST /campaigns/{id}/end`

## Request

- Base URL: `https://viral.app/api/v1`
- URL: `https://viral.app/api/v1/campaigns/{id}/end`
- Auth: API key in header `x-api-key`

Sets a campaign end date aligned to a billing cycle. Assignments reaching past the end fail the request unless the consent flags resolve them: endAssignments reschedules them to their last full period before the end, revokeAssignments deletes rows that cannot keep a single period. Settled payout windows past a row's target keep blocking regardless. Read GET /campaigns/{id}/end-context first for the aligned dates and the assignments the end would cut off. The response's warnings name Highest Tier bonus tiers the new end keeps from paying (bonus_tiers_unpaid_after_end); they never block the end.

## Path parameters

- `id` string, required: Campaign ID with orgcamp_ prefix

## Request body

- object: Request payload to end a campaign by setting its validUntil date.
  - `endBasis` 'prev' | 'current' | 'next' | 'custom', required
  - `endDate` string, date: Campaign valid until date in ISO format (YYYY-MM-DD)
  - `endAssignments` boolean
  - `revokeAssignments` boolean

## Response `200`

OK

- object: Updated campaign with the new validUntil date applied, plus the number of assignments the consent flags ended or deleted.
  - `id` string, required: Campaign ID with orgcamp_ prefix
  - `validUntil` string, required: ISO date (YYYY-MM-DD) when the campaign ends.
  - `endedAssignments` integer, required
  - `revokedAssignments` integer, required
  - `warnings` object[], required: What the new end date costs creators: bonus_tiers_unpaid_after_end when Highest Tier bonuses wait for an eligibility window that now closes after the campaign ends. Never blocks the end.
    - `code` 'long_payout_cycle' | 'daily_cadence' | 'future_start' | 'eligibility_window_exceeds_interval' | 'flat_bonus_waits_for_window' | 'bonus_tiers_unpaid_after_end' | 'performance_cap_below_bonus' | 'base_payouts_overlap' | 'cpm_payouts_overlap' | 'flat_bonuses_overlap' | 'manual_payouts_only' | 'rules_apply_immediately' | 'views_conditions_changed_after_payouts' | 'total_videos_changed_after_payouts' | 'payout_conditions_removed' | 'creative_payouts_removed' | 'time_zone_changed' | 'derived_from_job' | 'video_target_followers_frozen', required
    - `title` string, required
    - `message` string, 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)
