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

Read more about API keys →

Base URL

https://besokskollen.se/api/v1

Types of API Keys

There are two types of API keys with different permissions:

TypeAccessUsage
User LevelAll sites in accountDashboards, admin tools
Site LevelSingle site onlyISR, frontend integration

Read more about API keys →

Sites

Manage sites in your account. Requires User Level key.

List Sites

GET/sites
include_statsbooleanInclude 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/:siteId

Returns details for a specific site.

Statistics

Fetch traffic statistics for your sites.

Overview

GET/stats/overview
site_idstringSite ID *required
periodstring'7d', '30d', '90d', or 'custom'
from, tostringFor custom period (YYYY-MM-DD)
comparebooleanInclude 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/pages

Traffic Sources

GET/stats/referrers

Returns referrers. Use include_social=true to include social networks.

Countries

GET/stats/countries

Event Properties

Register and manage event properties to track custom data like product_id, category_slug, etc.

List Properties

GET/properties?site_id=xxx

Returns 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/properties

Register a new event property. Properties must be registered before they can be included in events.

{ "site_id": "xxx", "name": "product_id" }
namestringProperty name (lowercase, only letters, numbers, _ and -)

Delete Property

DELETE/properties?site_id=xxx&name=product_id

Removes a property and all its stored values.

Goals

Manage goals and conversions.

List Goals

GET/goals?site_id=xxx

Returns 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_xxx

Removes a goal and all conversion data.

Funnels

Manage funnels for conversion analysis.

List Funnels

GET/funnels?site_id=xxx

Create 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_xxx

Removes 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/products

Returns the most clicked products for a site.

Query Parameters

ParameterTypeDescription
site_idstringSite ID *required
daysnumberNumber of days to include (default: 30)
limitnumberMax number of products (default: 20)
category_slugstringFilter by category
brand_slugstringFilter by brand
min_clicksnumberMinimum 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/categories

Returns the most clicked categories for a site.

Query Parameters

site_idstringSite ID *required
daysnumberNumber of days to include (default: 30)
limitnumberMax number (default: 10)

Response

{
  "data": [
    { "category_slug": "mobilskal", "clicks": 234 },
    { "category_slug": "skarmskydd", "clicks": 189 }
  ],
  "meta": { ... }
}

Popular Partners

GET/popular/partners

Returns 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/products

Find products with unusually high activity compared to their baseline. Perfect for displaying "Hot Right Now" sections.

Query Parameters

ParameterTypeDescription
site_idstringSite ID *required
limitnumberMax number of products (default: 10)
recent_hoursnumberHours to analyze (default: 24)
baseline_daysnumberDays for baseline (default: 7)
min_growthnumberMinimum growth percentage (default: 100)
min_recent_clicksnumberMinimum clicks in period (default: 3)
category_slugstringFilter by category
brand_slugstringFilter 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/batch

Combine 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:

LevelCriteriaRecommendation
high50+ total clicksDisplay as normal
medium10-49 clicksDisplay with warning or larger sample
low<10 clicksConsider 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 429 when exceeded)
  • Batch endpoint counts as 1 request regardless of sub-requests
  • Headers include X-RateLimit-Remaining and X-RateLimit-Reset

Error Codes

CodeDescription
400Invalid request (missing parameters, wrong format)
401Missing or invalid API key
403API key does not have permission to this resource
429Rate limit exceeded - wait and try again
500Server 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:

ToolDescription
savri_list_sitesList all sites in your account
savri_get_statsGet visitor statistics for a site
savri_get_pagesGet popular pages
savri_list_propertiesList registered event properties
savri_create_propertyRegister a new event property
savri_delete_propertyDelete an event property
savri_list_goalsList goals and conversions
savri_create_goalCreate a new goal
savri_delete_goalDelete a goal
savri_list_funnelsList funnels
savri_create_funnelCreate a new funnel
savri_delete_funnelDelete a funnel
savri_get_funnel_statsGet 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