Sections
Theme

Rewards

REST API reference for rewards

This reference is generated from the Invitebase OpenAPI contract.

What is owed once a referral is validated, and its fulfillment.

List rewards

GET/v1/rewards

Authentication

Authorization: Bearer <secret key>.

Parameters

NameInRequiredSchemaDescription
limitqueryNo{"type":"integer","minimum":1,"maximum":100,"default":25}
starting_afterqueryNo{"type":"string"}A cursor (object id) for pagination; returns the page after this object.
statusqueryNo{"$ref":"#/components/schemas/RewardStatus"}
referral_idqueryNo{"type":"string"}Only rewards issued for this referral.
campaign_idqueryNo{"type":"string"}Only rewards issued under this campaign.
referrer_idqueryNo{"type":"string"}Only rewards whose referral belongs to this referrer.

Responses

200

A paginated list of rewards.

application/json schema:

{
  "allOf": [
    {
      "$ref": "#/components/schemas/ListResponse"
    },
    {
      "type": "object",
      "properties": {
        "data": {
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/Reward"
          }
        }
      }
    }
  ]
}

400

The request was malformed or invalid.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

401

Missing or invalid API key.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

403

The API key is valid but is not permitted to call this endpoint.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

429

Too many requests.

Response headers:

{
  "Retry-After": {
    "description": "Seconds until the caller may retry.",
    "schema": {
      "type": "integer",
      "minimum": 1
    }
  }
}

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

Retrieve a reward

GET/v1/rewards/{rewardId}

Authentication

Authorization: Bearer <secret key>.

Parameters

NameInRequiredSchemaDescription
rewardIdpathYes{"type":"string"}

Responses

200

The reward and its payout details.

application/json schema:

{
  "$ref": "#/components/schemas/Reward"
}

401

Missing or invalid API key.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

403

The API key is valid but is not permitted to call this endpoint.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

404

The requested resource does not exist.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

429

Too many requests.

Response headers:

{
  "Retry-After": {
    "description": "Seconds until the caller may retry.",
    "schema": {
      "type": "integer",
      "minimum": 1
    }
  }
}

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

Mark a reward fulfilled

POST/v1/rewards/{rewardId}/fulfill

Acknowledge fulfillment of an app-grant reward. When the customer's backend receives a reward.pending webhook and grants the entitlement in its own system, it acks with this endpoint: the reward moves to fulfilled, delivery retries stop, and a reward.fulfilled event fires. Idempotent — repeating the call returns the same result. Money-rail rewards are fulfilled by the payout provider and do not use this endpoint.

Authentication

Authorization: Bearer <secret key>.

Parameters

NameInRequiredSchemaDescription
rewardIdpathYes{"type":"string"}
Idempotency-KeyheaderNo{"type":"string"}A unique key for one logical mutation. The same key and request replay the original result for 24 hours; using the key with a different request returns 409.

Responses

200

Reward marked fulfilled.

application/json schema:

{
  "$ref": "#/components/schemas/Reward"
}

401

Missing or invalid API key.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

403

The API key is valid but is not permitted to call this endpoint.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

404

The requested resource does not exist.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

409

The request conflicts with the resource's current state.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

429

Too many requests.

Response headers:

{
  "Retry-After": {
    "description": "Seconds until the caller may retry.",
    "schema": {
      "type": "integer",
      "minimum": 1
    }
  }
}

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

Claim a platform-compatible offer code

POST/v1/rewards/{rewardId}/offer-code

Server-side delivery for a validated offer-code reward. Your backend verifies the recipient, supplies their external id and platform, then receives the one code reserved for this reward. Referral-link visits alone never reveal a code, and codes never fall back across platforms.

Authentication

Authorization: Bearer <secret key>.

Parameters

NameInRequiredSchemaDescription
rewardIdpathYes{"type":"string"}
Idempotency-KeyheaderNo{"type":"string"}A unique key for one logical mutation. The same key and request replay the original result for 24 hours; using the key with a different request returns 409.

