{"openapi":"3.1.0","info":{"title":"fivebar API","version":"1.8.0","summary":"Read your sites' stats from fivebar, cookieless web analytics, and list, add and check sites.","description":"The sites you can read, at /api/sites, and the figures each one's dashboard shows, as JSON: everything over a range at /stats, one pane in full at its own name, and how many are on the site now at /realtime. Each address answers a GET, and /api/sites a POST too, which adds a site; any other method is a 405 whose body is {\"error\": \"method not allowed\"}, with Allow naming those it takes. A parameter the API cannot read is never an error: a range it does not know is the last 7 days, a filter by a dimension it does not know, or past the sixth, is left out, and a number out of bounds is the nearest it takes. Every answer, error or not, is JSON sent with Cache-Control: no-store. The guide is https://fiveb.ar/docs/api.","contact":{"name":"fivebar","url":"https://fiveb.ar/docs/api"}},"externalDocs":{"description":"The API's guide","url":"https://fiveb.ar/docs/api"},"servers":[{"url":"https://fiveb.ar"}],"security":[{"token":[]},{"signedIn":[]},{}],"tags":[{"name":"Sites","description":"The sites a token or a sign-in reads."},{"name":"Stats","description":"A site's figures, as its dashboard shows them."}],"paths":{"/api/sites":{"get":{"operationId":"listSites","tags":["Sites"],"summary":"The sites you can read","description":"The sites the request may read, as the site list sections them: a token's chosen sites, or every site of its maker's for a token made for all of them, while its maker holds them; or a signed-in browser's. A public site a token was not made for is never listed. Every one, with how many.","security":[{"token":[]},{"signedIn":[]}],"parameters":[{"$ref":"#/components/parameters/group"}],"responses":{"200":{"description":"The sites.","headers":{"Cache-Control":{"$ref":"#/components/headers/Cache-Control"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sites"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CannotRead"},"404":{"$ref":"#/components/responses/UnknownGroup"},"429":{"$ref":"#/components/responses/TooManyRequests"},"502":{"$ref":"#/components/responses/SitesUnread"}}},"post":{"operationId":"addSite","tags":["Sites"],"summary":"Add a site to your account","description":"Adds a site to the token's maker's account, in their first group, as the Sites page adds one, with the tag to paste on it. A token can add sites only where it was made able to, in Settings. A token made for chosen sites is given each site it adds, so it can read it. A site already yours is answered again, adding nothing. Each request counts against the tokens' 60 a minute.","security":[{"token":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddSite"}}}},"responses":{"200":{"description":"The site was already yours: nothing added.","headers":{"Cache-Control":{"$ref":"#/components/headers/Cache-Control"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddedSite"}}}},"201":{"description":"The site, added.","headers":{"Cache-Control":{"$ref":"#/components/headers/Cache-Control"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddedSite"}}}},"400":{"$ref":"#/components/responses/NotADomain"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CannotAdd"},"409":{"$ref":"#/components/responses/DomainTaken"},"429":{"$ref":"#/components/responses/TooManyRequests"},"502":{"$ref":"#/components/responses/SiteNotAdded"}}}},"/api/{domain}/stats":{"get":{"operationId":"getStats","tags":["Stats"],"summary":"Everything the dashboard shows over a range","description":"The totals, the chart, every pane's top 8, the visits' figures and the period before, over the range asked for, under the filters asked for. Filtered by a goal, the answer is the goal's: its goal, the totals of its conversions and a series of conversions by day. What the dashboard leaves out under a filter is null or not there.","parameters":[{"$ref":"#/components/parameters/domain"},{"$ref":"#/components/parameters/range"},{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/f"},{"$ref":"#/components/parameters/dir"}],"responses":{"200":{"description":"The site's stats over the range.","headers":{"Cache-Control":{"$ref":"#/components/headers/Cache-Control"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Stats"}}}},"401":{"$ref":"#/components/responses/InvalidToken"},"403":{"$ref":"#/components/responses/CannotReadOrNoPlan"},"404":{"$ref":"#/components/responses/UnknownSite"},"429":{"$ref":"#/components/responses/TooManyRequests"},"502":{"$ref":"#/components/responses/StatsUnread"}}}},"/api/{domain}/realtime":{"get":{"operationId":"getRealtime","tags":["Stats"],"summary":"How many are on the site now","description":"The visits open now, counted as they happen, with no wait for the day's figures. It takes no parameters.","parameters":[{"$ref":"#/components/parameters/domain"}],"responses":{"200":{"description":"How many are on the site now.","headers":{"Cache-Control":{"$ref":"#/components/headers/Cache-Control"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Realtime"}}}},"401":{"$ref":"#/components/responses/InvalidToken"},"403":{"$ref":"#/components/responses/CannotReadOrNoPlan"},"404":{"$ref":"#/components/responses/UnknownSite"},"429":{"$ref":"#/components/responses/TooManyRequests"},"502":{"$ref":"#/components/responses/StatsUnread"}}}},"/api/{domain}/check":{"get":{"operationId":"checkInstall","tags":["Sites"],"summary":"Whether fivebar is installed and counting on a site","description":"Reads the site's home page, as the installation checker does, and says whether the tag is there and for this site, whether a Content Security Policy blocks it, with a policy to use instead, and whether anything has been counted yet, with what to do about each finding. The same check MCP's check_install makes. It reads only the home page as it arrives, so a tag a script adds after the page loads is not seen. Only a site that is yours: one a token reads only because its stats are public is not found. Each check fetches the site, so only a few are made a minute, beside the API's own limit.","security":[{"token":[]},{"signedIn":[]}],"parameters":[{"$ref":"#/components/parameters/domain"}],"responses":{"200":{"description":"What the check found.","headers":{"Cache-Control":{"$ref":"#/components/headers/Cache-Control"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallCheck"}}}},"401":{"$ref":"#/components/responses/InvalidToken"},"403":{"$ref":"#/components/responses/CannotReadOrNoPlan"},"404":{"$ref":"#/components/responses/UnknownSite"},"429":{"$ref":"#/components/responses/TooManyRequests"},"502":{"$ref":"#/components/responses/SiteNotChecked"}}}},"/api/{domain}/{facet}":{"get":{"operationId":"getFacet","tags":["Stats"],"summary":"One pane in full, a page of rows at a time","description":"Every row of one of the dashboard's panes, searched and paged, with each row's counts across the range, as its full view lists them, where it has one.","parameters":[{"$ref":"#/components/parameters/domain"},{"$ref":"#/components/parameters/facet"},{"$ref":"#/components/parameters/range"},{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/f"},{"$ref":"#/components/parameters/dir"},{"$ref":"#/components/parameters/q"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/offset"},{"$ref":"#/components/parameters/trend"},{"$ref":"#/components/parameters/status"}],"responses":{"200":{"description":"A page of the pane's rows.","headers":{"Cache-Control":{"$ref":"#/components/headers/Cache-Control"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Facet"}}}},"401":{"$ref":"#/components/responses/InvalidToken"},"403":{"$ref":"#/components/responses/CannotReadOrNoPlan"},"404":{"$ref":"#/components/responses/UnknownSiteOrFacet"},"429":{"$ref":"#/components/responses/TooManyRequests"},"502":{"$ref":"#/components/responses/StatsUnread"}}}}},"components":{"securitySchemes":{"token":{"type":"http","scheme":"bearer","description":"An API token made in Settings, as Authorization: Bearer fivebar_… One made to read stats, as a token is unless made only to send events, reads all its maker's sites, or the ones it was made for, while they are on their Sites page, and any site whose stats are public. One made only to send events reads nothing: every GET is a 403, token cannot read stats. When the header is there it alone decides, and a sign-in beside it is not read. A maker's tokens together make at most 60 requests a minute."},"signedIn":{"type":"apiKey","in":"cookie","name":"__Host-fivebar","description":"A browser signed in to fivebar, which reads the sites on its Sites page. The API sends no CORS headers, so a page on another site cannot read it from its visitors' browsers."}},"parameters":{"domain":{"name":"domain","in":"path","required":true,"description":"The site's domain, as in its dashboard's address: lower case, without www., and in punycode where it is written in a script of its own. Any site the request may not read is the same 404 as one fivebar does not have.","schema":{"type":"string"},"example":"example.com"},"facet":{"name":"facet","in":"path","required":true,"description":"The pane, named as in its full view's address, but for slowest-pages-lcp and slowest-pages-inp, which have no full view: the Speed page's Pages table lists the pages with the most poor loads. A custom property's is property- and its name; the data an event goal was sent with is data- and the data's name, read under a filter by that goal.","schema":{"anyOf":[{"type":"string","enum":["content-drilldown","top-pages","entry-pages","exit-pages","channels","sources","referrers","countries","cities","networks","medium","campaign","content","term","goals","devices","browsers","operating-systems","outbound-clicks","file-downloads","searches","errors","time-on-page","scroll-depth","slowest-pages-lcp","slowest-pages-inp"]},{"type":"string","pattern":"^property-[a-z0-9_-]{1,32}$"},{"type":"string","pattern":"^data-[a-z0-9_-]{1,32}$"}]},"example":"sources"},"range":{"name":"range","in":"query","description":"A named range, a day (2026-09-14) or a month (2026-09), in the site's own days. The last 7 days if left out or not known. from and to together win over it.","schema":{"anyOf":[{"type":"string","enum":["today","yesterday","this-week","this-week-sun","last-7-days","last-week","last-week-sun","last-14-days","this-month","last-30-days","last-month","all-time"]},{"type":"string","format":"date"},{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}$"}]},"example":"last-month"},"from":{"name":"from","in":"query","description":"The first day of a range of dates, with to, in the site's own days.","schema":{"type":"string","format":"date"},"example":"2026-09-01"},"to":{"name":"to","in":"query","description":"The last day of a range of dates, with from, in the site's own days.","schema":{"type":"string","format":"date"},"example":"2026-09-14"},"f":{"name":"f","in":"query","description":"A filter: a dimension, a colon and a value, matched exactly. Repeat it for up to 6, and every one must hold. The dimensions are path, source, referrer, country, city, device, browser, os, utm_medium, utm_campaign, utm_content, utm_term, asn, entry, exit, goal and channel, or prop: and a custom property's name.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string"},"maxItems":6},"example":["source:Google"]},"dir":{"name":"dir","in":"query","description":"The folder the content drilldown opens.","schema":{"type":"string","default":"/"},"example":"/blog/"},"q":{"name":"q","in":"query","description":"A search: only the rows whose label holds it, ignoring case. A country is found by its name or its code, a network by its name or its number, and a search term by its page too.","schema":{"type":"string","maxLength":100}},"limit":{"name":"limit","in":"query","description":"How many rows.","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},"offset":{"name":"offset","in":"query","description":"How many rows to skip, for the pages after the first.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}},"trend":{"name":"trend","in":"query","description":"0 or false to leave out each row's counts across the range.","schema":{"type":"string","enum":["0","false"]}},"status":{"name":"status","in":"query","description":"For errors alone: only the errors answered with this status, as the Errors page shows them filtered by it.","schema":{"type":"integer","minimum":400,"maximum":599},"example":404},"group":{"name":"group","in":"query","description":"Only the sites of the group of this name, matched as the site list matches a name typed: case aside, accents not. None is the first group.","schema":{"type":"string"},"example":"Clients"}},"headers":{"Cache-Control":{"description":"Every answer is no-store, so nothing on the way keeps a copy.","schema":{"type":"string","const":"no-store"}}},"responses":{"InvalidToken":{"description":"An Authorization header that is not a live API token.","headers":{"WWW-Authenticate":{"required":true,"schema":{"type":"string","const":"Bearer realm=\"fivebar\", error=\"invalid_token\""}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"invalid token"}}}},"CannotRead":{"description":"A token made only to send events, which reads nothing, as Read stats was not ticked when it was made: its WWW-Authenticate header says so too. Or a token sent over plain http, refused rather than answered, as it has already crossed the network readable: revoke it and make another.","headers":{"WWW-Authenticate":{"description":"Sent with token cannot read stats alone, as RFC 6750 has it for a token that lacks what the request needs.","schema":{"type":"string","const":"Bearer realm=\"fivebar\", error=\"insufficient_scope\""}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","enum":["https required","token cannot read stats"]}}},"example":{"error":"token cannot read stats"}}}},"CannotReadOrNoPlan":{"description":"A token made only to send events, which reads no site, public ones included, as Read stats was not ticked when it was made: its WWW-Authenticate header says so too. Or a token sent over plain http, refused rather than answered, as it has already crossed the network readable: revoke it and make another. Or a site of yours, or one the token reads, whose account has no plan: its stats are paused, and its settings still open, until the account that pays for it chooses one.","headers":{"WWW-Authenticate":{"description":"Sent with token cannot read stats alone, as RFC 6750 has it for a token that lacks what the request needs.","schema":{"type":"string","const":"Bearer realm=\"fivebar\", error=\"insufficient_scope\""}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","enum":["https required","token cannot read stats","This site's account has no plan."]}}},"example":{"error":"This site's account has no plan."}}}},"UnknownSite":{"description":"A site the request may not read, or one fivebar does not have: the two are the same answer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnknownSite"}}}},"UnknownSiteOrFacet":{"description":"A site the request may not read, or one fivebar does not have; or, on a site it may read, a name that is no pane, which lists the panes there are.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/UnknownSite"},{"$ref":"#/components/schemas/UnknownFacet"}]}}}},"TooManyRequests":{"description":"More than 60 requests in a minute from one account's tokens together; or, for a check, more checks in a minute than are made, as each fetches the site.","headers":{"Retry-After":{"required":true,"description":"Seconds to wait.","schema":{"type":"string","const":"60"}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","enum":["too many requests","too many checks"]}}},"example":{"error":"too many requests"}}}},"StatsUnread":{"description":"The stats could not be read. Try again shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"stats could not be read"}}}},"MethodNotAllowed":{"description":"Any method an address does not take: on /api/sites anything but GET and POST, and anything but GET everywhere else.","headers":{"Allow":{"required":true,"schema":{"type":"string","enum":["GET","GET, POST"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"method not allowed"}}}},"Unauthorized":{"description":"No token and no sign-in, or an Authorization header that is not a live API token.","headers":{"WWW-Authenticate":{"required":true,"schema":{"type":"string","enum":["Bearer realm=\"fivebar\"","Bearer realm=\"fivebar\", error=\"invalid_token\""]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"token required"}}}},"UnknownGroup":{"description":"A group the account does not have, listing those it has.","content":{"application/json":{"schema":{"type":"object","required":["error","groups"],"properties":{"error":{"type":"string","const":"unknown group"},"groups":{"type":"array","items":{"type":"string"},"description":"The account's groups with sites in them, None the first."}},"additionalProperties":false}}}},"SitesUnread":{"description":"The sites could not be read. Try again shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"sites could not be read"}}}},"NotADomain":{"description":"A body that is not a JSON object, or whose domain is no domain.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","enum":["invalid json","not a domain"]}}},"example":{"error":"not a domain"}}}},"CannotAdd":{"description":"A token not made able to add sites; or an account with no plan yet, which chooses one first; or an account with as many sites as it may own, with the limit and where to ask for more; or a token sent over plain http.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["error"],"properties":{"error":{"type":"string","enum":["token cannot add sites","Choose a plan first.","https required"]}},"additionalProperties":false},{"type":"object","required":["error","max","more"],"properties":{"error":{"type":"string","const":"account full"},"max":{"type":"integer","description":"How many sites the account may own; sites shared with it are not counted."},"more":{"type":"string","format":"uri","description":"Where to ask for more."}},"additionalProperties":false}]}}}},"DomainTaken":{"description":"The domain is a site of someone else's: a domain is one site across fivebar.","content":{"application/json":{"schema":{"type":"object","required":["error","domain"],"properties":{"error":{"type":"string","const":"domain taken"},"domain":{"type":"string"}},"additionalProperties":false}}}},"SiteNotAdded":{"description":"The site could not be added just now. Try again shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"site could not be added"}}}},"SiteNotChecked":{"description":"The site could not be checked just now. Try again in a minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"site could not be checked"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"What went wrong, in a few words."}}},"UnknownSite":{"type":"object","required":["error"],"properties":{"error":{"type":"string","const":"unknown site"}},"additionalProperties":false},"UnknownFacet":{"type":"object","required":["error","facets","properties"],"properties":{"error":{"type":"string","const":"unknown facet"},"facets":{"type":"array","description":"The panes' names.","items":{"type":"string"}},"properties":{"type":"string","description":"How a custom property's pane is named.","const":"property-<name>"}},"additionalProperties":false},"Realtime":{"type":"object","required":["current"],"properties":{"current":{"type":"integer","minimum":0,"description":"The visits open on the site now."}}},"Range":{"type":"object","required":["key","from","to"],"properties":{"key":{"type":"string","description":"The range read: a named range's key, custom for dates, or a number of days such as 28-days."},"from":{"type":["string","null"],"format":"date"},"to":{"type":["string","null"],"format":"date"}}},"Totals":{"type":"object","description":"The pageviews, visits and visitors over the range; under a goal filter, its conversions, its events and the visits its conversion rate is of.","properties":{"pageviews":{"type":["integer","null"]},"visits":{"type":["integer","null"]},"visitors":{"type":["integer","null"]}}},"Visit":{"type":["object","null"],"description":"The visits that have ended, how many of them bounced, and their seconds on screen.","properties":{"visits":{"type":"integer"},"bounces":{"type":"integer"},"duration":{"type":"number"}}},"Imported":{"type":"object","description":"The days of the site's history imported from another tool, Plausible or Google Analytics, that the range or the period before meets, each clipped to them; there only where some are. Imported days hold pageviews, visits and visitors by day, and may hold pageviews by page, source, country, device, browser and system, and are read only with no filter. Google Analytics counted visitors by cookie.","required":["read","days"],"properties":{"read":{"type":"boolean","description":"Whether this answer read them: false where it is filtered, or where what it counts is none of what the imports it meets hold."},"days":{"type":"array","items":{"type":"object","required":["source","from","to"],"properties":{"source":{"type":"string","enum":["plausible","google-analytics"]},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}}}}}},"PaneRow":{"type":"object","required":["label","n"],"properties":{"label":{"type":["string","null"]},"n":{"type":"number","description":"Its pageviews, or what the pane counts."}}},"Pane":{"type":["array","null"],"description":"A pane's top 8.","items":{"$ref":"#/components/schemas/PaneRow"}},"Stats":{"type":"object","required":["totals","bucket","series","range","source"],"properties":{"goal":{"description":"Filtered by a goal: the goal."},"totals":{"$ref":"#/components/schemas/Totals"},"bucket":{"type":"string","enum":["hour","day","week","month"],"description":"What each column of the series is."},"series":{"type":"array","description":"The chart: by the hour, each row an hour with its pageviews as n; otherwise each a day, with its pageviews as n, its visits and its visitors.","items":{"type":"object"}},"paths":{"$ref":"#/components/schemas/Pane"},"channels":{"$ref":"#/components/schemas/Pane"},"sources":{"$ref":"#/components/schemas/Pane"},"referrers":{"$ref":"#/components/schemas/Pane"},"countries":{"$ref":"#/components/schemas/Pane"},"cities":{"$ref":"#/components/schemas/Pane"},"networks":{"$ref":"#/components/schemas/Pane","description":"A network's label is its AS number, and its name the one the dashboard shows, or null where it has none."},"devices":{"$ref":"#/components/schemas/Pane"},"browsers":{"$ref":"#/components/schemas/Pane"},"oses":{"$ref":"#/components/schemas/Pane"},"utm_medium":{"$ref":"#/components/schemas/Pane"},"utm_campaign":{"$ref":"#/components/schemas/Pane"},"utm_content":{"$ref":"#/components/schemas/Pane"},"utm_term":{"$ref":"#/components/schemas/Pane"},"entries":{"$ref":"#/components/schemas/Pane"},"exits":{"$ref":"#/components/schemas/Pane"},"content":{"description":"The content drilldown."},"counts":{"type":["object","null"],"description":"How many values each pane has in all, by its dimension; a pane's own address returns the rest.","additionalProperties":{"type":"integer"}},"visit":{"$ref":"#/components/schemas/Visit"},"properties":{"description":"The custom properties."},"goals":{"description":"The Goals pane."},"outbound":{"description":"The Links section's outbound clicks."},"downloads":{"description":"The Links section's file downloads."},"searches":{"description":"The Site search section: each term with the page it was searched from, and none, its searches there that found nothing."},"searchPages":{"type":"integer","description":"How many pages the searches came from."},"searchTerms":{"type":"integer","description":"How many terms the searches are, each once however many pages it came from."},"engagement":{"description":"The Engagement section."},"week":{"description":"The Hours section: n has a list for each day of the week, Monday first, of the pageviews in its 24 hours, and days how many of each hour the range held."},"speed":{"description":"The six measures, the status mix and the errors that the Speed and Errors pages show, with errorTotal the errors in all, and serverTiming where the site's server sent a Server-Timing header: up to ten of its names, those reported by the most page loads and calls first, each as {name, p75, samples}, p75 its 75th percentile in milliseconds and samples the page loads and server events' calls that reported it; and serverCalls where the site's server events sent their own: how many of its calls did, a name's share being of the page loads and these calls together."},"previous":{"type":["object","null"],"description":"The period before, which each figure's change is from: its dates, its totals and its visit. For a range that runs to today, its last day is cut at the same time of day, and hour and minute say when. Null for all time.","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"hour":{"type":["integer","null"]},"minute":{"type":["integer","null"]},"totals":{"$ref":"#/components/schemas/Totals"},"visit":{"$ref":"#/components/schemas/Visit"}}},"imported":{"$ref":"#/components/schemas/Imported"},"range":{"allOf":[{"$ref":"#/components/schemas/Range"}],"description":"The dates read, and the time zone they are the site's days in.","properties":{"timezone":{"type":"string","description":"An IANA time zone, such as Europe/London."}},"required":["timezone"]},"source":{"type":"string","const":"postgres"}}},"FacetRow":{"type":"object","required":["value","label","n","share","filter"],"properties":{"value":{"type":"string","description":"The row's value, as a filter matches it."},"label":{"type":["string","null"],"description":"The row as the pane shows it."},"n":{"type":"number","description":"What the pane counts, in its unit."},"share":{"type":"number","minimum":0,"maximum":1,"description":"n over the whole pane's total, to four places."},"filter":{"type":["string","null"],"description":"The f= value that narrows the dashboard to this row, or null where none does."},"trend":{"type":"array","description":"The row's counts in each of the trend's buckets.","items":{"type":"number"}},"page":{"type":"string","description":"Searches: the page the term was searched from."},"kind":{"type":"string","description":"Goals: the goal's kind."},"events":{"type":"integer"},"visits":{"type":"integer"},"rate":{"type":"number","description":"Conversions over visits."},"code":{"type":"string","description":"Countries: the two-letter code."},"asn":{"type":["integer","null"],"description":"Networks: the AS number."},"name":{"type":["string","null"],"description":"Countries and networks: the name shown, or null where it has none."},"key":{"type":"string"},"folder":{"type":"boolean","description":"Content drilldown: whether the row is a folder."},"dir":{"type":"string","description":"Content drilldown: the folder's own address, as dir= opens it."},"path":{"type":"string"},"poor":{"type":"integer"},"samples":{"type":"integer"},"poorShare":{"type":"number"},"bounces":{"type":"integer"},"duration":{"type":"number"}}},"Facet":{"type":"object","required":["site","facet","title","unit","range","filters","available","source","q","limit","offset","total","count","more","rows"],"properties":{"site":{"type":"string","description":"The site's domain."},"facet":{"type":"string","description":"The pane's name, as asked for."},"title":{"type":"string","description":"The pane's title, as its full view shows it, where it has one."},"dimension":{"type":["string","null"],"description":"The dimension its rows are values of, as a filter names it."},"unit":{"type":"string","description":"What n counts: pageviews, visits, conversions, clicks, downloads, searches, readings, page loads or events."},"rated":{"type":"boolean","description":"Read from conversions: whether the rows have conversion rates."},"range":{"allOf":[{"$ref":"#/components/schemas/Range"}],"properties":{"days":{"type":["integer","null"],"description":"How many days the range holds."}}},"filters":{"type":"array","description":"The filters read, each [dimension, value].","items":{"type":"array","items":{"type":"string"}}},"dir":{"type":"string","description":"Content drilldown: the folder open."},"crumbs":{"type":"array","description":"Content drilldown: the folders above it."},"status":{"type":["integer","null"],"description":"Errors: the status they are narrowed to, or null for every one."},"available":{"type":"boolean","description":"Whether the pane can be read under these filters; false where the dashboard leaves it out, with no rows."},"imported":{"$ref":"#/components/schemas/Imported"},"source":{"type":"string","const":"postgres"},"q":{"type":"string","description":"The search read."},"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"number","description":"What every row of the pane counts to, which each row's share is of."},"count":{"type":"integer","description":"How many rows the pane has, searched where a search was asked for."},"matched":{"type":"number","description":"With a search: what the rows it found count to."},"pages":{"type":["integer","null"],"description":"Searches: how many pages the terms were searched from."},"terms":{"type":["integer","null"],"description":"Searches: how many terms the rows are."},"more":{"type":"integer","description":"How many rows are after this page."},"trend":{"type":"object","description":"The trend's buckets, which each row's trend counts in.","properties":{"unit":{"type":"string"},"buckets":{"type":"array","items":{"type":"object"}}}},"rows":{"type":"array","items":{"$ref":"#/components/schemas/FacetRow"}},"ms":{"type":"number","description":"How long the read took, in milliseconds."}}},"Site":{"type":"object","required":["domain","group","role","timezone","today","dashboard","public","stats"],"properties":{"domain":{"type":"string","description":"As in its dashboard's address, and in the API's."},"name":{"type":"string","description":"Where the domain is written in a script of its own, as the dashboard shows it, such as κουνησε.gr for xn--qxadimj0al.gr."},"group":{"type":["string","null"],"description":"Its group's name, or null for the first group."},"role":{"type":"string","enum":["owner","editor","viewer"],"description":"Your role on it: owner, the account that pays for it; editor, who may change its settings; or viewer, who reads its stats."},"timezone":{"type":"string","description":"The IANA time zone its days are in."},"today":{"type":"string","format":"date","description":"Today, in its time zone."},"dashboard":{"type":"string","format":"uri","description":"Its dashboard."},"public":{"type":"boolean","description":"Whether its stats are public."},"stats":{"type":"string","format":"uri","description":"Its /stats address in the API."}}},"Sites":{"type":"object","required":["sites","count"],"properties":{"sites":{"type":"array","items":{"$ref":"#/components/schemas/Site"}},"count":{"type":"integer","minimum":0,"description":"How many sites are listed."}}},"AddSite":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","maxLength":253,"description":"The site's domain, or an address on it, read as the Sites page reads what is typed: its host, lower case, without www.","examples":["example.com"]}}},"AddedSite":{"type":"object","required":["site","tag"],"properties":{"site":{"type":"object","required":["domain","start","timezone","dashboard","stats"],"properties":{"domain":{"type":"string"},"name":{"type":"string","description":"Where the domain is written in a script of its own, as the dashboard shows it."},"start":{"type":"string","format":"date","description":"The day its stats begin: the day it was added, or the first day it imported where earlier."},"timezone":{"type":"string","description":"The IANA time zone its days are in: the account's for new sites."},"dashboard":{"type":"string","format":"uri"},"stats":{"type":"string","format":"uri","description":"Its /stats address in the API."}}},"tag":{"type":"string","description":"The script tag to paste into the site's pages, in the <head>."}}},"InstallCheck":{"type":"object","required":["site","timezone","today","home_page","tag","content_security_policy","counted","ready","counting","findings","checker","dashboard"],"properties":{"site":{"type":"string","description":"The site's domain."},"timezone":{"type":"string"},"today":{"type":"string","format":"date"},"home_page":{"type":["object","null"],"description":"The page read, and its status; null where it could not be read.","properties":{"url":{"type":"string"},"status":{"type":["integer","null"]}}},"tag":{"type":["object","null"],"description":"The fivebar tag found, if any, and the site it counts for."},"content_security_policy":{"type":["object","null"],"description":"Whether the site's policies let the tag load and send what it counts, each policy with what it does to each and, where it blocks fivebar, the policy to use instead.","properties":{"loads":{"type":"boolean"},"sends":{"type":"boolean"},"policies":{"type":"array","items":{"type":"object"}},"notes":{"type":"array"}}},"counted":{"type":"object","description":"The first day counted, the visitors on the site now, and, where nothing is counted, the pageviews taken for bots.","properties":{"first_day":{"type":["string","null"],"format":"date"},"live_visitors":{"type":"integer"},"window_minutes":{"type":"integer"},"bot_pageviews":{"type":"integer"}}},"ready":{"type":"boolean","description":"Whether the tag is in place for this site and nothing blocks it."},"counting":{"type":"boolean","description":"Whether anything has been counted, or someone is on the site now."},"findings":{"type":"array","description":"Most pressing first, each with what to do.","items":{"type":"object","required":["finding","says"],"properties":{"finding":{"type":"string","enum":["unreachable","error_status","moved","no_tag","other_site","blocked_load","blocked_send","report_only_would_block","unchecked_policies","nothing_counted","counting_started"]},"says":{"type":"string","description":"What it found, and what to do."}}}},"checker":{"type":"string","format":"uri","description":"The installation checker's page for the site."},"dashboard":{"type":"string","format":"uri"},"notice":{"type":"string"}}}}}}