{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/growsurf-com/json-schema/growsurf-com-reward-schema.json",
  "title": "Reward",
  "description": "A single campaign reward (also known as a `CampaignReward`). This is different from a `ParticipantReward`, which is a reward earned by a participant.",
  "x-generated": "2026-11-10",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/growsurf-com-openapi.json#/components/schemas/Reward",
  "type": "object",
  "required": [
    "id",
    "type",
    "isUnlimited",
    "metadata"
  ],
  "properties": {
    "id": {
      "type": "string",
      "readOnly": true,
      "description": "The unique identifier of the campaign reward. You can find this ID from *Program Editor > 1. Rewards* and clicking the reward."
    },
    "type": {
      "$ref": "#/$defs/RewardType",
      "description": "The reward type."
    },
    "event": {
      "$ref": "#/$defs/RewardEvent",
      "description": "The event that earns this referral reward. Present for SINGLE_SIDED, DOUBLE_SIDED, and MILESTONE rewards. Legacy rewards return CONVERSION."
    },
    "title": {
      "type": [
        "string",
        "null"
      ],
      "description": "The reward title (internal only, never exposed to participants)."
    },
    "isVisible": {
      "type": "boolean",
      "description": "Whether the reward is enabled. When `false`, the reward is disabled: it is no longer awarded, and it is hidden from participants, including those who already earned it. Set `true` for the reward to be visible and awardable."
    },
    "description": {
      "type": [
        "string",
        "null"
      ],
      "description": "The reward description shown to the referrer."
    },
    "referralDescription": {
      "type": [
        "string",
        "null"
      ],
      "description": "The reward description shown to the referred friend (only applicable for double-sided reward types)."
    },
    "referredRewardUpfront": {
      "type": "boolean",
      "description": "Only applies to double-sided rewards. When `true`, the referred friend's reward is delivered upfront as a discount and no `ParticipantReward` is created for them when the referral triggers."
    },
    "isUnlimited": {
      "type": "boolean",
      "description": "`true` if this reward can be earned by a single participant an unlimited number of times."
    },
    "limit": {
      "type": [
        "integer",
        "null"
      ],
      "description": "The number of times a participant can earn this reward (overridden when `isUnlimited` is `true`). `-1` represents an unlimited reward in REST responses."
    },
    "conversionsRequired": {
      "type": [
        "integer",
        "null"
      ],
      "description": "The number of referrals a participant must make to earn this reward."
    },
    "numberOfWinners": {
      "type": [
        "integer",
        "null"
      ],
      "description": "The maximum number of winners. Only applies to `LEADERBOARD` rewards. When `limitDuration` is `PER_MONTH`, this many top referrers win each month; otherwise this many win in total."
    },
    "limitDuration": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "IN_TOTAL",
        "PER_MONTH",
        "PER_YEAR",
        null
      ],
      "description": "Whether the reward can be earned in total, on a monthly basis, or on a yearly basis."
    },
    "imageUrl": {
      "type": [
        "string",
        "null"
      ],
      "description": "The reward image URL."
    },
    "imageIconKey": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "GIFT_1",
        "GIFT_2",
        "GIFT_3",
        "GIFT_4",
        "GIFT_5",
        "GIFT_6",
        "GIFT_CARD",
        "CASH",
        "COIN",
        "CARD",
        "STAR_1",
        "STAR_2",
        "STAR_3",
        "TROPHY",
        "CROWN",
        "SEAL",
        "HEART_1",
        "HEART_2",
        "TAG",
        "DIAMOND",
        "CONFETTI",
        "ROCKET",
        null
      ],
      "description": "The starter icon shown for the reward, or `null` when `imageUrl` is your own image."
    },
    "couponCode": {
      "type": [
        "string",
        "null"
      ],
      "description": "A legacy static coupon code shown to the referrer in the reward-won email and webhook. Display text only; GrowSurf does not create or validate it in any billing system. If the program has a connected billing integration (Stripe, Chargebee, or Recurly) that issues a coupon for the referral, that issued code is shown instead."
    },
    "order": {
      "type": [
        "integer",
        "null"
      ],
      "description": "If there are multiple rewards, the order in which the reward should be displayed. `null` by default until set within the Design step of the program editor."
    },
    "nextMilestonePrefix": {
      "type": [
        "string",
        "null"
      ],
      "description": "Text displayed in front of a participant's referral count for UI purposes (e.g., \"You are only\"). Applicable for milestone rewards (when `type` is `MILESTONE`)."
    },
    "nextMilestoneSuffix": {
      "type": [
        "string",
        "null"
      ],
      "description": "Text displayed after a participant's referral count for UI purposes (e.g., \"referrals away from receiving a nice reward!\"). Applicable for milestone rewards (when `type` is `MILESTONE`)."
    },
    "metadata": {
      "$ref": "#/$defs/Metadata",
      "description": "The reward metadata."
    },
    "commissionStructure": {
      "oneOf": [
        {
          "$ref": "#/$defs/CommissionStructure"
        },
        {
          "type": "null"
        }
      ],
      "description": "The reward commission structure. Present only for affiliate programs."
    },
    "referralCouponCode": {
      "type": [
        "string",
        "null"
      ],
      "description": "A legacy static coupon code shown to the referred friend in the reward-won email and webhook (double-sided rewards). Same caveats as `couponCode`: display text only, not created or validated in any billing system, and superseded by a connected billing integration's issued coupon when one exists."
    },
    "value": {
      "oneOf": [
        {
          "$ref": "#/$defs/RewardTaxValuation"
        },
        {
          "type": "null"
        }
      ],
      "description": "Tax valuation for the reward (the referrer's side of a double-sided reward). `null` when no valuation is set. For commission rewards, both fields are `null`; GrowSurf classifies the actual commission amount as `NONEMPLOYEE_SERVICES`."
    },
    "referredValue": {
      "oneOf": [
        {
          "$ref": "#/$defs/RewardTaxValuation"
        },
        {
          "type": "null"
        }
      ],
      "description": "Tax valuation for the referred friend's side of a double-sided reward. `null` when no valuation is set. Commission rewards have no referred-friend side, so both fields are `null`."
    }
  },
  "$defs": {
    "CommissionStructure": {
      "type": "object",
      "description": "The commission configuration for an affiliate reward. Present only for affiliate programs.",
      "properties": {
        "amount": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 1,
          "maximum": 999999999999,
          "description": "Fixed commission amount in the currency's smallest denomination, used when `type` is `FIXED`. The maximum is `100000000` (1,000,000.00) for USD, EUR, and GBP. `null` for percentage-based commissions."
        },
        "amountISO": {
          "type": [
            "string",
            "null"
          ],
          "description": "ISO 4217 currency code for the fixed `amount`. Defaults to the program's currency when omitted. Must match the campaign `currencyISO` when provided. `null` for percentage-based commissions."
        },
        "event": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "CLICK",
            "LEAD",
            "SALE",
            null
          ],
          "description": "The event that generates a commission. Missing legacy values read as `SALE`."
        },
        "type": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "PERCENT",
            "FIXED",
            null
          ],
          "description": "How the commission is calculated: `PERCENT` (a percentage of the sale) or `FIXED` (a fixed `amount`)."
        },
        "minPaidReferrals": {
          "type": [
            "integer",
            "null"
          ],
          "description": "The minimum number of paid referrals required before commissions are earned."
        },
        "holdDuration": {
          "type": [
            "integer",
            "null"
          ],
          "description": "Number of days a commission is held before it can be paid out."
        },
        "duration": {
          "type": [
            "string",
            "null"
          ],
          "description": "How long commissions continue to be earned for a referred customer: `FOREVER`, `REPEATING`, or `ONCE`. Only applies when `event` is `SALE`. `null` for `CLICK` and `LEAD` commissions, which pay once per event."
        },
        "durationInMonths": {
          "type": [
            "integer",
            "null"
          ],
          "description": "When `duration` is `REPEATING`, the number of months over which commissions are earned. `null` otherwise."
        },
        "approvalRequired": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "`true` if commissions require manual approval before they can be paid out."
        },
        "percent": {
          "type": [
            "number",
            "null"
          ],
          "description": "The commission percentage, used when `type` is `PERCENT`."
        },
        "hasMaxAmount": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "`true` if a maximum commission amount cap is configured."
        },
        "maxAmount": {
          "type": [
            "integer",
            "null"
          ],
          "description": "The maximum commission amount cap in the currency's smallest denomination. `null` if no cap is set."
        },
        "maxAmountISO": {
          "type": [
            "string",
            "null"
          ],
          "description": "The [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) currency code for `maxAmount`. Must match the campaign `currencyISO` when provided."
        },
        "hasIntro": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "`true` if an introductory commission rate is configured. Only applies when `event` is `SALE`. Always `false` for `CLICK` and `LEAD` commissions, whose `intro*` fields are `null`."
        },
        "introType": {
          "type": [
            "string",
            "null"
          ],
          "description": "How the introductory commission is calculated: `PERCENT` or `FIXED`."
        },
        "introPercent": {
          "type": [
            "number",
            "null"
          ],
          "description": "The introductory commission percentage, used when `introType` is `PERCENT`."
        },
        "introAmount": {
          "type": [
            "integer",
            "null"
          ],
          "description": "The introductory commission amount in the currency's smallest denomination, used when `introType` is `FIXED`."
        },
        "introAmountISO": {
          "type": [
            "string",
            "null"
          ],
          "description": "The [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) currency code for `introAmount`. Must match the campaign `currencyISO` when provided."
        },
        "introDuration": {
          "type": [
            "string",
            "null"
          ],
          "description": "How long the introductory rate applies."
        },
        "introDurationInMonths": {
          "type": [
            "integer",
            "null"
          ],
          "description": "When `introDuration` is repeating, the number of months the introductory rate applies."
        }
      },
      "additionalProperties": false
    },
    "Metadata": {
      "type": "object",
      "description": "Shallow custom metadata object.",
      "additionalProperties": true
    },
    "RewardEvent": {
      "type": "string",
      "enum": [
        "LEAD",
        "CONVERSION"
      ],
      "description": "The referral event that earns the reward."
    },
    "RewardTaxValuation": {
      "type": "object",
      "additionalProperties": false,
      "description": "Tax valuation settings for a reward. Only relevant when the program collects tax documentation.",
      "properties": {
        "fairMarketValueUSD": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 90071992547409.9,
          "description": "Manual fair-market value in USD (major units) used as the fallback when the reward value cannot be resolved automatically. `null` = no manual value."
        },
        "taxCharacter": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "NONEMPLOYEE_SERVICES",
            "PRIZE_OR_AWARD",
            "PURCHASE_REBATE",
            "OTHER_INCOME",
            "REVIEW_REQUIRED",
            null
          ],
          "description": "The reason the recipient earns this reward. `null` inherits the program's confirmed tax treatment for configurable non-commission rewards. Commission rewards always use `NONEMPLOYEE_SERVICES`."
        }
      }
    },
    "RewardType": {
      "type": "string",
      "enum": [
        "SINGLE_SIDED",
        "DOUBLE_SIDED",
        "MILESTONE",
        "LEADERBOARD",
        "AFFILIATE"
      ]
    }
  }
}