> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.usegrade.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bonus templates

> Create, list, edit, and delete tiered bonus templates via /sdk/v1.

All endpoints below require:

* `X-Application-Id`
* `X-Api-Key`

Bonus templates define reusable tiered view bonuses for campaign creator
contracts. The legacy contract endpoint that accepted
`paymentTermTemplateId` is deprecated. To use a template through the API, read
its scope and tiers and put those values into `bonusPayment` on the unified
human-readable contract-history endpoint.

<Info>
  These endpoints configure tiered campaign bonuses. They do not issue a payout. `POST /sdk/v1/payouts/trigger` is still a direct payout endpoint and only pays the explicit `payoutAmount` or `lineItems` you send.
</Info>

## Bonus flow

1. Create a bonus template with thresholds and amounts.
2. Read the creator's current contract and its `versionId`.
3. Copy the template's scope and tiers into the contract's `bonusPayment`.
4. Write the complete contract with `basedOnVersionId`.
5. Add tracked campaign media for those creators.
6. Grade calculates eligible tiered bonus line items from tracked views and the contract's bonus settings.

## GET /sdk/v1/bonus-templates

List active tiered bonus templates for your agency.

### Query parameters

<ParamField query="includeHidden" type="boolean" default="false">
  Include templates hidden by `DELETE /sdk/v1/bonus-templates/:templateId`.
</ParamField>

### Response

```json theme={null}
{
  "success": true,
  "data": [
    {
      "templateId": "ptt_...",
      "name": "Launch view bonus",
      "description": "Bonus for high-performing launch posts",
      "colorCode": "#22C55E",
      "currency": "USD",
      "metric": "VIEWS",
      "tierScope": "CREATOR",
      "tiers": [
        { "threshold": 100000, "amount": 50 },
        { "threshold": 500000, "amount": 250 }
      ],
      "components": [
        {
          "type": "TIERED",
          "currency": "USD",
          "metric": "VIEWS",
          "tier_scope": "CREATOR",
          "tiers": [
            { "threshold": 100000, "amount": 50 },
            { "threshold": 500000, "amount": 250 }
          ]
        }
      ],
      "isDefault": false,
      "hidden": false,
      "createdAt": "2026-05-19T12:00:00.000Z",
      "updatedAt": "2026-05-19T12:00:00.000Z"
    }
  ]
}
```

## GET /sdk/v1/bonus-templates/:templateId

Fetch one tiered bonus template.

### Path parameters

<ParamField path="templateId" type="string" required>
  Bonus template ID returned by create or list.
</ParamField>

### Query parameters

<ParamField query="includeHidden" type="boolean" default="false">
  Allow fetching a hidden template.
</ParamField>

### Common errors

* `404`: template not found, belongs to another agency, is hidden, or is not a tiered bonus template

## POST /sdk/v1/bonus-templates

Create a tiered bonus template.

### Body

```json theme={null}
{
  "name": "Launch view bonus",
  "description": "Bonus for high-performing launch posts",
  "colorCode": "#22C55E",
  "currency": "USD",
  "metric": "VIEWS",
  "tierScope": "CREATOR",
  "tiers": [
    { "threshold": 100000, "amount": 50 },
    { "threshold": 500000, "amount": 250 }
  ]
}
```

<ParamField body="name" type="string" required>
  Display name. Names must be unique among visible bonus templates for the agency.
</ParamField>

<ParamField body="description" type="string">
  Optional description.
</ParamField>

<ParamField body="colorCode" type="string" required>
  Six-digit hex color, such as `#22C55E`.
</ParamField>

<ParamField body="currency" type="string" required>
  Bonus payout currency. All tiers in one template use the same currency.
</ParamField>

<ParamField body="metric" type="string" default="VIEWS">
  Must be `VIEWS`. Other metrics are rejected because they are not supported
  by the payout calculator.
</ParamField>

