Skip to content
Developer docs
⌘ K
Dashboard ↗

Webhook events

milestone.reversed

Sent when a report is reversed. Reversing a report that is already reversed sends nothing. rewardIds lists every reward for the person and milestone. The report's own rewards and bonuses whose count fell below their saved threshold reverse and also send reward.reversed.

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": "milestone.reversed",
  "data": {
    "partners": [
      {
        "partnerId": "partner-example",
        "partnerExternalId": "merchant-partner-001"
      }
    ],
    "eventId": "payment-example",
    "customerId": "customer-example",
    "milestone": "first_booking",
    "status": "reversed",
    "programIds": [
      "program-example"
    ],
    "rewardIds": [
      "reward-example"
    ],
    "reportEventId": "reportEventId-example",
    "reversalCents": 500,
    "reversedAt": "2026-10-11T12:00:00.000Z"
  },
  "createdAt": "2026-10-11T12:00:00.000Z"
}

Payload fields

FieldTypeRequiredDetails
partnersarrayYes
partnerIdstringNo
partnerExternalIdstringNo
eventIdstringYes
customerIdstringYes
milestonestringYes
status"recorded", "revoked", "reinstated", "reversed"Yes
programIdsarrayYes
rewardIdsarrayYes
countintegerNominimum 0
reportEventIdstringYes
reasonstringNo
reversalCentsintegerYesminimum 0. maximum 9007199254740991
reversedAtstringYesdate-time

partners[]

FieldTypeRequiredDetails
partners.partnerIdstringYes
partners.partnerExternalIdstringYes

Payload schema

json
{
  "type": "object",
  "properties": {
    "partners": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "partnerId": {
            "type": "string",
            "minLength": 1
          },
          "partnerExternalId": {
            "type": "string",
            "minLength": 1
          }
        },
        "required": [
          "partnerId",
          "partnerExternalId"
        ],
        "additionalProperties": true
      }
    },
    "partnerId": {
      "type": "string",
      "minLength": 1
    },
    "partnerExternalId": {
      "type": "string",
      "minLength": 1
    },
    "eventId": {
      "type": "string",
      "minLength": 1
    },
    "customerId": {
      "type": "string",
      "minLength": 1
    },
    "milestone": {
      "type": "string",
      "minLength": 1
    },
    "status": {
      "type": "string",
      "enum": [
        "recorded",
        "revoked",
        "reinstated",
        "reversed"
      ]
    },
    "programIds": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "rewardIds": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "count": {
      "type": "integer",
      "minimum": 0
    },
    "reportEventId": {
      "type": "string",
      "minLength": 1
    },
    "reason": {
      "type": "string"
    },
    "reversalCents": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "reversedAt": {
      "type": "string",
      "format": "date-time"
    }
  },
  "required": [
    "partners",
    "eventId",
    "customerId",
    "milestone",
    "status",
    "programIds",
    "rewardIds",
    "reportEventId",
    "reversalCents",
    "reversedAt"
  ],
  "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.