game set engage
  • Solutions

    • Fan Engagement
    • Revenue Growth
    • Community Building
    • Data & Analytics

    By Fan Base

    • Local Up to 1K fans
    • City Up to 10K fans
    • National Up to 100K fans
    • Global Up to 1M fans

    Resources

    • Earnings Calculator New
    • Implementation Guide
    • Developers
    • Support Center
    See All Club Features 10+ seasons of experience
  • Venue Types

    • Sports Bars
    • Pubs & Restaurants
    • Entertainment Venues
    • Retail Partners

    Why Partner?

    Pay per check-in

    Simple per-visit pricing

    Quick approval

    Get listed in minutes

    More foot traffic

    Fans discover you via clubs

    See All Venue Features Partner with clubs & athletes
  • For Fans
  • Pricing
  • Learn

    • Blog
    • Use Cases
    • Guides & eBooks

    Support

    • Help Center
    • Developers
    • System Status
    • Contact Us
Sign In Start Engaging Free

Solutions

Fan Engagement Revenue Growth Community Building Data & Analytics

By Fan Base

LocalUp to 1K fans CityUp to 10K fans NationalUp to 100K fans GlobalUp to 1M fans

Resources

Earnings Calculator New Implementation Guide Developers

Venue Types

Sports Bars Pubs & Restaurants Entertainment Venues Retail Partners

Why Partner?

Pay per check-in
Quick approval
More foot traffic
See All Venue Features
For Fans Pricing

Learn

Blog Use Cases Guides & eBooks

Support

Help Center Developers System Status Contact Us
Start Engaging Free Sign In
Developers

Your club. Your app. Our engine.

The white-label API for clubs on the National and Global plans — register your club, generate your keys, and ship a fan app powered by the Game Set Engage platform.

Last updated: August 11, 2026

Club Integration API

Build your club's own fan app on the Game Set Engage platform. Your brand and your build — our campaign engine, points ledger, venue network and fan accounts underneath. Your users live in a single-club universe: they belong to your club from the moment they register, and they only ever see your campaigns, your venue offers and their own data.

The Game Set Engage API is a closed platform: it serves our own apps and approved club integrations. Your club's API key is your app's identity — there is no anonymous or general-purpose access.


1. Get access

  1. Register your club — create your club account and complete onboarding.
  2. Be on the National or Global plan — API access is included in National and Global. Lower tiers can upgrade at any time; your fans, points and history carry over.
  3. Generate your keys — in your club dashboard open Club Management → API Access and press Generate API keys.

You get two keys:

Key Looks like Where it lives What it does
Publishable key gse_pk_… Inside your app Identifies your club and scopes every request to it. Not a secret.
Secret key gse_sk_… Your servers only Reserved for server-to-server calls. Shown once at generation — store it in a secret manager, never in the app.

You can rotate the secret at any time (the publishable key survives), rotate the publishable key (coordinate with an app release — it breaks shipped builds), or revoke access entirely.

2. The basics

  • Production: https://api.gamesetengage.com/api/v1
  • Staging: https://dev.gamesetengage.com/api/v1 — same keys, test here first.
  • JSON in, JSON out. Non-GET requests need Content-Type: application/json.
  • Send your publishable key on every request:
X-Club-Key: gse_pk_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

An invalid or revoked key fails loudly with 401 INVALID_CLUB_KEY — it never silently falls back. If your plan drops below National, requests return 403 CLUB_PLAN_REQUIRED until you upgrade again.

Every response uses one envelope. Quote meta.request_id when you contact support.

{ "success": true,  "message": "…", "data": { }, "meta": { "timestamp": "…", "request_id": "…", "version": "v1" } }
{ "success": false, "error": { "code": "FORBIDDEN", "message": "…" }, "meta": { } }

3. Register and sign in your users

Accounts created through your app are automatically subscribed to your club — no club pickers, no discovery screens. Under the hood they are platform accounts, so verified email, password reset, account deletion and fraud protection all come for free.

Create a fan (requires explicit terms acceptance):

curl -X POST https://api.gamesetengage.com/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -H "X-Club-Key: gse_pk_XXXX" \
  -d '{
    "user": {
      "email": "[email protected]",
      "password": "aStrongPassword!",
      "first_name": "Alex",
      "last_name": "Carter"
    },
    "terms_accepted": true
  }'

The fan receives a verification email; confirm with POST /auth/verify-email ({ "token": "<6-digit code>" }) — the response already includes the JWT tokens.

