HTTP endpoints
sendEvent
POST /api/v1/events
Requires events:write. Keep the Bearer key on your server.
SDK
grizzlee.sendEvent(event: { type: "order.refunded"; orderId: string; occurredAt: string; eventId: string; refundedTotalCents?: number | undefined; refundedCommissionableCents?: number | undefined; fullRefund?: boolean | undefined; } | { type: "order.adjusted"; orderId: string; occurredAt: string; eventId: string; reason?: string | undefined; totalCents?: number | undefined; commissionableCents?: number | undefined; } | { type: "order.completed"; customerId: string; orderId: string; occurredAt: string; eventId: string; commissionableCents: number; currency: "CAD" | "USD" | "EUR" | "GBP"; customerDisplayName?: string | undefined; newCustomer?: boolean | undefined; categories?: string[] | undefined; customerOrderNumber?: number | undefined; totalCents?: number | undefined; customerEmail?: string | undefined; incentiveAppliedCents?: number | undefined; }): Promise<EventResult>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/events' \
-H "Authorization: Bearer $GRIZZLEE_SERVER_KEY" \
-H 'Content-Type: application/json' \
--data '{"type":"order.completed","eventId":"payment-example","orderId":"order-example","customerId":"customer-example","currency":"CAD","totalCents":10000,"commissionableCents":10000,"occurredAt":"2026-10-11T12:00:00.000Z"}'Request body
Variant 1
| Field | Type | Required | Details |
|---|---|---|---|
type | "order.completed" | Yes | |
eventId | string | Yes | |
orderId | string | Yes | |
customerId | string | Yes | |
customerDisplayName | string | No | |
customerEmail | string | No | |
newCustomer | boolean | No | |
customerOrderNumber | integer | No | minimum 1. maximum 1000000 |
currency | "CAD", "USD", "EUR", "GBP" | Yes | |
totalCents | integer | No | minimum 0. maximum 1000000000000 |
commissionableCents | integer | Yes | minimum 0. maximum 1000000000000 |
incentiveAppliedCents | integer | No | minimum 0. maximum 1000000000000 |
categories | array | No | |
occurredAt | string | Yes | date-time |
categories[]
Type: string.
Type: string.
Variant 2
| Field | Type | Required | Details |
|---|---|---|---|
type | "order.refunded" | Yes | |
eventId | string | Yes | |
orderId | string | Yes | |
refundedTotalCents | integer | No | minimum 0. maximum 1000000000000 |
refundedCommissionableCents | integer | No | minimum 0. maximum 1000000000000 |
fullRefund | boolean | No | |
occurredAt | string | Yes | date-time |
Variant 3
| Field | Type | Required | Details |
|---|---|---|---|
type | "order.adjusted" | Yes | |
eventId | string | Yes | |
orderId | string | Yes | |
totalCents | integer | No | minimum 0. maximum 1000000000000 |
commissionableCents | integer | No | minimum 0. maximum 1000000000000 |
reason | string | No | |
occurredAt | string | Yes | date-time |
Request schema
{
"anyOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "order.completed"
},
"eventId": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"orderId": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"customerId": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"customerDisplayName": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"customerEmail": {
"type": "string",
"format": "email",
"maxLength": 254
},
"newCustomer": {
"type": "boolean"
},
"customerOrderNumber": {
"type": "integer",
"minimum": 1,
"maximum": 1000000
},
"currency": {
"type": "string",
"enum": [
"CAD",
"USD",
"EUR",
"GBP"
]
},
"totalCents": {
"type": "integer",
"minimum": 0,
"maximum": 1000000000000
},
"commissionableCents": {
"type": "integer",
"minimum": 0,
"maximum": 1000000000000
},
"incentiveAppliedCents": {
"type": "integer",
"minimum": 0,
"maximum": 1000000000000
},
"categories": {
"type": "array",
"items": {
"allOf": [
{
"type": "string"
},
{
"type": "string",
"pattern": "^[a-z0-9][a-z0-9_-]{0,39}$"
}
]
},
"maxItems": 20
},
"occurredAt": {
"type": "string",
"format": "date-time"
}
},
"required": [
"type",
"eventId",
"orderId",
"customerId",
"currency",
"commissionableCents",
"occurredAt"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "order.refunded"
},
"eventId": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"orderId": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"refundedTotalCents": {
"type": "integer",
"minimum": 0,
"maximum": 1000000000000
},
"refundedCommissionableCents": {
"type": "integer",
"minimum": 0,
"maximum": 1000000000000
},
"fullRefund": {
"type": "boolean"
},
"occurredAt": {
"type": "string",
"format": "date-time"
}
},
"required": [
"type",
"eventId",
"orderId",
"occurredAt"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "order.adjusted"
},
"eventId": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"orderId": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"totalCents": {
"type": "integer",
"minimum": 0,
"maximum": 1000000000000
},
"commissionableCents": {
"type": "integer",
"minimum": 0,
"maximum": 1000000000000
},
"reason": {
"type": "string",
"minLength": 1,
"maxLength": 500
},
"occurredAt": {
"type": "string",
"format": "date-time"
}
},
"required": [
"type",
"eventId",
"orderId",
"occurredAt"
],
"additionalProperties": false
}
]
}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 |
|---|---|---|---|
eventId | string | Yes | |
orderId | string | Yes | |
duplicate | boolean | Yes | |
customerOrderNumber | number | No | Completions only. The purchase number Grizzlee gave the order. |
incentiveFlag | object | No | Completions only. Present when incentiveAppliedCents did not match the reservation. |
decisions | array | Yes | |
rewardIds | array | Yes | |
reversalCents | number | Yes | |
restoredCents | number | No | Reward amount given back because the order's cumulative refund total went down. |
increasedCents | number | No | Adjustments only. Reward value a higher order total added. Lower totals report reversalCents. |
stale | union | No | True when a refund or adjustment event was older than the latest applied one of its kind for the order and changed nothing. |
referralSelection | object | No |
incentiveFlag
| Field | Type | Required | Details |
|---|---|---|---|
incentiveFlag.reason | union | Yes | |
incentiveFlag.rewardId | string | No | |
incentiveFlag.programId | string | No | Program of the reservation or referral checked. Absent for no_referral. |
incentiveFlag.reservationId | string | No | The reservation sent with the order, when there was one. |
incentiveFlag.maxCents | union | Yes | Largest discount the terms allow on one order. Null when they set no cap or there are no terms. |
incentiveFlag.reportedCents | number | Yes | incentiveAppliedCents as the merchant reported it. |
incentiveFlag.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.
incentiveFlag.maxCents
Variant 1
Type: null.
Variant 2
Type: number.
decisions[]
| Field | Type | Required | Details |
|---|---|---|---|
decisions.programId | string | Yes | |
decisions.programName | string | Yes | |
decisions.partnerId | string | No | |
decisions.outcome | union | Yes | |
decisions.reason | string | Yes | |
decisions.reasonParts | array | No | reason as codes. Absent on decisions made before codes existed. |
decisions.amountCents | number | Yes | |
decisions.selfReferral | object | No | Present when the customer's identity signals matched the partner's. blocked comes with a skipped outcome. review comes with a reward held as pending. flagged comes with a reward that follows the program's usual approval. |
decisions.fraud | object | No | Present when fraud rules fired. blocked comes with a skipped outcome. review comes with a reward held as pending. flagged comes with a reward that follows the program's usual approval. |
decisions.milestoneCount | number | No | Milestone decisions that reached the count check: the person's reports that count for this program, at or after the referral and not reversed, this report included. |
decisions.milestoneThreshold | number | No | The effective bonus count, or 1 for each-report-only programs. |
decisions.outcome
Variant 1
Type: string.
Variant 2
Type: string.
decisions.reasonParts[]
| Field | Type | Required | Details |
|---|---|---|---|
decisions.reasonParts.code | union | Yes | |
decisions.reasonParts.params | object | No |
decisions.reasonParts.code
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.
Variant 10
Type: string.
Variant 11
Type: string.
Variant 12
Type: string.
Variant 13
Type: string.
Variant 14
Type: string.
Variant 15
Type: string.
Variant 16
Type: string.
Variant 17
Type: string.
Variant 18
Type: string.
Variant 19
Type: string.
Variant 20
Type: string.
Variant 21
Type: string.
Variant 22
Type: string.
Variant 23
Type: string.
Variant 24
Type: string.
Variant 25
Type: string.
Variant 26
Type: string.
Variant 27
Type: string.
Variant 28
Type: string.
Variant 29
Type: string.
Variant 30
Type: string.
Variant 31
Type: string.
Variant 32
Type: string.
Variant 33
Type: string.
Variant 34
Type: string.
Variant 35
Type: string.
Variant 36
Type: string.
Variant 37
Type: string.
Variant 38
Type: string.
decisions.reasonParts.params
Type: object.
decisions.selfReferral
| Field | Type | Required | Details |
|---|---|---|---|
decisions.selfReferral.action | union | Yes | |
decisions.selfReferral.signals | array | Yes |
decisions.selfReferral.action
Variant 1
Type: string.
Variant 2
Type: string.
Variant 3
Type: string.
decisions.selfReferral.signals[]
Variant 1
Type: string.
Variant 2
Type: string.
Variant 3
Type: string.
Variant 4
Type: string.
Variant 5
Type: string.
Variant 6
Type: string.
decisions.fraud
| Field | Type | Required | Details |
|---|---|---|---|
decisions.fraud.action | union | Yes | |
decisions.fraud.rules | array | Yes |
decisions.fraud.action
Variant 1
Type: string.
Variant 2
Type: string.
Variant 3
Type: string.
decisions.fraud.rules[]
| Field | Type | Required | Details |
|---|---|---|---|
decisions.fraud.rules.action | union | Yes | |
decisions.fraud.rules.rule | union | Yes | |
decisions.fraud.rules.signals | array | Yes | Matching signal types, never values. Empty for disposable_email. |
decisions.fraud.rules.count | number | No | Customers counted, this one included when referred inside the window. Velocity rules only. |
decisions.fraud.rules.action
Variant 1
Type: string.
Variant 2
Type: string.
Variant 3
Type: string.
decisions.fraud.rules.rule
Variant 1
Type: string.
Variant 2
Type: string.
Variant 3
Type: string.
Variant 4
Type: string.
decisions.fraud.rules.signals[]
Variant 1
Type: string.
Variant 2
Type: string.
Variant 3
Type: string.
Variant 4
Type: string.
Variant 5
Type: string.
stale
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": {
"eventId": {
"type": "string"
},
"orderId": {
"type": "string"
},
"duplicate": {
"type": "boolean"
},
"customerOrderNumber": {
"type": "number",
"description": "Completions only. The purchase number Grizzlee gave the order."
},
"incentiveFlag": {
"type": "object",
"properties": {
"reason": {
"anyOf": [
{
"type": "string",
"const": "no_reservation"
},
{
"type": "string",
"const": "reservation_expired"
},
{
"type": "string",
"const": "reservation_released"
},
{
"type": "string",
"const": "reservation_consumed"
},
{
"type": "string",
"const": "reservation_locked"
},
{
"type": "string",
"const": "no_referral"
},
{
"type": "string",
"const": "exceeds_terms"
},
{
"type": "string",
"const": "category_not_eligible"
}
]
},
"rewardId": {
"type": "string"
},
"programId": {
"type": "string",
"description": "Program of the reservation or referral checked. Absent for no_referral."
},
"reservationId": {
"type": "string",
"description": "The reservation sent with the order, when there was one."
},
"maxCents": {
"anyOf": [
{
"type": "null"
},
{
"type": "number"
}
],
"description": "Largest discount the terms allow on one order. Null when they set no cap or there are no terms."
},
"reportedCents": {
"type": "number",
"description": "incentiveAppliedCents as the merchant reported it."
}
},
"required": [
"reason",
"maxCents",
"reportedCents"
],
"description": "Completions only. Present when incentiveAppliedCents did not match the reservation."
},
"decisions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"programId": {
"type": "string"
},
"programName": {
"type": "string"
},
"partnerId": {
"type": "string"
},
"outcome": {
"anyOf": [
{
"type": "string",
"const": "skipped"
},
{
"type": "string",
"const": "rewarded"
}
]
},
"reason": {
"type": "string"
},
"reasonParts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": {
"anyOf": [
{
"type": "string",
"const": "fixed"
},
{
"type": "string",
"const": "no_referral"
},
{
"type": "string",
"const": "percentage"
},
{
"type": "string",
"const": "offer"
},
{
"type": "string",
"const": "report"
},
{
"type": "string",
"const": "report_percentage"
},
{
"type": "string",
"const": "milestone_bonus"
},
{
"type": "string",
"const": "schedule_month"
},
{
"type": "string",
"const": "tier_bonus"
},
{
"type": "string",
"const": "custom_partner_terms"
},
{
"type": "string",
"const": "custom_customer_terms"
},
{
"type": "string",
"const": "capped"
},
{
"type": "string",
"const": "no_order_referral"
},
{
"type": "string",
"const": "no_customer_referral"
},
{
"type": "string",
"const": "partner_not_in_program"
},
{
"type": "string",
"const": "self_referral_blocked"
},
{
"type": "string",
"const": "fraud_blocked"
},
{
"type": "string",
"const": "milestone_before_referral"
},
{
"type": "string",
"const": "order_before_referral"
},
{
"type": "string",
"const": "report_value_missing"
},
{
"type": "string",
"const": "milestone_window_expired"
},
{
"type": "string",
"const": "order_window_expired"
},
{
"type": "string",
"const": "milestone_progress"
},
{
"type": "string",
"const": "report_limit_reached"
},
{
"type": "string",
"const": "milestone_already_rewarded"
},
{
"type": "string",
"const": "report_value_no_reward"
},
{
"type": "string",
"const": "customer_cap_reached"
},
{
"type": "string",
"const": "partner_cap_reached"
},
{
"type": "string",
"const": "category_excluded"
},
{
"type": "string",
"const": "categories_missing"
},
{
"type": "string",
"const": "categories_required"
},
{
"type": "string",
"const": "first_order_only"
},
{
"type": "string",
"const": "first_order_after_referral_only"
},
{
"type": "string",
"const": "first_orders_only"
},
{
"type": "string",
"const": "first_orders_after_referral_only"
},
{
"type": "string",
"const": "duration_ended"
},
{
"type": "string",
"const": "rate_no_reward"
},
{
"type": "string",
"const": "order_no_reward"
}
]
},
"params": {
"type": "object",
"properties": {},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
}
},
"required": [
"code"
]
},
"description": "reason as codes. Absent on decisions made before codes existed."
},
"amountCents": {
"type": "number"
},
"selfReferral": {
"type": "object",
"properties": {
"action": {
"anyOf": [
{
"type": "string",
"const": "blocked"
},
{
"type": "string",
"const": "review"
},
{
"type": "string",
"const": "flagged"
}
]
},
"signals": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"const": "email"
},
{
"type": "string",
"const": "phone"
},
{
"type": "string",
"const": "card"
},
{
"type": "string",
"const": "device"
},
{
"type": "string",
"const": "ip"
},
{
"type": "string",
"const": "customer_id"
}
]
}
}
},
"required": [
"action",
"signals"
],
"description": "Present when the customer's identity signals matched the partner's. blocked comes with a\nskipped outcome. review comes with a reward held as pending. flagged comes with a reward that\nfollows the program's usual approval."
},
"fraud": {
"type": "object",
"properties": {
"action": {
"anyOf": [
{
"type": "string",
"const": "blocked"
},
{
"type": "string",
"const": "review"
},
{
"type": "string",
"const": "flagged"
}
]
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"action": {
"anyOf": [
{
"type": "string",
"const": "blocked"
},
{
"type": "string",
"const": "review"
},
{
"type": "string",
"const": "flagged"
}
]
},
"rule": {
"anyOf": [
{
"type": "string",
"const": "duplicate_accounts"
},
{
"type": "string",
"const": "rapid_repeats"
},
{
"type": "string",
"const": "repeat_customer"
},
{
"type": "string",
"const": "disposable_email"
}
]
},
"signals": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"const": "email"
},
{
"type": "string",
"const": "phone"
},
{
"type": "string",
"const": "card"
},
{
"type": "string",
"const": "device"
},
{
"type": "string",
"const": "ip"
}
]
},
"description": "Matching signal types, never values. Empty for disposable_email."
},
"count": {
"type": "number",
"description": "Customers counted, this one included when referred inside the window. Velocity rules only."
}
},
"required": [
"action",
"rule",
"signals"
]
}
}
},
"required": [
"action",
"rules"
],
"description": "Present when fraud rules fired. blocked comes with a skipped outcome. review comes with a\nreward held as pending. flagged comes with a reward that follows the program's usual approval."
},
"milestoneCount": {
"type": "number",
"description": "Milestone decisions that reached the count check: the person's reports that count for this\nprogram, at or after the referral and not reversed, this report included."
},
"milestoneThreshold": {
"type": "number",
"description": "The effective bonus count, or 1 for each-report-only programs."
}
},
"required": [
"programId",
"programName",
"outcome",
"reason",
"amountCents"
]
}
},
"rewardIds": {
"type": "array",
"items": {
"type": "string"
}
},
"reversalCents": {
"type": "number"
},
"restoredCents": {
"type": "number",
"description": "Reward amount given back because the order's cumulative refund total went down."
},
"increasedCents": {
"type": "number",
"description": "Adjustments only. Reward value a higher order total added. Lower totals report reversalCents."
},
"stale": {
"anyOf": [
{
"type": "boolean",
"const": false
},
{
"type": "boolean",
"const": true
}
],
"description": "True when a refund or adjustment event was older than the latest applied one of its kind for\nthe order and changed nothing."
},
"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": [
"eventId",
"orderId",
"duplicate",
"decisions",
"rewardIds",
"reversalCents"
]
}Errors
Failures return { "error": { "code": "...", "message": "...", "details": {} } }. Details are optional. See error statuses. Reuse an unchanged event payload when retrying.