Daily Reward Webhook
The daily_reward.get webhook resolves which items a player receives from a daily reward program. When a program is configured to be webhook-driven, Aghanim calls your server to ask which items to grant per day (and for the extra reward), and builds the player-facing reward based on your response in real time.
The webhook serves two kinds of programs:
- Basic, schedule, and seasonal programs with a webhook selected. Your response sets the items, and Aghanim runs the cycle.
- Custom programs. Your response also decides when each reward opens and when a new cycle starts. See Daily Rewards for how they look on the game hub.
This webhook is triggered in the following cases:
- A player opens the daily reward widget in the game hub.
- A player claims a daily reward.
If your server does not respond, responds with a non-2xx status, times out, or returns an invalid body, Aghanim falls back to the program's static rewards. Selecting a webhook for a program clears those rewards, though, so in practice the program shows no rewards and claims fail. Custom programs have no static rewards at all. See Errors in custom programs.
Requirements
To use the daily_reward.get webhook from Aghanim, configure your webhook server as follows:
- HTTPS endpoint, accepting POST webhook requests.
- Listen for events generated and signed by Aghanim.
- Respond with
2xxstatus codes and a JSON body describing the reward items. - Respond quickly. Slow responses degrade the hub experience, and a timeout leaves the program without rewards.
Configuration
- Develop a function for the
daily_reward.getwebhook processing. - Make your endpoint available.
- Register your endpoint within your Aghanim account → Game → Webhooks → Add webhook by choosing the
daily_reward.getevent type. - In the daily reward program settings, select the webhook so the program resolves its items through it. Custom programs require a webhook.
- Place the daily reward widget on your game hub page so players can open it and trigger the webhook.
Alternatively, you can register your endpoint within Aghanim using the Create Webhook API method.
Trigger values
| Value | Description |
|---|---|
hub.interact | When the player opens the daily reward widget in the game hub. |
hub.daily_reward_claim | When the player claims a daily reward — to resolve the items to grant. For custom programs, it's a pre-check before the claim. See Claims in custom programs. |
test | When using the "Send test event" in the Dashboard. |
See the full events and triggers matrix for how daily_reward.get relates to other event types.
Request schema
Below is an example of an daily_reward.get webhook request:
- HTTP
- cURL
POST /your/webhook/uri HTTP/1.1
Content-Type: application/json
Host: your-webhook-endpoint.com
User-Agent: Aghanim/0.1.0
X-Aghanim-Signature: 2e45ed4dede5e09506717490655d2f78e96d4261040ef48cc623a780bda38812
X-Aghanim-Signature-Timestamp: 1725548450
{
"event_type": "daily_reward.get",
"event_data": {
"player_id": "2D2R-OP3C",
"id": "dlrwd_eAeXgQGcaie",
"key": "season-1",
"is_anonymous": false
},
"event_time": 1725548450,
"event_id": "whevt_eCacGbJVbvToOgzjXUgOCitkQE",
"idempotency_key": null,
"request_id": "d1593e9c-c291-4004-8846-6679c2e5810b",
"sandbox": false,
"trigger": "hub.interact",
"transaction_id": "whtx_eCacGbJVbvT",
"context": null,
"game_id": "gm_exTAyxPsVwh"
}
curl "https://your-webhook-endpoint.com/your/webhook/uri" \
-X POST \
-H "Content-Type: application/json" \
-H "User-Agent: Aghanim/0.1.0" \
-H "X-Aghanim-Signature: 2e45ed4dede5e09506717490655d2f78e96d4261040ef48cc623a780bda38812" \
-H "X-Aghanim-Signature-Timestamp: 1725548450" \
-d '{
"event_type": "daily_reward.get",
"event_data": {
"player_id": "2D2R-OP3C",
"id": "dlrwd_eAeXgQGcaie",
"key": "season-1",
"is_anonymous": false
},
"event_time": 1725548450,
"event_id": "whevt_eCacGbJVbvToOgzjXUgOCitkQE",
"idempotency_key": null,
"request_id": "d1593e9c-c291-4004-8846-6679c2e5810b",
"sandbox": false,
"trigger": "hub.interact",
"transaction_id": "whtx_eCacGbJVbvT",
"context": null,
"game_id": "gm_exTAyxPsVwh"
}'
The Event schema
| Key | Type | Description |
|---|---|---|
event_id | string | Unique Event ID generated by Aghanim. |
game_id | string | Your game ID in the Aghanim system. |
event_type | string | The type of the event, daily_reward.get in this case. |
event_time | number | The time the event was sent, in Unix epoch time. May differ across duplicate deliveries of the same event. |
event_data | EventData | Contains the event-specific data, with possible keys for inherited objects. |
idempotency_key | string|null | Ensures webhook actions are executed only once, even if retried. Can be null depending on event type. |
request_id | string|null | If the event was triggered by an API request, the request ID is included. |
sandbox | boolean | Indicates whether the event was sent from the sandbox game environment. |
trigger | string|null | The trigger that caused the event to be sent. |
transaction_id | string | The transaction ID generated by Aghanim. This ID may be the same for multiple events emitted within the same transaction. |
context | EventContext|null | Contextual information about the event. |
The EventContext schema
| Key | Type | Description |
|---|---|---|
order | OrderContext|null | Order information associated with the event if applicable. |
player | PlayerContext|null | (Optional) Player information. To add this, enable "Add player context" in the webhook settings. |
The EventData schema
| Key | Type | Description |
|---|---|---|
player_id | string | The unique Player ID chosen for player authentication. |
id | string | Unique daily reward program ID generated by Aghanim. |
key | string|null | Game-defined key of the daily reward program. |
is_anonymous | boolean | Indicates whether the current user is unauthenticated (anonymous). |
progress | DailyRewardProgress | The player's progress in the current cycle. Sent only for custom programs and authenticated players. |
The DailyRewardProgress schema
| Key | Type | Description |
|---|---|---|
cycle_number | number | Number of the current cycle, assigned by Aghanim. Starts at 1. |
claims | DailyRewardClaim[] | Days the player has claimed in the current cycle. Empty until the first claim in the cycle. |
The DailyRewardClaim schema
| Key | Type | Description |
|---|---|---|
day_number | number | The claimed day. |
claimed_at | number | When the day was claimed, in Unix epoch time, in seconds. |
Below is an example of event_data for a custom program, where the player has claimed days 1 and 2 of the third cycle:
{
"id": "dlrwd_eAeXgQGcaie",
"key": "daily",
"player_id": "2D2R-OP3C",
"is_anonymous": false,
"progress": {
"cycle_number": 3,
"claims": [
{ "day_number": 1, "claimed_at": 1791100000 },
{ "day_number": 2, "claimed_at": 1791200000 }
]
}
}
For a player who hasn't claimed anything yet, progress is { "cycle_number": 1, "claims": [] }.
Anonymous players have no progress: the request carries is_anonymous: true and no progress block. For a custom program, respond as you would to a new player, with cycle_number set to 1, the current day (usually day 1) with its available_at, and the final day. Anonymous players can't claim rewards. The hub shows them the final reward and keeps the other slots closed, with a countdown on the current day if it hasn't opened yet.
Response schema
Return 200 OK with a JSON payload. Its shape depends on the program type:
Response for basic, schedule, and seasonal programs
The response fully replaces the program's rewards: list every day of the cycle and the extra reward if there is one. For example, if you return days 1–3 for a 7-day program, the program has 3 days. If you omit extra_reward_items, the program has no extra reward.
| Key | Type | Description | Required? |
|---|---|---|---|
days | DailyRewardDay[] | Items granted per reward day. At least one day, in ascending order and numbered consecutively from 1 without gaps. | Yes |
extra_reward_items | DailyRewardItem[] | Items granted for the extra reward. | No |
If none of a day's SKUs match your catalog, the day drops out of the program. If one of these programs gets a response with cycle_number, which is meant for custom programs, Aghanim ignores it and treats it as a failed call, so the program shows no rewards.
The DailyRewardDay schema
| Key | Type | Description | Required? |
|---|---|---|---|
day_number | number | Reward day the items belong to (≥ 1). | Yes |
items | DailyRewardItem[] | Items granted for the day (1–10 items). | Yes |
Example response
{
"days": [
{
"day_number": 1,
"items": [
{ "sku": "sword-001", "quantity": 1 },
{ "sku": "coins-pack", "quantity": 500 }
]
},
{
"day_number": 2,
"items": [
{ "sku": "shield-001" }
]
}
],
"extra_reward_items": [
{ "sku": "gem-pack", "quantity": 10 }
]
}
Response for custom programs
Return the current state of the player's cycle: the cycle number, the current day, and the final day. Aghanim uses cycle_number to recognize a custom response, so a custom response without it is invalid.
| Key | Type | Description | Required? |
|---|---|---|---|
cycle_number | number | progress.cycle_number to continue the current cycle, or progress.cycle_number + 1 to start a new one. See Cycles in custom programs. | Yes |
days | CustomDailyRewardDay[] | One or two days in ascending day_number order, with no repeats: the current day first, then the final day. If the current day is the final one, send only that day. | Yes |
extra_reward_items isn't allowed: custom programs have no extra reward.
The CustomDailyRewardDay schema
| Key | Type | Description | Required? |
|---|---|---|---|
day_number | number | Position of the reward in the cycle (≥ 1). It isn't tied to the calendar: your server decides when each reward opens. The final day's number is the cycle length, up to 365 days. | Yes |
available_at | number | When the day opens, in Unix epoch time, in seconds. Once this moment has passed, the day is open and the player can claim it. A time in the past is fine. For the final day, it only drives the countdown on the final slot. | For the current day |
items | DailyRewardItem[] | Items granted for the day (1–10 items). | Yes |
A response that breaks any of these rules fails validation and is handled as an error. See Errors in custom programs.
Example response
The request in this example arrived at 1791300000 with days 1 and 2 claimed. Day 3 opens an hour later, and the final day 7 four days after that.
{
"cycle_number": 3,
"days": [
{
"day_number": 3,
"available_at": 1791303600,
"items": [{ "sku": "coins", "quantity": 500 }]
},
{
"day_number": 7,
"available_at": 1791649200,
"items": [
{ "sku": "coins", "quantity": 5000 },
{ "sku": "boost" }
]
}
]
}
The DailyRewardItem schema
| Key | Type | Description | Required? |
|---|---|---|---|
sku | string | SKU of the item granted for the reward. Must match a SKU in your catalog. | Yes |
quantity | number|null | Item quantity. Falls back to the item's default when omitted. | No |
metadata | object|null | Custom key-value pairs for the item to support additional logic on your end. | No |
SKUs that do not match an item in the game's Aghanim catalog are silently ignored.
Cycles in custom programs
Every request for a custom program carries progress.cycle_number. Respond with the same number to continue the cycle, or with the number plus one to start a new cycle.
When the player claims the final day, respond with the next cycle straight away: cycle_number + 1 and its day 1 with an available_at. Until that moment, the player sees the completed cycle and a countdown. Once day 1 opens, Aghanim starts the new cycle, and the following requests carry the new cycle_number with empty claims. To reset a cycle midway, respond the same way.
A new cycle starts only when all of the following are true:
cycle_numberin your response is one more thanprogress.cycle_number.- The player has claimed at least one day in the current cycle.
- The
available_atof day 1 in the new cycle has passed.
After the switch, requests carry the new number, so responding with it again continues the cycle.
The 7-day cycle example walks through a full cycle with requests and responses.
Claims in custom programs
When a player claims a day, Aghanim calls the webhook with the hub.daily_reward_claim trigger. It's a pre-check: respond with the current state as usual and don't record the claim on your side. The request doesn't say which day the player claims.
The player gets the reward only if, according to this fresh response, the day is the current one and its available_at has passed. Aghanim then records the claim and delivers the items with the item.add webhook, where context.daily_reward.day_number holds the claimed day. The claim also shows up in progress.claims of the following requests.
To refuse a claim, return an available_at in the future or a different current day.
Errors in custom programs
If your server responds with an error, returns an invalid body, or doesn't respond within 10 seconds, the claim fails and the player gets nothing. Custom programs don't fall back to static rewards. If this happens when the player opens the widget, the hub can't show the reward days.
Need help? Contact our integration team at integration@aghanim.com
Need help?
Contact our integration team at integration@aghanim.com