reward.award-granted
Version 2 of the reward.award-granted webhook event.
One award settled in Reward Management: one of the six system kinds - a badge, achievement, medal, trophy, prize, or organization badge - or a kind the tenant published in its own registry. Every trigger produces exactly one durable award record and this one outcome: applied when the holding was recorded (and any value settled through the grant spine as grantId), rejected when the trigger could not be honored (missing definition, duplicate holding, or a spine rejection), and unresolved when the recipient could not be attributed to a Player yet. An unresolved award is a settled record awaiting an operator, never a dropped delivery.
| Event type | reward.award-granted |
| Schema version | 2 |
| Routing key | event.reward.award-granted.v2 |
| Produced by | Reward Management |
| Schema | urn:defendr:contract:reward:award-granted:2 |
data fields
| Field | Type | Required | Description |
|---|---|---|---|
awardId | string | yes | |
awardKey | string | yes | |
kind | "achievement", "badge", "medal", "trophy", "prize", "organization-badge" or string | yes | A system award kind or a canonical lowercase-slug kind the tenant published in its own registry. Custom kinds are off-chain only. |
subjectType | "player", "organization" | yes | |
playerId | string or null | yes | |
organizationId | string or null | yes | |
status | "applied", "rejected", "unresolved" | yes | |
provenance | "gamification-mission", "gamification-battle-pass", "gamification-chest", "gamification-leaderboard", "tournament-award", "player-action", "operator-grant", "shop-purchase", "membership-grant", "reward-key", "unknown", "gamification-quiz" | yes | |
grantId | string or null | yes | |
rejection | object or null | yes | |
rejection.code | string | yes | |
rejection.reason | string | yes | |
trigger | object | yes | |
trigger.type | string | yes | |
trigger.messageId | string | yes | |
awardedAt | string (date-time) | yes |
Some fields are required only in particular states. The JSON Schema below is authoritative.
Example delivery
Signed with the example secret whsec_placeholder_example_webhooks_signing_secret, so you can check your verifier against it. See Verifying signatures.
POST /your/webhook/endpoint HTTP/1.1
content-type: application/json
webhook-id: whd_00000000-0000-4000-8000-000000000022
webhook-timestamp: 1800000000
webhook-signature: v1,5A5do/irC69YE3vJPWwyowaC1DEIb1eOnk5cxDnFRKg=
tanitar-event-type: reward.award-granted
tanitar-schema-version: 2
tanitar-delivery-attempt: 1
{"messageId":"evt_00000000-0000-4000-8000-000000000022","kind":"event","type":"reward.award-granted","schemaVersion":2,"occurredAt":"2027-01-15T10:00:00.000Z","producer":"reward-management-service","accountId":"acc_11111111-1111-4111-8111-111111111111","correlationId":"corr_00000000-0000-4000-8000-000000000022","data":{"awardId":"awd_demo","awardKey":"first-blood","kind":"loyalty-tier","subjectType":"player","playerId":"player_demo","organizationId":null,"status":"applied","provenance":"gamification-mission","grantId":null,"rejection":null,"trigger":{"type":"gamification.badge-award-intended","messageId":"msg_demo"},"awardedAt":"2026-09-10T00:00:00.000Z"}}The same body, formatted:
{
"messageId": "evt_00000000-0000-4000-8000-000000000022",
"kind": "event",
"type": "reward.award-granted",
"schemaVersion": 2,
"occurredAt": "2027-01-15T10:00:00.000Z",
"producer": "reward-management-service",
"accountId": "acc_11111111-1111-4111-8111-111111111111",
"correlationId": "corr_00000000-0000-4000-8000-000000000022",
"data": {
"awardId": "awd_demo",
"awardKey": "first-blood",
"kind": "loyalty-tier",
"subjectType": "player",
"playerId": "player_demo",
"organizationId": null,
"status": "applied",
"provenance": "gamification-mission",
"grantId": null,
"rejection": null,
"trigger": {
"type": "gamification.badge-award-intended",
"messageId": "msg_demo"
},
"awardedAt": "2026-09-10T00:00:00.000Z"
}
}JSON Schema
urn:defendr:contract:reward:award-granted:2
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:defendr:contract:reward:award-granted:2",
"title": "Reward award granted event payload",
"description": "One award settled in Reward Management: one of the six system kinds - a badge, achievement, medal, trophy, prize, or organization badge - or a kind the tenant published in its own registry. Every trigger produces exactly one durable award record and this one outcome: `applied` when the holding was recorded (and any value settled through the grant spine as `grantId`), `rejected` when the trigger could not be honored (missing definition, duplicate holding, or a spine rejection), and `unresolved` when the recipient could not be attributed to a Player yet. An unresolved award is a settled record awaiting an operator, never a dropped delivery.",
"type": "object",
"additionalProperties": false,
"required": [
"awardId",
"awardKey",
"kind",
"subjectType",
"playerId",
"organizationId",
"status",
"provenance",
"grantId",
"rejection",
"trigger",
"awardedAt"
],
"properties": {
"awardId": {
"type": "string",
"minLength": 1
},
"awardKey": {
"type": "string",
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
},
"kind": {
"description": "A system award kind or a canonical lowercase-slug kind the tenant published in its own registry. Custom kinds are off-chain only.",
"anyOf": [
{
"enum": [
"achievement",
"badge",
"medal",
"trophy",
"prize",
"organization-badge"
]
},
{
"type": "string",
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
"maxLength": 64
}
]
},
"subjectType": {
"enum": [
"player",
"organization"
]
},
"playerId": {
"type": [
"string",
"null"
]
},
"organizationId": {
"type": [
"string",
"null"
]
},
"status": {
"enum": [
"applied",
"rejected",
"unresolved"
]
},
"provenance": {
"$ref": "urn:defendr:contract:common:source-provenance:1"
},
"grantId": {
"type": [
"string",
"null"
]
},
"rejection": {
"type": [
"object",
"null"
],
"additionalProperties": false,
"required": [
"code",
"reason"
],
"properties": {
"code": {
"type": "string",
"pattern": "^[A-Z0-9_]+$"
},
"reason": {
"type": "string",
"minLength": 1
}
}
},
"trigger": {
"type": "object",
"additionalProperties": false,
"required": [
"type",
"messageId"
],
"properties": {
"type": {
"type": "string",
"minLength": 1
},
"messageId": {
"type": "string",
"minLength": 1
}
}
},
"awardedAt": {
"type": "string",
"format": "date-time"
}
},
"allOf": [
{
"if": {
"type": "object",
"required": [
"status"
],
"properties": {
"status": {
"const": "applied"
}
}
},
"then": {
"type": "object",
"properties": {
"rejection": {
"type": "null"
}
}
}
},
{
"if": {
"type": "object",
"required": [
"status"
],
"properties": {
"status": {
"const": "rejected"
}
}
},
"then": {
"type": "object",
"properties": {
"grantId": {
"type": "null"
},
"rejection": {
"type": "object"
}
}
}
},
{
"if": {
"type": "object",
"required": [
"status"
],
"properties": {
"status": {
"const": "unresolved"
}
}
},
"then": {
"type": "object",
"properties": {
"grantId": {
"type": "null"
},
"rejection": {
"type": "null"
},
"playerId": {
"type": "null"
}
}
}
}
]
}