Webhook events
self_referral.detected
Sent when a new completed order or milestone report matched a linked customer ID or the referring partner's identity signals. blocked: the program created no reward. review: rewardId names the reward held as pending. flagged: rewardId names a reward that follows the usual approval. signals lists the matching signal types, never their values.
Example payload
This illustrative payload follows the current event validator. Amounts use minor units.
json
{
"id": "00000000-0000-4000-8000-000000000001",
"companyId": "company-example",
"type": "self_referral.detected",
"data": {
"partnerId": "partner-example",
"partnerExternalId": "merchant-partner-001",
"action": "blocked",
"signals": [
"customer_id"
],
"eventId": "payment-example",
"programId": "program-example",
"customerId": "customer-example",
"trigger": "order",
"orderId": "order-example"
},
"createdAt": "2026-10-11T12:00:00.000Z"
}Payload fields
| Field | Type | Required | Details |
|---|---|---|---|
partnerId | string | Yes | |
partnerExternalId | string | Yes | |
action | "blocked", "review", "flagged" | Yes | |
signals | array | Yes | |
eventId | string | Yes | |
programId | string | Yes | |
customerId | string | Yes | |
rewardId | string | No |
Variant 1
| Field | Type | Required | Details |
|---|---|---|---|
trigger | "order" | Yes | |
orderId | string | Yes |
Variant 2
| Field | Type | Required | Details |
|---|---|---|---|
trigger | "milestone" | Yes | |
milestone | string | Yes |
Payload schema
json
{
"allOf": [
{
"type": "object",
"properties": {
"partnerId": {
"type": "string",
"minLength": 1
},
"partnerExternalId": {
"type": "string",
"minLength": 1
},
"action": {
"type": "string",
"enum": [
"blocked",
"review",
"flagged"
]
},
"signals": {
"type": "array",
"items": {
"type": "string",
"enum": [
"customer_id",
"email",
"phone",
"card",
"device",
"ip"
]
}
},
"eventId": {
"type": "string",
"minLength": 1
},
"programId": {
"type": "string",
"minLength": 1
},
"customerId": {
"type": "string",
"minLength": 1
},
"rewardId": {
"type": "string",
"minLength": 1
}
},
"required": [
"partnerId",
"partnerExternalId",
"action",
"signals",
"eventId",
"programId",
"customerId"
],
"additionalProperties": true
},
{
"anyOf": [
{
"type": "object",
"properties": {
"trigger": {
"type": "string",
"const": "order"
},
"orderId": {
"type": "string",
"minLength": 1
}
},
"required": [
"trigger",
"orderId"
],
"additionalProperties": true
},
{
"type": "object",
"properties": {
"trigger": {
"type": "string",
"const": "milestone"
},
"milestone": {
"type": "string",
"minLength": 1
}
},
"required": [
"trigger",
"milestone"
],
"additionalProperties": true
}
]
}
]
}Handle delivery
Verify the signature over the raw body before parsing JSON. Check that the body ID matches Grizzlee-Event-Id. Process each ID once, since delivery can repeat.