Sign in:

curl -X POST https://api.gamesetengage.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -H "X-Club-Key: gse_pk_XXXX" \
  -d '{ "user": { "email": "[email protected]", "password": "aStrongPassword!" } }'
{
  "success": true,
  "message": "Login successful",
  "data": {
    "user": {
      "unique_id": "usr_9f2ac1…",
      "email": "[email protected]",
      "first_name": "Alex",
      "role": "fan",
      "email_verified": true,
      "engagement_points": 127,
      "points_by_club": [
        { "club_unique_id": "club_hollowmere", "club_name": "Hollowmere Town FC", "points": 127 }
      ],
      "subscribed_club": { "unique_id": "club_hollowmere", "name": "Hollowmere Town FC" }
    },
    "tokens": {
      "access_token": "eyJhbGciOiJIUzI1NiJ9…",
      "refresh_token": "9f8c4e2b…",
      "expires_in": 900
    }
  }
}

Access tokens live 15 minutes — refresh with POST /auth/refresh. Send Authorization: Bearer <access_token> plus X-Club-Key on every call from here on.

Two login cases to handle in your UI:

  • A fan who already has a Game Set Engage account is subscribed to your club automatically on first sign-in through your app.
  • If that account already follows the platform maximum of 3 clubs, login returns 403 with a clear message — show it as-is.

After every successful login, register the device's push token (POST /devices) so notifications follow the signed-in account.

4. List your campaigns

curl https://api.gamesetengage.com/api/v1/campaigns \
  -H "X-Club-Key: gse_pk_XXXX" \
  -H "Authorization: Bearer <access_token>"

Returns your club's active campaigns, paginated. Fetch one with GET /campaigns/:unique_id — the detail includes everything your UI needs:

{
  "success": true,
  "data": {
    "unique_id": "cmp_derby_checkin",
    "name": "Derby Day Check-in",
    "campaign_type": "event_check_in",
    "engagement_points": 50,
    "supportive_engagement_points": 10,
    "venue_engagement_points": 30,
    "start_date": "2026-09-12T16:00:00Z",
    "end_date": "2026-09-12T23:00:00Z",
    "can_participate": true,
    "user_participated": false,
    "my_club_points": 127,
    "deal_codes_remaining": null,
    "prediction_locked": false,
    "checkin_location": { "latitude": 51.5549, "longitude": -0.1084, "radius_km": 0.5 },
    "my_participation": null
  }
}

