MENU navbar-image

Introduction

API for managing promotions, receipts, entries, members, products, locations, and more.

Welcome

This documentation provides all the information you need to integrate with the SocialHive Promo API.

The API is organized into two sections:

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_API_TOKEN}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Authenticate using a Sanctum API token. You can create tokens from the API Tokens page in your dashboard. Pass the token as a Bearer token in the Authorization header.

Promotion Participants

List promotion participants

requires authentication

Return a paginated list of participants for the given promotion.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/participants?filter%5Bname%5D=Alice&filter%5Bphone%5D=18765554444&filter%5Bid%5D=42&filter%5Bemail%5D=alice%40example.com&sort=-joined_at&page=1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/participants"
);

const params = {
    "filter[name]": "Alice",
    "filter[phone]": "18765554444",
    "filter[id]": "42",
    "filter[email]": "[email protected]",
    "sort": "-joined_at",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/participants';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'filter[name]' => 'Alice',
            'filter[phone]' => '18765554444',
            'filter[id]' => '42',
            'filter[email]' => '[email protected]',
            'sort' => '-joined_at',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 45,
            "phone": "18765580001",
            "name": "E2E Voter",
            "email": "[email protected]",
            "country": "JM",
            "status": "active",
            "pivot": {
                "joined_at": "2026-05-01T10:15:30.000000Z",
                "vote_status": "complete",
                "vote_rounds_completed": 1,
                "voted_at": "2026-05-01T10:15:30.000000Z"
            }
        }
    ],
    "links": {
        "first": "http://promo-next.test/api/v1/promotions/community-vote-2026/participants?page=1",
        "last": "http://promo-next.test/api/v1/promotions/community-vote-2026/participants?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "http://promo-next.test/api/v1/promotions/community-vote-2026/participants",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/promotions/{promotion_slug}/participants

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: community-vote-2026

Query Parameters

filter[name]   string  optional    

Filter participants by name. Example: Alice

filter[phone]   string  optional    

Filter participants by phone number. Example: 18765554444

filter[id]   integer  optional    

Filter participants by internal member ID. Example: 42

filter[email]   string  optional    

Filter participants by email address. Example: [email protected]

sort   string  optional    

Sort by name or joined_at. Use -joined_at for descending order. Example: -joined_at

page   integer  optional    

The page number. Example: 1

Create or attach a participant

requires authentication

Create a member if needed, attach them to the promotion, and optionally record voting responses.

Example request:
curl --request POST \
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/participants" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"member_id\": \"18765552222\",
    \"name\": \"API Participant\",
    \"email\": \"[email protected]\",
    \"dob\": \"1990-06-15\",
    \"country\": \"JM\",
    \"location\": \"Kingston\",
    \"opt_in\": true,
    \"metadata\": {
        \"source\": \"manual-entry\"
    },
    \"responses\": {
        \"district\": \"Kingston\",
        \"community\": \"Harbour View\"
    }
}"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/participants"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "member_id": "18765552222",
    "name": "API Participant",
    "email": "[email protected]",
    "dob": "1990-06-15",
    "country": "JM",
    "location": "Kingston",
    "opt_in": true,
    "metadata": {
        "source": "manual-entry"
    },
    "responses": {
        "district": "Kingston",
        "community": "Harbour View"
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/participants';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'member_id' => '18765552222',
            'name' => 'API Participant',
            'email' => '[email protected]',
            'dob' => '1990-06-15',
            'country' => 'JM',
            'location' => 'Kingston',
            'opt_in' => true,
            'metadata' => [
                'source' => 'manual-entry',
            ],
            'responses' => [
                'district' => 'Kingston',
                'community' => 'Harbour View',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": "success",
    "message": "Participant added to promotion successfully.",
    "data": {
        "id": 45,
        "phone": "18765552222",
        "name": "API Participant",
        "email": "[email protected]",
        "country": "JM",
        "status": "active"
    }
}
 

Request      

POST api/v1/promotions/{promotion_slug}/participants

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: community-vote-2026

Body Parameters

member_id   string     

The participant identifier, stored as the member phone number. Example: 18765552222

name   string     

The participant name. Example: API Participant

email   string  optional    

The participant email address. Example: [email protected]

dob   date  optional    

The participant date of birth. Example: 1990-06-15

country   string  optional    

The participant country. Example: JM

location   string  optional    

The participant location. Example: Kingston

opt_in   boolean  optional    

Whether the participant opted in to marketing. Example: true

metadata   object  optional    

Additional promotion-specific metadata to store on the pivot record.

responses   object  optional    

Voting responses keyed by question key for voting promotions.

Promotion Entries

List promotion entries

requires authentication

Return a paginated list of entries for the given promotion.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/summer-cashback/entries?filter%5Bmember_id%5D=42&filter%5Bstatus%5D=valid&filter%5Bsource_type%5D=App%5CModels%5CReceipt&sort=-created_at&page=1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/summer-cashback/entries"
);

