Für Entwickler
Stats API
1 Schnellstart
- Öffnen Sie in Visitics Organisation → API und erstellen Sie einen Schlüssel; er wird nur einmal angezeigt — bewahren Sie ihn auf Ihrem Server auf.
- Senden Sie ihn im Authorization-Header jeder Anfrage.
- Fragen Sie einen Bereich der Übersicht einer Ihrer Websites ab:
curl -H "Authorization: Bearer vtk_…" "https://www.getvisitics.com/api/v1/stats?site=example.com§ion=overview&days=30"Die API liefert nur zusammengefasste Zahlen — nie IP-Adressen, Fingerabdrücke, Formularinhalte oder Chatverläufe. Standorte tragen die Namensnennung von DB-IP (CC BY 4.0); behalten Sie sie bei den Daten.
2 Schlüssel und Berechtigungen
Ein Schlüssel gehört einer Organisation und liest nur, er ändert nichts. Beim Erstellen wählen Sie seine Berechtigungen, die Websites, die er lesen darf (alle oder einige), und ob er abläuft.
| Berechtigung | Erlaubt |
|---|---|
stats:read | Die Websites, die Bereiche der Übersicht und die Besucher in Echtzeit. |
export:read | Die Tabellen der Bereiche als CSV oder JSON. |
Ein Schlüssel gehört auf einen Server: Die API antwortet keinen Browsern anderer Websites (kein CORS). Setzen Sie einen Schlüssel nie in eine Adresse — er bliebe in Logs und Verläufen. Ein geleakter Schlüssel wird mit einem Klick widerrufen und gilt sofort nicht mehr.
3 Limits und Caching
Der Tarif bestimmt die Anfragen eines Schlüssels pro Stunde: Aura 600, Luna 3.000, Cosmos 10.000. Jede Antwort sagt, wie viele übrig sind:
| Header | Bedeutung |
|---|---|
RateLimit-Limit | Requests an hour of the plan. |
RateLimit-Remaining | Requests left in the current hour. |
RateLimit-Reset | Seconds until a request leaves the window. |
X-Request-Id | The request's ID — quote it when you write to support. |
ETag | Send it back in If-None-Match: the same answer comes as 304 Not Modified. |
Retry-After | Seconds to wait after a 429 answer. |
Die Zahlen von heute ändern sich im Lauf des Tages, die Tage davor bleiben. Behalten Sie eine Antwort mindestens eine Minute und fragen Sie mit If-None-Match — eine unveränderte Antwort muss nicht erneut gesendet werden.
4 Fehler
Ein Fehler kommt als Problem Details (RFC 9457) mit einem maschinenlesbaren Code in code und der ID der Anfrage — nennen Sie sie, wenn Sie uns schreiben.
{
"type": "https://www.getvisitics.com/developers/api/#error-site_not_found",
"title": "Site not found",
"status": 404,
"detail": "The key has no site example.org.",
"code": "site_not_found",
"request_id": "3f9c2a1b7d4e8f60"
}| code | HTTP | Bedeutung |
|---|---|---|
unauthorized | 401 | The Authorization header is missing, or the key is unknown, revoked or expired. |
insufficient_scope | 403 | The key exists but lacks the permission the request needs (stats:read, export:read). |
site_not_found | 404 | No such site, or the key may not read it (a key can be limited to some sites). |
not_found | 404 | No such endpoint. |
method_not_allowed | 405 | The API only reads: use GET (or HEAD). |
invalid_section | 400 | section is not one of the dashboard sections. |
invalid_key | 400 | key is not a table of the section (the problem lists the allowed ones). |
invalid_format | 400 | format is neither csv nor json. |
rate_limited | 429 | Over the plan's requests an hour; Retry-After says when to try again. |
over_limit | 402 | The organization was over its plan's pageviews two whole months: the data waits for a bigger plan, as in the dashboard. |
suspended | 423 | The organization is suspended (or being deleted): its data is not read through the API. |
5 Versionen und Änderungen
Version 1 ändert sich nur kompatibel: Neue Felder und Parameter können hinzukommen, nichts wird entfernt oder umbenannt. Ein unbekanntes Feld ignorieren Sie. Ein Ende einer Version kündigen wir 12 Monate vorher mit den Headern Deprecation und Sunset und per E-Mail an die Inhaber der Schlüssel an.
6 GET /sites
The sites the key may read
{
"data": [
{
"domain": "example.com",
"name": "Example shop",
"timezone": "Europe/Bratislava",
"created_at": "2026-10-01T08:15:00Z"
}
]
}7 GET /sites/{domain}
One site
| Parameter | Type | Description |
|---|---|---|
domain required |
string |
{
"data": {
"domain": "example.com",
"name": "Example shop",
"timezone": "Europe/Bratislava",
"created_at": "2026-10-01T08:15:00Z"
}
}8 GET /stats
A section of the dashboard — The numbers of one section for a period, with the previous period of the same length for comparison (`kpi.prev`). The fields are those of the dashboard; new fields may be added.
| Parameter | Type | Description |
|---|---|---|
site required |
string | The site's domain as in the dashboard. |
section |
string: overview | behavior | sources | audience | conversions | funnels | ux | speed (overview) | A section of the dashboard. |
days |
integer (30) | The last N days including today in the site's time zone (the plan decides which periods are allowed; the longest one otherwise). Ignored with from and to. |
from |
string | The first day (YYYY-MM-DD), with to. Cut to the plan's history and to at most a year. |
to |
string | The last day (YYYY-MM-DD), with from; at most today. |
scope |
string (all) | A part of the site: all, or a group of pages defined in the dashboard (group:<name>). |
funnel |
integer | section=funnels: the funnel's ID from the dashboard. |
{
"site": {
"domain": "example.com",
"name": "Example shop"
},
"section": "overview",
"timezone": "Europe/Bratislava",
"range": {
"from": "2026-10-16",
"to": "2026-10-22",
"days": 7,
"prev_from": "2026-10-09",
"prev_to": "2026-10-15",
"today": "2026-10-22"
},
"kpi": {
"cur": {
"visitors": 342,
"views": 762,
"conversions": 14,
"bounce_rate": 0.17
},
"prev": {
"visitors": 370,
"views": 752,
"conversions": 16,
"bounce_rate": 0.18
}
},
"series": {
"dates": [
"2026-10-16",
"2026-10-17"
],
"total": [
58,
41
]
},
"pages": [
{
"path": "/products/",
"views": 183,
"visitors": 153
}
],
"sources": [
{
"source": "Google",
"channel": "search",
"visitors": 146
}
]
}9 GET /realtime
Visitors right now — Visitors in the last 5 minutes and the pages they are on.
| Parameter | Type | Description |
|---|---|---|
site required |
string | The site's domain as in the dashboard. |
{
"data": {
"visitors": 16,
"window_seconds": 300,
"pages": [
{
"path": "/products/",
"visitors": 5
}
]
}
}10 GET /export
A table of a section as CSV or JSON — The rows of one table — for spreadsheets and BI tools. Tables by section: overview: pages, sources, channels, countries; behavior: pages, entries, exits, search, not_found; sources: sources, referrers, campaigns, channels; audience: countries, regions, cities, langs; conversions: events, goal_sources, forms, outbound, downloads; funnels: funnel.steps, funnel.by_channel, funnel.by_device; ux: ux_pages, ux_elements, js_errors; speed: vitals_pages.
| Parameter | Type | Description |
|---|---|---|
site required |
string | The site's domain as in the dashboard. |
section |
string: overview | behavior | sources | audience | conversions | funnels | ux | speed (overview) | A section of the dashboard. |
key required |
string | The table. |
format |
string: csv | json (csv) | |
days |
integer (30) | The last N days including today in the site's time zone (the plan decides which periods are allowed; the longest one otherwise). Ignored with from and to. |
from |
string | The first day (YYYY-MM-DD), with to. Cut to the plan's history and to at most a year. |
to |
string | The last day (YYYY-MM-DD), with from; at most today. |
scope |
string (all) | A part of the site: all, or a group of pages defined in the dashboard (group:<name>). |
source,channel,visitors
Google,search,146