CRM gifts
A CRM or marketing automation system sends a gift when a player reaches a journey step, such as a birthday, a deposit milestone, or a win-back. The CRM picks the segment, creates one personal link for each player, and sends it through its own channel.
Requires: a key with the PERSONAL_LINKS scope, and a webhook URL to follow claims.
Set up campaigns
Section titled “Set up campaigns”Ask your Luxorr contact for one campaign for each journey type, such as “VIP birthday” or “Deposit milestone”. A campaign holds the gifts a player can choose from, under one or more of your brands.
To find each campaign’s ID, call GET /campaigns, or copy the ID from the campaign’s page in the Luxorr workspace. Store the ID with the journey step.
Ask your team for an order field that holds your player ID, such as “Customer ID”. GET /me lists it in tenant.customFields, with its id.
Create a link for each player
Section titled “Create a link for each player”When a player reaches the step, create their link:
POST /v1/personal-linksIdempotency-Key: birthday-2026:player-1001{ "campaignId": "1e2d3c4b-5a69-4c1f-9a52-8d0e4f4b9a3e", "fullName": "Alice Smith", "message": "Happy birthday from the VIP team!", "locale": "en-US", "customFields": [ { "fieldId": "5c4b3a29-1807-4f6e-8d5c-4b3a29180746", "textValue": "player-1001" } ]}Keep the following in mind:
- Build the
Idempotency-Keyfrom the occasion and the player. If the journey runs again for the same player, or your job fails and reruns the segment, the same key returns the first link instead of a second gift. A replay lasts 7 days. After that, the same key creates a new link. - After a timeout or a
5xxcode, send the same request again with the same key. A different body with the same key returns422 idempotency_key_reused. - After
400 invalid_request, nothing was created.errors[]names each field, for example a language that isn’t enabled for your account (GET /melists them intenant.locales), or a missing required custom field. Fix the player’s data, and send the request again. - The link lasts as long as its campaign. Its
expiresAtshows when it ends, so you can add a “claim by” date to your message.nullmeans no end date. The link expires when the campaign ends or passes that date.
Store the link id and claimUrl with the player.
Deliver the link
Section titled “Deliver the link”Put claimUrl in your message: email, push, in-app inbox, or chat. The gift site shows your brand.
If your account requires approval, links start as REQUESTED and the player can’t claim them yet. Send the message after personal_link.approved arrives.
Update the journey
Section titled “Update the journey”Every event carries the whole link, including its customFields. Match an event to your player by the field that holds your player ID, or by the link id you stored.
The following table shows what each event means for the journey:
| Event | Meaning |
|---|---|
personal_link.approved |
Your team approved the link. Send it now. |
personal_link.claimed |
The player chose a gift. Mark the step done. |
personal_link.cancelled |
The link was withdrawn. Stop reminders. |
personal_link.expired |
The campaign ended, and the link with it. Stop reminders. |
personal_link.created |
A link was created outside your journey, for example in the workspace. Links that your key created are in the create response and the feed, not in webhooks. |
If your system processes events in batches, read the event feed on a schedule instead. The feed keeps 30 days of events and is the way to sync link changes.
Send reminders and cancel links
Section titled “Send reminders and cancel links”To send a reminder, use the same claimUrl. To withdraw a link that your key created, call POST /personal-links/{linkId}:cancel with a reason. A retry is safe with or without an Idempotency-Key. The player then sees the link as expired. If your team created the link, the API returns 409 not_cancellable with reason: "created_elsewhere".

