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 in a fixed 1-hour window that starts at your first request and resets one hour later.
| Plan | Requests per hour |
|---|---|
| Starter | 1,000 |
| Growth | 2,000 |
| Scale | 3,000 |
| Agency | 5,000 |
Responses that pass authentication include rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix timestamp). Authentication failures (401, and 403 plan_required) do not include them.
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:
| Parameter | Default | Description |
|---|---|---|
range | 30d | Time range: 24h, 7d, 30d, 90d, 12m, or custom |
start | - | Start date for custom range (ISO 8601) |
end | - | End date for custom range (ISO 8601) |
limit | 10 | Number 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) |
hostname | - | Filter by hostname |
utm_source | - | Filter by UTM source |
Country exclusions
If you have configured excluded countries in your site settings, those exclusions are automatically applied to all API responses. You do not need to pass any additional parameters. The API uses the same exclusion list as the dashboard and email reports.
Endpoints
/api/v1/stats/overviewAggregated 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": "..." }
}/api/v1/stats/timeseriesDaily 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": "..." }
}/api/v1/stats/pagesMost 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": "..." }
}/api/v1/stats/referrersTop 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": "..." }
}/api/v1/stats/channelsVisitor 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": "..." }
}/api/v1/stats/devicesVisitor 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": "..." }
}/api/v1/stats/geoVisitor 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": "..." }
}/api/v1/stats/eventsCustom 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": "..." }
}/api/v1/stats/utmVisitor breakdown by UTM source.
{
"data": [
{ "name": "google", "visitors": 320 },
{ "name": "newsletter", "visitors": 85 }
],
"meta": { "site_id": "...", "range": "30d", "limit": 10, "generated_at": "..." }
}Error codes
| Status | Code | Description |
|---|---|---|
| 401 | unauthorized | Missing or invalid Authorization header |
| 401 | invalid_key | API key not found or invalid format |
| 401 | key_disabled | API key has been disabled |
| 401 | key_expired | API key has passed its expiry date |
| 400 | site_required | Account key used without ?site_id= |
| 400 | invalid_parameter | Invalid query parameter value |
| 400 | invalid_date | start or end is not a valid date |
| 400 | unsupported_filter | Filter (browser, os, channel) is not yet supported |
| 403 | plan_required | API access requires a Starter plan or higher |
| 403 | forbidden | Key does not have access to that site |
| 429 | rate_limit_exceeded | Too many requests. Check X-RateLimit-Reset header |
| 500 | internal_error | Server 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 via