curl --request POST \
--url https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email": "referrer@example.com",
"first_name": "Ada",
"ip_address": "203.0.113.42"
}
'import requests
url = "https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations"
payload = {
"email": "referrer@example.com",
"first_name": "Ada",
"ip_address": "203.0.113.42"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({email: 'referrer@example.com', first_name: 'Ada', ip_address: '203.0.113.42'})
};
fetch('https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations",
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([
'email' => 'referrer@example.com',
'first_name' => 'Ada',
'ip_address' => '203.0.113.42'
]),
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;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations"
payload := strings.NewReader("{\n \"email\": \"referrer@example.com\",\n \"first_name\": \"Ada\",\n \"ip_address\": \"203.0.113.42\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"referrer@example.com\",\n \"first_name\": \"Ada\",\n \"ip_address\": \"203.0.113.42\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"referrer@example.com\",\n \"first_name\": \"Ada\",\n \"ip_address\": \"203.0.113.42\"\n}"
response = http.request(request)
puts response.read_body{
"referral_urls": {
"direct": "<string>",
"facebook": "<string>",
"twitter": "<string>",
"email": "<string>",
"whatsapp": "<string>",
"instagram": "<string>",
"device_share": "<string>"
}
}{
"error": {
"message": "<string>",
"details": {}
}
}{
"error": {
"message": "<string>",
"code": "<string>",
"details": {}
}
}{
"error": {
"message": "<string>",
"code": "<string>",
"details": {}
}
}{
"error": {
"code": "guest_referrals_not_enabled"
}
}{
"error": {
"code": "rate_limited"
}
}Register Guest Referrer
curl --request POST \
--url https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email": "referrer@example.com",
"first_name": "Ada",
"ip_address": "203.0.113.42"
}
'import requests
url = "https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations"
payload = {
"email": "referrer@example.com",
"first_name": "Ada",
"ip_address": "203.0.113.42"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({email: 'referrer@example.com', first_name: 'Ada', ip_address: '203.0.113.42'})
};
fetch('https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations",
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([
'email' => 'referrer@example.com',
'first_name' => 'Ada',
'ip_address' => '203.0.113.42'
]),
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;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations"
payload := strings.NewReader("{\n \"email\": \"referrer@example.com\",\n \"first_name\": \"Ada\",\n \"ip_address\": \"203.0.113.42\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"referrer@example.com\",\n \"first_name\": \"Ada\",\n \"ip_address\": \"203.0.113.42\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.loyaltylion.com/headless/2025-06/{site_id}/referrals/guest_registrations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"referrer@example.com\",\n \"first_name\": \"Ada\",\n \"ip_address\": \"203.0.113.42\"\n}"
response = http.request(request)
puts response.read_body{
"referral_urls": {
"direct": "<string>",
"facebook": "<string>",
"twitter": "<string>",
"email": "<string>",
"whatsapp": "<string>",
"instagram": "<string>",
"device_share": "<string>"
}
}{
"error": {
"message": "<string>",
"details": {}
}
}{
"error": {
"message": "<string>",
"code": "<string>",
"details": {}
}
}{
"error": {
"message": "<string>",
"code": "<string>",
"details": {}
}
}{
"error": {
"code": "guest_referrals_not_enabled"
}
}{
"error": {
"code": "rate_limited"
}
}referral_urls, the same set of channel links an
enrolled customer has. The shopper is not enrolled by this request: they get a
customer record so their referrals have somewhere to be attributed, and if
they later enrol with the same email, their referrals carry over.
The request is only available when guest referrals are turned on in your
referral settings, and your program has an active referral rule. Otherwise it
is rejected with guest_referrals_not_enabled.
The ip_address must be the shopper’s own address, the one that reached your
server, never your server’s. Each shopper is rate limited on it, so sending
your own address gives every shopper you have one shared allowance. A 429
means that shopper, or your site as a whole, has registered too many guests in
a short window: wait and retry.
It’s safe to retry: registering an address that already holds links returns
the same links rather than a second set. If the address belongs to an
enrolled member, they keep their membership and the response says nothing
about it.
When a guest’s friend claims the incentive, the claim needs the friend’s email
address, because there is no membership to attribute the referral to. See
referee_email_required on Claim Referee
Incentive.Authorizations
An API key linked to a Program in LoyaltyLion, with a set of permissions (scopes). API keys can be created manually, or acquired through an OAuth2 flow. The API key should be provided as a Bearer token in the Authorization header
Path Parameters
Your LoyaltyLion Site ID
Body
Body
The email address of the shopper taking a referral link. It is what their referrals are attributed to, and what a later enrollment is matched against
Repeating the request with an address that already holds links returns the same ones rather than a second set
^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$"referrer@example.com"
The shopper's first name, recorded on the customer created for them. Applied only on creation: an address that already belongs to a customer keeps the name it has
1"Ada"
The IP address of the shopper taking the link — the one that reached your server, not your server's own. It is the bucket an individual shopper is rate limited on, so sending your own address throttles every shopper you have to a single shared allowance
Send a single address. A forwarded-for list is rejected: take the client entry from it yourself
^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$"203.0.113.42"
Response
The shopper holds referral links. The response is the same whether the address was new or already belonged to a customer, and says nothing about which — a shopper who is already a member keeps the membership they have, and is not enrolled or re-enrolled by this
The shopper holds referral links. The response is the same whether the address was new or already belonged to a customer, and says nothing about which — a shopper who is already a member keeps the membership they have, and is not enrolled or re-enrolled by this
The links this shopper shares, one per channel — the same set an enrolled customer's referral_urls carries
Show child attributes
Show child attributes