---
title: "Create a reward"
method: POST
path: "/v1/programs/{program_id}/rewards"
tags: ["Rewards"]
---

# Create a reward

`POST /v1/programs/{program_id}/rewards`

## Request

- Base URL: `https://api.scrip.dev`
- URL: `https://api.scrip.dev/v1/programs/{program_id}/rewards`
- Auth: HTTP bearer

Create a new reward in the program's catalog.

## Path parameters

- `program_id` string, uuid, required

## Headers

- `Idempotency-Key` string

## Request body

- CreateRewardRequest: Adds a reward to a program's catalog.
  - `asset_id` string, uuid, required: Asset used to price this reward (must be linked to the program). Immutable after creation.
  - `available_from` string, date-time: Start of the availability window (RFC 3339, null if always available)
  - `available_until` string, date-time: End of the availability window (RFC 3339, null if no end date)
  - `category` string: Grouping label for organizing rewards in the catalog
  - `description` string: Details about the reward
  - `max_per_participant` integer: Per-participant redemption limit (UNIT_BASED only, null = unlimited)
  - `max_total` integer: Global inventory limit (UNIT_BASED only, null = unlimited)
  - `metadata` object: Custom key-value data attached to this reward
  - `name` string, required: The name people see for the reward in the catalog.
  - `redemption_type` 'UNIT_BASED' | 'AMOUNT_BASED', required: How the reward is redeemed: UNIT_BASED (discrete quantities) or AMOUNT_BASED (variable amounts). Immutable after creation.
  - `status` 'DRAFT' | 'ACTIVE' | 'OUT_OF_STOCK' | 'ARCHIVED', required: Lifecycle status: DRAFT, ACTIVE, OUT_OF_STOCK, or ARCHIVED
  - `unit_cost` string, required: Cost per unit in the reward's asset (decimal string for precision, must be positive)

## Response `201`

Reward created

- RewardResponse: A reward with its pricing, inventory, availability, and metadata
  - `asset_id` string, uuid: Asset used to price this reward
  - `auto_managed` boolean: Whether the catalog sync manages this item's lifecycle automatically
  - `available_from` string, date-time: Start of the availability window (RFC 3339, null if always available)
  - `available_until` string, date-time: End of the availability window (RFC 3339, null if no end date)
  - `category` string: Grouping label for organizing rewards in the catalog
  - `committed_units` integer, nullable: UNIT_BASED units currently consuming inventory. Includes delivered and pending units. Null for AMOUNT_BASED rewards.
  - `created_at` string, date-time: When this reward was created (RFC 3339)
  - `delivered_units` integer, nullable: UNIT_BASED units whose redemption has been captured. Null for AMOUNT_BASED rewards.
  - `description` string: Details about the reward
  - `display` ProductDisplay: Descriptive content a provider supplies for a product. The HTML comes from the provider, so sanitize it before you show it.
    - `description_html` string: Product description in HTML; sanitize before rendering
    - `disclosure_html` string: Product disclosures in HTML; sanitize before rendering
    - `image_url` string: A link to a picture of the product.
    - `instructions_html` string: Redemption instructions in HTML; sanitize before rendering
  - `face_currency` string: ISO 4217 currency of the face value (PROVIDER items only)
  - `face_value` Money: A fiat amount: an integer count of the currency's minor units, such as cents, and the ISO 4217 currency code.
    - `amount_minor` integer, required: Amount in the currency's minor units, such as cents for USD
    - `currency` string, required: ISO 4217 currency code
  - `fulfillment` RewardFulfillment: How Scrip buys a managed reward: the provider's countries, currencies, denominations and delivery method.
    - `account_status` 'ACTIVE' | 'DISABLED' | 'PENDING_ONBOARDING' | 'PENDING_REVIEW' | 'REJECTED' | 'ARCHIVED': Lifecycle status of the fulfillment account backing this reward. Redemptions are accepted only while ACTIVE; ARCHIVED means the account was removed.
    - `asset_scale` integer: Decimal places supported by the asset used to pay for this reward
    - `countries` string[]: Countries where the product can be used
    - `currencies` string[]: Currencies accepted when redeeming this reward
    - `delivery_method` 'claim_link': How the participant accesses a successfully fulfilled reward
    - `denominations` Money[]: Allowed fixed face values, in addition to any allowed range, listed once per accepted currency
      - `amount_minor` integer, required: Amount in the currency's minor units, such as cents for USD
      - `currency` string, required: ISO 4217 currency code
    - `rate` string: Asset units per currency minor unit. Charge is the face value's amount_minor * rate rounded up to the asset_scale precision, with no currency conversion. Omitted for fixed-price rewards.
    - `value_max` Money: A fiat amount: an integer count of the currency's minor units, such as cents, and the ISO 4217 currency code.
      - `amount_minor` integer, required: Amount in the currency's minor units, such as cents for USD
      - `currency` string, required: ISO 4217 currency code
    - `value_min` Money: A fiat amount: an integer count of the currency's minor units, such as cents, and the ISO 4217 currency code.
      - `amount_minor` integer, required: Amount in the currency's minor units, such as cents for USD
      - `currency` string, required: ISO 4217 currency code
  - `fulfillment_product_id` string, uuid: Product ordered when this reward is redeemed. Present for managed rewards (kind PROVIDER).
  - `id` string, uuid: Unique identifier for this reward
  - `kind` string: Whether you created the reward directly (CUSTOM) or Scrip manages it through a reward source (PROVIDER)
  - `max_per_participant` integer, nullable: Per-participant redemption limit (UNIT_BASED only, null = unlimited)
  - `max_total` integer, nullable: Global inventory limit (UNIT_BASED only, null = unlimited)
  - `metadata` object: Custom key-value data attached to this reward
  - `name` string: The name people see for the reward in the catalog.
  - `pending_units` integer, nullable: UNIT_BASED units awaiting fulfillment. Null for AMOUNT_BASED rewards.
  - `program_id` string, uuid: Program this reward belongs to
  - `redemption_type` 'UNIT_BASED' | 'AMOUNT_BASED': Whether the reward is redeemed in discrete units or in variable amounts.
  - `reward_source_id` string, uuid: Reward source that supplies this managed reward
  - `status` 'DRAFT' | 'ACTIVE' | 'OUT_OF_STOCK' | 'ARCHIVED': The reward's lifecycle state.
  - `unit_cost` string: Fixed price per unit. For variable-value managed rewards, use fulfillment.rate to calculate the charge.
  - `updated_at` string, date-time: When this reward was last modified (RFC 3339)

## Other responses

- `400`: Validation failed (code: validation_error | invalid_json)
- `401`: The API key is missing or not valid. See [Authentication](https://docs.scrip.dev/authentication).
- `403`: The caller is not allowed to do this.
- `404`: Program or asset not found (code: program_not_found | asset_not_found)
- `409`: Reward name already exists in program or program is archived (code: reward_name_already_exists | program_archived)
- `429`: Too many requests. Wait the number of seconds in the `Retry-After` header, then retry. See [Limits and durations](https://docs.scrip.dev/limits#rate-limits).
- `500`: Something failed on Scrip's side. Retry the request, and quote `request_id` if it keeps failing. [Errors](https://docs.scrip.dev/errors) lists every code, and the [API introduction](https://docs.scrip.dev/api-reference/introduction) describes the error format.

---

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