---
title: "List one campaign's contracts"
method: GET
path: "/contracts/campaigns/{campaign_id}"
tags: ["Contracts"]
---

# List one campaign's contracts

`GET /contracts/campaigns/{campaign_id}`

## Request

- Base URL: `https://api.reacherapp.com/public/v1`
- URL: `https://api.reacherapp.com/public/v1/contracts/campaigns/{campaign_id}`
- Auth: API key in header `x-api-key` and API key in header `x-shop-id`

Every contract generated for one campaign, newest first — the campaign-scoped view of GET /contracts. Same row shape.

404 when the campaign does not belong to this shop.

Cursor-paginated: pass the `next_cursor` from the previous response to get the next page. A null `next_cursor` means the last page. Single-shop only.

## Path parameters

- `campaign_id` integer, required: Campaign id from GET /campaigns.

## Query parameters

- `cursor` string, nullable: Opaque cursor from `next_cursor`.
- `limit` integer: Rows per page (max 200).

## Response `200`

Successful Response

- PaginatedEnvelopes
  - `data` ContractEnvelopeOut[], required
    - `id` string, uuid, required
    - `batch_id` string, uuid, required
    - `campaign_id` integer, required
    - `campaign_name` string, required
    - `creator_id` integer, required
    - `creator_name` string, required
    - `creator_handle` string, required
    - `contract_title` string, required
    - `template_source` 'standard', required
    - `terms` ContractTerms, required
      - `campaign_type` 'retainer' | 'challenge' | 'leaderboard' | 'reimbursement', required
      - `brand_name` string, required
      - `brand_representative_name` string, required
      - `deliverables` integer, required
      - `posting_platform` 'TikTok' | 'Instagram' | 'YouTube' | 'TikTok+Instagram'
      - `posting_requirements` string
      - `posting_start_date` string, date, required
      - `effective_date` string, date, required
      - `expiry_date` string, date, required
      - `products` ContractProduct[]
        - `product_id` string, required
        - `product_name` string, nullable
      - `all_products` boolean
      - `require_video_link_email` boolean
      - `video_link_email` string, nullable
      - `commission_pct` number, nullable
      - `expenses_reimbursable` boolean
      - `revision_rounds` 0 | 1 | 2
      - `include_usage_rights` boolean
      - `usage_rights_months` integer
      - `usage_rights_duration_days` integer
      - `usage_rights_scope` 'organic_only' | 'organic_and_paid' | 'paid_only'
      - `usage_exclusivity_enabled` boolean
      - `usage_exclusivity_months` integer
      - `agreement_clause` string, nullable
      - `termination_notice_days` integer
      - `governing_law_jurisdiction` string
      - `reward` union, required
        - RetainerReward
          - `kind` 'retainer', required
          - `mode` 'fixed' | 'tiered', required
          - `payment_per_creator` union
            - number
            - string
          - `payment_per_post` union
            - number
            - string
          - `tiers` RetainerTier[], nullable
            - `name` string, required
            - `retainer` union, required
              - …
            - `gmv_threshold` number, required
          - `gmv_bonus_tiers` GmvBonusTier[], nullable
            - `gmv_threshold` number, required
            - `bonus_amount` union, required
              - …
          - `recurring` boolean
          - `payment_schedule` 'one_time' | 'monthly'
          - `payment_due_days` integer
          - `minimum_gmv_floor` number, nullable
          - `live_sessions` integer, nullable
          - `live_min_minutes` integer, nullable
          - `hourly_rate` union
            - number
            - string
          - `max_paid_hours` integer, nullable
          - `minimum_live_gmv_floor` number, nullable
          - `gmv_floor_combined` boolean, nullable
        - ChallengeReward
          - `kind` 'challenge', required
          - `metric_type` 'gmv' | 'views' | 'video_count' | 'gmv_videos' | 'live_gmv' | 'gmv_and_live_gmv' | 'videos_gmv_and_live_gmv' | 'sessions' | 'sessions_and_live_gmv', required
          - `payment_tiers` ChallengePaymentTier[], required
            - `threshold` number, required
            - `compensation` union, required
              - …
            - `videos_required` integer, nullable
            - `sessions_required` integer, nullable
          - `minimum_gate` ChallengeGate
            - `metric` 'video_count' | 'gmv', required
            - `threshold` number, required
          - `gmv_floor` number, nullable
          - `videos_floor` integer, nullable
          - `views_floor` integer, nullable
          - `live_gmv_floor` number, nullable
          - `sessions_floor` integer, nullable
          - `lives_count_as_posts` boolean, nullable
          - `live_min_minutes` integer, nullable
          - `ranking_priority` 'gmv' | 'videos' | 'live_gmv' | 'sessions', nullable
          - `payment_due_days` integer
        - LeaderboardReward
          - `kind` 'leaderboard', required
          - `mode` 'rank' | 'tier', required
          - `contest_ranks` ContestRank[], nullable
            - `rank` integer, required
            - `reward` union, required
              - …
          - `tiers` LeaderboardTier[], nullable
            - `name` string, required
            - `bonus` union, required
              - …
            - `threshold` number, required
            - `videos_required` integer, nullable
            - `num_winners` integer, nullable
          - `random_winner_wheel` boolean
          - `scoring_mode` 'single' | 'weighted', nullable
          - `weighted_metrics` ContractWeightedMetric[], nullable
            - `metric_type` 'gmv' | 'avg_views_per_post' | 'views' | 'videos_posted' | 'units_sold' | 'live_gmv' | 'combined_gmv' | 'sessions', required
            - `weight` number, required
          - `metric_type` 'gmv' | 'views' | 'videos_posted' | 'gmv_videos' | 'live_gmv' | 'gmv_and_live_gmv' | 'videos_gmv_and_live_gmv', nullable
          - `gmv_floor` number, nullable
          - `videos_floor` integer, nullable
          - `live_gmv_floor` number, nullable
          - `sessions_floor` integer, nullable
          - `payment_due_days` integer
        - ReimbursementReward
          - `kind` 'reimbursement', required
          - `reimbursement_amount` number, required
          - `reimbursement_bonus` number, nullable
          - `minimum_star_rating` integer, nullable
          - `steps` ReimbursementStep[], required
            - `id` string, required
            - `label` string, required
            - `description` string, required
          - `payment_due_days` integer
    - `status` 'draft' | 'sent' | 'awaiting_brand' | 'active' | 'expired' | 'voided' | 'delivery_failed', required
    - `signing_order` 'brand_first' | 'creator_first'
    - `brand_signed_at` string, date-time, nullable
    - `creator_signed_at` string, date-time, nullable
    - `effective_date` string, date, required
    - `expiry_date` string, date, required
    - `last_error` string, nullable
  - `next_cursor` string, nullable