Request body

Required.

application/json schema:

{
  "$ref": "#/components/schemas/OfferCodeClaimRequest"
}

Responses

200

The code reserved for this reward. Treat this response as sensitive.

application/json schema:

{
  "$ref": "#/components/schemas/OfferCodeDelivery"
}

400

The request was malformed or invalid.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

401

Missing or invalid API key.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

403

The API key is valid but is not permitted to call this endpoint.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

404

The requested resource does not exist.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

409

The request conflicts with the resource's current state.

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

429

Too many requests.

Response headers:

{
  "Retry-After": {
    "description": "Seconds until the caller may retry.",
    "schema": {
      "type": "integer",
      "minimum": 1
    }
  }
}

application/json schema:

{
  "$ref": "#/components/schemas/Error"
}

Schemas

Schema references below resolve against these definitions. Required fields, enums, bounds, and composed types are preserved from the contract.

The RewardStatus object

Full schema:

{
  "type": "string",
  "enum": [
    "pending",
    "held_for_review",
    "approved",
    "fulfilled",
    "failed",
    "rejected"
  ]
}

The ListResponse object

FieldTypeRequiredDescription
objectstringYes
has_morebooleanYes
dataarrayYes

Full schema:

{
  "type": "object",
  "required": [
    "object",
    "data",
    "has_more"
  ],
  "properties": {
    "object": {
      "type": "string",
      "const": "list"
    },
    "has_more": {
      "type": "boolean"
    },
    "data": {
      "type": "array",
      "items": {}
    }
  }
}

The Reward object

FieldTypeRequiredDescription
idstringYes
objectstringYes
statusRewardStatusYes
referral_idstringYes
campaign_idstringNo
recipientstringNo
configRewardConfigNoHow one recipient of a validated referral is rewarded. A campaign's reward is an array of these, one per recipient. Validated at write time: unknown fields are rejected, money methods require amount + currency, free_access requires free_access_duration, and money rewards must be included in the account's plan (otherwise 400 reward_not_in_plan). Delivery is separate from method: the same free_access reward can arrive over your webhook or as a code, without changing what the recipient is promised.
payoutPayoutNoThe actual disbursement or app grant.
modeModeNoWhether the object exists in test or live mode (determined by the API key).
livemodebooleanYes
created_atstringYes

Full schema:

{
  "type": "object",
  "required": [
    "id",
    "object",
    "status",
    "referral_id",
    "livemode",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "example": "rwd_123"
    },
    "object": {
      "type": "string",
      "const": "reward"
    },
    "status": {
      "$ref": "#/components/schemas/RewardStatus"
    },
    "referral_id": {
      "type": "string"
    },
    "campaign_id": {
      "type": "string"
    },
    "recipient": {
      "type": "string",
      "enum": [
        "referrer",
        "referred_user"
      ]
    },
    "config": {
      "$ref": "#/components/schemas/RewardConfig"
    },
    "payout": {
      "$ref": "#/components/schemas/Payout"
    },
    "mode": {
      "$ref": "#/components/schemas/Mode"
    },
    "livemode": {
      "type": "boolean"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}

Reward statuses

StatusMeaning
pendingCreated on validation, awaiting fulfillment. For app grants this is the acting state: reward.pending fires and your backend confirms the grant.
held_for_reviewHeld back from fulfillment, and blocked from being fulfilled until it is approved. Fires reward.held_for_review.
approvedQueued for fulfillment once any hold window elapses.
fulfilledDelivered — app grants when your backend confirms the grant; payouts when the provider completes.
failedPayout fulfillment failed (money rewards only, e.g. payout error). App grants cannot fail.
rejectedFlagged with its referral by the AI fraud check, or clawed back inside the hold window. Not paid or billed unless the referral is unblocked.

The RewardConfig object

How one recipient of a validated referral is rewarded. A campaign's reward is an array of these, one per recipient. Validated at write time: unknown fields are rejected, money methods require amount + currency, free_access requires free_access_duration, and money rewards must be included in the account's plan (otherwise 400 reward_not_in_plan). Delivery is separate from method: the same free_access reward can arrive over your webhook or as a code, without changing what the recipient is promised.

FieldTypeRequiredDescription
methodstringYesWhat the recipient gets — never how it reaches them, which is delivery. in_app and free_access are app grants with no money movement. The rest are money rewards paid through our payout partner, drawn from the prefunded balance: a store gift_card, a prepaid_visa card, a charity donation, or cash (see cash_methods). monetary lets the recipient choose among categories at claim time. Plans gate categories: Indie offers gift_card and charity; prepaid_visa and cash need Growth or Enterprise, which offer all four. The former single-rail methods paypal, venmo and ach are rejected — use cash with cash_methods.
categoriesarrayNomonetary only. The categories the recipient may choose from. Omit it to offer every category your plan includes; the stored campaign shows the resolved list.
cash_methodsarrayNoFor cash, or monetary offering cash. The cash options the recipient may pick: PayPal, Venmo, Cash App, bank transfer, or debit card. Omit it to offer every cash option your plan includes.
recipientstringYesWho this entry rewards. Add one configuration per side to make a campaign double-sided.
amountintegerNoValue in smallest currency unit (for money methods) or app-defined units.
currencyCurrencyNoISO 4217 currency code (lowercase), e.g. "usd".
free_access_durationobjectNoRequired for method = free_access. The term your referral pages advertise — e.g. &#123; "count": 3, "unit": "month" &#125;. For code deliveries this is the advertised term only: the enforced one is baked into the code you supply, so generate codes that match.
deliverystringNoFor method = free_access — how the grant reaches the recipient. webhook (the default) calls your backend over the signed reward webhook. manual, api, and app_store_connect hand over a code from campaign inventory, and an active campaign using one of them requires stocked inventory. revenuecat grants the entitlement through your RevenueCat project.
in_app_payloadobjectNoFor method = in_app — what to grant (e.g. grant the gold skin).
milestone_thresholdintegerNoReward only after the referrer reaches N validated referrals (e.g. 5).
cap_per_referrerintegerNoMax rewards per referrer (fraud control).
cap_per_monthintegerNoMax rewards per campaign per month (fraud control).
expires_in_daysintegerNo

Full schema:

{
  "type": "object",
  "required": [
    "method",
    "recipient"
  ],
  "additionalProperties": false,
  "description": "How one recipient of a validated referral is rewarded. A campaign's `reward` is an array of these, one per recipient. Validated at write time: unknown fields are rejected, money methods require `amount` + `currency`, `free_access` requires `free_access_duration`, and money rewards must be included in the account's plan (otherwise 400 `reward_not_in_plan`). Delivery is separate from method: the same `free_access` reward can arrive over your webhook or as a code, without changing what the recipient is promised.\n",
  "properties": {
    "method": {
      "type": "string",
      "enum": [
        "in_app",
        "free_access",
        "monetary",
        "gift_card",
        "prepaid_visa",
        "charity",
        "cash"
      ],
      "description": "What the recipient gets — never how it reaches them, which is `delivery`. `in_app` and `free_access` are app grants with no money movement. The rest are money rewards paid through our payout partner, drawn from the prefunded balance: a store `gift_card`, a `prepaid_visa` card, a `charity` donation, or `cash` (see `cash_methods`). `monetary` lets the recipient choose among `categories` at claim time. Plans gate categories: Indie offers `gift_card` and `charity`; `prepaid_visa` and `cash` need Growth or Enterprise, which offer all four. The former single-rail methods `paypal`, `venmo` and `ach` are rejected — use `cash` with `cash_methods`.\n"
    },
    "categories": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "$ref": "#/components/schemas/RewardCategory"
      },
      "description": "`monetary` only. The categories the recipient may choose from. Omit it to offer every category your plan includes; the stored campaign shows the resolved list.\n"
    },
    "cash_methods": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "$ref": "#/components/schemas/CashMethod"
      },
      "description": "For `cash`, or `monetary` offering `cash`. The cash options the recipient may pick: PayPal, Venmo, Cash App, bank transfer, or debit card. Omit it to offer every cash option your plan includes.\n"
    },
    "recipient": {
      "type": "string",
      "enum": [
        "referrer",
        "referred_user"
      ],
      "description": "Who this entry rewards. Add one configuration per side to make a campaign double-sided.\n"
    },
    "amount": {
      "type": "integer",
      "description": "Value in smallest currency unit (for money methods) or app-defined units."
    },
    "currency": {
      "$ref": "#/components/schemas/Currency"
    },
    "free_access_duration": {
      "type": "object",
      "required": [
        "count",
        "unit"
      ],
      "additionalProperties": false,
      "description": "Required for method = free_access. The term your referral pages advertise — e.g. `{ \"count\": 3, \"unit\": \"month\" }`. For code deliveries this is the advertised term only: the enforced one is baked into the code you supply, so generate codes that match.\n",
      "properties": {
        "count": {
          "type": "integer",
          "minimum": 1,
          "maximum": 120
        },
        "unit": {
          "type": "string",
          "enum": [
            "day",
            "week",
            "month"
          ]
        }
      }
    },
    "delivery": {
      "type": "string",
      "enum": [
        "webhook",
        "manual",
        "api",
        "app_store_connect",
        "revenuecat"
      ],
      "default": "webhook",
      "description": "For method = free_access — how the grant reaches the recipient. `webhook` (the default) calls your backend over the signed reward webhook. `manual`, `api`, and `app_store_connect` hand over a code from campaign inventory, and an active campaign using one of them requires stocked inventory. `revenuecat` grants the entitlement through your RevenueCat project.\n"
    },
    "in_app_payload": {
      "type": "object",
      "additionalProperties": true,
      "description": "For method = in_app — what to grant (e.g. grant the gold skin)."
    },
    "milestone_threshold": {
      "type": "integer",
      "description": "Reward only after the referrer reaches N validated referrals (e.g. 5)."
    },
    "cap_per_referrer": {
      "type": "integer",
      "description": "Max rewards per referrer (fraud control)."
    },
    "cap_per_month": {
      "type": "integer",
      "description": "Max rewards per campaign per month (fraud control)."
    },
    "expires_in_days": {
      "type": "integer"
    }
  }
}