const params = {
    "filter[member_id]": "42",
    "filter[status]": "valid",
    "filter[source_type]": "App\Models\Receipt",
    "sort": "-created_at",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/summer-cashback/entries';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'filter[member_id]' => '42',
            'filter[status]' => 'valid',
            'filter[source_type]' => 'App\Models\Receipt',
            'sort' => '-created_at',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 123,
            "member": {
                "id": 45,
                "phone": "18765580001",
                "name": "E2E Voter",
                "email": "[email protected]",
                "country": "JM",
                "status": "active"
            },
            "status": "valid",
            "source_type": "App\\Models\\Receipt",
            "source_id": 987,
            "created_at": "2026-05-01T10:15:30.000000Z"
        }
    ],
    "links": {
        "first": "http://promo-next.test/api/v1/promotions/summer-cashback/entries?page=1",
        "last": "http://promo-next.test/api/v1/promotions/summer-cashback/entries?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "http://promo-next.test/api/v1/promotions/summer-cashback/entries",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/promotions/{promotion_slug}/entries

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: summer-cashback

Query Parameters

filter[member_id]   integer  optional    

Filter entries by member ID. Example: 42

filter[status]   string  optional    

Filter entries by entry status. Example: valid

filter[source_type]   string  optional    

Filter entries by source type. Example: App\Models\Receipt

sort   string  optional    

Sort by created_at. Use -created_at for descending order. Example: -created_at

page   integer  optional    

The page number. Example: 1

Show a promotion entry

requires authentication

Return a single entry that belongs to the given promotion.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/summer-cashback/entries/3" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/summer-cashback/entries/3"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/summer-cashback/entries/3';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "id": 123,
        "member": {
            "id": 45,
            "phone": "18765580001",
            "name": "E2E Voter",
            "email": "[email protected]",
            "country": "JM",
            "status": "active"
        },
        "status": "valid",
        "source_type": "App\\Models\\Receipt",
        "source_id": 987,
        "created_at": "2026-05-01T10:15:30.000000Z"
    }
}
 

Example response (404):


{
    "message": "Not Found"
}
 

Request      

GET api/v1/promotions/{promotion_slug}/entries/{entry_id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: summer-cashback

entry_id   integer     

The ID of the entry. Example: 3

entry   integer     

The entry ID. Example: 123

Promotion Codes

List promotion codes

requires authentication

Return a paginated list of codes for the given promotion.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/win-big-2026/codes?page=1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/win-big-2026/codes"
);

const params = {
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/win-big-2026/codes';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "current_page": 1,
    "data": [
        {
            "id": 12,
            "promotion_id": 5,
            "code": "WINCODE123",
            "used_at": null,
            "used_by": null,
            "expired_at": null,
            "active": true,
            "metadata": null,
            "created_at": "2026-05-01T10:15:30.000000Z",
            "updated_at": "2026-05-01T10:15:30.000000Z"
        }
    ],
    "first_page_url": "http://promo-next.test/api/v1/promotions/win-big-2026/codes?page=1",
    "from": 1,
    "last_page": 1,
    "last_page_url": "http://promo-next.test/api/v1/promotions/win-big-2026/codes?page=1",
    "links": [
        {
            "url": null,
            "label": "« Previous",
            "active": false
        },
        {
            "url": "http://promo-next.test/api/v1/promotions/win-big-2026/codes?page=1",
            "label": "1",
            "active": true
        },
        {
            "url": null,
            "label": "Next »",
            "active": false
        }
    ],
    "next_page_url": null,
    "path": "http://promo-next.test/api/v1/promotions/win-big-2026/codes",
    "per_page": 50,
    "prev_page_url": null,
    "to": 1,
    "total": 1
}
 

Request      

GET api/v1/promotions/{promotion_slug}/codes

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: win-big-2026

Query Parameters

page   integer  optional    

The page number. Example: 1

Check a promotion code

