API reference

Access your analytics data programmatically with the Glyphex REST API.

Authentication

All API requests require a Bearer token. Create an API key in your site settings under API keys.

curl https://glyphex.io/api/v1/stats/overview?range=30d \
  -H "Authorization: Bearer glx_your_api_key_here"

Your full API key is shown only once when you create it. Store it securely.

Base URL

https://glyphex.io/api/v1

Rate limits

Rate limits are applied per API key on a sliding 1-hour window.

PlanRequests per hour
Free100
Pro1,000

Every response includes rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix timestamp).

Response format

All successful responses return JSON with this structure:

{
  "data": { ... },
  "meta": {
    "site_id": "your-site-id",
    "range": "30d",
    "generated_at": "2026-02-18T12:00:00.000Z"
  }
}

Errors return a similar structure with an error object:

{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid Authorization header. Use: Bearer glx_..."
  }
}

Query parameters

All endpoints accept these query parameters:

ParameterDefaultDescription
range30dTime range: 24h, 7d, 30d, 90d, or custom
start-Start date for custom range (ISO 8601)
end-End date for custom range (ISO 8601)
limit10Number of results (1-100). Applies to pages, referrers, devices, geo, events, utm
country-Filter by country code (e.g. US, DE)
device-Filter by device type (desktop, mobile, tablet)
browser-Filter by browser name
os-Filter by operating system
hostname-Filter by hostname
channel-Filter by traffic channel
utm_source-Filter by UTM source

Endpoints

GET/api/v1/stats/overview

Aggregated stats for the selected period with comparison to the previous period.

Change values are percentages. A null change value means the previous period had zero.

{
  "data": {
    "current": {
      "visitors": 1240,
      "pageviews": 3891,
      "sessions": 1580,
      "bounce_rate": 42,
      "avg_duration": 127
    },
    "previous": {
      "visitors": 1100,
      "pageviews": 3200,
      "sessions": 1400,
      "bounce_rate": 45,
      "avg_duration": 115
    },
    "change": {
      "visitors": 13,
      "pageviews": 22,
      "sessions": 13,
      "bounce_rate": -7,
      "avg_duration": 10
    }
  },
  "meta": { "site_id": "...", "range": "30d", "generated_at": "..." }
}
GET/api/v1/stats/timeseries

Daily visitor and pageview counts for the selected period.

{
  "data": [
    { "date": "2026-02-01", "visitors": 42, "pageviews": 128 },
    { "date": "2026-02-02", "visitors": 38, "pageviews": 104 }
  ],
  "meta": { "site_id": "...", "range": "30d", "generated_at": "..." }
}
GET/api/v1/stats/pages

Most visited pages ranked by views.

{
  "data": [
    { "pathname": "/", "title": "Home", "views": 520, "visitors": 380 },
    { "pathname": "/pricing", "title": "Pricing", "views": 210, "visitors": 180 }
  ],
  "meta": { "site_id": "...", "range": "30d", "limit": 10, "generated_at": "..." }
}
GET/api/v1/stats/referrers

Top traffic sources by referrer domain.

{
  "data": [
    { "referrer": "google.com", "views": 320, "visitors": 280 },
    { "referrer": "twitter.com", "views": 85, "visitors": 72 }
  ],
  "meta": { "site_id": "...", "range": "30d", "limit": 10, "generated_at": "..." }
}
GET/api/v1/stats/channels

Visitor breakdown by traffic channel (direct, organic, social, referral, etc.).

{
  "data": [
    { "channel": "Organic", "visitors": 580, "percentage": 47 },
    { "channel": "Direct", "visitors": 340, "percentage": 27 },
    { "channel": "Social", "visitors": 200, "percentage": 16 }
  ],
  "meta": { "site_id": "...", "range": "30d", "generated_at": "..." }
}
GET/api/v1/stats/devices

Visitor breakdown by device type.

{
  "data": [
    { "name": "Desktop", "visitors": 820 },
    { "name": "Mobile", "visitors": 350 },
    { "name": "Tablet", "visitors": 70 }
  ],
  "meta": { "site_id": "...", "range": "30d", "limit": 10, "generated_at": "..." }
}
GET/api/v1/stats/geo

Visitor breakdown by country.

{
  "data": [
    { "name": "United States", "visitors": 480 },
    { "name": "Germany", "visitors": 220 },
    { "name": "United Kingdom", "visitors": 180 }
  ],
  "meta": { "site_id": "...", "range": "30d", "limit": 10, "generated_at": "..." }
}
GET/api/v1/stats/events

Custom event counts and unique visitors.

{
  "data": [
    { "name": "signup_click", "count": 142, "visitors": 130 },
    { "name": "download_pdf", "count": 87, "visitors": 65 }
  ],
  "meta": { "site_id": "...", "range": "30d", "limit": 10, "generated_at": "..." }
}
GET/api/v1/stats/utm

Visitor breakdown by UTM source.

{
  "data": [
    { "name": "google", "visitors": 320 },
    { "name": "newsletter", "visitors": 85 }
  ],
  "meta": { "site_id": "...", "range": "30d", "limit": 10, "generated_at": "..." }
}

Error codes

StatusCodeDescription
401unauthorizedMissing or invalid Authorization header
401invalid_keyAPI key not found or invalid format
401key_disabledAPI key has been disabled
401key_expiredAPI key has passed its expiry date
429rate_limit_exceededToo many requests. Check X-RateLimit-Reset header
500internal_errorServer error fetching data

CORS

All endpoints allow cross-origin requests. Responses include Access-Control-Allow-Origin: *. You can call the API from browser-side JavaScript, but be careful not to expose your API key in client-side code.

Example: fetch top pages from JavaScript

const response = await fetch(
  "https://glyphex.io/api/v1/stats/pages?range=7d&limit=5",
  {
    headers: {
      "Authorization": "Bearer glx_your_api_key_here"
    }
  }
);

const { data, meta } = await response.json();

// data = [{ pathname: "/", title: "Home", views: 520, visitors: 380 }, ...]

Need help?

If you have questions about the API, reach out at support@glyphex.io