The RewardCategory object

A kind of money reward. Each is a product offered by our payout partner.

Full schema:

{
  "type": "string",
  "description": "A kind of money reward. Each is a product offered by our payout partner.",
  "enum": [
    "gift_card",
    "prepaid_visa",
    "charity",
    "cash"
  ]
}

The CashMethod object

How a cash reward reaches the recipient, through our payout partner: paypal, venmo, cash_app, bank (bank transfer), or debit (debit card).

Full schema:

{
  "type": "string",
  "description": "How a cash reward reaches the recipient, through our payout partner: `paypal`, `venmo`, `cash_app`, `bank` (bank transfer), or `debit` (debit card).\n",
  "enum": [
    "paypal",
    "venmo",
    "cash_app",
    "bank",
    "debit"
  ]
}

The Currency object

ISO 4217 currency code (lowercase), e.g. "usd".

Full schema:

{
  "type": "string",
  "description": "ISO 4217 currency code (lowercase), e.g. \"usd\".",
  "example": "usd"
}

The Payout object

The actual disbursement or app grant.

FieldTypeRequiredDescription
methodstringNoThe reward's method. Campaigns stored before cash became a category may still report the retired paypal, venmo or ach.
providerstringNoIdentifies the app grant or money payout provider.
provider_referencestringNoExternal id (payout partner order id or webhook delivery id).
statusstringNo
amountintegerNo
currencyCurrencyNoISO 4217 currency code (lowercase), e.g. "usd".