requires authentication

Validate a code for the given promotion without redeeming it.

Example request:
curl --request POST \
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/win-big-2026/codes/check" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"code\": \"VALIDCODE\"
}"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/win-big-2026/codes/check"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "code": "VALIDCODE"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/win-big-2026/codes/check';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'code' => 'VALIDCODE',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "message": "Code is valid and available.",
    "status": "available"
}
 

Example response (404):


{
    "message": "Invalid code for this promotion.",
    "status": "invalid"
}
 

Request      

POST api/v1/promotions/{promotion_slug}/codes/check

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: win-big-2026

Body Parameters

code   string     

The promotion code to check. Example: VALIDCODE

Redeem a promotion code

requires authentication

Validate and redeem a code for a member in the given promotion.

Example request:
curl --request POST \
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/win-big-2026/codes/redeem" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"code\": \"REDEEMME\",
    \"phone\": \"18765551234\",
    \"member_id\": \"18765551234\"
}"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/win-big-2026/codes/redeem"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "code": "REDEEMME",
    "phone": "18765551234",
    "member_id": "18765551234"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/win-big-2026/codes/redeem';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'code' => 'REDEEMME',
            'phone' => '18765551234',
            'member_id' => '18765551234',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "message": "Code redeemed successfully.",
    "data": {
        "code": "REDEEMME",
        "prize": "Free Drink"
    }
}
 

Example response (409):


{
    "message": "This code has already been used."
}
 

Request      

POST api/v1/promotions/{promotion_slug}/codes/redeem

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: win-big-2026

Body Parameters

code   string     

The promotion code to redeem. Example: REDEEMME

phone   string  optional    

The member phone number. Required when member_id is not supplied. Example: 18765551234

member_id   string  optional    

The member identifier fallback, treated as a phone number. Required when phone is not supplied. Example: 18765551234

Promotion Votes

List votes

requires authentication

Return a paginated, filterable list of individual votes for a voting promotion.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes?filter%5Bquestion_key%5D=community&filter%5Banswer%5D=Harbour+View&filter%5Bmember_id%5D=45&filter%5Bvote_round%5D=1&filter%5Bdistrict%5D=Belize&include=member&sort=-created_at&page=1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes"
);

const params = {
    "filter[question_key]": "community",
    "filter[answer]": "Harbour View",
    "filter[member_id]": "45",
    "filter[vote_round]": "1",
    "filter[district]": "Belize",
    "include": "member",
    "sort": "-created_at",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'filter[question_key]' => 'community',
            'filter[answer]' => 'Harbour View',
            'filter[member_id]' => '45',
            'filter[vote_round]' => '1',
            'filter[district]' => 'Belize',
            'include' => 'member',
            'sort' => '-created_at',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 91,
            "member_id": 45,
            "member": {
                "id": 45,
                "phone": "18765580001",
                "name": "E2E Voter",
                "email": "[email protected]",
                "country": "JM",
                "status": "active"
            },
            "question_key": "community",
            "answer": "Harbour View",
            "vote_round": 1,
            "created_at": "2026-05-01T10:15:30.000000Z",
            "updated_at": "2026-05-01T10:15:30.000000Z"
        }
    ],
    "links": {
        "first": "http://promo-next.test/api/v1/promotions/community-vote-2026/votes?page=1",
        "last": "http://promo-next.test/api/v1/promotions/community-vote-2026/votes?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "http://promo-next.test/api/v1/promotions/community-vote-2026/votes",
        "per_page": 15,
        "to": 1,
        "total": 1,
        "question_labels": {
            "district": "District?",
            "community": "Community?"
        }
    }
}
 

Request      

GET api/v1/promotions/{promotion_slug}/votes

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: community-vote-2026

Query Parameters

filter[question_key]   string  optional    

Filter votes by question key. Example: community

filter[answer]   string  optional    

Filter votes by a partial answer match. Example: Harbour View

filter[member_id]   integer  optional    

Filter votes by member ID. Example: 45

filter[vote_round]   integer  optional    

Filter votes by vote round. Example: 1

filter[district]   string  optional    

Filter votes by another configured question answer. Example: Belize

include   string  optional    

Include related resources. Supported value: member. Example: member

sort   string  optional    

Sort by created_at, question_key, answer, or vote_round. Example: -created_at

page   integer  optional    

The page number. Example: 1

Show the leaderboard

requires authentication

