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

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" }

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
  }
}

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