Public API
Integrate your application with our REST API to fetch statistics, manage sites, and automate workflows.
Quick Links
Authentication
All API calls require an API key sent in the Authorization header:
Authorization: Bearer bk_din_api_nyckel
Base URL
https://besokskollen.se/api/v1
Types of API Keys
There are two types of API keys with different permissions:
| Type | Access | Usage |
|---|---|---|
| User Level | All sites in account | Dashboards, admin tools |
| Site Level | Single site only | ISR, frontend integration |
Sites
Manage sites in your account. Requires User Level key.
List Sites
GET/sitesinclude_stats | boolean | Include visitor statistics (last 7d) |
{
"data": [
{ "id": "site_abc123", "domain": "example.com", "verified": true, "has_data": true }
],
"meta": { "total": 1 }
}Create Site
POST/sites{ "domain": "example.com", "name": "Min sajt" }Get Site
GET/sites/:siteIdReturns details for a specific site.
Statistics
Fetch traffic statistics for your sites.
Overview
GET/stats/overviewsite_id | string | Site ID *required |
period | string | '7d', '30d', '90d', or 'custom' |
from, to | string | For custom period (YYYY-MM-DD) |
compare | boolean | Include comparison with previous period |
{
"data": {
"period": { "from": "2026-01-01", "to": "2026-01-14" },
"visitors": 1234,
"pageviews": 5678,
"sessions": 2345,
"bounce_rate": 42,
"daily": [{ "date": "2026-01-01", "visitors": 100, "pageviews": 300 }, ...]
}
}Popular Pages
GET/stats/pagesTraffic Sources
GET/stats/referrersReturns referrers. Use include_social=true to include social networks.
Countries
GET/stats/countriesGoals
Manage goals and conversions.
List Goals
GET/goals?site_id=xxxReturns all goals for a site with conversion statistics.
Create Goal
POST/goals// Pageview-mål
{ "site_id": "xxx", "name": "Checkout", "event_type": "pageview", "match_path": "/checkout" }
// Event-mål
{ "site_id": "xxx", "name": "Köp", "event_type": "event", "match_event": "purchase" }Funnels
Manage funnels for conversion analysis.
List Funnels
GET/funnels?site_id=xxxCreate Funnel
POST/funnels{
"site_id": "xxx",
"name": "Checkout-flöde",
"steps": [
{ "name": "Startsida", "type": "pageview", "match_value": "/" },
{ "name": "Produktsida", "type": "pageview", "match_value": "/produkt", "match_type": "startswith" },
{ "name": "Checkout", "type": "pageview", "match_value": "/checkout" },
{ "name": "Köp", "type": "event", "match_value": "purchase" }
]
}Get Funnel Statistics
GET/funnels/:funnelId/stats{
"data": {
"funnel": { "id": "...", "name": "Checkout-flöde" },
"steps": [
{ "name": "Startsida", "sessions": 1000, "dropoff_rate": 0, "conversion_from_start": 100 },
{ "name": "Produktsida", "sessions": 600, "dropoff_rate": 40, "conversion_from_start": 60 },
{ "name": "Checkout", "sessions": 200, "dropoff_rate": 67, "conversion_from_start": 20 },
{ "name": "Köp", "sessions": 50, "dropoff_rate": 75, "conversion_from_start": 5 }
],
"overall_conversion": 5
}
}Affiliate Analytics
Endpoints for fetching click data from affiliate sites. Perfect for displaying popular products, trending items, and category statistics.
GET/popular/productsReturns the most clicked products for a site.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
site_id | string | Site ID *required |
days | number | Number of days to include (default: 30) |
limit | number | Max number of products (default: 20) |
category_slug | string | Filter by category |
brand_slug | string | Filter by brand |
min_clicks | number | Minimum number of clicks |
Example
curl -H "Authorization: Bearer bk_xxx" \ "https://besokskollen.se/api/v1/popular/products?site_id=mobildelar-se&days=7&limit=5"
{
"data": [
{ "product_id": "iphone-15-skal", "product_slug": "iphone-15-skal", "clicks": 47 },
{ "product_id": "samsung-s24-glas", "product_slug": "samsung-s24-glas", "clicks": 35 }
],
"meta": {
"period": { "from": "2025-01-01T00:00:00Z", "to": "2025-01-07T23:59:59Z" },
"total_clicks": 523,
"confidence": "high"
}
}Popular Categories
GET/popular/categoriesReturns the most clicked categories for a site.
Query Parameters
site_id | string | Site ID *required |
days | number | Number of days to include (default: 30) |
limit | number | Max number (default: 10) |
Response
{
"data": [
{ "category_slug": "mobilskal", "clicks": 234 },
{ "category_slug": "skarmskydd", "clicks": 189 }
],
"meta": { ... }
}Popular Partners
GET/popular/partnersReturns the most used affiliate partners with click distribution.
Response
{
"data": [
{ "partner_slug": "teknikdelar", "clicks": 156, "share": 0.42 },
{ "partner_slug": "kjell", "clicks": 98, "share": 0.26 }
],
"meta": { ... }
}Trending Products
GET/trending/productsFind products with unusually high activity compared to their baseline. Perfect for displaying "Hot Right Now" sections.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
site_id | string | Site ID *required |
limit | number | Max number of products (default: 10) |
recent_hours | number | Hours to analyze (default: 24) |
baseline_days | number | Days for baseline (default: 7) |
min_growth | number | Minimum growth percentage (default: 100) |
min_recent_clicks | number | Minimum clicks in period (default: 3) |
category_slug | string | Filter by category |
brand_slug | string | Filter by brand |
Example
curl -H "Authorization: Bearer bk_xxx" \ "https://besokskollen.se/api/v1/trending/products?site_id=mobildelar-se&min_growth=50"
{
"data": [
{
"product_id": "airpods-pro-2",
"product_slug": "airpods-pro-2",
"clicks_recent": 15,
"clicks_baseline_avg": 3.2,
"growth_percent": 369
},
{
"product_id": "iphone-16-skal",
"product_slug": "iphone-16-skal",
"clicks_recent": 8,
"clicks_baseline_avg": 2.1,
"growth_percent": 281
}
],
"meta": {
"recent_period": { "hours": 24, "from": "...", "to": "..." },
"baseline_period": { "days": 7, "from": "...", "to": "..." },
"total_trending": 12
}
}Use Cases
- "Hot Right Now" - Display products with sudden popularity surge
- Trending badges - Show "Trending" badges on products with >200% growth
- Push notifications - Send notifications about trending products
Batch Requests
POST/batchCombine multiple API calls in one request to reduce latency and request count.
Request body
{
"site_id": "mobildelar-se",
"requests": [
{ "endpoint": "popular/products", "params": { "limit": 10, "days": 7 } },
{ "endpoint": "popular/categories", "params": { "limit": 5, "days": 30 } },
{ "endpoint": "trending/products", "params": { "min_growth": 50 } }
]
}Response
{
"results": [
{ "endpoint": "popular/products", "data": [...], "meta": {...} },
{ "endpoint": "popular/categories", "data": [...], "meta": {...} },
{ "endpoint": "trending/products", "data": [...], "meta": {...} }
]
}Caching and ISR
All endpoints return cache headers that work well with Next.js ISR (Incremental Static Regeneration).
Cache-Control: public, max-age=1800, stale-while-revalidate=3600, stale-if-error=86400
- max-age=1800: Data is fresh for 30 minutes
- stale-while-revalidate=3600: Can serve stale data while fetching new (1 hour)
- stale-if-error=86400: On error, use stale data up to 24 hours
Important for ISR
Use revalidate: 1800 in your Next.js config to sync with our cache headers.
Confidence Level
Affiliate endpoints return a confidence field in meta indicating data quality:
| Level | Criteria | Recommendation |
|---|---|---|
| high | 50+ total clicks | Display as normal |
| medium | 10-49 clicks | Display with warning or larger sample |
| low | <10 clicks | Consider showing fallback content |
Example: Fallback at low confidence
const response = await fetch('/api/v1/popular/products?site_id=xxx');
const data = await response.json();
if (data.meta.confidence === 'low') {
// Använd fallback: visa senast uppdaterade produkter istället
return getFallbackProducts();
}
return data.data;Rate Limiting
The API has rate limiting to ensure stable performance for all users. Current limits:
- 100 requests per minute per API key (returns
429when exceeded) - Batch endpoint counts as 1 request regardless of sub-requests
- Headers include X-RateLimit-Remaining and X-RateLimit-Reset
Error Codes
| Code | Description |
|---|---|
400 | Invalid request (missing parameters, wrong format) |
401 | Missing or invalid API key |
403 | API key does not have permission to this resource |
429 | Rate limit exceeded - wait and try again |
500 | Server error - contact support if it continues |
Tips for Best Performance
- Use batch endpoint to combine multiple calls
- Respect cache headers to avoid unnecessary calls
- Implement exponential backoff on 429 errors
- Cache responses client-side when possible