Fields worth wiring up: can_participate (drive your CTA), my_club_points (the fan's balance with your club — needed for auctions and point-spend campaigns), deal_codes_remaining (stock indicator for special_deal_code), my_participation (result + code after the fan has taken part).

5. Participation cookbook — every campaign type

All eight types hit the same endpoint — POST /campaigns/:unique_id/participate — only the payload differs. Points rules, per-fan limits, quotas and time windows are enforced server-side and transactionally: a failed participation never burns points or codes.

Two things are true for every type:

  • Who is participating comes from the Authorization header, never the payload. An "empty" {} payload is only empty of campaign data — the JWT identifies the fan on every call.
  • location is optional everywhere. Types that don't require it (basic, deal_code, special_deal_code, survey, prediction, auction) still accept "location": { "latitude", "longitude", "accuracy" } — when you send it, it is stored on the participation record and enriches the club's engagement analytics. Send it whenever the fan has granted location permission.

event_check_in — GPS check-in

location is required. Points are tiered by where the fan is (values are set per campaign by you, not auto-multiplied): full points inside the venue radius, reduced "watching from home" points outside it (if you enabled them), and partner-venue points through the venue QR flow (§6).

POST /campaigns/cmp_derby_checkin/participate
{ "location": { "latitude": 51.5549, "longitude": -0.1084, "accuracy": 8 } }
{
  "success": true,
  "data": {
    "participation": { "points_earned": 50, "total_points": 50 },
    "checkin": { "tier": "main", "at_main_location": true, "points": 50, "warning": null }
  }
}

A home check-in returns tier: "home", lower points, and a warning string to surface. If home points are disabled, an outside check-in is rejected (422 You must be near the event location to check in).

basic — one-tap participation

Empty payload; awards the campaign's points.

POST /campaigns/cmp_season_kickoff/participate
{}

…or, if the fan has granted location permission, send it along (optional — stored on the participation record, enriches your analytics):

POST /campaigns/cmp_season_kickoff/participate
{ "location": { "latitude": 51.5549, "longitude": -0.1084, "accuracy": 8 } }
{ "success": true, "data": { "participation": { "points_earned": 2, "total_points": 2 } } }

deal_code — shared discount code

Empty payload (optional location accepted). Every fan receives the same code; show it prominently.

POST /campaigns/cmp_friday_pint/participate
{}
{
  "success": true,
  "data": {
    "participation": { "points_earned": 1, "total_points": 1 },
    "deal_code": "HOLLOWMERE-FRIDAY-20OFF"
  }
}

special_deal_code — unique code from a limited pool

Empty payload (optional location accepted). Each fan draws a different code; when the pool runs out the call returns 422 All deal codes have been claimed. Use deal_codes_remaining from campaign detail as a stock badge.

POST /campaigns/cmp_limited_jersey/participate
{}
{
  "success": true,
  "data": {
    "participation": { "points_earned": 0, "total_points": 0 },
    "deal_code": "JERSEY-7F3K9Q"
  }
}

qr_based — scan at the venue

The fan scans your campaign QR; your app calls POST /campaigns/scan with the QR payload to resolve the campaign, then participates with location (these campaigns are usually pinned to a geofence — a fan outside the radius gets 422 You must be at the campaign location to participate).

POST /campaigns/cmp_east_stand_qr/participate
{ "location": { "latitude": 51.5549, "longitude": -0.1084, "accuracy": 9 } }
{ "success": true, "data": { "participation": { "points_earned": 3, "total_points": 3 } } }

survey — questions, optional quiz bonus

survey_responses is required (optional location accepted alongside), keyed by the question index as a string. Questions you marked with a correct answer pay a bonus per correct reply; pure opinion surveys just pay the base points.

POST /campaigns/cmp_matchday_quiz/participate
{ "survey_responses": { "0": "Hollowmere", "1": "Reyes" } }
{
  "success": true,
  "message": "Survey complete! 2 correct, 10 bonus points earned.",
  "data": {
    "participation": { "points_earned": 5, "quiz_bonus_points": 10, "quiz_correct_count": 2, "total_points": 15 }
  }
}

prediction — points only for being right

Same payload shape as survey (optional location accepted alongside), different economics: taking part earns nothing. If the outcome is already known the bonus (or a miss) is returned immediately; otherwise the result is pending and points arrive when your club resolves the outcome. Always render from the result object — never frame a pending or wrong pick as a win.

POST /campaigns/cmp_final_score/participate
{ "survey_responses": { "0": "2-1" } }
{
  "success": true,
  "data": {
    "participation": { "points_earned": 0, "total_points": 0 },
    "result": {
      "outcome": "pending",
      "resolved": false,
      "points_awarded": 0,
      "title": "Prediction locked in",
      "text": "We'll add your points once the result is confirmed."
    }
  }
}

After resolution, GET /campaigns/:unique_id shows the outcome under my_participation, and prediction_locked: true closes new entries.

auction — bid engagement points

bid_amount is required (optional location accepted alongside) and is paid in club engagement points, never money. A bid must clear the current bid plus the step, and fit the fan's balance (my_club_points). Outbid fans can always re-bid; the winner pays at close via automatic settlement.

POST /campaigns/cmp_signed_shirt/participate
{ "bid_amount": 75 }
{ "success": true, "data": { "participation": { "points_earned": 0, "total_points": 0 } } }

Rejections are explicit: 422 Bid must be at least 80 · 422 Insufficient points. You have 60 points for this club. Poll GET /campaigns/:unique_id/auction for the live state (highest bid, your position, time left) or subscribe to the WebSocket for realtime updates.

6. Venue network

Your partner venues come with the platform — pubs, bars and restaurants where your fans check in, earn points and claim your venue offers. Every venue flow follows the same mechanic: your app shows a QR, venue staff scan and confirm it in person, your app polls until the decision lands. QRs expire after 10 minutes.

Find venues

GET /fan/nearby_venues?latitude=51.55&longitude=-0.10&radius_km=5 — partner venues around the fan:

{
  "success": true,
  "data": {
    "venues": [
      {
        "unique_id": "ven_redlion",
        "name": "The Red Lion",
        "category": "Pub",
        "address": "12 High St",
        "city": "London",
        "rating": 4.6,
        "distance_km": 0.42,
        "operating_status": "Open",
        "coordinates": { "latitude": 51.5521, "longitude": -0.1044 }
      }
    ],
    "search_params": { "latitude": 51.55, "longitude": -0.1, "radius_km": 5.0, "total_found": 1 }
  }
}

For a check-in campaign, GET /campaigns/:unique_id/venues lists its affiliated venues with each venue's side deal (e.g. "Buy 1 beer, 2nd 50% off") and checked_in_today so your UI can mark venues as done.

Venue check-in (QR confirmed by staff)

POST /campaigns/cmp_derby_checkin/venue_checkins
{ "venue_id": "ven_redlion" }
{
  "success": true,
  "message": "Show this QR to the venue to confirm",
  "data": {
    "unique_id": "vchk_8f2a…",
    "status": "pending",
    "qr_payload": "VCHK:Xb7…",
    "venue_points": 30,
    "side_deal": "Buy 1 beer, 2nd 50% off",
    "expires_at": "2026-09-12T21:10:00Z"
  }
}

Render qr_payload as a QR code, then poll GET /venue_checkins/:unique_id until status is approved (points + side deal to show staff) or rejected / expired. Re-calling the create endpoint while a QR is still live resumes the same QR (and re-notifies the venue) instead of duplicating it. Venue check-in points are once-per-day; on later same-day check-ins the fan still gets the side deal, just no extra points.

Venue offers (standalone promos)

GET /venue_offers?latitude=…&longitude=… — your club's active offers nearby, each with discount, fan_points, runs_today and the venue block. Claiming mirrors the check-in mechanic:

POST /venue_offers/vof_9ad21c/claim
{}
{
  "success": true,
  "message": "Show this QR to the venue to confirm",
  "data": {
    "unique_id": "vofc_8f2a…",
    "status": "pending",
    "qr_payload": "VOFR:Xb7…",
    "discount": "50% off mains",
    "fan_points": 25,
    "expires_at": "2026-09-10T19:40:00Z"
  }
}

Poll GET /venue_offer_claims/:unique_id until approved — the response then carries points_awarded and the discount to show at the till. Claims are once per offer per day; claiming outside the offer's weekdays returns 422 This offer isn't available today.

7. Profile & points

The profile object

GET /profile:

{
  "success": true,
  "data": {
    "unique_id": "usr_9f2ac1…",
    "email": "[email protected]",
    "first_name": "Alex",
    "last_name": "Carter",
    "avatar_url": "https://…",
    "engagement_points": 127,
    "points_by_club": [
      { "club_unique_id": "club_hollowmere", "club_name": "Hollowmere Town FC", "points": 127 }
    ],
    "subscribed_clubs": [
      { "unique_id": "club_hollowmere", "name": "Hollowmere Town FC", "subscribed_at": "2026-08-01T10:00:00Z" }
    ]
  }
}

PUT /profile updates first_name / last_name. Avatar upload is the one multipart endpoint: POST /profile/avatar with an avatar file field. DELETE /profile (password-confirmed) anonymizes the account permanently — wire it to your "delete account" screen; app-store rules require it.

Points & history

GET /profile/engagement_points — balance, last action and the fan's five most recent participations. GET /profile/campaign_history — the full paginated log; each row is self-contained:

{
  "id": 4211,
  "campaign": { "unique_id": "cmp_friday_pint", "name": "Friday Pint Deal", "campaign_type": "deal_code", "club_name": "Hollowmere Town FC" },
  "points_earned": 1,
  "bonus_points_earned": 0,
  "total_points": 1,
  "status": "success",
  "participated_at": "2026-08-07T18:12:00Z",
  "deal_code": "HOLLOWMERE-FRIDAY-20OFF",
  "location": { "latitude": 51.5549, "longitude": -0.1084, "accuracy": 8.0 }
}

deal_code re-surfaces the fan's earned codes (shared or unique) so your "my rewards" screen never loses them; location echoes what you sent at participation (null if you didn't).

