API Documentation

Welcome! This is the documentation for the NeatStats API, which lets you pull your own site’s view statistics programmatically.

Authentication

All requests require authentication with an API key, which you can find on your account page. You can use the key with an Authorization: Bearer <token> header (where the token is your API key), or as the password in an HTTP Basic authentication request (the username can be anything, as long as the password is your API key).

Every request is scoped to a single site, specified in the URL path. Your API key must belong to the account that owns that site (you can only retrieve stats for sites you own).

The API supports cross-origin requests (CORS), so it's safe to call directly from browser-based JavaScript.

Common parameters

Most endpoints accept a range parameter, and several also accept a limit parameter. There’s also a sort parameter that can be used where it makes sense. Here’s how these work:

Errors

When something goes wrong, you'll get a non-200 http_response_code along with an error field describing what happened:

{
	"http_response_code": 400,
	"http_response_text": "Bad Request",
	"error": "Invalid range. Must be one of: 24h, 7d, 30d, 6m, 1y."
}

Endpoints

The API currently offers endpoints in a single category: Sites.

Sites

Site endpoints support retrieving stats for your sites, identified by the site domain in the URL path.

Get site info

GET /api/v1/sites/site/info

Fetches basic info about a site, like its verification status and a lifetime summary of its views.

Sample response

{
	"http_response_code": 200,
	"http_response_text": "OK",
	"site": {
		"domain": "example.com",
		"verified": true,
		"verified_at": "2026-01-19 03:12:07 UTC",
		"verified_by": "dns",
		"summary": {
			"view_count": 303908,
			"first_view_at": 1768863455,
			"last_view_at": 1788524730,
			"executive_summary": "Your site has a total of 303,908 views since 2026-01-19. The most recent view was 9 minutes ago."
		}
	}
}

Get page views

GET /api/v1/sites/site/views

Fetches a time-series of view counts, bucketed automatically based on the requested range (15-minute buckets for 24h, hourly for 7d, every six hours for 30d, daily for 6m, and weekly for 1y). Also returns an SVG line chart of the same data. And the total number of views recorded for the requested range.

Accepts: range

Sample response

{
	"http_response_code": 200,
	"http_response_text": "OK",
	"site": "example.com",
	"range": "24h",
	"bucket_seconds": 900,
	"start": 1788490800,
	"end": 1788577200,
	"total_views": 13,
	"data": [
		{ "ts": 1788490800, "views": 4 },
		{ "ts": 1788491700, "views": 7 },
		{ "ts": 1788492600, "views": 2 }
	],
	"chart_svg": ""
}

Get browser breakdown

GET /api/v1/sites/site/browsers

Fetches a breakdown of views by browser, along with an SVG donut chart of the same data.

Accepts: range, limit

Sample response

{
	"http_response_code": 200,
	"http_response_text": "OK",
	"site": "example.com",
	"range": "7d",
	"data": {
		"Chrome": 412,
		"Safari": 298,
		"Firefox": 54,
		"Edge": 22,
		"Yandex": 9
	},
	"chart_svg": ""
}

Get platform breakdown

GET /api/v1/sites/site/platforms

Fetches a breakdown of views by platform (operating system), along with an SVG donut chart of the same data.

Accepts: range, limit

Sample response

{
	"http_response_code": 200,
	"http_response_text": "OK",
	"site": "example.com",
	"range": "7d",
	"data": {
		"Macintosh": 301,
		"Windows": 187,
		"Android": 122,
		"iPhone": 98,
		"Linux": 41
	},
	"chart_svg": ""
}

Get top pages

GET /api/v1/sites/site/pages

Fetches the most viewed pages on your site, ranked by view count.

Accepts: range, limit

Sample response

{
	"http_response_code": 200,
	"http_response_text": "OK",
	"site": "example.com",
	"range": "7d",
	"total_paths": 47,
	"data": {
		"/": 1204,
		"/about": 389,
		"/blog/hello-world": 201
	}
}

Get top referrers

GET /api/v1/sites/site/referrers

Fetches the sites and pages that sent you the most traffic, ranked by view count.

Accepts: range, limit

Sample response

{
	"http_response_code": 200,
	"http_response_text": "OK",
	"site": "example.com",
	"range": "7d",
	"total_referrers": 132,
	"data": {
		"https://google.com/": 1204,
		"https://reddit.com/": 897,
		"https://neatnik.net/": 213
	}
}

Get map data

GET /api/v1/sites/site/map

Fetches per-location view counts, with coordinates suitable for plotting on a map.

Accepts: range, limit

Sample response

{
	"http_response_code": 200,
	"http_response_text": "OK",
	"site": "example.com",
	"range": "24h",
	"total_locations": 62,
	"data": [
		{
			"geonameid": 5128581,
			"name": "New York City",
			"country_iso": "US",
			"latitude": 40.71427,
			"longitude": -74.00597,
			"views": 214
		},
		{
			"geonameid": 2643743,
			"name": "London",
			"country_iso": "GB",
			"latitude": 51.50853,
			"longitude": -0.12574,
			"views": 88
		}
	]
}

Get country totals

GET /api/v1/sites/site/countries

Fetches view totals grouped by country, using ISO 3166-1 alpha-2 country codes.

Accepts: range, limit

Sample response

{
	"http_response_code": 200,
	"http_response_text": "OK",
	"site": "example.com",
	"range": "24h",
	"total_countries": 18,
	"data": {
		"US": 512,
		"GB": 88,
		"DE": 41
	}
}

You've reached the end of our API documentation.

We hope this was helpful. If you have questions, or there's an endpoint you'd find useful that isn't here yet, please let us know.