Return ranked tallies for the promotion's configured tally field.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes/leaderboard?filter%5Bdistrict%5D=Belize" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes/leaderboard"
);

const params = {
    "filter[district]": "Belize",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes/leaderboard';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'filter[district]' => 'Belize',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": null,
    "data": {
        "question_key": "community",
        "question_label": "Community?",
        "total_entries": 3,
        "leaderboard": [
            {
                "rank": 1,
                "name": "Harbour View",
                "votes": 2
            },
            {
                "rank": 2,
                "name": "Bull Bay",
                "votes": 1
            }
        ]
    }
}
 

Request      

GET api/v1/promotions/{promotion_slug}/votes/leaderboard

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: community-vote-2026

Query Parameters

filter[district]   string  optional    

Filter the leaderboard by another configured question answer. Example: Belize

Show voting statistics

requires authentication

Return summary counts for participants and responses in a voting promotion.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes/stats" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes/stats"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes/stats';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": null,
    "data": {
        "total_participants": 2,
        "completed_votes": 1,
        "partial_votes": 1,
        "total_responses": 3,
        "questions_configured": 2,
        "per_question": [
            {
                "question_key": "district",
                "question_label": "District?",
                "respondents": 2
            },
            {
                "question_key": "community",
                "question_label": "Community?",
                "respondents": 1
            }
        ]
    }
}
 

Request      

GET api/v1/promotions/{promotion_slug}/votes/stats

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: community-vote-2026

Get question options

requires authentication

Return the available options for a question, optionally resolved from context or member history.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes/options/community?filter%5Bdistrict%5D=Belize&filter%5Bmember_id%5D=18765559001&filter%5Bmember_phone%5D=18765559002&api_key=1%7Cabcdefghijklmnopqrstuvwx" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes/options/community"
);

const params = {
    "filter[district]": "Belize",
    "filter[member_id]": "18765559001",
    "filter[member_phone]": "18765559002",
    "api_key": "1|abcdefghijklmnopqrstuvwx",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/community-vote-2026/votes/options/community';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'filter[district]' => 'Belize',
            'filter[member_id]' => '18765559001',
            'filter[member_phone]' => '18765559002',
            'api_key' => '1|abcdefghijklmnopqrstuvwx',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": null,
    "data": {
        "question_key": "community",
        "question_label": "Community?",
        "allow_other": true,
        "options": [
            "Belize City",
            "Burrell Boom",
            "Ladyville"
        ],
        "total": 4,
        "options_whatsapp": "1. Belize City\n2. Burrell Boom\n3. Ladyville\n4. Other"
    }
}
 

Example response (404):


{
    "status": "error",
    "message": "Question 'community' not found in config.",
    "errors": null
}
 

Request      

GET api/v1/promotions/{promotion_slug}/votes/options/{question_key}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: community-vote-2026

question_key   string     

The question key to resolve options for. Example: community

Query Parameters

filter[district]   string  optional    

Provide explicit context using another question answer. Example: Belize

filter[member_id]   string  optional    

Resolve context from a member ID or phone number. Example: 18765559001

filter[member_phone]   string  optional    

Resolve context from a member phone number. Example: 18765559002

api_key   string  optional    

Alternative API token for bot callers. Example: 1|abcdefghijklmnopqrstuvwx

Promotion Promoters

List promoters

requires authentication

Return a paginated list of promoters for the given promotion.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters?filter%5Bname%5D=Jane&filter%5Bphone%5D=18761234567&filter%5Bidentifier%5D=PROMO001&filter%5Bstatus%5D=active&sort=-created_at&page=1" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters"
);

