HTTP endpoints
releaseIncentive
Frees an open hold when its order is cancelled. Safe to repeat.
POST /api/v1/referrals/incentive/reservations/{reservationId}/release
Requires events:write. Keep the Bearer key on your server.
SDK
grizzlee.releaseIncentive(reservationId: string): Promise<IncentiveReservation>HTTP
Use your backend's HTTP client. The cURL request shows the wire format. Replace path parameters and example values.
curl --fail-with-body --request POST \
'https://app.grizzlee.ca/api/v1/referrals/incentive/reservations/{reservationId}/release' \
-H "Authorization: Bearer $GRIZZLEE_SERVER_KEY"Response
HTTP responses wrap this value in data. The SDK returns the value directly unless the note above describes a wrapper.
| Field | Type | Required | Details |
|---|---|---|---|
id | string | Yes | |
companyId | string | Yes | |
orderId | string | No | The placed order. Absent only on historical quote holds released by migration. |
customerId | string | Yes | |
programId | string | Yes | |
partnerId | string | Yes | |
status | union | Yes | |
terms | union | Yes | Terms when the reservation was made. Later program edits leave them alone. |
incentiveKind | union | No | Absent on historical friend holds. |
rewardId | string | No | |
programVersion | number | No | The program version the terms come from. Absent on reservations made before programs had versions. |
currency | union | Yes | |
incentiveExpiresAt | union | Yes | When the offer itself stops applying. Earned holds keep the reward's offer expiry. Null when it never expires. |
referredAt | string | Yes | Earned holds use the reward's createdAt, when the offer was earned. |
customerOrderNumber | number | Yes | The purchase number Grizzlee expected for the order when it reserved. |
newCustomer | union | No | The merchant's answer when this hold was made. Omitted, eligibility used recorded purchases. |
baseCents | number | No | |
suggestedDiscountCents | number | No | |
categories | array | No | The categories the order sent when it reserved. The order's own categories are checked again when it completes. |
createdAt | string | Yes | |
updatedAt | string | Yes | |
referralSelection | object | No |
status
Variant 1
Type: string.
Variant 2
Type: string.
Variant 3
Type: string.
terms
Variant 1
| Field | Type | Required | Details |
|---|---|---|---|
terms.type | "percent" | Yes | |
terms.rateBps | number | Yes | |
terms.orders | number | Yes | How many of the friend's orders get the incentive. |
terms.newCustomersOnly | boolean | Yes | true: use the merchant's newCustomer answer, or recorded purchases when omitted. false: returning customers qualify too. A supplied answer uses the order limit after the referral. |
terms.expiresAfterDays | union | Yes | Days after the referral was captured, claimed or entered. null means it never expires. |
terms.returnOnFullRefund | boolean | Yes | true: a full refund gives the use back, so the customer can get the offer again. |
terms.maxDiscountCents | number | No | Largest discount for one order. |
terms.minOrderCents | number | No | The friend's order total before the discount must reach this amount. Checked by the merchant's checkout. |
terms.orderCategories | object | No | Order categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies. |
terms.expiresAfterDays
Variant 1
Type: null.
Variant 2
Type: number.
terms.orderCategories
| Field | Type | Required | Details |
|---|---|---|---|
terms.orderCategories.include | array | No | |
terms.orderCategories.exclude | array | No |
Variant 2
| Field | Type | Required | Details |
|---|---|---|---|
terms.type | "fixed" | Yes | |
terms.orders | number | Yes | How many of the friend's orders get the incentive. |
terms.newCustomersOnly | boolean | Yes | true: use the merchant's newCustomer answer, or recorded purchases when omitted. false: returning customers qualify too. A supplied answer uses the order limit after the referral. |
terms.expiresAfterDays | union | Yes | Days after the referral was captured, claimed or entered. null means it never expires. |
terms.returnOnFullRefund | boolean | Yes | true: a full refund gives the use back, so the customer can get the offer again. |
terms.amountCents | number | Yes | |
terms.minOrderCents | number | No | The friend's order total before the discount must reach this amount. Checked by the merchant's checkout. |
terms.orderCategories | object | No | Order categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies. |
terms.expiresAfterDays
Variant 1
Type: null.
Variant 2
Type: number.
terms.orderCategories
| Field | Type | Required | Details |
|---|---|---|---|
terms.orderCategories.include | array | No | |
terms.orderCategories.exclude | array | No |
Variant 3
| Field | Type | Required | Details |
|---|---|---|---|
terms.type | "percent" | Yes | |
terms.rateBps | number | Yes | |
terms.orders | number | Yes | How many of the friend's orders get the incentive. |
terms.expiresAfterDays | union | Yes | Days after the referral was captured, claimed or entered. null means it never expires. |
terms.returnOnFullRefund | boolean | Yes | true: a full refund gives the use back, so the customer can get the offer again. |
terms.maxDiscountCents | number | No | Largest discount for one order. |
terms.minOrderCents | number | No | The friend's order total before the discount must reach this amount. Checked by the merchant's checkout. |
terms.orderCategories | object | No | Order categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies. |
terms.expiresAfterDays
Variant 1
Type: null.
Variant 2
Type: number.
terms.orderCategories
| Field | Type | Required | Details |
|---|---|---|---|
terms.orderCategories.include | array | No | |
terms.orderCategories.exclude | array | No |
Variant 4
| Field | Type | Required | Details |
|---|---|---|---|
terms.type | "fixed" | Yes | |
terms.orders | number | Yes | How many of the friend's orders get the incentive. |
terms.expiresAfterDays | union | Yes | Days after the referral was captured, claimed or entered. null means it never expires. |
terms.returnOnFullRefund | boolean | Yes | true: a full refund gives the use back, so the customer can get the offer again. |
terms.amountCents | number | Yes | |
terms.minOrderCents | number | No | The friend's order total before the discount must reach this amount. Checked by the merchant's checkout. |
terms.orderCategories | object | No | Order categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies. |
terms.expiresAfterDays
Variant 1
Type: null.
Variant 2
Type: number.
terms.orderCategories
| Field | Type | Required | Details |
|---|---|---|---|
terms.orderCategories.include | array | No | |
terms.orderCategories.exclude | array | No |
incentiveKind
Variant 1
Type: string.
Variant 2
Type: string.
currency
Variant 1
Type: string.
Variant 2
Type: string.
Variant 3
Type: string.
Variant 4
Type: string.
incentiveExpiresAt
Variant 1
Type: null.
Variant 2
Type: string.
newCustomer
Variant 1
Type: boolean.
Variant 2
Type: boolean.
referralSelection
| Field | Type | Required | Details |
|---|---|---|---|
referralSelection.winner | union | Yes | |
referralSelection.skipped | array | Yes |
referralSelection.winner
Variant 1
Type: null.
Variant 2
| Field | Type | Required | Details |
|---|---|---|---|
referralSelection.winner.programId | string | Yes | |
referralSelection.winner.partnerId | string | Yes | |
referralSelection.winner.occurredAt | string | Yes | |
referralSelection.winner.type | union | No | |
referralSelection.winner.providerPromoCodeId | string | No | |
referralSelection.winner.index | number | No | Absent when the customer's recorded attribution is retained. |
referralSelection.winner.type
Variant 1
Type: string.
Variant 2
Type: string.
referralSelection.skipped[]
| Field | Type | Required | Details |
|---|---|---|---|
referralSelection.skipped.index | number | Yes | |
referralSelection.skipped.reason | union | Yes |
referralSelection.skipped.reason
Variant 1
Type: string.
Variant 2
Type: string.
Variant 3
Type: string.
Variant 4
Type: string.
Variant 5
Type: string.
Variant 6
Type: string.
Variant 7
Type: string.
Variant 8
Type: string.
Variant 9
Type: string.
Response schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"companyId": {
"type": "string"
},
"orderId": {
"type": "string",
"description": "The placed order. Absent only on historical quote holds released by migration."
},
"customerId": {
"type": "string"
},
"programId": {
"type": "string"
},
"partnerId": {
"type": "string"
},
"status": {
"anyOf": [
{
"type": "string",
"const": "open"
},
{
"type": "string",
"const": "consumed"
},
{
"type": "string",
"const": "released"
}
]
},
"terms": {
"anyOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "percent"
},
"rateBps": {
"type": "number"
},
"orders": {
"type": "number",
"description": "How many of the friend's orders get the incentive."
},
"newCustomersOnly": {
"type": "boolean",
"description": "true: use the merchant's newCustomer answer, or recorded purchases when omitted. false:\nreturning customers qualify too. A supplied answer uses the order limit after the referral."
},
"expiresAfterDays": {
"anyOf": [
{
"type": "null"
},
{
"type": "number"
}
],
"description": "Days after the referral was captured, claimed or entered. null means it never expires."
},
"returnOnFullRefund": {
"type": "boolean",
"description": "true: a full refund gives the use back, so the customer can get the offer again."
},
"maxDiscountCents": {
"type": "number",
"description": "Largest discount for one order."
},
"minOrderCents": {
"type": "number",
"description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
},
"orderCategories": {
"type": "object",
"properties": {
"include": {
"type": "array",
"items": {
"type": "string"
}
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
},
"description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
}
},
"required": [
"type",
"rateBps",
"orders",
"newCustomersOnly",
"expiresAfterDays",
"returnOnFullRefund"
]
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "fixed"
},
"orders": {
"type": "number",
"description": "How many of the friend's orders get the incentive."
},
"newCustomersOnly": {
"type": "boolean",
"description": "true: use the merchant's newCustomer answer, or recorded purchases when omitted. false:\nreturning customers qualify too. A supplied answer uses the order limit after the referral."
},
"expiresAfterDays": {
"anyOf": [
{
"type": "null"
},
{
"type": "number"
}
],
"description": "Days after the referral was captured, claimed or entered. null means it never expires."
},
"returnOnFullRefund": {
"type": "boolean",
"description": "true: a full refund gives the use back, so the customer can get the offer again."
},
"amountCents": {
"type": "number"
},
"minOrderCents": {
"type": "number",
"description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
},
"orderCategories": {
"type": "object",
"properties": {
"include": {
"type": "array",
"items": {
"type": "string"
}
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
},
"description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
}
},
"required": [
"type",
"orders",
"newCustomersOnly",
"expiresAfterDays",
"returnOnFullRefund",
"amountCents"
]
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "percent"
},
"rateBps": {
"type": "number"
},
"orders": {
"type": "number",
"description": "How many of the friend's orders get the incentive."
},
"expiresAfterDays": {
"anyOf": [
{
"type": "null"
},
{
"type": "number"
}
],
"description": "Days after the referral was captured, claimed or entered. null means it never expires."
},
"returnOnFullRefund": {
"type": "boolean",
"description": "true: a full refund gives the use back, so the customer can get the offer again."
},
"maxDiscountCents": {
"type": "number",
"description": "Largest discount for one order."
},
"minOrderCents": {
"type": "number",
"description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
},
"orderCategories": {
"type": "object",
"properties": {
"include": {
"type": "array",
"items": {
"type": "string"
}
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
},
"description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
}
},
"required": [
"type",
"rateBps",
"orders",
"expiresAfterDays",
"returnOnFullRefund"
]
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "fixed"
},
"orders": {
"type": "number",
"description": "How many of the friend's orders get the incentive."
},
"expiresAfterDays": {
"anyOf": [
{
"type": "null"
},
{
"type": "number"
}
],
"description": "Days after the referral was captured, claimed or entered. null means it never expires."
},
"returnOnFullRefund": {
"type": "boolean",
"description": "true: a full refund gives the use back, so the customer can get the offer again."
},
"amountCents": {
"type": "number"
},
"minOrderCents": {
"type": "number",
"description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
},
"orderCategories": {
"type": "object",
"properties": {
"include": {
"type": "array",
"items": {
"type": "string"
}
},
"exclude": {
"type": "array",
"items": {
"type": "string"
}
}
},
"description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
}
},
"required": [
"type",
"orders",
"expiresAfterDays",
"returnOnFullRefund",
"amountCents"
]
}
],
"description": "Terms when the reservation was made. Later program edits leave them alone."
},
"incentiveKind": {
"anyOf": [
{
"type": "string",
"const": "friend"
},
{
"type": "string",
"const": "earned"
}
],
"description": "Absent on historical friend holds."
},
"rewardId": {
"type": "string"
},
"programVersion": {
"type": "number",
"description": "The program version the terms come from. Absent on reservations made before programs had versions."
},
"currency": {
"anyOf": [
{
"type": "string",
"const": "CAD"
},
{
"type": "string",
"const": "USD"
},
{
"type": "string",
"const": "EUR"
},
{
"type": "string",
"const": "GBP"
}
]
},
"incentiveExpiresAt": {
"anyOf": [
{
"type": "null"
},
{
"type": "string"
}
],
"description": "When the offer itself stops applying. Earned holds keep the reward's offer expiry. Null when it never expires."
},
"referredAt": {
"type": "string",
"description": "Earned holds use the reward's createdAt, when the offer was earned."
},
"customerOrderNumber": {
"type": "number",
"description": "The purchase number Grizzlee expected for the order when it reserved."
},
"newCustomer": {
"anyOf": [
{
"type": "boolean",
"const": false
},
{
"type": "boolean",
"const": true
}
],
"description": "The merchant's answer when this hold was made. Omitted, eligibility used recorded purchases."
},
"baseCents": {
"type": "number"
},
"suggestedDiscountCents": {
"type": "number"
},
"categories": {
"type": "array",
"items": {
"type": "string"
},
"description": "The categories the order sent when it reserved. The order's own categories are checked again when it completes."
},
"createdAt": {
"type": "string"
},
"updatedAt": {
"type": "string"
},
"referralSelection": {
"type": "object",
"properties": {
"winner": {
"anyOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"programId": {
"type": "string"
},
"partnerId": {
"type": "string"
},
"occurredAt": {
"type": "string"
},
"type": {
"anyOf": [
{
"type": "string",
"const": "code"
},
{
"type": "string",
"const": "receipt"
}
]
},
"providerPromoCodeId": {
"type": "string"
},
"index": {
"type": "number",
"description": "Absent when the customer's recorded attribution is retained."
}
},
"required": [
"programId",
"partnerId",
"occurredAt"
]
}
]
},
"skipped": {
"type": "array",
"items": {
"type": "object",
"properties": {
"index": {
"type": "number"
},
"reason": {
"anyOf": [
{
"type": "string",
"const": "expired"
},
{
"type": "string",
"const": "invalid"
},
{
"type": "string",
"const": "self_referral"
},
{
"type": "string",
"const": "wrong_program"
},
{
"type": "string",
"const": "program_inactive"
},
{
"type": "string",
"const": "partner_inactive"
},
{
"type": "string",
"const": "fraud"
},
{
"type": "string",
"const": "customer_already_referred"
},
{
"type": "string",
"const": "older"
}
]
}
},
"required": [
"index",
"reason"
]
}
}
},
"required": [
"winner",
"skipped"
]
}
},
"required": [
"id",
"companyId",
"customerId",
"programId",
"partnerId",
"status",
"terms",
"currency",
"incentiveExpiresAt",
"referredAt",
"customerOrderNumber",
"createdAt",
"updatedAt"
]
}Errors
Failures return { "error": { "code": "...", "message": "...", "details": {} } }. Details are optional. See error statuses. Reuse an unchanged event payload when retrying.