Notifications & devices

GET /profile/notification_preferences returns exactly four booleans — all_campaigns, matchday_reminders, weekly_digest, partner_deals; PUT accepts a partial object of the same keys (anything else is rejected).

Register the push token after every successful login:

POST /devices
{
  "device_token": "a1b2c3…",
  "platform": "ios",
  "device_id": "3F2504E0-…",
  "app_version": "1.0.0",
  "apns_environment": "production"
}

Registration is idempotent and follows the signed-in account — on an account switch the handset's pushes switch with it. Call DELETE /devices/unregister on logout.

8. Errors your app should handle

Every error uses the same envelope; error.message is written to be shown to the fan as-is, so most error UI is one generic sheet:

{
  "success": false,
  "error": { "code": "UNPROCESSABLE_ENTITY", "message": "You've already participated in this campaign" },
  "meta": { "timestamp": "2026-09-12T18:00:00Z", "request_id": "7223a11b-…", "version": "v1" }
}
Code Status What to do
INVALID_CLUB_KEY 401 Your X-Club-Key is wrong or revoked. Config error — fail the build loudly, check the dashboard.
CLUB_PLAN_REQUIRED 403 Plan dropped below National — API access paused until upgrade.
AUTH_REQUIRED · TOKEN_EXPIRED · INVALID_TOKEN 401 Silently POST /auth/refresh; only on refresh failure send the fan to login.
EMAIL_NOT_VERIFIED 403 Points-earning actions need a verified email — reopen your verification screen (POST /auth/resend-verification).
ACCOUNT_SUSPENDED 403 Fraud-blocked account — show the message with your support link.
FORBIDDEN (on login) 403 The 3-club cap — show the server's message as-is.
NOT_FOUND 404 Doesn't exist — or belongs outside your club's universe. Treat both the same.
UNPROCESSABLE_ENTITY 422 Business rule: already participated, pool empty, bid too low, off-schedule offer, outside the geofence… Show message.
VALIDATION_ERROR 422 Invalid input — error.details is an array of field errors.
BAD_REQUEST 400 Malformed request (missing param, wrong content type).

