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.
| Plan | Requests per hour |
|---|---|
| Free | 100 |
| Pro | 1,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:
| Parameter | Default | Description |
|---|---|---|
range | 30d | Time range: 24h, 7d, 30d, 90d, 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) |
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
/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 |
| 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 at support@glyphex.io