<ParamField body="tierScope" type="string" default="CREATOR">
  How views are counted for the bonus. Use `CREATOR`, `MEDIA`, or `BEST_MEDIA`.
</ParamField>

<ParamField body="tiers" type="object[]" required>
  Threshold/amount pairs. Each `threshold` and `amount` must be a non-negative number.
</ParamField>

<ParamField body="isDefault" type="boolean" default="false">
  Marks this template as an agency default for selection UIs.
</ParamField>

You can also send raw tiered components instead of `currency` plus `tiers`:

```json theme={null}
{
  "name": "Per-video bonus",
  "colorCode": "#0EA5E9",
  "components": [
    {
      "type": "TIERED",
      "currency": "USD",
      "metric": "VIEWS",
      "tier_scope": "MEDIA",
      "tiers": [
        { "threshold": 250000, "amount": 100 }
      ]
    }
  ]
}
```

### Response

Returns `201` with the created template in `data`.

### Common errors

* `400`: missing name, color, currency, tiers, or invalid tier values
* `400`: metric is not `VIEWS`
* `400`: component type is not `TIERED`
* `409`: a visible template with this name already exists

## PATCH /sdk/v1/bonus-templates/:templateId

Edit a tiered bonus template. `PUT` is also accepted with the same body.

### Body

Send at least one updatable field:

* `name`
* `description`
* `colorCode`
* `tiers`
* `components`
* `tierScope`
* `isDefault`

```json theme={null}
{
  "name": "Launch view bonus v2",
  "applicablePostsUploadedOnOrAfter": "2026-07-24",
  "tiers": [
    { "threshold": 100000, "amount": 75 },
    { "threshold": 500000, "amount": 300 }
  ]
}
```

<ParamField body="applicablePostsUploadedOnOrAfter" type="string">
  Required when changing tiers on a template that is already applied to creator contracts. The same date creates the new bonus-term history boundary for every linked contract.
</ParamField>

<Warning>
  If a template is already applied to creator contracts, you can only edit TIERED threshold and amount values, and you must provide `applicablePostsUploadedOnOrAfter`. Currency, metric, component shape, and `tierScope` are locked until those contracts use a different template.
</Warning>

### Common errors

* `400`: no updatable fields
* `400`: invalid tier values or non-tiered components
* `400`: missing or invalid `applicablePostsUploadedOnOrAfter` for an in-use tier change
* `400`: attempted currency, metric, or scope change while the template is applied
* `409`: a visible template with this name already exists
* `409`: template is locked by a pending payout approval

## DELETE /sdk/v1/bonus-templates/:templateId

Hide a tiered bonus template from future selection.

<Note>
  Delete is a soft delete. Hidden templates stay available to existing calculations if they were already applied to contracts.
</Note>

### Response

```json theme={null}
{
  "success": true,
  "message": "Deleted"
}
```

## Use a bonus template in a contract

After you create or fetch a template, read the creator's contract history,
copy the template values into `bonusPayment`, and submit the complete contract.
Map `tierScope` to `appliesTo` as follows: `CREATOR` → `CREATOR`, `MEDIA` →
`POST`, and `BEST_MEDIA` → `BEST_POST`. For a template with
`tierScope: "MEDIA"`, use `appliesTo: "POST"`:

```json theme={null}
{
  "basedOnVersionId": "CCCH_CURRENT",
  "effectiveDate": "2026-05-01",
  "contract": {
    "...": "all fields returned by the contract-history GET",
    "bonusPayment": {
      "appliesTo": "POST",
      "pays": "CAMPAIGN_COMPLETION",
      "rules": [
        {
          "currency": "USD",
          "conversionPolicy": null,
          "metric": "VIEWS",
          "tiers": [
            { "minimum": 100000, "amount": 50 },
            { "minimum": 500000, "amount": 250 }
          ]
        }
      ]
    }
  }
}
```

See [Create a contract version](/campaign-creators/create-contract-version)
for the required complete contract shape and stale-write safeguard.
