Skip to content
Developer docs
⌘ K
Dashboard ↗

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

FieldTypeRequiredDetails
partnerIdstringYes
partnerExternalIdstringYes
action"blocked", "review", "flagged"Yes
signalsarrayYes
eventIdstringYes
programIdstringYes
customerIdstringYes
rewardIdstringNo

Variant 1

FieldTypeRequiredDetails
trigger"order"Yes
orderIdstringYes

Variant 2

FieldTypeRequiredDetails
trigger"milestone"Yes
milestonestringYes

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.