Concrete 422 messages you will meet in the wild — all display-ready:

You've already participated in this campaign
All deal codes have been claimed
You must be near the event location to check in
You must be at the campaign location to participate
Bid must be at least 80
Insufficient points. You have 60 points for this club.
Survey responses are required
This offer isn't available today
You've already claimed this offer today

Rate limits: 100 requests/min per IP, 300 per token; login, register and password-reset endpoints are throttled harder. A 429 comes from the edge with a plain body (error, message, retry_after seconds) — back off and retry after the given delay.

9. Launch checklist

Setup

  1. Generate keys in Dashboard → API Access; embed gse_pk_… in the app, vault gse_sk_… on your servers.
  2. Send X-Club-Key on every request — including register and login.
  3. Point your builds at staging (dev.gamesetengage.com) until your flows are green; the same keys work on both.

Auth flows to test end-to-end

  1. Register → verify email → login → refresh loop (tokens live 15 minutes — refresh proactively, not on failure only).
  2. Login with an existing Game Set Engage account (auto-subscribe path) and with an account at the 3-club cap (expect the 403, show it kindly).
  3. Register the push token after every successful login; unregister on logout. Test an account switch on one device — pushes must follow.

Campaign flows to test per type you'll run

  1. One participation per type from §5, plus the repeat attempt (expect the friendly 422), the empty deal-code pool, and — for geofenced types — a check-in from outside the radius.
  2. Send optional location wherever the fan has granted permission — it costs nothing and feeds your analytics.

Venue flows (if you use the venue network)

  1. Open a venue check-in QR, let it expire (10 min), reopen; then a real staff-confirmed approve and the poll loop to approved.

Before the store release

  1. Wire DELETE /profile (account deletion) into settings — app-store rules require it.
  2. Make sure error sheets show error.message verbatim and quote meta.request_id in your support links.
  3. Switch base URL to production, do one full smoke pass, ship.

Questions, or a capability you're missing? Contact us — we answer fast.

Game Set Engage

We help sports clubs know their fans, reward the ones who show up, and prove it to sponsors. Free to start.

Solutions

  • For Clubs
  • For Venues
  • For Fans
  • Fan Engagement
  • Revenue Growth
  • Community Building
  • Data & Analytics

Industries

  • College Athletics
  • Small Programs (D2/D3)
  • Local Councils
  • Sports Bars
  • Pubs & Restaurants
  • Entertainment
  • Retail Partners

Product

  • Pricing
  • Developers
  • naim AI
  • Use Cases
  • System Status

Resources

  • Fan Engagement Platform
  • What Is Fan Engagement?
  • Sports Fundraising Ideas
  • Blog
  • Compare
  • Guides & eBooks
  • The Data-Driven Fan
  • Help Center

Company

  • About Us
  • Careers
  • Contact
  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • GDPR
© 2026 Game Set Engage Ltd. All rights reserved.

We use cookies to measure site performance and improve your experience. Cookie Policy.