Public API
Integrate your application with our REST API to fetch statistics, manage sites, and automate workflows.
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/countriesEvent Properties
Register and manage event properties to track custom data like product_id, category_slug, etc.
List Properties
GET/properties?site_id=xxxReturns all registered properties for a site with unique value counts.
{
"data": [
{ "id": 1, "name": "product_id", "created_at": "2026-01-15T10:00:00Z", "unique_values": 156 },
{ "id": 2, "name": "category_slug", "created_at": "2026-01-15T10:00:00Z", "unique_values": 12 }
],
"meta": { "total": 2 }
}Create Property
POST/propertiesRegister a new event property. Properties must be registered before they can be included in events.
{ "site_id": "xxx", "name": "product_id" }name | string | Property name (lowercase, only letters, numbers, _ and -) |
Delete Property
DELETE/properties?site_id=xxx&name=product_idRemoves a property and all its stored values.
Goals
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" }Delete Goal
DELETE/goals?site_id=xxx&goal_id=goal_xxxRemoves a goal and all conversion data.
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
}
}Delete Funnel
DELETE/funnels?site_id=xxx&funnel_id=funnel_xxxRemoves a funnel and all its steps.
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
MCP / AI Integration
Use MCP (Model Context Protocol) to let AI assistants like Claude interact directly with your analytics data.
What is MCP?
MCP is an open protocol that lets AI models connect to external tools and data sources. With @savri/mcp you can talk to Claude and ask it to manage your analytics - create properties, set up funnels, fetch statistics and more.
Installation
Add the following to your Claude Desktop configuration (claude_desktop_config.json):
{
"mcpServers": {
"savri": {
"command": "npx",
"args": ["@savri/mcp"],
"env": {
"SAVRI_API_KEY": "bk_your_api_key_here"
}
}
}
}Available Tools
The MCP server exposes the following tools that Claude can use:
| Tool | Description |
|---|---|
savri_list_sites | List all sites in your account |
savri_get_stats | Get visitor statistics for a site |
savri_get_pages | Get popular pages |
savri_list_properties | List registered event properties |
savri_create_property | Register a new event property |
savri_delete_property | Delete an event property |
savri_list_goals | List goals and conversions |
savri_create_goal | Create a new goal |
savri_delete_goal | Delete a goal |
savri_list_funnels | List funnels |
savri_create_funnel | Create a new funnel |
savri_delete_funnel | Delete a funnel |
savri_get_funnel_stats | Get funnel statistics with conversion data |
Example Usage
Here's an example of how you can talk to Claude to configure your analytics:
User: "Registrera en property för product_id på min sajt" Claude: Jag registrerar property "product_id" för din sajt. [savri_create_property: site_id=xxx, name=product_id] ✅ Property "product_id" har skapats! Nu kan du inkludera denna property i dina affiliate_click events.
Use Cases
- Quick setup - Ask Claude to configure properties and goals for your new site
- Funnel analysis - Let Claude create and analyze conversion funnels
- Daily reports - Ask Claude about yesterday's traffic or trends
- Debugging - Ask Claude to verify your tracking is working correctly