Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/samgutentag/sbburgerweek/llms.txt

Use this file to discover all available pages before exploring further.

The Cloudflare Worker exposes a simple REST API for event ingestion and stats queries. All endpoints live on the Worker’s root URL (e.g. https://sbburgerweek-track.YOUR_SUBDOMAIN.workers.dev). CORS is enabled for all origins — the Worker reflects the request’s Origin header back as Access-Control-Allow-Origin, so it works when called from any domain including your GitHub Pages site.
The Worker sets Access-Control-Allow-Origin to the request’s Origin header (falling back to * when no Origin is present). This means CORS preflight requests succeed from any domain — no additional configuration is required.

POST /

Record a tracking event. Called automatically by track.js via navigator.sendBeacon whenever a user interacts with the map. Request body — JSON with two fields:
action
string
required
The event type, e.g. "view", "directions-google", "upvote". See Tracking Events for the full list.
label
string
required
The subject of the event — usually a restaurant name, area name, tag name, or "tip-jar".
Response — plain text "ok" with a 200 status.
body
string
"ok"
No authentication is required. The endpoint accepts requests from any origin.
// Example — manually fire a tracking event
fetch("https://sbburgerweek-track.YOUR_SUBDOMAIN.workers.dev", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ action: "view", label: "Mesa Burger" }),
});
During an active event, the POST handler writes a data point to the Cloudflare Analytics Engine binding (TRACKER). When winding down after an event, an early return new Response("ok") is added to disable writes while keeping the GET endpoints functional. See the Architecture page for the wind-down process.

GET /

Return a per-restaurant breakdown of all tracked action counts since the event start date. No query parameters required. Response — JSON object keyed by restaurant name. Each value is an object of action → count pairs.
body
object
{ "Mesa Burger": { "view": 142, "directions-google": 37, "website": 18, "upvote": 55, ... }, ... }
{
  "Mesa Burger": {
    "view": 142,
    "directions-google": 37,
    "directions-apple": 12,
    "website": 18,
    "phone": 4,
    "instagram": 9,
    "share": 21,
    "upvote": 55,
    "un-upvote": 3
  },
  "The Lark": {
    "view": 98,
    "directions-google": 22
  }
}
This endpoint is queried by the /stats leaderboard page to build its engagement rankings.

GET /?upvotes=true

Return net upvote counts (upvotes minus un-upvotes) per restaurant, filtered to restaurants with a positive net score. Response — flat JSON object of restaurant name → net upvote count.
body
object
{ "Mesa Burger": 52, "The Lark": 31, ... } — only restaurants with net > 0 are included.
{
  "Mesa Burger": 52,
  "The Lark": 31,
  "Lucky's": 19
}

GET /?hourly=true

Return a breakdown of event action counts grouped by hour. Defaults to the last 7 days if no date range is provided. Query parameters:
hourly
string
required
Must be "true" to activate this mode.
start
string
Start date in YYYY-MM-DD format (inclusive). Uses 00:00:00 of that day.
end
string
End date in YYYY-MM-DD format (inclusive). Uses 23:59:59 of that day.
Response — JSON object keyed by ISO 8601 hour timestamp. Each value is an action → count map.
body
object
{ "2026-02-19T14:00:00Z": { "view": 83, "share": 12, ... }, ... }
{
  "2026-02-19T14:00:00Z": {
    "view": 83,
    "share": 12,
    "directions-google": 29
  },
  "2026-02-19T15:00:00Z": {
    "view": 61,
    "share": 8
  }
}

GET /?hourly=true&label=X

Return hourly event counts for a specific restaurant or label. Useful for per-restaurant trend charts. Query parameters:
hourly
string
required
Must be "true".
label
string
required
The restaurant name (or any label value) to filter by.
start
string
Start date in YYYY-MM-DD format (optional; defaults to last 7 days).
end
string
End date in YYYY-MM-DD format (optional).
Response — flat JSON object of hour → total event count for the given label.
body
object
{ "2026-02-19T14:00:00Z": 47, "2026-02-19T15:00:00Z": 31, ... }
{
  "2026-02-19T14:00:00Z": 47,
  "2026-02-19T15:00:00Z": 31,
  "2026-02-19T16:00:00Z": 19
}

GET /?rum=true

Return device type, browser, and operating system breakdowns from Cloudflare Web Analytics (RUM) for the last 7 days. Response — JSON object with three sub-objects.
devices
object
Device type → page load count. E.g. { "Mobile": 4821, "Desktop": 2104, "Tablet": 312 }.
browsers
object
Browser name → count. E.g. { "Chrome": 3200, "Safari": 2900, ... }.
os
object
OS name → count. E.g. { "iOS": 2800, "Android": 2100, "macOS": 1200, ... }.
{
  "devices": { "Mobile": 4821, "Desktop": 2104, "Tablet": 312 },
  "browsers": { "Chrome": 3200, "Safari": 2900, "Firefox": 210 },
  "os": { "iOS": 2800, "Android": 2100, "macOS": 1200, "Windows": 800 }
}
This endpoint requires RUM_SITE_TAG to be set in wrangler.toml and a valid CF_API_TOKEN Worker secret with Analytics Engine read access.

GET /?active=true

Return a real-time snapshot of recent activity: event count in the last 5 minutes and unique page-load visitors in the last hour. Response — JSON object with two fields.
recentActions
number
Total tracked events fired in the last 5 minutes (from Analytics Engine).
visitors1h
number
Page load events in the last 1 hour (from Cloudflare RUM).
{
  "recentActions": 14,
  "visitors1h": 203
}
The response is served with Cache-Control: public, max-age=30 to limit upstream API calls while still providing a near-real-time feed.

GET /?admin=true&token=X

Return the top search queries entered by users over the last 7 days. This endpoint is token-protected. Query parameters:
admin
string
required
Must be "true".
token
string
required
Must exactly match the ADMIN_TOKEN Worker secret. Returns 403 Forbidden if missing or incorrect.
Response — JSON array of query objects, ordered by count descending.
body
array
[{ "query": "gluten free", "count": 42 }, ...] — up to 500 results.
[
  { "query": "gluten free", "count": 42 },
  { "query": "downtown", "count": 38 },
  { "query": "vegetarian", "count": 27 }
]
Set ADMIN_TOKEN via wrangler secret put ADMIN_TOKEN from the workers/track/ directory. Choose any password — you’ll pass it as ?token=yourpassword in the browser.

Build docs developers (and LLMs) love