{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/growsurf-com/json-schema/growsurf-com-campaign-options-schema.json",
  "title": "CampaignOptions",
  "description": "A program's options (the dashboard Program Editor's Options tab). To see the full object with every field and its current value, `GET` this resource, then `PATCH` back only the fields you want to change. Some fields are program-type specific (see the per-field notes).",
  "x-generated": "2026-11-10",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/growsurf-com-openapi.json#/components/schemas/CampaignOptions",
  "type": "object",
  "properties": {
    "affiliateApplicationMode": {
      "type": "string",
      "enum": [
        "OPEN_ENROLLMENT",
        "MANUAL_REVIEW",
        "AUTO_APPROVE"
      ],
      "description": "Affiliate programs only. How public signups join the program. `OPEN_ENROLLMENT` enrolls signups directly (the default for programs created before applications existed). `MANUAL_REVIEW` collects an application you approve or deny. `AUTO_APPROVE` collects the full application and approves it immediately. Switching to a reviewed mode requires a saved Program Page. Trusted enrollment through the API, CSV import, dashboard, or invites is never blocked by this setting."
    },
    "affiliateReapplicationPolicy": {
      "type": "string",
      "enum": [
        "AFTER_COOLDOWN",
        "DISABLED"
      ],
      "description": "Affiliate programs only. Whether a denied applicant may apply again. `AFTER_COOLDOWN` (the default) allows a new application once `affiliateReapplicationCooldownDays` has passed; `DISABLED` never allows one."
    },
    "affiliateReapplicationCooldownDays": {
      "type": "integer",
      "minimum": 1,
      "maximum": 365,
      "description": "Affiliate programs only. How many days a denied applicant waits before they can apply again (1-365, default 30). Only used when `affiliateReapplicationPolicy` is `AFTER_COOLDOWN`."
    },
    "affiliateApplicationReviewEstimateBusinessDays": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 1,
      "maximum": 60,
      "description": "Affiliate programs only. Optional review-time expectation (in business days, 1-60) shown to pending applicants. Send `null` to clear it; when unset, applicants see neutral \"we'll email you\" copy instead."
    },
    "requireManualRewardApproval": {
      "type": "boolean",
      "description": "Referral programs only. When `true`, each reward a participant earns is held for you to manually approve before it unlocks (and before the reward-won email is sent); when `false`, earned rewards are approved automatically. Cannot be `true` together with `autoFulfillRewards`."
    },
    "autoFulfillRewards": {
      "type": "boolean",
      "description": "Referral programs only. When `true`, rewards a participant earns are automatically marked as sent instead of you marking each one by hand, usually paired with an automated reward-delivery integration. Cannot be `true` together with `requireManualRewardApproval`."
    },
    "requireManualFraudApproval": {
      "type": "boolean",
      "description": "When `true`, no signup is automatically blocked for fraud. Every participant is allowed to join, and any suspected fraud is flagged in your dashboard for you to review. Cannot be `true` together with `autoBlockFraud`."
    },
    "autoBlockFraud": {
      "type": "boolean",
      "description": "When `true`, signups flagged as high fraud risk are automatically blocked from joining; when `false`, they are allowed in and flagged in your dashboard for review. Cannot be `true` together with `requireManualFraudApproval`."
    },
    "requireParticipantAuth": {
      "type": "boolean",
      "description": "Require returning participants to authenticate. Affiliate programs require this to be `true`."
    },
    "enforceGdprCompliance": {
      "type": "boolean",
      "description": "When `true`, GrowSurf stores only the minimum participant data needed to help you meet GDPR/CCPA requirements. Some participant fields are omitted and fraud screening is limited while this is on."
    },
    "blockPaidAdsTraffic": {
      "type": "boolean",
      "description": "When `true`, referrals from visitors who arrived through paid ads (for example Google or Facebook ads) are not attributed, so the referring participant is not credited for them. Recommended so participants don't compete with you for your own paid keywords."
    },
    "attributionModel": {
      "type": "string",
      "enum": [
        "LAST_CLICK",
        "FIRST_CLICK"
      ],
      "default": "LAST_CLICK",
      "description": "Selects which server-verified visit receives conversion credit within `referralCookieWindowDays`. `LAST_CLICK` is used when this field is missing, including for programs created before attribution models were configurable."
    },
    "referralCookieWindowDays": {
      "type": "integer",
      "enum": [
        1,
        3,
        7,
        14,
        30,
        60,
        90,
        180,
        365,
        400
      ],
      "description": "How long, in days, a referral-link click is remembered in the visitor's browser. If the visitor signs up within this window, the referral is credited to the participant whose link they clicked."
    },
    "referralCreditWindowDays": {
      "type": [
        "integer",
        "null"
      ],
      "enum": [
        1,
        3,
        7,
        14,
        30,
        60,
        90,
        180,
        365,
        null
      ],
      "description": "How long, in days, a referred friend has to complete a qualifying action for their referrer to earn credit and unlock a reward. After this window the referral no longer counts toward rewards. `null` = never expires."
    },
    "payoutThreshold": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 0,
      "description": "Affiliate programs only. Minimum payout in the program's currency minor units (`0` or `null` = no minimum). Requires `currencyISO` to be set."
    },
    "fraud": {
      "$ref": "#/$defs/CampaignOptionsFraud",
      "description": "Anti-fraud settings — block and allow lists for emails, IPs, and countries; toggles for blocking burner emails, data-center IPs, and referrals from high-risk referrers; per-IP signup rate limits; and reCAPTCHA."
    },
    "taxDocumentation": {
      "$ref": "#/$defs/CampaignOptionsTaxDocumentation",
      "description": "Affiliate programs only. Your company's billing details (name, address, and VAT number) used on affiliate payout invoices and for VAT handling."
    },
    "notificationEmails": {
      "$ref": "#/$defs/CampaignOptionsNotificationEmails",
      "description": "Owner notification-email settings — who receives program notifications and which events they are notified about."
    },
    "languages": {
      "$ref": "#/$defs/CampaignOptionsLanguages",
      "description": "The languages your program runs in, and whether the language picker shows flags."
    }
  },
  "$defs": {
    "CampaignOptionsFraud": {
      "type": "object",
      "description": "Anti-fraud settings.",
      "properties": {
        "blockedEmails": {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 100
          },
          "description": "Blocked emails. Each new entry must be an email address or an email pattern with `*` wildcards, such as `*@hooli.com`. Max 10000. Replaces the whole list."
        },
        "blockedIps": {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 100
          },
          "description": "Blocked IP addresses. Each new entry must be an IPv4 or IPv6 address or a pattern with `*` wildcards, such as `203.0.113.*`. Max 10000. Replaces the whole list."
        },
        "blockedCountries": {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 100
          },
          "description": "Blocked countries (ISO 3166-1 alpha-2 codes)."
        },
        "allowedEmails": {
          "description": "Allowed email addresses or patterns. Each new entry must be an email address or an email pattern with `*` wildcards. Replaces the whole list.",
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 100
          }
        },
        "allowedIps": {
          "description": "Allowed IP addresses or patterns. Each new entry must be an IPv4 or IPv6 address or a pattern with `*` wildcards. Replaces the whole list.",
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 100
          }
        },
        "allowedCountries": {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 100
          },
          "description": "Allowed countries (ISO 3166-1 alpha-2 codes)."
        },
        "blockBurnerEmails": {
          "description": "Whether signups from burner or disposable email addresses are blocked.",
          "type": "boolean"
        },
        "blockDataCenterIps": {
          "description": "Whether signups from known data-center IP addresses are blocked.",
          "type": "boolean"
        },
        "blockHighRiskReferrers": {
          "description": "Whether referrals from participants marked as high fraud risk are blocked.",
          "type": "boolean"
        },
        "autoBlockHighRiskIps": {
          "description": "Whether high-risk signup IP addresses are added to the blocked IP list automatically.",
          "type": "boolean"
        },
        "maxSignupsPerIp2Min": {
          "description": "Maximum signups allowed from one IP address in a 2-minute window.",
          "type": "integer",
          "minimum": 1,
          "maximum": 100
        },
        "maxSignupsPerIp10Min": {
          "description": "Maximum signups allowed from one IP address in a 10-minute window.",
          "type": "integer",
          "minimum": 1,
          "maximum": 100
        },
        "recaptcha": {
          "description": "reCAPTCHA settings for signup forms.",
          "$ref": "#/$defs/CampaignOptionsRecaptcha"
        }
      }
    },
    "CampaignOptionsLanguages": {
      "type": "object",
      "description": "The languages your program runs in (Options > Languages in the dashboard). Participants see the program in their language, and their emails follow it.",
      "properties": {
        "baseLanguage": {
          "type": "string",
          "enum": [
            "en",
            "es",
            "fr",
            "de",
            "it",
            "pt-BR",
            "nl",
            "pl",
            "sv",
            "tr",
            "ja",
            "ko",
            "zh-CN",
            "id",
            "da",
            "nb",
            "nn",
            "fi",
            "is",
            "cs",
            "sk",
            "hu",
            "ro",
            "hr",
            "sl",
            "et",
            "lv",
            "lt",
            "el",
            "bg",
            "uk",
            "ru",
            "pt-PT",
            "ca",
            "vi",
            "ms",
            "fil",
            "af",
            "sw",
            "zh-TW",
            "es-419"
          ],
          "default": "en",
          "description": "The language you write the program in. Participants see it when their language isn't one of the program's languages, and for any text you haven't translated."
        },
        "additionalLanguages": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "en",
              "es",
              "fr",
              "de",
              "it",
              "pt-BR",
              "nl",
              "pl",
              "sv",
              "tr",
              "ja",
              "ko",
              "zh-CN",
              "id",
              "da",
              "nb",
              "nn",
              "fi",
              "is",
              "cs",
              "sk",
              "hu",
              "ro",
              "hr",
              "sl",
              "et",
              "lv",
              "lt",
              "el",
              "bg",
              "uk",
              "ru",
              "pt-PT",
              "ca",
              "vi",
              "ms",
              "fil",
              "af",
              "sw",
              "zh-TW",
              "es-419"
            ]
          },
          "description": "Other languages participants can see, besides `baseLanguage`. Send the full list; send `[]` to turn them all off. Translations are managed in the dashboard and are kept when you remove a language."
        },
        "showFlags": {
          "type": "boolean",
          "description": "Shows a flag next to each language name in the language picker participants use. New programs start with `false`."
        },
        "flagCountries": {
          "type": "object",
          "description": "The flag shown next to each language name when `showFlags` is on. Only languages with more than one flag to choose from are listed, with the flag each one shows now. Values are ISO 3166 country codes; `ES-CT` is Catalonia. Send `null` for a language to go back to its default flag. iOS and Android apps show Catalan without a flag, because Catalonia has no emoji flag.",
          "properties": {
            "en": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "US",
                "GB",
                "AU",
                "CA",
                "IE",
                "NZ",
                "IN",
                "SG",
                "ZA",
                null
              ],
              "default": "US",
              "description": "The flag shown next to English. Send `null` to go back to the default."
            },
            "es": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "ES",
                "MX",
                "AR",
                "CO",
                "CL",
                "PE",
                "US",
                null
              ],
              "default": "ES",
              "description": "The flag shown next to Spanish. Send `null` to go back to the default."
            },
            "fr": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "FR",
                "CA",
                "BE",
                "CH",
                null
              ],
              "default": "FR",
              "description": "The flag shown next to French. Send `null` to go back to the default."
            },
            "de": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "DE",
                "AT",
                "CH",
                null
              ],
              "default": "DE",
              "description": "The flag shown next to German. Send `null` to go back to the default."
            },
            "it": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "IT",
                "CH",
                null
              ],
              "default": "IT",
              "description": "The flag shown next to Italian. Send `null` to go back to the default."
            },
            "nl": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "NL",
                "BE",
                null
              ],
              "default": "NL",
              "description": "The flag shown next to Dutch. Send `null` to go back to the default."
            },
            "zh-CN": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "CN",
                "SG",
                null
              ],
              "default": "CN",
              "description": "The flag shown next to Chinese (Simplified). Send `null` to go back to the default."
            },
            "ms": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "MY",
                "SG",
                null
              ],
              "default": "MY",
              "description": "The flag shown next to Malay. Send `null` to go back to the default."
            },
            "sw": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "TZ",
                "KE",
                null
              ],
              "default": "TZ",
              "description": "The flag shown next to Swahili. Send `null` to go back to the default."
            },
            "ca": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "ES-CT",
                "ES",
                "AD",
                null
              ],
              "default": "ES-CT",
              "description": "The flag shown next to Catalan. Send `null` to go back to the default."
            },
            "zh-TW": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "TW",
                "HK",
                null
              ],
              "default": "TW",
              "description": "The flag shown next to Chinese (Traditional). Send `null` to go back to the default."
            },
            "es-419": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "MX",
                "AR",
                "CO",
                "CL",
                "PE",
                "US",
                null
              ],
              "default": "MX",
              "description": "The flag shown next to Spanish (Latin America). Send `null` to go back to the default."
            }
          }
        }
      }
    },
    "CampaignOptionsNotificationEmails": {
      "type": "object",
      "description": "Owner notification-email settings.",
      "properties": {
        "recipients": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "maxLength": 254
          },
          "description": "Email addresses that receive program notifications. Send at least one valid address. Joined with `, `, the list can have up to 500 characters."
        },
        "events": {
          "type": "object",
          "description": "Per-event on/off toggles. The available events depend on the program type.",
          "properties": {
            "PARTICIPANT_REACHED_A_GOAL": {
              "description": "Notify recipients when a participant unlocks a reward.",
              "type": "boolean"
            },
            "NEW_PARTICIPANT_ADDED_NON_REFERRED": {
              "description": "Notify recipients when a participant joins without being referred.",
              "type": "boolean"
            },
            "NEW_PARTICIPANT_ADDED_REFERRED": {
              "description": "Notify recipients when a participant joins through a referral link.",
              "type": "boolean"
            },
            "CAMPAIGN_ENDED": {
              "description": "Notify recipients when the program ends.",
              "type": "boolean"
            },
            "WEEKLY_PERFORMANCE_REPORT": {
              "description": "Send recipients the weekly performance report.",
              "type": "boolean"
            },
            "MONTHLY_PERFORMANCE_REPORT": {
              "description": "Send recipients the monthly performance report.",
              "type": "boolean"
            },
            "MONTHLY_REWARD_REMINDER": {
              "description": "Referral programs only. Send recipients an email on the first of each month when manual rewards are unsent or need approval. No email is sent when there is nothing to do.",
              "type": "boolean"
            },
            "WEEKLY_REWARD_REMINDER": {
              "description": "Referral programs only. Send recipients an email each Monday when manual rewards are unsent or need approval. No email is sent when there is nothing to do.",
              "type": "boolean"
            },
            "NEW_COMMISSION_ADDED": {
              "description": "Notify recipients when an affiliate earns a new commission.",
              "type": "boolean"
            },
            "COMMISSION_ADJUSTED": {
              "description": "Notify recipients when an affiliate commission is adjusted.",
              "type": "boolean"
            },
            "NEW_PAYOUT_ISSUED": {
              "description": "Notify recipients when an affiliate payout is issued.",
              "type": "boolean"
            },
            "AFFILIATE_BATCH_PAYOUT_COMPLETED": {
              "description": "Notify recipients when an affiliate payout batch completes.",
              "type": "boolean"
            },
            "MONTHLY_PAYOUT_REMINDER": {
              "description": "Send recipients the monthly affiliate payout reminder.",
              "type": "boolean"
            },
            "AFFILIATE_APPLICATIONS_PENDING_REVIEW": {
              "description": "Affiliate programs only. Notify recipients when new affiliate applications are waiting for review. Digests are sent at most once every 24 hours.",
              "type": "boolean"
            }
          }
        }
      }
    },
    "CampaignOptionsRecaptcha": {
      "type": "object",
      "properties": {
        "isEnabled": {
          "description": "Whether reCAPTCHA is enabled on signup forms.",
          "type": "boolean"
        },
        "siteKey": {
          "description": "Public reCAPTCHA site key used by the signup form.",
          "type": [
            "string",
            "null"
          ],
          "maxLength": 100
        },
        "secretKey": {
          "type": [
            "string",
            "null"
          ],
          "maxLength": 100,
          "writeOnly": true,
          "description": "The reCAPTCHA secret key. Write-only — never returned by GET."
        }
      }
    },
    "CampaignOptionsTaxDocumentation": {
      "type": "object",
      "description": "Affiliate programs only. Your company's billing details (name, address, and VAT number) used on affiliate payout invoices and for VAT handling.",
      "properties": {
        "companyName": {
          "description": "Legal or billing company name used on affiliate payout invoices.",
          "type": [
            "string",
            "null"
          ],
          "maxLength": 255
        },
        "vatNumber": {
          "description": "Your company VAT number, when VAT collection applies.",
          "type": [
            "string",
            "null"
          ],
          "maxLength": 100
        },
        "addressLine1": {
          "description": "First line of the company address used on affiliate payout invoices.",
          "type": [
            "string",
            "null"
          ],
          "maxLength": 255
        },
        "addressLine2": {
          "description": "Second line of the company address used on affiliate payout invoices.",
          "type": [
            "string",
            "null"
          ],
          "maxLength": 255
        },
        "city": {
          "description": "City for the company address used on affiliate payout invoices.",
          "type": [
            "string",
            "null"
          ],
          "maxLength": 255
        },
        "state": {
          "description": "State, province, or region for the company address used on affiliate payout invoices.",
          "type": [
            "string",
            "null"
          ],
          "maxLength": 255
        },
        "postalCode": {
          "description": "Postal or ZIP code for the company address used on affiliate payout invoices.",
          "type": [
            "string",
            "null"
          ],
          "maxLength": 100
        },
        "country": {
          "type": [
            "string",
            "null"
          ],
          "description": "ISO 3166-1 alpha-2 country code."
        },
        "collectAffiliateVat": {
          "type": "boolean",
          "description": "Requires `vatNumber` to be set."
        }
      }
    }
  }
}