Full schema:

{
  "type": "object",
  "description": "The actual disbursement or app grant.",
  "properties": {
    "method": {
      "type": "string",
      "description": "The reward's method. Campaigns stored before cash became a category may still report the retired `paypal`, `venmo` or `ach`.\n",
      "enum": [
        "in_app",
        "free_access",
        "monetary",
        "gift_card",
        "prepaid_visa",
        "charity",
        "cash",
        "paypal",
        "venmo",
        "ach"
      ]
    },
    "provider": {
      "type": "string",
      "enum": [
        "webhook",
        "tremendous"
      ],
      "description": "Identifies the app grant or money payout provider."
    },
    "provider_reference": {
      "type": "string",
      "description": "External id (payout partner order id or webhook delivery id)."
    },
    "status": {
      "type": "string",
      "enum": [
        "pending",
        "sent",
        "delivered",
        "failed"
      ]
    },
    "amount": {
      "type": "integer"
    },
    "currency": {
      "$ref": "#/components/schemas/Currency"
    }
  }
}

The Mode object

Whether the object exists in test or live mode (determined by the API key).

Full schema:

{
  "type": "string",
  "enum": [
    "test",
    "live"
  ],
  "description": "Whether the object exists in test or live mode (determined by the API key)."
}

The Error object

FieldTypeRequiredDescription
errorobjectYes

Full schema:

{
  "type": "object",
  "required": [
    "error"
  ],
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "type",
        "code",
        "message",
        "doc_url"
      ],
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "invalid_request_error",
            "authentication_error",
            "rate_limit_error",
            "api_error"
          ]
        },
        "code": {
          "type": "string"
        },
        "message": {
          "type": "string"
        },
        "param": {
          "type": "string"
        },
        "doc_url": {
          "type": "string",
          "format": "uri"
        }
      }
    }
  }
}

The OfferCodeClaimRequest object

FieldTypeRequiredDescription
platformstringYesThe recipient's actual redemption platform. No fallback occurs.
recipient_external_idstringYesThe recipient identity your authenticated backend has verified.

Full schema:

{
  "type": "object",
  "required": [
    "platform",
    "recipient_external_id"
  ],
  "additionalProperties": false,
  "properties": {
    "platform": {
      "type": "string",
      "enum": [
        "ios",
        "android",
        "web",
        "custom"
      ],
      "description": "The recipient's actual redemption platform. No fallback occurs."
    },
    "recipient_external_id": {
      "type": "string",
      "maxLength": 512,
      "description": "The recipient identity your authenticated backend has verified."
    }
  }
}

The OfferCodeDelivery object

FieldTypeRequiredDescription
idstringYesThe associated reward id.
objectstringYes
reward_idstringYes
recipientstringYes
platformstringYes
codestringYesSensitive one-time assigned offer code. Do not log it.
redemption_urlstring or nullNo
expires_atstring or nullNo
livemodebooleanYes

Full schema:

{
  "type": "object",
  "required": [
    "id",
    "object",
    "reward_id",
    "recipient",
    "platform",
    "code",
    "livemode"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "The associated reward id."
    },
    "object": {
      "type": "string",
      "const": "offer_code_delivery"
    },
    "reward_id": {
      "type": "string"
    },
    "recipient": {
      "type": "string",
      "enum": [
        "referrer",
        "referred_user"
      ]
    },
    "platform": {
      "type": "string",
      "enum": [
        "ios",
        "android",
        "web",
        "custom"
      ]
    },
    "code": {
      "type": "string",
      "description": "Sensitive one-time assigned offer code. Do not log it."
    },
    "redemption_url": {
      "type": [
        "string",
        "null"
      ],
      "format": "uri"
    },
    "expires_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "livemode": {
      "type": "boolean"
    }
  }
}

What's next

On this page