{"openapi":"3.1.0","info":{"title":"Kipstats API","version":"1.0.0","description":"Read the analytics of the sites in your Kipstats account, and record server-side events. All dates are UTC. Documentation: https://kipstats.com/docs/api"},"servers":[{"url":"https://kipstats.com/api/v1"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Account API key (`ks_...`), created in Settings → API keys."},"ingestKey":{"type":"http","scheme":"bearer","description":"Per-site ingest key (`kpi_...`), found in the site settings. Server-side only."}},"schemas":{"Error":{"type":"object","properties":{"statusCode":{"type":"integer"},"statusMessage":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/sites":{"get":{"summary":"List sites","operationId":"listSites","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domain":{"type":"string"},"trackingId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Site not found in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (1000 requests per hour per key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sites/{site}/stats":{"get":{"summary":"Aggregate stats","operationId":"getStats","parameters":[{"name":"site","in":"path","required":true,"description":"The site to query: its domain (`example.com`), its tracking ID (`kp_1a2b3c4d`) or its internal ID.","schema":{"type":"string"}},{"name":"period","in":"query","description":"Relative period. Ignored when `from` or `to` is set.","schema":{"type":"string","enum":["today","24h","7d","30d","90d","month","12mo"],"default":"7d"}},{"name":"from","in":"query","description":"Start of a custom range, `YYYY-MM-DD` (start of day, UTC) or ISO 8601.","schema":{"type":"string"}},{"name":"to","in":"query","description":"End of a custom range, `YYYY-MM-DD` (end of day, UTC) or ISO 8601. Max range: 400 days.","schema":{"type":"string"}},{"name":"compare","in":"query","description":"Set to `previous` to add the previous period of the same length and the % change.","schema":{"type":"string","enum":["previous"]}},{"name":"country","in":"query","description":"ISO 3166-1 alpha-2 country code, e.g. `FR`.","schema":{"type":"string"}},{"name":"browser","in":"query","description":"Browser name, e.g. `Chrome`.","schema":{"type":"string"}},{"name":"device","in":"query","description":"`desktop`, `mobile` or `tablet`.","schema":{"type":"string"}},{"name":"referrer","in":"query","description":"Referrer domain, e.g. `google.com`.","schema":{"type":"string"}},{"name":"page","in":"query","description":"Keep sessions whose entry page contains this string.","schema":{"type":"string"}},{"name":"traffic","in":"query","description":"`humans` keeps sessions with a confirmed human interaction, `bots` keeps declared robots, `all` (default) keeps everything.","schema":{"type":"string","enum":["all","humans","bots"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"site":{"type":"string"},"period":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"data":{"type":"object","properties":{"visitors":{"type":"integer","description":"Unique visitors (daily-rotating anonymous hash)."},"pageviews":{"type":"integer"},"sessions":{"type":"integer"},"bounceRate":{"type":"integer","description":"Percentage of single-page sessions, 0 to 100."},"avgDuration":{"type":"integer","description":"Average session duration in seconds."}}},"previous":{"type":"object","properties":{"period":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"data":{"type":"object","properties":{"visitors":{"type":"integer","description":"Unique visitors (daily-rotating anonymous hash)."},"pageviews":{"type":"integer"},"sessions":{"type":"integer"},"bounceRate":{"type":"integer","description":"Percentage of single-page sessions, 0 to 100."},"avgDuration":{"type":"integer","description":"Average session duration in seconds."}}}}},"change":{"type":"object","additionalProperties":{"type":["integer","null"]}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Site not found in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (1000 requests per hour per key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sites/{site}/timeseries":{"get":{"summary":"Visitors and pageviews over time","description":"Hourly buckets for ranges up to 2 days, daily buckets beyond. Pass `event` to get the series of one event instead.","operationId":"getTimeseries","parameters":[{"name":"site","in":"path","required":true,"description":"The site to query: its domain (`example.com`), its tracking ID (`kp_1a2b3c4d`) or its internal ID.","schema":{"type":"string"}},{"name":"period","in":"query","description":"Relative period. Ignored when `from` or `to` is set.","schema":{"type":"string","enum":["today","24h","7d","30d","90d","month","12mo"],"default":"7d"}},{"name":"from","in":"query","description":"Start of a custom range, `YYYY-MM-DD` (start of day, UTC) or ISO 8601.","schema":{"type":"string"}},{"name":"to","in":"query","description":"End of a custom range, `YYYY-MM-DD` (end of day, UTC) or ISO 8601. Max range: 400 days.","schema":{"type":"string"}},{"name":"event","in":"query","description":"Event name, e.g. `signup`.","schema":{"type":"string"}},{"name":"country","in":"query","description":"ISO 3166-1 alpha-2 country code, e.g. `FR`.","schema":{"type":"string"}},{"name":"browser","in":"query","description":"Browser name, e.g. `Chrome`.","schema":{"type":"string"}},{"name":"device","in":"query","description":"`desktop`, `mobile` or `tablet`.","schema":{"type":"string"}},{"name":"referrer","in":"query","description":"Referrer domain, e.g. `google.com`.","schema":{"type":"string"}},{"name":"page","in":"query","description":"Keep sessions whose entry page contains this string.","schema":{"type":"string"}},{"name":"traffic","in":"query","description":"`humans` keeps sessions with a confirmed human interaction, `bots` keeps declared robots, `all` (default) keeps everything.","schema":{"type":"string","enum":["all","humans","bots"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"site":{"type":"string"},"period":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"interval":{"type":"string","enum":["hour","day"]},"data":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","description":"`YYYY-MM-DD` or `YYYY-MM-DD HH:00:00` (UTC)."},"visitors":{"type":"integer"},"pageviews":{"type":"integer"},"events":{"type":"integer","description":"With `event` only."},"sessions":{"type":"integer","description":"With `event` only."}}}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Site not found in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (1000 requests per hour per key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sites/{site}/breakdown/{dimension}":{"get":{"summary":"Top values of a dimension","description":"Filters apply to session-based dimensions; `pages` and `events` are not filtered.","operationId":"getBreakdown","parameters":[{"name":"site","in":"path","required":true,"description":"The site to query: its domain (`example.com`), its tracking ID (`kp_1a2b3c4d`) or its internal ID.","schema":{"type":"string"}},{"name":"dimension","in":"path","required":true,"schema":{"type":"string","enum":["pages","exit-pages","referrers","channels","countries","browsers","os","devices","events","utm_source","utm_medium","utm_campaign","utm_term","utm_content"]}},{"name":"period","in":"query","description":"Relative period. Ignored when `from` or `to` is set.","schema":{"type":"string","enum":["today","24h","7d","30d","90d","month","12mo"],"default":"7d"}},{"name":"from","in":"query","description":"Start of a custom range, `YYYY-MM-DD` (start of day, UTC) or ISO 8601.","schema":{"type":"string"}},{"name":"to","in":"query","description":"End of a custom range, `YYYY-MM-DD` (end of day, UTC) or ISO 8601. Max range: 400 days.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Number of rows, 1 to 100.","schema":{"type":"integer","default":10,"minimum":1,"maximum":100}},{"name":"country","in":"query","description":"ISO 3166-1 alpha-2 country code, e.g. `FR`.","schema":{"type":"string"}},{"name":"browser","in":"query","description":"Browser name, e.g. `Chrome`.","schema":{"type":"string"}},{"name":"device","in":"query","description":"`desktop`, `mobile` or `tablet`.","schema":{"type":"string"}},{"name":"referrer","in":"query","description":"Referrer domain, e.g. `google.com`.","schema":{"type":"string"}},{"name":"page","in":"query","description":"Keep sessions whose entry page contains this string.","schema":{"type":"string"}},{"name":"traffic","in":"query","description":"`humans` keeps sessions with a confirmed human interaction, `bots` keeps declared robots, `all` (default) keeps everything.","schema":{"type":"string","enum":["all","humans","bots"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"site":{"type":"string"},"period":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"dimension":{"type":"string"},"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Site not found in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (1000 requests per hour per key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sites/{site}/friction":{"get":{"summary":"Rage clicks, dead clicks, JavaScript errors and abandoned forms","operationId":"getFriction","parameters":[{"name":"site","in":"path","required":true,"description":"The site to query: its domain (`example.com`), its tracking ID (`kp_1a2b3c4d`) or its internal ID.","schema":{"type":"string"}},{"name":"period","in":"query","description":"Relative period. Ignored when `from` or `to` is set.","schema":{"type":"string","enum":["today","24h","7d","30d","90d","month","12mo"],"default":"7d"}},{"name":"from","in":"query","description":"Start of a custom range, `YYYY-MM-DD` (start of day, UTC) or ISO 8601.","schema":{"type":"string"}},{"name":"to","in":"query","description":"End of a custom range, `YYYY-MM-DD` (end of day, UTC) or ISO 8601. Max range: 400 days.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Number of rows, 1 to 100.","schema":{"type":"integer","default":10,"minimum":1,"maximum":50}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"site":{"type":"string"},"period":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"data":{"type":"object","properties":{"rageClicks":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"element":{"type":"string"},"sel":{"type":"string"},"count":{"type":"integer"}}}},"deadClicks":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"element":{"type":"string"},"sel":{"type":"string"},"count":{"type":"integer"}}}},"jsErrors":{"type":"array","items":{"type":"object","properties":{"message":{"type":"string"},"src":{"type":"string"},"path":{"type":"string"},"count":{"type":"integer"}}}},"formAbandons":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"form":{"type":"string"},"field":{"type":"string"},"count":{"type":"integer"}}}},"totals":{"type":"object","additionalProperties":{"type":"integer"}}}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Site not found in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (1000 requests per hour per key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sites/{site}/realtime":{"get":{"summary":"Visitors active in the last 5 minutes","operationId":"getRealtime","parameters":[{"name":"site","in":"path","required":true,"description":"The site to query: its domain (`example.com`), its tracking ID (`kp_1a2b3c4d`) or its internal ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"site":{"type":"string"},"data":{"type":"object","properties":{"visitors":{"type":"integer"},"window":{"type":"string"}}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Site not found in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (1000 requests per hour per key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/collect/server":{"servers":[{"url":"https://kipstats.com/api"}],"post":{"summary":"Record a server-side event","description":"For facts your server witnesses and the browser may not: payments, webhooks, background jobs. No session is created. Sending the same `ref` twice records the event once.","operationId":"recordServerEvent","security":[{"ingestKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255,"example":"purchase"},"data":{"type":"object","additionalProperties":true,"example":{"amount":900,"currency":"EUR","plan":"pro"}},"url":{"type":"string","maxLength":2000},"ref":{"type":"string","maxLength":128,"description":"Idempotency key: the ID of the fact at its source (e.g. a Stripe charge ID)."},"occurredAt":{"type":"string","format":"date-time","description":"When it happened. Defaults to now; a future date is replaced by now."}}}}}},"responses":{"200":{"description":"Recorded, or already recorded with this `ref`","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","duplicate"]},"ref":{"type":["string","null"]}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid ingest key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}