Skip to main content
GET
/
api
/
v1
/
stats
URL Statistics
curl --request GET \
  --url https://spoo.me/api/v1/stats \
  --header 'Authorization: Bearer <token>'
{
  "scope": "<string>",
  "filters": {},
  "group_by": [
    "<string>"
  ],
  "timezone": "<string>",
  "time_range": {
    "start_date": "<string>",
    "end_date": "<string>"
  },
  "summary": {
    "total_clicks": 123,
    "unique_clicks": 123,
    "avg_redirection_time": 123,
    "first_click": "<string>",
    "last_click": "<string>"
  },
  "metrics": {},
  "generated_at": "<string>",
  "api_version": "<string>",
  "short_code": "<string>",
  "time_bucket_info": {
    "strategy": "<string>",
    "mongo_format": "<string>",
    "display_format": "<string>",
    "timezone": "<string>",
    "interval_minutes": 123
  },
  "computed_metrics": {
    "unique_click_rate": 123,
    "repeat_click_rate": 123,
    "average_clicks_per_visitor": 123
  }
}

Authorizations

Authorization
string
header
required

API key authentication. Pass your key as: Bearer spoo_<your_key>

Query Parameters

scope
enum<string>
required

Statistics scope: all (authenticated only) or anon (public access).

  • all — aggregate stats across all URLs owned by the authenticated user. Requires authentication.
  • anon — public stats for a single URL. Requires short_code parameter. No authentication needed (unless stats are private).
Available options:
all,
anon
short_code
string | null

URL alias to query stats for. Required when scope=anon. When scope=all, this is optional and filters stats to a specific URL.

Example:

"mylink"

start_date
string | null

Start of time range. Accepts ISO 8601 datetime string (e.g., 2025-01-01T00:00:00Z) or Unix timestamp in seconds (e.g., 1735689600). If omitted, defaults to the URL creation date.

Example:

"2025-01-01T00:00:00Z"

end_date
string | null

End of time range. Accepts ISO 8601 datetime string (e.g., 2025-12-31T23:59:59Z) or Unix timestamp in seconds (e.g., 1767225599). If omitted, defaults to now.

Example:

"2025-12-31T23:59:59Z"

group_by
string | null

Comma-separated grouping dimensions for the statistics breakdown. Defaults to time if omitted.

Available dimensions:

  • time — group by time buckets (day/week/month, auto-selected based on range)
  • browser — group by browser name (e.g., Chrome, Firefox, Safari)
  • os — group by operating system (e.g., Windows, macOS, Linux)
  • country — group by country
  • city — group by city
  • referrer — group by referrer URL
  • short_code — group by URL alias (only with scope=all)

Multiple dimensions can be combined: time,browser returns time series broken down by browser.

Example:

"time,browser"

metrics
string | null

Comma-separated metrics to include. Defaults to clicks,unique_clicks if omitted.

Available metrics:

  • clicks — total click count
  • unique_clicks — unique visitor count (deduplicated by IP + User-Agent)
Example:

"clicks,unique_clicks"

timezone
string
default:UTC

IANA timezone name for time-based grouping and output formatting (e.g., UTC, America/New_York, Asia/Kolkata). Defaults to UTC.

Examples:

"UTC"

"America/New_York"

filters
string | null

Method 1: JSON Filters Object

JSON string containing dimension filters. Format: {"dimension": ["value1", "value2"]}

Available filter dimensions:

  • browser — Filter by browser name (e.g., Chrome, Firefox, Safari, Edge)
  • os — Filter by operating system (e.g., Windows, macOS, Linux, iOS, Android)
  • country — Filter by country name (e.g., United States, Canada, Germany)
  • city — Filter by city name (e.g., New York, London, Mumbai)
  • referrer — Filter by referrer URL (e.g., https://google.com, https://twitter.com)
  • short_code — Filter by URL alias (e.g., mylink, promo2024) — not allowed with scope=anon

Value format: Array of strings for each dimension.

Important: Filter values are case-sensitive. Use exact capitalization as stored in the database.

Examples:

  • {"browser": ["Chrome", "Firefox"]} — Chrome OR Firefox clicks
  • {"country": ["United States", "Canada"], "browser": ["Chrome"]} — US/CA clicks from Chrome
  • {"short_code": ["link1", "link2"]} — Stats for specific URLs (scope=all only)

Alternative: You can also pass filters as individual query parameters (see browser, os, country, city, referrer parameters below).

Example:

"{\"browser\":[\"Chrome\",\"Firefox\"]}"

browser
string | null

Method 2: Individual Filter Parameter

Comma-separated browser names. Alternative to using the filters JSON parameter.

Important: Values are case-sensitive. Common values include: Chrome, Firefox, Safari, Edge, Opera, Samsung Internet.

Note: Both filters JSON and individual parameters can be combined.

Example:

"Chrome,Firefox"

os
string | null

Method 2: Individual Filter Parameter

Comma-separated operating system names. Alternative to using the filters JSON parameter.

Important: Values are case-sensitive. Common values include: Windows, macOS, Linux, iOS, Android, Chrome OS.

Note: Both filters JSON and individual parameters can be combined.

Example:

"Windows,macOS"

country
string | null

Method 2: Individual Filter Parameter

Comma-separated country names. Alternative to using the filters JSON parameter.

Important: Values are case-sensitive. Use full country names as stored in the database (e.g., United States, Canada, United Kingdom, India, Germany, France, Japan).

Note: Both filters JSON and individual parameters can be combined.

Example:

"United States,Germany"

city
string | null

Method 2: Individual Filter Parameter

Comma-separated city names. Alternative to using the filters JSON parameter.

Important: Values are case-sensitive. Use exact capitalization as stored in the database.

Note: Both filters JSON and individual parameters can be combined.

Example:

"San Francisco,Berlin"

referrer
string | null

Method 2: Individual Filter Parameter

Comma-separated referrer URLs. Alternative to using the filters JSON parameter.

Important: Values are case-sensitive. Include the full URL including protocol.

Note: Both filters JSON and individual parameters can be combined.

Example:

"https://google.com,https://twitter.com"

Response

Successful Response

Response body for GET /api/v1/stats.

metrics uses dynamic keys ({metric}by{dimension}), each mapping to a list of data-point dicts. Optional fields (short_code, time_bucket_info, computed_metrics) are absent when not applicable.

scope
string
required
filters
Filters · object
required
group_by
string[]
required
timezone
string
required
time_range
StatsTimeRange · object
required

Time range metadata inside StatsResponse.

summary
StatsSummary · object
required

Summary statistics block inside StatsResponse.

metrics
Metrics · object

Keyed by '{metric}by{dimension}' (e.g. 'clicks_by_browser', 'unique_clicks_by_time'). Each value is a list of data-point objects whose keys are the dimension name, the metric name, and '{metric}_percentage'.

generated_at
string | null
api_version
string | null
short_code
string | null
time_bucket_info
TimeBucketInfo · object

Time bucketing metadata — only present when 'time' is in group_by.

computed_metrics
ComputedMetrics · object

Optional computed metrics added by format_stats_response_with_metadata.