## Other responses

- `422`: Validation Error

## Changes

> 76 revisions in range; 1 not diffed.

- **2026-10-14** `2a7ed9f8c407`: 2 warning, 3 info
  - added the new `gmv_and_live_gmv` enum value to the `data/items/terms/reward/oneOf[subschema #2: ChallengeReward]/metric_type` response property for the response status `200`
  - added the new `videos_gmv_and_live_gmv` enum value to the `data/items/terms/reward/oneOf[subschema #2: ChallengeReward]/metric_type` response property for the response status `200`
  - added the optional property `data/items/terms/reward/oneOf[subschema #2: ChallengeReward]/live_min_minutes` to the response with the `200` status
  - added the optional property `data/items/terms/reward/oneOf[subschema #2: ChallengeReward]/lives_count_as_posts` to the response with the `200` status
  - …1 more
- **2026-10-14** `34cc040be296`: 6 info
  - added the optional property `data/items/terms/reward/oneOf[subschema #1: RetainerReward]/gmv_floor_combined` to the response with the `200` status
  - added the optional property `data/items/terms/reward/oneOf[subschema #1: RetainerReward]/hourly_rate` to the response with the `200` status
  - added the optional property `data/items/terms/reward/oneOf[subschema #1: RetainerReward]/live_min_minutes` to the response with the `200` status
  - added the optional property `data/items/terms/reward/oneOf[subschema #1: RetainerReward]/live_sessions` to the response with the `200` status
  - …2 more
- …earlier changes not shown

[Operation history](https://skmtc.dev/reacherapp/apis/reacher-data-api/changes/contracts/campaigns/:campaign_id/get.md)

---

[API](https://skmtc.dev/reacherapp/apis/reacher-data-api.md) - [All operations](https://skmtc.dev/reacherapp/apis/reacher-data-api/llms.txt) - [OpenAPI document](https://skmtc.dev/reacherapp/apis/reacher-data-api/revisions/63ce74b30b5a?raw)
