GoatCounter Sites API
The Sites API from GoatCounter — 2 operation(s) for sites.
The Sites API from GoatCounter — 2 operation(s) for sites.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/goatcounter-sites-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Goatcounter Sites API
version: '1.0'
description: 'Operations tagged sites across 2 of this provider''s published API definitions: goatcounter-api-swagger20.json, goatcounter-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://goatcounter.com/api/v0
description: Hosted GoatCounter (replace host with your site's subdomain)
tags:
- name: sites
paths:
/api/v0/sites:
get:
operationId: GET_api_v0_sites
responses:
'200':
description: 200 OK
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.apiSitesResponse'
'400':
description: 400 Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.apiError'
'401':
description: 401 Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
'403':
description: 403 Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
summary: List all sites.
tags:
- sites
security:
- basicAuth: []
put:
operationId: PUT_api_v0_sites
responses:
'200':
description: 200 OK
content:
application/json:
schema:
$ref: '#/components/schemas/goatcounter.Site'
'400':
description: 400 Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.apiError'
'401':
description: 401 Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
'403':
description: 403 Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
summary: Create a new site.
tags:
- sites
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/goatcounter.Site'
required: true
security:
- basicAuth: []
/api/v0/sites/{id}:
get:
description: Get all information about one site.
operationId: GET_api_v0_sites_{id}
parameters:
- in: path
name: id
required: true
schema:
type: integer
responses:
'200':
description: 200 OK
content:
application/json:
schema:
$ref: '#/components/schemas/goatcounter.Site'
'400':
description: 400 Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.apiError'
'401':
description: 401 Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
'403':
description: 403 Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
summary: Get information about a site.
tags:
- sites
security:
- basicAuth: []
post:
description: 'A POST request will *replace* the entire site with what''s sent, blanking out
any existing fields that may exist. A PATCH request will only update the
fields that are sent.'
operationId: POST_api_v0_sites_{id}
parameters:
- in: path
name: id
required: true
schema:
type: integer
responses:
'200':
description: 200 OK
content:
application/json:
schema:
$ref: '#/components/schemas/goatcounter.Site'
'400':
description: 400 Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.apiError'
'401':
description: 401 Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
'403':
description: 403 Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
summary: Update a site.
tags:
- sites
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.apiSiteUpdateRequest'
required: true
security:
- basicAuth: []
patch:
description: 'A POST request will *replace* the entire site with what''s sent, blanking out
any existing fields that may exist. A PATCH request will only update the
fields that are sent.'
operationId: PATCH_api_v0_sites_{id}
parameters:
- in: path
name: id
required: true
schema:
type: integer
responses:
'200':
description: 200 OK
content:
application/json:
schema:
$ref: '#/components/schemas/goatcounter.Site'
'400':
description: 400 Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.apiError'
'401':
description: 401 Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
'403':
description: 403 Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.authError'
summary: Update a site.
tags:
- sites
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/handlers.apiSiteUpdateRequest'
required: true
security:
- basicAuth: []
/sites:
get:
summary: List sites
operationId: listSites
tags:
- sites
responses:
'200':
description: A list of sites.
security:
- bearerAuth: []
put:
summary: Create a new site
operationId: createSite
tags:
- sites
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Site'
responses:
'200':
description: Site created.
security:
- bearerAuth: []
servers:
- url: https://goatcounter.com/api/v0
description: Hosted GoatCounter (replace host with your site's subdomain)
/sites/{id}:
get:
summary: Get site detail
operationId: getSite
tags:
- sites
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Site detail.
security:
- bearerAuth: []
post:
summary: Update a site
operationId: updateSitePost
tags:
- sites
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Site'
responses:
'200':
description: Site updated.
security:
- bearerAuth: []
patch:
summary: Patch a site
operationId: patchSite
tags:
- sites
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Site'
responses:
'200':
description: Site updated.
security:
- bearerAuth: []
servers:
- url: https://goatcounter.com/api/v0
description: Hosted GoatCounter (replace host with your site's subdomain)
components:
schemas:
goatcounter.View:
title: View
description: 'Views for the dashboard; these settings apply to all widget and are
configurable in the yellow box at the top.'
type: object
properties:
filter:
type: string
group:
type: integer
name:
type: string
period:
description: '"week", "month", etc., or n days: "8"'
type: string
handlers.apiSiteUpdateRequest:
title: apiSiteUpdateRequest
type: object
properties:
cname:
type: string
link_domain:
type: string
settings:
$ref: '#/components/schemas/goatcounter.SiteSettings'
goatcounter.UserSettings:
title: UserSettings
description: UserSettings are all user preferences.
type: object
properties:
date_format:
type: string
datepicker:
type: boolean
email_reports:
type: integer
fewer_numbers:
type: boolean
fewer_numbers_lock_until:
type: string
format: date-time
language:
type: string
number_format:
type: string
sunday_starts_week:
type: boolean
theme:
type: string
timezone:
$ref: '#/components/schemas/tz.Zone'
twenty_four_hours:
type: boolean
views:
type: array
items:
$ref: '#/components/schemas/goatcounter.View'
widgets:
type: array
items:
$ref: '#/components/schemas/goatcounter.Widget'
tz.Zone:
title: Zone
description: Zone represents a time zone.
type: object
properties:
Abbr:
description: WITA – the correct abbreviation may change depending on the time of year (i.e. CET and CEST, depending on DST).
type: array
items:
type: string
Comments:
description: Borneo (east, south); Sulawesi/Celebes, Bali, Nusa Tengarra; Timor (west)
type: string
CountryCode:
description: ID
type: string
CountryName:
description: Indonesia
type: string
Zone:
description: Asia/Makassar
type: string
goatcounter.Widget:
title: Widget
description: Widgets is a list of widgets to be printed, in order.
type: object
handlers.apiError:
title: apiError
description: 'Generic API error. An error will have either the "error" or "errors"
field set, but not both.'
type: object
properties:
error:
type: string
errors:
type: object
handlers.authError:
title: authError
description: 'Authentication error: the API key was not provided or incorrect.'
type: object
properties:
Error:
type: string
goatcounter.SiteSettings:
title: SiteSettings
description: 'SiteSettings contains all the user-configurable settings for a site, with
the exception of the domain settings.
This is stored as JSON in the database.'
type: object
properties:
allow_bosmang:
type: boolean
allow_counter:
type: boolean
allow_embed:
type: array
items:
type: string
collect:
type: integer
collect_regions:
type: array
items:
type: string
data_retention:
type: integer
ignore_ips:
type: array
items:
type: string
public:
type: string
secret:
type: string
goatcounter.Site:
title: Site
type: object
properties:
cname:
description: 'Custom domain, e.g. "stats.example.com".
When self-hosting this is the domain/vhost your site is accessible at.'
type: string
cname_setup_at:
description: When the CNAME was verified.
type: string
format: date-time
readOnly: true
code:
description: 'Domain code (e.g. "arp242", which makes arp242.goatcounter.com). Only
used for goatcounter.com and not when self-hosting.'
type: string
created_at:
type: string
format: date-time
first_hit_at:
type: string
format: date-time
id:
type: integer
readOnly: true
link_domain:
description: 'Site domain for linking (www.arp242.net). Note this can be a full URL and
is a bit misnamed.'
type: string
parent:
type: integer
readOnly: true
received_data:
description: 'Whether this site has received any data; will be true after the first
pageview.'
type: boolean
setttings:
$ref: '#/components/schemas/goatcounter.SiteSettings'
state:
type: string
updated_at:
type: string
format: date-time
user_defaults:
$ref: '#/components/schemas/goatcounter.UserSettings'
handlers.apiSitesResponse:
title: apiSitesResponse
type: object
properties:
sites:
type: array
items:
$ref: '#/components/schemas/goatcounter.Site'
Site:
type: object
properties:
code:
type: string
cname:
type: string
link_domain:
type: string
settings:
type: object
securitySchemes:
basicAuth:
type: http
scheme: basic
bearerAuth:
type: http
scheme: bearer
x-refined-from:
- goatcounter-api-swagger20.json
- goatcounter-openapi.yml