IntegrationsWebhooks
Payload Examples
Worked webhook deliveries for the events most integrations start with — an entity snapshot, a grant, a usage signal, an evaluation, a deployment — on the Kaiten Sushi Shop.
Every delivery carries the same three fields — name, type, data — plus an optional headers object, and the event catalog names the schema data follows for each event. The examples below are illustrative deliveries on the seeded Kaiten Sushi Shop: the values are the seed's, the identifiers are abbreviated, and the timestamps are examples — the seeder dates its records relative to the moment it runs. Records the seeder writes name the Ops Team service account as their actor. The field-by-field contract for every event is in the generated API reference's Webhooks group.
Two field conventions run through data, and both are exactly what the reference shows. Entity snapshots — the same objects the REST API returns — use camelCase (externalCustomerId, licenseSlug). Change records, specific to one event, use snake_case (entitlement_slug, flag_slug). Event name values are upper snake case; type strings are dot-separated with snake_case segments.
The optional headers object
A delivery can carry a fourth field beside name, type and data: headers, an object of metadata about the event. It is optional — present when the event has metadata to carry — and a handler should ignore the keys it does not read.
| Key | Content |
|---|---|
instance_id | The id of the Instance the event concerns. Set on every event of the Instances domain: the instance's own changes, and every usage event |
traceparent | The W3C trace context of the request that produced the event |
headers.instance_id is where a usage event names its Instance. The usage payloads — EntitlementUsage, the report outcomes, the threshold and cap records — identify the entitlement, and EntitlementUsage the License too; the Instance travels beside them, in headers. The examples below show headers where it names an Instance.
CUSTOMER_CREATED
Sakura Tokyo is created with the CRM's record id on externalCustomerId — the BYO-ID your consumer matches on without a lookup table.
{
"name": "CUSTOMER_CREATED",
"type": "com.kaiten.customer.v1.created",
"data": {
"id": "8e41…",
"name": "Sakura Tokyo",
"slug": "sakura-tokyo",
"externalCustomerId": "crm-1024",
"createdAt": "2026-07-01T09:12:40Z",
"createdBy": { "id": "…", "name": "Ops Team" },
"updatedAt": "2026-07-01T09:12:40Z",
"updatedBy": { "id": "…", "name": "Ops Team" }
}
}INSTANCE_CREATED
The Instance snapshot carries both the ids and the slugs of what it is attached to — the customer, the License version, the deployment zone — so a consumer needs no second call to name them. sakura-tokyo-prod is pinned to premium-v2, the version the Premium family serves.
{
"name": "INSTANCE_CREATED",
"type": "com.kaiten.instance.v1.created",
"data": {
"id": "c2f7…",
"name": "Sakura Tokyo Production",
"slug": "sakura-tokyo-prod",
"description": "Production environment for the Sakura Tokyo restaurant group.",
"customerId": "8e41…",
"customerSlug": "sakura-tokyo",
"licenseId": "5d09…",
"licenseSlug": "premium-v2",
"deploymentZoneId": "a713…",
"deploymentZoneSlug": "sakura-dedicated",
"startLicenseDate": "2026-07-01T00:00:00Z",
"endLicenseDate": "2027-07-01T00:00:00Z",
"status": "HEALTHY",
"metadata": { "environment": "production" },
"createdAt": "2026-07-01T09:20:11Z",
"createdBy": { "id": "…", "name": "Ops Team" },
"updatedAt": "2026-07-01T09:20:11Z",
"updatedBy": { "id": "…", "name": "Ops Team" }
},
"headers": {
"instance_id": "c2f7…",
"traceparent": "00-…-…-01"
}
}headers.instance_id repeats data.id here; on the usage events below it is the only place the Instance appears.
LICENSE_ENTITLEMENT_ASSIGNED
The contract changes: monthly-orders is granted at 1,000 on premium-v2. A grant belongs to one version of a License, so the payload names that version's slug. The value is typed — number, boolean, or object — exactly as it was written on the grant.
{
"name": "LICENSE_ENTITLEMENT_ASSIGNED",
"type": "com.kaiten.license.entitlement.v1.assigned",
"data": {
"licenseId": "5d09…",
"licenseSlug": "premium-v2",
"entitlementName": "Monthly Orders",
"entitlementSlug": "monthly-orders",
"entitlementType": "NUMBER",
"value": { "type": "number", "value": 1000 },
"limitCapExceededOveragePercent": 20,
"createdAt": "2026-07-01T10:05:00Z",
"createdBy": { "id": "…", "name": "Ops Team" },
"updatedAt": "2026-07-01T10:05:00Z",
"updatedBy": { "id": "…", "name": "Ops Team" }
}
}ENTITLEMENT_USAGE_REPORT_ACCEPTED
Sakura Tokyo processes one more order on top of the 730 the seed records this month. A change record: the report's behavior and value, the count of reports folded into the current window — this one included — and whether it was persisted. The record names the entitlement; headers.instance_id names the Instance that reported — sakura-tokyo-prod, by the id INSTANCE_CREATED delivered above.
{
"name": "ENTITLEMENT_USAGE_REPORT_ACCEPTED",
"type": "com.kaiten.instance.entitlement.v1.usage_report_accepted",
"data": {
"entitlement_slug": "monthly-orders",
"behavior": "append",
"value": 1,
"event_count": 731,
"status": "ACCEPTED"
},
"headers": {
"instance_id": "c2f7…",
"traceparent": "00-…-…-01"
}
}A report refused because it would take usage past the grant's maximum — the granted value at a hard cap (limit_cap_exceeded_overage_percent of 0), or the value plus its allowance — is delivered as ENTITLEMENT_USAGE_REPORT_REJECTED with the same shape and "status": "REJECTED".
INSTANCE_ENTITLEMENT_USAGE_REACHED
Ninja Osaka publishes its fifth menu item on a Starter license that grants five. Usage lands exactly on the grant, and the event carries the resolved usage — the value measured, the limit it is measured against — for the entitlement and license concerned. The Instance, ninja-osaka-prod, is named by its id in headers.instance_id.
{
"name": "INSTANCE_ENTITLEMENT_USAGE_REACHED",
"type": "com.kaiten.instance.entitlement.v1.usage_reached",
"data": {
"entitlementId": "1b2c…",
"entitlementSlug": "menu-items",
"licenseId": "e0a4…",
"licenseSlug": "starter",
"value": { "type": "number", "value": 5, "event_count": 4 },
"limit": { "type": "number", "value": 5 }
},
"headers": {
"instance_id": "7ab3…",
"traceparent": "00-…-…-01"
}
}currentPeriodStart and currentPeriodEnd appear on this payload when the entitlement has a reset period; menu-items is a lifetime gauge, so they are absent here.
FEATURE_FLAG_EVALUATED
Sakura Tokyo's product evaluates delivery-tracking-enabled. The rule Delivery tracking entitlement granted reads the delivery-tracking entitlement, matches, and serves on. The payload names the flag, the variant, the reason, and the rule — and carries no evaluation context, so nothing the caller sent leaves your product.
{
"name": "FEATURE_FLAG_EVALUATED",
"type": "com.kaiten.feature_flag.v1.evaluated",
"data": {
"flag_id": "9f31…",
"flag_slug": "delivery-tracking-enabled",
"variant": "on",
"reason": "TARGETING_MATCH",
"matched_rule_name": "Delivery tracking entitlement granted"
}
}RELEASE_DEPLOYED
Release 2026.8.0 lands on the shared-apac zone. The payload is the Deployment journal entry itself: which release, which zone, when, and who recorded it.
{
"name": "RELEASE_DEPLOYED",
"type": "com.kaiten.deployment_zone.v1.release_deployed",
"data": {
"id": "4c88…",
"releaseId": "72be…",
"deploymentZoneId": "3e5f…",
"createdAt": "2026-08-13T09:00:00Z",
"createdBy": { "id": "…", "name": "Ops Team" }
}
}Where to go next
- Event catalog — every event, with the schema its
datafollows - Verifying signatures — before acting on any of these in production
- Consuming events — the same
data, as the outbox row'spayload, on a self-hosted stack