curl --request POST \
--url https://api.mageloyalty.com/v1/webhook-subscriptions \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"url": "https://example.com/webhooks/mage",
"events": ["points.earned", "customer.tier_upgrade"],
"description": "Production points + tier sync"
}'
const response = await fetch("https://api.mageloyalty.com/v1/webhook-subscriptions", {
method: "POST",
headers: {
Authorization: "<api-key>",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com/webhooks/mage",
events: ["points.earned", "customer.tier_upgrade"],
description: "Production points + tier sync",
}),
});
const data = await response.json();
import requests
response = requests.post(
"https://api.mageloyalty.com/v1/webhook-subscriptions",
headers={"Authorization": "<api-key>"},
json={
"url": "https://example.com/webhooks/mage",
"events": ["points.earned", "customer.tier_upgrade"],
"description": "Production points + tier sync",
},
)
data = response.json()
<?php
$ch = curl_init("https://api.mageloyalty.com/v1/webhook-subscriptions");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"url" => "https://example.com/webhooks/mage",
"events" => ["points.earned", "customer.tier_upgrade"],
"description" => "Production points + tier sync",
]),
]);
$data = json_decode(curl_exec($ch), true);
{
"data": {
"type": "webhook_subscription",
"id": "whsub_abc123",
"attributes": {
"url": "https://example.com/webhooks/mage",
"events": ["points.earned", "customer.tier_upgrade"],
"is_active": true,
"description": "Production points + tier sync",
"secret": "9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a",
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}
}
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "url is required"
}
]
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "url must be a valid URL"
}
]
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "events must be a non-empty array"
}
]
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "Invalid event(s): points.created. Valid events: points.earned, points.redeemed, customer.tier_upgrade, customer.tier_downgrade"
}
]
}
Managing Subscriptions
Create a webhook subscription
Register a URL to receive loyalty event notifications and get a signing secret.
POST
/
v1
/
webhook-subscriptions
curl --request POST \
--url https://api.mageloyalty.com/v1/webhook-subscriptions \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"url": "https://example.com/webhooks/mage",
"events": ["points.earned", "customer.tier_upgrade"],
"description": "Production points + tier sync"
}'
const response = await fetch("https://api.mageloyalty.com/v1/webhook-subscriptions", {
method: "POST",
headers: {
Authorization: "<api-key>",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com/webhooks/mage",
events: ["points.earned", "customer.tier_upgrade"],
description: "Production points + tier sync",
}),
});
const data = await response.json();
import requests
response = requests.post(
"https://api.mageloyalty.com/v1/webhook-subscriptions",
headers={"Authorization": "<api-key>"},
json={
"url": "https://example.com/webhooks/mage",
"events": ["points.earned", "customer.tier_upgrade"],
"description": "Production points + tier sync",
},
)
data = response.json()
<?php
$ch = curl_init("https://api.mageloyalty.com/v1/webhook-subscriptions");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"url" => "https://example.com/webhooks/mage",
"events" => ["points.earned", "customer.tier_upgrade"],
"description" => "Production points + tier sync",
]),
]);
$data = json_decode(curl_exec($ch), true);
{
"data": {
"type": "webhook_subscription",
"id": "whsub_abc123",
"attributes": {
"url": "https://example.com/webhooks/mage",
"events": ["points.earned", "customer.tier_upgrade"],
"is_active": true,
"description": "Production points + tier sync",
"secret": "9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a",
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}
}
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "url is required"
}
]
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "url must be a valid URL"
}
]
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "events must be a non-empty array"
}
]
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "Invalid event(s): points.created. Valid events: points.earned, points.redeemed, customer.tier_upgrade, customer.tier_downgrade"
}
]
}
Register an HTTPS endpoint to receive webhook deliveries for the events you select. Mage Loyalty signs every delivery with the signing secret returned here, so you can verify that requests are genuine.
The
secret is returned only in this 201 Created response. It is shown once and never again. Store it securely. If you lose it, rotate the secret to issue a new one. See Verifying webhook signatures for how to use it.Request body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The HTTPS endpoint that will receive deliveries. Must be a valid URL |
events | string[] | Yes | A non-empty array of events to subscribe to. Valid events: points.earned, points.redeemed, customer.tier_upgrade, customer.tier_downgrade |
description | string | No | Optional label to help you identify the subscription |
Response
Returns201 Created with the new subscription, including the secret.
Errors
| Status | Scenario |
|---|---|
400 | url missing, url not a valid URL, events empty or missing, one or more events invalid, or invalid JSON |
401 | Missing or invalid API key |
403 | The API key is read-only and cannot perform write operations |
429 | Rate limit exceeded (6 requests/second) |
curl --request POST \
--url https://api.mageloyalty.com/v1/webhook-subscriptions \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"url": "https://example.com/webhooks/mage",
"events": ["points.earned", "customer.tier_upgrade"],
"description": "Production points + tier sync"
}'
const response = await fetch("https://api.mageloyalty.com/v1/webhook-subscriptions", {
method: "POST",
headers: {
Authorization: "<api-key>",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com/webhooks/mage",
events: ["points.earned", "customer.tier_upgrade"],
description: "Production points + tier sync",
}),
});
const data = await response.json();
import requests
response = requests.post(
"https://api.mageloyalty.com/v1/webhook-subscriptions",
headers={"Authorization": "<api-key>"},
json={
"url": "https://example.com/webhooks/mage",
"events": ["points.earned", "customer.tier_upgrade"],
"description": "Production points + tier sync",
},
)
data = response.json()
<?php
$ch = curl_init("https://api.mageloyalty.com/v1/webhook-subscriptions");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"url" => "https://example.com/webhooks/mage",
"events" => ["points.earned", "customer.tier_upgrade"],
"description" => "Production points + tier sync",
]),
]);
$data = json_decode(curl_exec($ch), true);
{
"data": {
"type": "webhook_subscription",
"id": "whsub_abc123",
"attributes": {
"url": "https://example.com/webhooks/mage",
"events": ["points.earned", "customer.tier_upgrade"],
"is_active": true,
"description": "Production points + tier sync",
"secret": "9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a",
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}
}
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "url is required"
}
]
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "url must be a valid URL"
}
]
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "events must be a non-empty array"
}
]
}
{
"errors": [
{
"status": "400",
"title": "Bad Request",
"detail": "Invalid event(s): points.created. Valid events: points.earned, points.redeemed, customer.tier_upgrade, customer.tier_downgrade"
}
]
}
⌘I