const params = {
    "filter[name]": "Jane",
    "filter[phone]": "18761234567",
    "filter[identifier]": "PROMO001",
    "filter[status]": "active",
    "sort": "-created_at",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'filter[name]' => 'Jane',
            'filter[phone]' => '18761234567',
            'filter[identifier]' => 'PROMO001',
            'filter[status]' => 'active',
            'sort' => '-created_at',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 11,
            "promotion_id": 5,
            "identifier": "PROMO001",
            "name": "Jane Promoter",
            "phone": "18761234567",
            "status": "active",
            "metadata": {
                "region": "Belize City"
            },
            "created_at": "2026-05-01T10:15:30.000000Z",
            "updated_at": "2026-05-01T10:15:30.000000Z"
        }
    ],
    "links": {
        "first": "http://promo-next.test/api/v1/promotions/retailer-drive-2026/promoters?page=1",
        "last": "http://promo-next.test/api/v1/promotions/retailer-drive-2026/promoters?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "http://promo-next.test/api/v1/promotions/retailer-drive-2026/promoters",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/promotions/{promotion_slug}/promoters

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: retailer-drive-2026

Query Parameters

filter[name]   string  optional    

Filter promoters by name. Example: Jane

filter[phone]   string  optional    

Filter promoters by phone number. Example: 18761234567

filter[identifier]   string  optional    

Filter promoters by external identifier. Example: PROMO001

filter[status]   string  optional    

Filter promoters by status. Example: active

sort   string  optional    

Sort by name, created_at, or status. Example: -created_at

page   integer  optional    

The page number. Example: 1

Create a promoter

requires authentication

Create a new promoter for the given promotion.

Example request:
curl --request POST \
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"identifier\": \"PROMO001\",
    \"name\": \"API Promoter\",
    \"phone\": \"18761234567\",
    \"status\": \"active\",
    \"metadata\": {
        \"region\": \"Belize City\"
    }
}"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "identifier": "PROMO001",
    "name": "API Promoter",
    "phone": "18761234567",
    "status": "active",
    "metadata": {
        "region": "Belize City"
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'identifier' => 'PROMO001',
            'name' => 'API Promoter',
            'phone' => '18761234567',
            'status' => 'active',
            'metadata' => [
                'region' => 'Belize City',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": "success",
    "message": "Promoter created.",
    "data": {
        "id": 11,
        "promotion_id": 5,
        "identifier": "PROMO001",
        "name": "API Promoter",
        "phone": "18761234567",
        "status": "active",
        "metadata": null,
        "created_at": "2026-05-01T10:15:30.000000Z",
        "updated_at": "2026-05-01T10:15:30.000000Z"
    }
}
 

Request      

POST api/v1/promotions/{promotion_slug}/promoters

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: retailer-drive-2026

Body Parameters

identifier   string  optional    

External promoter identifier. Example: PROMO001

name   string     

The promoter name. Example: API Promoter

phone   string  optional    

The promoter phone number. Example: 18761234567

status   string  optional    

The promoter status. Allowed values: active, inactive. Example: active

metadata   object  optional    

Additional promoter metadata.

Show a promoter

requires authentication

Return a single promoter record for the given promotion.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters/4" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters/4"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters/4';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": null,
    "data": {
        "id": 11,
        "promotion_id": 5,
        "identifier": "PROMO001",
        "name": "Jane Promoter",
        "phone": "18761234567",
        "status": "active",
        "metadata": {
            "region": "Belize City"
        },
        "created_at": "2026-05-01T10:15:30.000000Z",
        "updated_at": "2026-05-01T10:15:30.000000Z"
    }
}
 

Request      

GET api/v1/promotions/{promotion_slug}/promoters/{promoter_id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: retailer-drive-2026

promoter_id   integer     

The ID of the promoter. Example: 4

promoter   integer     

The promoter ID. Example: 11

Update a promoter

requires authentication

Update a promoter record for the given promotion.

Example request:
curl --request PUT \
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters/4" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"identifier\": \"PROMO002\",
    \"name\": \"Changed Name\",
    \"phone\": \"18761234567\",
    \"status\": \"inactive\",
    \"metadata\": {
        \"region\": \"Orange Walk\"
    }
}"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters/4"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "identifier": "PROMO002",
    "name": "Changed Name",
    "phone": "18761234567",
    "status": "inactive",
    "metadata": {
        "region": "Orange Walk"
    }
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters/4';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'identifier' => 'PROMO002',
            'name' => 'Changed Name',
            'phone' => '18761234567',
            'status' => 'inactive',
            'metadata' => [
                'region' => 'Orange Walk',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": "Promoter updated.",
    "data": {
        "id": 11,
        "promotion_id": 5,
        "identifier": "PROMO002",
        "name": "Changed Name",
        "phone": "18761234567",
        "status": "inactive",
        "metadata": {
            "region": "Orange Walk"
        },
        "created_at": "2026-05-01T10:15:30.000000Z",
        "updated_at": "2026-05-01T11:00:00.000000Z"
    }
}
 

Request      

