curl --request POST \
--url https://api.rigaly.com/api/v1/rewards \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Free Coffee",
"description": "Any medium hot drink",
"points_cost": 500,
"conditions": "Valid for SKUs COF-M-* only",
"max_redemptions": 100,
"delivery_mode": "in_store",
"time_active": {
"monday": {
"active": true,
"start": "09:00",
"end": "17:00"
}
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Free Coffee',
description: 'Any medium hot drink',
points_cost: 500,
conditions: 'Valid for SKUs COF-M-* only',
max_redemptions: 100,
delivery_mode: 'in_store',
time_active: {monday: {active: true, start: '09:00', end: '17:00'}}
})
};
fetch('https://api.rigaly.com/api/v1/rewards', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.rigaly.com/api/v1/rewards"
payload = {
"name": "Free Coffee",
"description": "Any medium hot drink",
"points_cost": 500,
"conditions": "Valid for SKUs COF-M-* only",
"max_redemptions": 100,
"delivery_mode": "in_store",
"time_active": { "monday": {
"active": True,
"start": "09:00",
"end": "17:00"
} }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.rigaly.com/api/v1/rewards",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Free Coffee',
'description' => 'Any medium hot drink',
'points_cost' => 500,
'conditions' => 'Valid for SKUs COF-M-* only',
'max_redemptions' => 100,
'delivery_mode' => 'in_store',
'time_active' => [
'monday' => [
'active' => true,
'start' => '09:00',
'end' => '17:00'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"success": true,
"message": "<string>",
"data": {
"reward": {
"name": "Free Coffee",
"description": "<string>",
"points_cost": 500,
"active": true,
"start_date": "2023-12-25",
"end_date": "2023-12-25",
"time_active": {
"monday": {
"active": true,
"start": "09:00",
"end": "17:00"
},
"tuesday": {
"active": true,
"start": "09:00",
"end": "17:00"
}
},
"conditions": "<string>",
"cooldown_mode": "none",
"cooldown_count": 123,
"cooldown_amount": 123,
"cooldown_unit": "minute",
"absence_amount": 123,
"absence_unit": "minute",
"birthday": false,
"birthday_window_mode": "exact",
"birthday_days_before": 123,
"birthday_days_after": 123,
"tier_gate": {},
"tier_overrides": [
{}
],
"max_redemptions": 10,
"delivery_mode": "in_store",
"digital_asset_type": "code",
"digital_asset_source": "static",
"digital_asset_value": "SUMMER24",
"digital_webhook_url": "https://api.example.com/rigaly/provision",
"digital_email_delivery": false,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"business_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "standard",
"image_url": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"redemptions_count": 7,
"redemptions_remaining": 3,
"deactivated_by_limit": false,
"deactivated_by_pool": false,
"pool_remaining": 4863,
"digital_webhook_secret": "b3f1c0a9d4e2…"
}
}
}{
"success": false,
"error": {
"message": "Provide exactly one of \"user_id\" or \"identifier\""
}
}Create a reward
Creates a reward customers can redeem with points. Scheduling
(start_date/end_date), time-of-day windows (time_active),
cooldowns, birthday gating, and free-text conditions are supported —
see the guides for how conditions powers product-specific rewards.
max_redemptions caps how many times the reward can be redeemed in
total (it switches itself off at the cap), and delivery_mode chooses
whether the reward is collected in store, shipped, or delivered
digitally — see the delivery modes guide.
Digital rewards additionally pick a digital_asset_source:
static (one fixed digital_asset_value), pool (a batch of one-time
values you upload afterwards) or external (Rigaly calls your
digital_webhook_url at redemption time). Creating an external reward
returns digital_webhook_secret on the reward object once — store
it, no read endpoint ever returns it. A pool reward always comes back
switched off (active: false, deactivated_by_pool: true) — there is
nothing to hand out yet; the first upload to
POST /rewards/{id}/pool/codes opens it automatically.
curl --request POST \
--url https://api.rigaly.com/api/v1/rewards \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Free Coffee",
"description": "Any medium hot drink",
"points_cost": 500,
"conditions": "Valid for SKUs COF-M-* only",
"max_redemptions": 100,
"delivery_mode": "in_store",
"time_active": {
"monday": {
"active": true,
"start": "09:00",
"end": "17:00"
}
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Free Coffee',
description: 'Any medium hot drink',
points_cost: 500,
conditions: 'Valid for SKUs COF-M-* only',
max_redemptions: 100,
delivery_mode: 'in_store',
time_active: {monday: {active: true, start: '09:00', end: '17:00'}}
})
};
fetch('https://api.rigaly.com/api/v1/rewards', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.rigaly.com/api/v1/rewards"
payload = {
"name": "Free Coffee",
"description": "Any medium hot drink",
"points_cost": 500,
"conditions": "Valid for SKUs COF-M-* only",
"max_redemptions": 100,
"delivery_mode": "in_store",
"time_active": { "monday": {
"active": True,
"start": "09:00",
"end": "17:00"
} }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.rigaly.com/api/v1/rewards",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Free Coffee',
'description' => 'Any medium hot drink',
'points_cost' => 500,
'conditions' => 'Valid for SKUs COF-M-* only',
'max_redemptions' => 100,
'delivery_mode' => 'in_store',
'time_active' => [
'monday' => [
'active' => true,
'start' => '09:00',
'end' => '17:00'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"success": true,
"message": "<string>",
"data": {
"reward": {
"name": "Free Coffee",
"description": "<string>",
"points_cost": 500,
"active": true,
"start_date": "2023-12-25",
"end_date": "2023-12-25",
"time_active": {
"monday": {
"active": true,
"start": "09:00",
"end": "17:00"
},
"tuesday": {
"active": true,
"start": "09:00",
"end": "17:00"
}
},
"conditions": "<string>",
"cooldown_mode": "none",
"cooldown_count": 123,
"cooldown_amount": 123,
"cooldown_unit": "minute",
"absence_amount": 123,
"absence_unit": "minute",
"birthday": false,
"birthday_window_mode": "exact",
"birthday_days_before": 123,
"birthday_days_after": 123,
"tier_gate": {},
"tier_overrides": [
{}
],
"max_redemptions": 10,
"delivery_mode": "in_store",
"digital_asset_type": "code",
"digital_asset_source": "static",
"digital_asset_value": "SUMMER24",
"digital_webhook_url": "https://api.example.com/rigaly/provision",
"digital_email_delivery": false,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"business_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "standard",
"image_url": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"redemptions_count": 7,
"redemptions_remaining": 3,
"deactivated_by_limit": false,
"deactivated_by_pool": false,
"pool_remaining": 4863,
"digital_webhook_secret": "b3f1c0a9d4e2…"
}
}
}{
"success": false,
"error": {
"message": "Provide exactly one of \"user_id\" or \"identifier\""
}
}Authorizations
API key from the Rigaly dashboard: Authorization: Bearer rgly_sk_...
Body
"Free Coffee"
x >= 0500
Per-day time-of-day windows. Omit a day to leave it unrestricted; omit the whole field for always-active.
Show child attributes
Show child attributes
{
"monday": {
"active": true,
"start": "09:00",
"end": "17:00"
},
"tuesday": {
"active": true,
"start": "09:00",
"end": "17:00"
}
}
Free-text conditions shown to customers and returned on validation — use it to encode product restrictions your system enforces.
1000none, limit, once Required when cooldown_mode = limit
Required when cooldown_mode = limit
minute, hour, day, month Only offer after the customer has been absent this long (pair with absence_unit)
minute, hour, day, month birthday_days_before/after required when 'days'
exact, days, month Restrict the reward to a tier/level (mode: minimum|only)
Per-tier cooldown / early-access overrides
Global redemption cap — the reward can be redeemed this many times in
total, across all customers. null (the default) = unlimited. Only
completed redemptions count. On reaching the cap the reward is
switched off automatically (active: false, deactivated_by_limit: true)
and disappears from the customer app; raising the cap (or setting it
to null) switches it back on. Cannot be lowered below
redemptions_count.
1 <= x <= 100000010
How the reward reaches the customer — see the
delivery modes guide.
in_store: the customer gets a redemption code you validate and
complete at your counter (points are deducted on completion).
shipping: the customer submits a shipping address in the app;
points are deducted immediately and you fulfil the order via the
redemption endpoints.
digital: the customer receives a code or link instantly in the app;
points are deducted immediately.
in_store, shipping, digital What the customer receives. Required when delivery_mode is digital; must be omitted/null otherwise. An external reward's endpoint must return this exact type — a mismatch is rejected.
code, link Where the delivered value comes from — digital rewards only, and the
customer experience is identical for all three. See the
delivery modes guide.
static: one fixed digital_asset_value every customer receives.
pool: a stored batch of one-time values; each redemption consumes
exactly one, atomically — no two customers can ever get the same value.
external: Rigaly calls your digital_webhook_url at redemption time
and delivers whatever it mints.
Sending anything other than static on a non-digital reward is rejected.
static, pool, external The voucher code or URL handed to the customer. Required when digital_asset_source is static, and rejected for pool (upload the values to the reward's pool instead) and external (the endpoint supplies the value). Must be a valid http(s) URL when digital_asset_type is link. Never returned on customer-facing payloads.
1 - 500"SUMMER24"
HTTPS endpoint Rigaly POSTs to at redemption time to mint the
value. Required when digital_asset_source is external, rejected
otherwise. Must be https, carry no embedded credentials, and
resolve to a public address — private, loopback, link-local and
cloud-metadata hosts are refused at save time. Creating a reward as
external, or switching an existing one to external, returns
digital_webhook_secret once; changing only the URL afterwards
does not rotate it.
500"https://api.example.com/rigaly/provision"
Digital rewards only — also email the code/link to the customer when they redeem.