PUT api/v1/promotions/{promotion_slug}/promoters/{promoter_id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: retailer-drive-2026

promoter_id   integer     

The ID of the promoter. Example: 4

promoter   integer     

The promoter ID. Example: 11

Body Parameters

identifier   string  optional    

External promoter identifier. Example: PROMO002

name   string  optional    

The promoter name. Required when present. Example: Changed Name

phone   string  optional    

The promoter phone number. Example: 18761234567

status   string  optional    

The promoter status. Allowed values: active, inactive. Example: inactive

metadata   object  optional    

Additional promoter metadata.

Delete a promoter

requires authentication

Permanently delete a promoter from the given promotion.

Example request:
curl --request DELETE \
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters/4" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters/4"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/promotions/retailer-drive-2026/promoters/4';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": "Promoter deleted.",
    "data": null
}
 

Request      

DELETE api/v1/promotions/{promotion_slug}/promoters/{promoter_id}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

promotion_slug   string     

The promotion slug. Example: retailer-drive-2026

promoter_id   integer     

The ID of the promoter. Example: 4

promoter   integer     

The promoter ID. Example: 11

Tools

List available tools

requires authentication

Return all registered API tools and their input/output schemas.

Example request:
curl --request GET \
    --get "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/tools" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/tools"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/tools';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": null,
    "data": [
        {
            "slug": "date-formatter",
            "name": "Date Formatter & Age Gate",
            "description": "Formats a date string and checks if the person meets a minimum age requirement. Auto-detects the input date format, or accepts an explicit input_format for ambiguous dates.",
            "input_schema": [
                {
                    "name": "date",
                    "type": "string",
                    "required": true,
                    "description": "Date string (e.g., \"28/11/1972\", \"1972-11-28\", \"Nov 28, 1972\")"
                }
            ],
            "output_schema": [
                {
                    "name": "formatted_date",
                    "type": "string",
                    "description": "Date in the requested output format"
                }
            ]
        },
        {
            "slug": "phone-country",
            "name": "Phone Country Lookup",
            "description": "Parses a phone number and returns the normalized number, country calling code, country code, and country name.",
            "input_schema": [
                {
                    "name": "phone",
                    "type": "string",
                    "required": true,
                    "description": "Phone number in any format"
                }
            ],
            "output_schema": [
                {
                    "name": "country_code",
                    "type": "string",
                    "description": "ISO 3166-1 alpha-2 country code"
                }
            ]
        }
    ]
}
 

Request      

GET api/v1/tools

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

Execute a tool

requires authentication

Run the selected tool with the supplied input. Body fields depend on the tool slug.

Example request:
curl --request POST \
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/tools/date-formatter" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"date\": \"28\\/11\\/1972\",
    \"input_format\": \"d\\/m\\/Y\",
    \"output_format\": \"Y-m-d\",
    \"min_age\": 18,
    \"phone\": \"5016283170\",
    \"default_region\": \"BZ\"
}"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/tools/date-formatter"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "date": "28\/11\/1972",
    "input_format": "d\/m\/Y",
    "output_format": "Y-m-d",
    "min_age": 18,
    "phone": "5016283170",
    "default_region": "BZ"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/tools/date-formatter';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'date' => '28/11/1972',
            'input_format' => 'd/m/Y',
            'output_format' => 'Y-m-d',
            'min_age' => 18,
            'phone' => '5016283170',
            'default_region' => 'BZ',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": null,
    "data": {
        "formatted_date": "28.11.1972",
        "status": "approved",
        "age": 53
    }
}
 

Example response (404):


{
    "status": "error",
    "message": "Tool not found.",
    "errors": null
}
 

Request      

POST api/v1/tools/{tool}

Headers

Authorization        

Example: Bearer {YOUR_API_TOKEN}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

tool   string     

The tool slug. Example: date-formatter

Body Parameters

date   string  optional    

Required when tool is date-formatter. The date to format. Example: 28/11/1972

input_format   string  optional    

Optional input format for date-formatter. Example: d/m/Y

output_format   string  optional    

Optional output format for date-formatter. Example: Y-m-d

min_age   integer  optional    

Optional minimum age for date-formatter. Example: 18

phone   string  optional    

Required when tool is phone-country. The phone number to parse. Example: 5016283170

default_region   string  optional    

Optional fallback region for phone-country. Example: BZ

Webhooks

Handle a MessengerPeople webhook

Accept an inbound bot payload and route it to receipt, code, sweepstakes, or voting processing.

Example request:
curl --request POST \
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/webhooks/messenger-people/550e8400-e29b-41d4-a716-446655440000/summer-cashback" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"member_id\": \"18765551234\",
    \"name\": \"John Doe\",
    \"image\": \"https:\\/\\/example.com\\/receipt.jpg\",
    \"chat\": \"WINCODE123\",
    \"chat_time\": 1772426400,
    \"promoter\": \"PROMO001\"
}"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/webhooks/messenger-people/550e8400-e29b-41d4-a716-446655440000/summer-cashback"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "member_id": "18765551234",
    "name": "John Doe",
    "image": "https:\/\/example.com\/receipt.jpg",
    "chat": "WINCODE123",
    "chat_time": 1772426400,
    "promoter": "PROMO001"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/webhooks/messenger-people/550e8400-e29b-41d4-a716-446655440000/summer-cashback';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'member_id' => '18765551234',
            'name' => 'John Doe',
            'image' => 'https://example.com/receipt.jpg',
            'chat' => 'WINCODE123',
            'chat_time' => 1772426400,
            'promoter' => 'PROMO001',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": "Receipt received successfully.",
    "data": {
        "type": "receipt",
        "receipt_id": 123,
        "test_mode": false
    }
}
 

Example response (403):


{
    "status": "error",
    "message": "This account has been temporarily suspended.",
    "errors": null
}
 

Request      

POST api/v1/webhooks/messenger-people/{team_uuid}/{promotion_slug}

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

team_uuid   string     

The team UUID. Example: 550e8400-e29b-41d4-a716-446655440000

promotion_slug   string     

The promotion slug. Example: summer-cashback

Body Parameters

member_id   string     

The sender identifier, usually a phone number. Example: 18765551234

name   string  optional    

The sender display name. Example: John Doe

image   string  optional    

Receipt image URL for receipt promotions. Example: https://example.com/receipt.jpg

chat   string  optional    

Text message content for code and sweepstakes promotions. Example: WINCODE123

chat_time   integer  optional    

Unix timestamp when the message was sent. Example: 1772426400

promoter   string  optional    

Promoter identifier to attach to a receipt entry. Example: PROMO001

Handle a SendSeven webhook

Accept inbound message, delivery status, conversation, and contact events from SendSeven.

Example request:
curl --request POST \
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/webhooks/sendseven/550e8400-e29b-41d4-a716-446655440000/summer-cashback" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"id\": \"evt_123456789\",
    \"event_id\": \"evt_123456789\",
    \"type\": \"message.received\",
    \"created_at\": \"2026-05-01T10:15:30Z\"
}"
const url = new URL(
    "https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/webhooks/sendseven/550e8400-e29b-41d4-a716-446655440000/summer-cashback"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "id": "evt_123456789",
    "event_id": "evt_123456789",
    "type": "message.received",
    "created_at": "2026-05-01T10:15:30Z"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://unknown-headline-volunteer-brochure.trycloudflare.com/api/v1/webhooks/sendseven/550e8400-e29b-41d4-a716-446655440000/summer-cashback';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'id' => 'evt_123456789',
            'event_id' => 'evt_123456789',
            'type' => 'message.received',
            'created_at' => '2026-05-01T10:15:30Z',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": "success",
    "message": "Receipt received successfully.",
    "data": {
        "type": "receipt",
        "receipt_id": 123,
        "test_mode": false
    }
}
 

Example response (401):


{
    "status": "error",
    "message": "Invalid webhook signature.",
    "errors": null
}
 

Request      

POST api/v1/webhooks/sendseven/{team_uuid}/{promotion_slug}

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

team_uuid   string     

The team UUID. Example: 550e8400-e29b-41d4-a716-446655440000

promotion_slug   string     

The promotion slug. Example: summer-cashback

Body Parameters

id   string  optional    

A unique webhook event ID. Example: evt_123456789

event_id   string  optional    

Alternative event identifier. Example: evt_123456789

type   string     

The SendSeven event type. Example: message.received

created_at   string  optional    

The event timestamp in ISO 8601 format. Example: 2026-05-01T10:15:30Z

data   object  optional    
message   object  optional    
from_id   string  optional    

The sender phone number for inbound messages. Example: 18765551234

message_type   string  optional    

The incoming message type. Example: image

text   string  optional    

The incoming text content. Example: WINCODE123

attachments   string[]  optional    

Attachments for image messages.

contact   object  optional    
name   string  optional    

The contact display name. Example: John Doe

phone   string  optional    

The contact phone number. Example: 18765551234