{"openapi":"3.1.0","info":{"title":"tidekeeper","description":"Web analytics that reads the tideline, not the visitor.","contact":{"name":"Christina Sørensen","email":"ces@fem.gg"},"license":{"name":"LicenseRef-proprietary","identifier":"LicenseRef-proprietary"},"version":"0.3.38"},"paths":{"/api/v1/about":{"get":{"tags":["about"],"summary":"What anyone may know of this deployment: how to reach whoever runs it,\nwhat it publishes, and whether customers get the command line.","operationId":"get_about","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/About"}}}}}}},"/api/v1/account":{"get":{"tags":["account"],"summary":"What the account is: its name, and whether it is suspended or to be deleted.","operationId":"get_account","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountView"}}}}}},"patch":{"tags":["account"],"summary":"Call the account something else (doc/launch.md, 2.4). Owners only.","operationId":"patch_account","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountRename"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/account/deletion":{"post":{"tags":["account"],"summary":"Ask for the account to be deleted, a week from now. Owners only.","operationId":"post_deletion","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletionAsk"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["account"],"summary":"Stop a deletion that was asked for.","operationId":"delete_deletion","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/account/export":{"get":{"tags":["account"],"summary":"Everything the account has, as one `.zip`.","operationId":"get_export","responses":{"200":{"description":"A zip archive","content":{"application/zip":{}}}}}},"/api/v1/account/support":{"post":{"tags":["account"],"summary":"Let the operator who asked see the account's figures, for some days.","operationId":"post_support","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportGrantAsk"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["account"],"summary":"End support's access, or decline an ask for it.","operationId":"delete_support","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/accounts":{"post":{"tags":["team"],"summary":"Make another account, yours to own.","operationId":"post_account","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewAccount"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts":{"get":{"tags":["operator"],"summary":"Every account, searched, filtered and sorted. Operators only.","operationId":"get_accounts","parameters":[{"name":"q","in":"query","description":"Looked for in names, addresses and sites","required":false,"schema":{"type":"string"}},{"name":"plan","in":"query","description":"A plan's id","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","description":"A subscription's state, or held, suspended, deletion","required":false,"schema":{"type":"string"}},{"name":"sort","in":"query","description":"age, usage or seen","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccounts"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}":{"get":{"tags":["operator"],"summary":"One account: what it is, and everything that was done to it.","operationId":"get_account","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/cancel":{"post":{"tags":["operator"],"summary":"Stop the account's plan from renewing.","operationId":"post_cancel","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reason"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/deletion":{"post":{"tags":["operator"],"summary":"Set the day the account is deleted, a week or more ahead.","operationId":"post_deletion","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDeletion"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/deletion/stop":{"post":{"tags":["operator"],"summary":"Stop a deletion.","operationId":"post_deletion_stop","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reason"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/limits":{"post":{"tags":["operator"],"summary":"Set limits of the account's own, in place of its plan's.","operationId":"post_limits","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminLimitsSet"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/limits/clear":{"post":{"tags":["operator"],"summary":"Back to the plan's limits.","operationId":"post_limits_clear","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reason"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/notes":{"post":{"tags":["operator"],"summary":"Write a note about the account, for the other operators.","operationId":"post_note","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminNoteNew"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/plan":{"post":{"tags":["operator"],"summary":"Put the account on a plan.","operationId":"post_plan","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlan"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/resend":{"post":{"tags":["operator"],"summary":"Have a mail about the plan sent again.","operationId":"post_resend","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminResend"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/resume":{"post":{"tags":["operator"],"summary":"Count for the account again.","operationId":"post_resume","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reason"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/support":{"post":{"tags":["operator"],"summary":"Ask the account's owners for access to its figures.","operationId":"post_support","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reason"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/suspend":{"post":{"tags":["operator"],"summary":"Stop counting for the account. Its owners are mailed first.","operationId":"post_suspend","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reason"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/accounts/{id}/trial":{"post":{"tags":["operator"],"summary":"Extend the account's trial.","operationId":"post_trial","parameters":[{"name":"id","in":"path","description":"The account","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrial"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccount"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/log":{"get":{"tags":["operator"],"summary":"What operators did, newest first.","operationId":"get_log","parameters":[{"name":"account","in":"query","description":"One account's lines only","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","description":"How many, 200 unless said","required":false,"schema":{"type":"integer","format":"int32","minimum":0}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminLog"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/admin/overview":{"get":{"tags":["operator"],"summary":"Who signed up, what needs someone, and what comes in. Operators only.","operationId":"get_overview","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOverview"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/alert-settings":{"get":{"tags":["api"],"summary":"Quiet hours, how often, and whether to say when something is over.","operationId":"get_alert_settings","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}}}}},"put":{"tags":["api"],"operationId":"put_alert_settings","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/alerts/{id}/mute":{"post":{"tags":["api"],"summary":"Stop being told about one open problem for some days.","operationId":"mute_alert","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Mute"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["api"],"operationId":"unmute_alert","responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/annotations/{id}":{"delete":{"tags":["api"],"operationId":"delete_annotation","responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/attention":{"get":{"tags":["api"],"summary":"Open problems on any site, grouped by what to do about them, with what\nrecovered this week and what is muted.","operationId":"attention","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Attention"}}}}}}},"/api/v1/audit":{"get":{"tags":["team"],"operationId":"get_audit","parameters":[{"name":"site","in":"path","description":"A site's id or name. Without it, the whole account.","required":true,"schema":{"type":["string","null"]}},{"name":"limit","in":"path","required":true,"schema":{"type":["integer","null"],"format":"int32","minimum":0}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LogLineView"}}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/confirm":{"post":{"tags":["signin"],"operationId":"post_confirm","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeUse"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/email/confirm":{"post":{"tags":["signin"],"summary":"The new address shown to be theirs: the change is made, and the old\naddress is told. It signs nobody in: a link to an address is not the\npassword or the second step.","operationId":"post_email_confirm","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeUse"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailChange"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"410":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/invitation":{"get":{"tags":["team"],"summary":"What an invitation is to. Whoever holds the link may ask; nobody else can.","operationId":"get_invitation","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationShown"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["team"],"summary":"Accept an invitation: the member is made and signed in.","operationId":"accept_invitation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationAccept"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/link":{"post":{"tags":["signin"],"summary":"Email a sign-in link. The answer is the same whether or not the address has an account.","operationId":"post_link","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailOnly"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sent"}}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/link/use":{"post":{"tags":["signin"],"operationId":"post_link_use","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeUse"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["routes"],"summary":"Email and password sign-in. Hosted (`signup`) only.","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Login"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/logout":{"post":{"tags":["routes"],"operationId":"logout","responses":{"204":{}}}},"/api/v1/auth/reset":{"get":{"tags":["signin"],"operationId":"get_reset","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetOpen"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["signin"],"summary":"Email a link to choose a new password. The answer is the same whether or not the address has an account.","operationId":"post_reset","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailOnly"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sent"}}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/reset/finish":{"post":{"tags":["signin"],"operationId":"post_reset_finish","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetFinish"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetDone"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/signup":{"post":{"tags":["signin"],"summary":"Ask for an account. A link goes to the address; nothing exists until it is opened.","operationId":"post_signup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupStart"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sent"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/auth/ways":{"get":{"tags":["signin"],"operationId":"get_ways","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ways"}}}}}}},"/api/v1/billing":{"get":{"tags":["billing"],"operationId":"get_billing","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/billing/cancel":{"post":{"tags":["billing"],"summary":"Cancel the plan: the renewal stops, counting goes on until the period ends.","operationId":"post_cancel","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["billing"],"operationId":"delete_cancel","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/billing/checkout":{"post":{"tags":["billing"],"summary":"Start paying for a plan: answers with the provider's page to go to.","operationId":"post_checkout","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanChoice"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Away"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/billing/details":{"put":{"tags":["billing"],"operationId":"put_details","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingDetails"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/billing/dpa":{"post":{"tags":["billing"],"operationId":"post_dpa","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/billing/events/{provider}":{"post":{"tags":["billing"],"summary":"A payment provider's own events, each checked by its signature. A\nretry is answered as done.","operationId":"post_events","parameters":[{"name":"provider","in":"path","description":"The provider's name","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/billing/plan":{"post":{"tags":["billing"],"operationId":"post_plan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanChoice"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/billing/portal":{"post":{"tags":["billing"],"summary":"The provider's page for the card and the invoices.","operationId":"post_portal","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Away"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/billing/provider":{"post":{"tags":["billing"],"summary":"For a payment provider's relay: an account's plan as it now is,\nsigned. `x-tidekeeper-signature` is the HMAC-SHA256 of the body in hex.","operationId":"post_provider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanEvent"}}},"required":true},"responses":{"204":{},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/channels":{"get":{"tags":["api"],"operationId":"list_channels","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChannelView"}}}}}}},"post":{"tags":["api"],"operationId":"create_channel","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/channels/{id}":{"delete":{"tags":["api"],"operationId":"delete_channel","responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"tags":["api"],"summary":"Rename a channel, point it elsewhere, switch it off, or choose which\nalerts it is told about.","operationId":"update_channel","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelUpdate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/channels/{id}/test":{"post":{"tags":["api"],"summary":"Send a test message to one channel, now, and say how it went.","operationId":"test_channel","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestResult"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/definitions":{"get":{"tags":["api"],"summary":"What every figure means: the one definition of each metric, the\nreasons a hit is left out, the channel rules, and what the script sends.","operationId":"definitions","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Definitions"}}}}}}},"/api/v1/deliveries":{"get":{"tags":["api"],"summary":"Every attempt to deliver, newest first, with its error if it had one.","operationId":"list_deliveries","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryView"}}}}}}}},"/api/v1/goals/{id}":{"get":{"tags":["api"],"operationId":"get_goal","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["api"],"operationId":"delete_goal","responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"tags":["api"],"summary":"Rename, pause, or change the definition. A changed definition is a new\nversion.","operationId":"update_goal","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalUpdate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalView"}}}}}}},"/api/v1/goals/{id}/versions":{"get":{"tags":["api"],"summary":"Every version of a goal's definition, oldest first.","operationId":"goal_versions","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GoalVersionView"}}}}}}}},"/api/v1/health":{"get":{"tags":["routes"],"summary":"What this server is.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/api/v1/instance":{"get":{"tags":["routes"],"summary":"What this instance runs with: for the instance's own account, and\n`null` for every other.","operationId":"instance","responses":{"200":{"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/InstanceView"},{"type":"null"}]}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me":{"get":{"tags":["routes"],"operationId":"me","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"tags":["team"],"operationId":"patch_me","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NameChange"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}}}}},"/api/v1/me/account":{"post":{"tags":["team"],"summary":"Act in another of your accounts.","operationId":"post_my_account","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountChoice"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me/email":{"post":{"tags":["signin"],"summary":"A new address to sign in with (doc/launch.md, 2.5): a link goes to it,\nand nothing changes until the link is opened. Only the person, signed in\nthemselves: a token cannot move where a person's mail goes.","operationId":"post_email","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailChange"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sent"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me/password":{"post":{"tags":["signin"],"operationId":"post_password","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordChange"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me/push":{"get":{"tags":["api"],"summary":"The account's devices for push, and what a browser needs to become\none.","operationId":"push","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushView"}}}}}},"post":{"tags":["api"],"summary":"Add the browser this is asked from as a device: what it gave when it\nsubscribed to its push service.","operationId":"add_push","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushSubscribe"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushDeviceView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me/push/{id}":{"delete":{"tags":["api"],"summary":"Remove a device: one's own, or any of the account's for whoever\nmanages it.","operationId":"remove_push","parameters":[{"name":"id","in":"path","description":"The device","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me/second-step":{"post":{"tags":["signin"],"summary":"Turn the second step on, with six digits from the app that was just set up.","operationId":"post_second","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SixDigits"}}},"required":true},"responses":{"204":{},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me/second-step/off":{"post":{"tags":["signin"],"summary":"Turn it off, with six digits to show it is still theirs.","operationId":"post_second_off","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SixDigits"}}},"required":true},"responses":{"204":{},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me/second-step/start":{"post":{"tags":["signin"],"operationId":"post_second_start","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecondStepStart"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me/security":{"get":{"tags":["signin"],"operationId":"get_security","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Security"}}}}}}},"/api/v1/me/snooze":{"post":{"tags":["api"],"summary":"\"Remind me later\": do not show this member something again for some\ndays.","operationId":"snooze","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Snooze"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/me/snooze/{what}":{"delete":{"tags":["api"],"summary":"Be reminded again from now.","operationId":"unsnooze","parameters":[{"name":"what","in":"path","description":"What was put off: `plan`","required":true,"schema":{"type":"string"}}],"responses":{"204":{}}}},"/api/v1/nightly":{"get":{"tags":["api"],"summary":"The nightly check, as it last ran on this tidekeeper.","operationId":"nightly","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NightlyView"}}}}}},"post":{"tags":["api"],"summary":"Run the check now. For whoever runs this tidekeeper.","operationId":"run_nightly","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NightlyView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/overview":{"get":{"tags":["api"],"summary":"Every site of the account, with its visitors, its trend and whether\nhits are arriving.","operationId":"overview","parameters":[{"name":"period","in":"query","description":"`7d` when left out","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Overview"}}}}}}},"/api/v1/plans":{"get":{"tags":["billing"],"summary":"The plans this tidekeeper offers. Nobody signs in to read a price.","operationId":"get_plans","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlansView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/reports/digest":{"get":{"tags":["reports"],"summary":"One email for every site of the account.","operationId":"get_digest","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportSetting"}}}}}},"put":{"tags":["reports"],"operationId":"put_digest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportSetting"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportSetting"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sessions":{"get":{"tags":["team"],"operationId":"list_sessions","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SessionView"}}}}}}},"delete":{"tags":["team"],"summary":"Sign out everywhere else: every session of the member but the one asking.","operationId":"end_other_sessions","responses":{"204":{}}}},"/api/v1/sessions/{id}":{"delete":{"tags":["team"],"operationId":"end_session","responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/share/{site}":{"get":{"tags":["share"],"summary":"A site's shared figures. Nobody signs in: the site's public dashboard\nis on, or the request carries a private link's key.","operationId":"get_view","parameters":[{"name":"site","in":"path","description":"The site's name","required":true,"schema":{"type":"string"}},{"name":"period","in":"path","description":"`today`, `7d`, `30d` or `12mo`.","required":true,"schema":{"type":["string","null"]}},{"name":"key","in":"path","description":"A private link's key.","required":true,"schema":{"type":["string","null"]}},{"name":"pass","in":"path","description":"What unlocking a link with a password gave.","required":true,"schema":{"type":["string","null"]}},{"name":"filter","in":"path","description":"One row to look at alone: `page:/install`, `source:github.com`,\n`country:DK`, `device:phone`.","required":true,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareView"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/share/{site}/count":{"get":{"tags":["share"],"summary":"A page's view count, for a site that chose to show it. Any page may\nask from a browser: it is a number, and it is public.","operationId":"get_count","parameters":[{"name":"site","in":"path","description":"The site's name","required":true,"schema":{"type":"string"}},{"name":"path","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageCount"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/share/{site}/unlock":{"post":{"tags":["share"],"operationId":"post_unlock","parameters":[{"name":"site","in":"path","description":"The site's name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareUnlock"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareUnlocked"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites":{"get":{"tags":["api"],"operationId":"list_sites","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SiteView"}}}}}}},"post":{"tags":["api"],"operationId":"create_site","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites-offered":{"post":{"tags":["team"],"summary":"Take a site another account offered, with the code its owner was given.","operationId":"post_take","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TakeSite"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteRef"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}":{"get":{"tags":["api"],"operationId":"get_site","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["api"],"summary":"Delete a site and everything counted for it. Typed to confirm: the\nsite's name in `confirm`.","operationId":"delete_site","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"confirm","in":"query","description":"The site's name","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"tags":["api"],"operationId":"update_site","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteUpdate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/annotations":{"get":{"tags":["api"],"operationId":"list_annotations","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnnotationView"}}}}}}},"post":{"tags":["api"],"operationId":"create_annotation","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationView"}}}}}}},"/api/v1/sites/{site}/around":{"get":{"tags":["api"],"summary":"Where readers of a page came from inside the site, and went next.","operationId":"around","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"path","in":"query","description":"The page","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AroundResponse"}}}}}}},"/api/v1/sites/{site}/ask":{"post":{"tags":["team"],"summary":"Ask the owners for a site of your account that you were not given.","operationId":"post_ask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskAccess"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/banner":{"get":{"tags":["hard_api"],"summary":"The banner: what is live, the draft, and every version that was shown.","operationId":"get_banner","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BannersView"}}}}}}},"/api/v1/sites/{site}/banner/draft":{"put":{"tags":["hard_api"],"summary":"Save the draft. It may fail the rules; the answer says which.","operationId":"put_banner_draft","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BannerView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/banner/publish":{"post":{"tags":["hard_api"],"summary":"Publish the draft. A draft that fails a rule is refused.","operationId":"publish_banner","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BannerView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/changed":{"get":{"tags":["api"],"summary":"What moved between a period and the one before it, by page and by source.","operationId":"changed","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"period","in":"query","description":"The period; the one before it is what it is compared with","required":false,"schema":{"type":"string"}},{"name":"metrics","in":"query","description":"`visitors` (the default) or `views`","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangedResponse"}}}}}}},"/api/v1/sites/{site}/changes":{"get":{"tags":["api"],"summary":"Every change to a site's settings: who, what, when, old and new.","operationId":"site_changes","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SiteChangeView"}}}}}}}},"/api/v1/sites/{site}/check":{"post":{"tags":["api"],"summary":"Look at a page of the site: does it load, and is the tag in it?","operationId":"site_check","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/consent":{"get":{"tags":["hard_api"],"summary":"How many were asked and what they answered, day by day.","operationId":"consent_summary","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"period","in":"query","description":"7d, 30d, all, or two dates","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentSummary"}}}}}}},"/api/v1/sites/{site}/consent/export":{"get":{"tags":["hard_api"],"summary":"Every record as CSV, oldest first: what a regulator is handed.","operationId":"consent_export","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"CSV","content":{"text/csv":{}}}}}},"/api/v1/sites/{site}/consent/records":{"get":{"tags":["hard_api"],"summary":"Every answer and every withdrawal, newest first.","operationId":"consent_records","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"kind","in":"query","description":"agreed, declined, gpc, withdrew or changed","required":false,"schema":{"type":"string"}},{"name":"before","in":"query","description":"Unix seconds","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"limit","in":"query","description":"50 when left out","required":false,"schema":{"type":"integer","format":"int32","minimum":0}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RecordView"}}}}}}}},"/api/v1/sites/{site}/consent/records/{id}":{"get":{"tags":["hard_api"],"summary":"One record, with what the visitor was shown, word for word.","operationId":"consent_record","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The record","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDetail"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/dry-run":{"get":{"tags":["install"],"summary":"`GET /api/v1/sites/{site}/dry-run`: what arrives for a site being tried\nout, as it arrives. Nothing of it is stored.","operationId":"dry_run","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"text/event-stream: `hit` events, each a DryRunView","content":{"text/event-stream":{}}}}}},"/api/v1/sites/{site}/events":{"post":{"tags":["team"],"summary":"An event from a site's own backend, counted like one from the script.\n`Idempotency-Key` makes a retry safe: the same key counts once.","operationId":"post_event","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventIn"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventTaken"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/events/batch":{"post":{"tags":["team"],"summary":"Up to 500 events in one request. A malformed one refuses the batch\nbefore any of it is counted.","operationId":"post_events","requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventIn"}}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventsTaken"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/export":{"get":{"tags":["import"],"summary":"The site as a `.zip`: `site.json` and `daily.csv`.","operationId":"get_export","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"type":"array","items":{"type":"integer","format":"int32","minimum":0}}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/funnels":{"get":{"tags":["hard_api"],"operationId":"list_funnels","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FunnelView"}}}}}}},"post":{"tags":["hard_api"],"operationId":"create_funnel","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunnelCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunnelView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/funnels/{id}":{"get":{"tags":["hard_api"],"summary":"A funnel across visits for visitors who agreed, and the same steps\ninside one visit for everyone. Never added.","operationId":"funnel_report","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The funnel","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"period","in":"query","description":"30d when left out","required":false,"schema":{"type":"string"}},{"name":"by","in":"query","description":"source, country or device","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunnelReport"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"put":{"tags":["hard_api"],"operationId":"update_funnel","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The funnel","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunnelCreate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunnelView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["hard_api"],"operationId":"delete_funnel","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The funnel","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/goals":{"get":{"tags":["api"],"operationId":"list_goals","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GoalView"}}}}}}},"post":{"tags":["api"],"operationId":"create_goal","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/goals/test":{"post":{"tags":["more"],"operationId":"post_goal_test","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalTest"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/hard":{"get":{"tags":["hard_api"],"summary":"A site's mode, what turning hard mode on still needs, and what each\nmode does.","operationId":"get_hard","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HardView"}}}}}},"put":{"tags":["hard_api"],"summary":"Save what hard mode keeps and for how long. Does not turn it on.","operationId":"put_hard","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HardView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/hard/off":{"post":{"tags":["hard_api"],"summary":"Turn hard mode off, and say what happens to what was collected. Typed\nto confirm.","operationId":"hard_off","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HardOff"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemovedView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/hard/on":{"post":{"tags":["hard_api"],"summary":"Turn hard mode on. Every step before it has to be done.","operationId":"hard_on","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HardOn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HardView"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/hard/policy":{"post":{"tags":["hard_api"],"summary":"Say where the privacy policy is and that it has the paragraph.","operationId":"confirm_policy","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyConfirm"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyFound"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/holds":{"get":{"tags":["api"],"summary":"What deleting a site would take with it: said before its name is typed.","operationId":"site_holds","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteHolds"}}}}}}},"/api/v1/sites/{site}/icon":{"get":{"tags":["icons"],"summary":"A site's icon: its own, as its pages name it, or its first letter on a\ntile. Always a picture, so a list never has a hole in it.","operationId":"get_icon","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The site's own icon, or its first letter on a tile","content":{"image/*":{"schema":{"type":"array","items":{"type":"integer","format":"int32","minimum":0}}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/imports":{"get":{"tags":["import"],"operationId":"get_imports","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportsView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["import"],"summary":"Import a file. It is read again, exactly as the check read it.","operationId":"post_import","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}},{"name":"source","in":"path","description":"`plausible`, `umami`, `goatcounter`, `matomo` or `tidekeeper`.","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","description":"The file's name, to show beside the import.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/octet-stream":{"schema":{"type":"array","items":{"type":"integer","format":"int32","minimum":0}}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/imports/check":{"post":{"tags":["import"],"summary":"What an import would do. The file is the request's body; nothing is written.","operationId":"post_check","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}},{"name":"source","in":"path","description":"`plausible`, `umami`, `goatcounter`, `matomo` or `tidekeeper`.","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","description":"The file's name, to show beside the import.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/octet-stream":{"schema":{"type":"array","items":{"type":"integer","format":"int32","minimum":0}}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportPreview"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/imports/matomo":{"post":{"tags":["import"],"summary":"Fetch a stretch of a Matomo's reports. The answer is a file: check it\nand import it like any other, with `source=matomo`. The token is used\nfor this one request and not kept.","operationId":"post_matomo","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatomoFetch"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/imports/{id}":{"delete":{"tags":["import"],"operationId":"delete_import","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The import","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/install":{"get":{"tags":["api"],"summary":"What the install page shows: the tag, the proxy locations, the size.","operationId":"site_install","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallView"}}}}}}},"/api/v1/sites/{site}/left-out":{"get":{"tags":["api"],"summary":"Hits received and not counted, by reason.","operationId":"left_out","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LeftOutView"}}}}}}}},"/api/v1/sites/{site}/live":{"get":{"tags":["api"],"summary":"Who is on a site now, by page.","operationId":"live","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveResponse"}}}}}}},"/api/v1/sites/{site}/nightly":{"get":{"tags":["api"],"summary":"The nightly check on a site's own page: with what its scan found\namong what that site's pages sent.","operationId":"site_nightly","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NightlyView"}}}}}}},"/api/v1/sites/{site}/offer":{"post":{"tags":["team"],"operationId":"post_offer","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferSite"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteOffered"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["team"],"operationId":"delete_offer","responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/overlay":{"get":{"tags":["api"],"summary":"The page overlay: a stored copy of a page with the clicks each thing\non it got, and how far down readers got.","operationId":"overlay","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"path","in":"path","description":"The page: `/install`.","required":true,"schema":{"type":"string"}},{"name":"device","in":"path","description":"`desktop` or `phone`.","required":true,"schema":{"type":"string"}},{"name":"period","in":"path","required":true,"schema":{"type":"string"}},{"name":"show","in":"path","description":"`clicks` or `depth`.","required":true,"schema":{"type":"string"}},{"name":"el","in":"path","description":"The thing on the page that is selected, by its number.","required":true,"schema":{"type":["integer","null"],"format":"int32","minimum":0}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverlayView"}}}}}}},"/api/v1/sites/{site}/paths":{"get":{"tags":["hard_api"],"summary":"What came before and after a page or an event.","operationId":"paths","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","description":"page:/a/path or event:a name","required":false,"schema":{"type":"string"}},{"name":"reach","in":"query","description":"visit or visitor","required":false,"schema":{"type":"string"}},{"name":"steps","in":"query","description":"1 to 3","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"period","in":"query","description":"30d when left out","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathsReport"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/pick":{"get":{"tags":["api"],"summary":"The picker: a stored copy of a page with everything on it that can\nbe picked, and what the selected thing's selector matches.","operationId":"pick","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"path","in":"path","required":true,"schema":{"type":"string"}},{"name":"device","in":"path","description":"`desktop` or `phone`.","required":true,"schema":{"type":"string"}},{"name":"el","in":"path","description":"The thing on the copy that is selected, by its number.","required":true,"schema":{"type":["integer","null"],"format":"int32","minimum":0}},{"name":"selector","in":"path","description":"A selector written by hand, to be counted in place of the\nselected thing's own.","required":true,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PickView"}}}}}}},"/api/v1/sites/{site}/picks":{"get":{"tags":["api"],"summary":"The elements picked on a site's pages.","operationId":"list_picks","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PickedView"}}}}}}},"post":{"tags":["api"],"summary":"Count a click on what a selector matches as an event. The site's\nscript carries it: nothing on the site's pages changes.","operationId":"add_pick","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PickCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PickedView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/picks/{id}":{"delete":{"tags":["api"],"summary":"Stop counting clicks on a picked element.","operationId":"remove_pick","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The picked element","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/props":{"get":{"tags":["api"],"summary":"An event's properties, or how often each value of one of them was sent.","operationId":"props","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"event","in":"query","description":"The event. Left out, views","required":false,"schema":{"type":"string"}},{"name":"key","in":"query","description":"One property, to list its values","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Counted"}}}}}}}},"/api/v1/sites/{site}/reports":{"get":{"tags":["reports"],"operationId":"get_site","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportSetting"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"put":{"tags":["reports"],"operationId":"put_site","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportSetting"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportSetting"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/requests":{"get":{"tags":["hard_api"],"summary":"Visitors' requests about their data, newest first.","operationId":"list_requests","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestsView"}}}}}},"post":{"tags":["hard_api"],"summary":"Open a request for someone who wrote to you.","operationId":"open_request","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/requests/{id}/close":{"post":{"tags":["hard_api"],"summary":"Close a request without doing it, saying why.","operationId":"close_request","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The request","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestDone"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/requests/{id}/finish":{"post":{"tags":["hard_api"],"summary":"Do what a request asks: hand over the copy, or delete.","operationId":"finish_request","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The request","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestDone"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/reset":{"post":{"tags":["api"],"summary":"Drop everything counted for a site and keep the site. Typed to confirm.","operationId":"reset_site","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"confirm","in":"path","required":true,"schema":{"type":["string","null"]}},{"name":"from","in":"path","description":"The first day to delete, `2026-03-01`. With `to`. Without both,\neverything counted is deleted.","required":true,"schema":{"type":["string","null"]}},{"name":"to","in":"path","required":true,"schema":{"type":["string","null"]}}],"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/retention":{"get":{"tags":["hard_api"],"summary":"Of the visitors first seen in a week or month, the share who came back.","operationId":"retention","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"grain","in":"query","description":"week or month","required":false,"schema":{"type":"string"}},{"name":"what","in":"query","description":"visit, or goal:<name>","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReport"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/revenue":{"get":{"tags":["hard_api"],"summary":"Revenue in one currency, and who gets the credit three ways.","operationId":"revenue","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"period","in":"query","description":"30d when left out","required":false,"schema":{"type":"string"}},{"name":"currency","in":"query","description":"Three letters; the site's own when left out","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevenueReport"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/series":{"get":{"tags":["api"],"summary":"The same metrics over time: one point for every day or hour.","operationId":"series","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"grain","in":"query","description":"`day` or `hour`. Follows the period when left out","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/share":{"get":{"tags":["share"],"operationId":"get_share","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareAdmin"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"put":{"tags":["share"],"operationId":"put_share","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareChange"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareAdmin"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/share/links":{"post":{"tags":["share"],"operationId":"post_link","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinkCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinkView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/share/links/{id}":{"delete":{"tags":["share"],"operationId":"delete_link","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The link","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/snapshots":{"get":{"tags":["api"],"summary":"The stored copies of a site's pages, and whether this tidekeeper can\nshow them.","operationId":"list_snapshots","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnapshotsView"}}}}}},"post":{"tags":["api"],"summary":"Store a copy of one of the site's own pages, as a desktop and as a\nphone are sent it, with everything that runs taken out.","operationId":"take_snapshot","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnapshotTake"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SnapshotView"}}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["api"],"summary":"Remove the copies of a page.","operationId":"remove_snapshot","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"path","in":"query","description":"The page's path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/snapshots/frame":{"get":{"tags":["api"],"summary":"Where a copy of a page can be shown for the next hour: an address on\nthe other origin, for a frame.","operationId":"snapshot_frame","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"path","in":"query","description":"The page's path","required":true,"schema":{"type":"string"}},{"name":"device","in":"query","description":"`desktop` or `phone`","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnapshotFrame"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/stats":{"get":{"tags":["api"],"summary":"Metrics for a site, optionally broken down by one dimension, filtered,\nand compared with another period.","operationId":"stats","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"period","in":"query","description":"`today`, `yesterday`, `7d`, `30d`, `month`, `year`, `all`, a date, or two dates with `..` between","required":false,"schema":{"type":"string"}},{"name":"metrics","in":"query","description":"Comma-separated metric names. `visitors,views` when left out","required":false,"schema":{"type":"string"}},{"name":"by","in":"query","description":"A dimension to break down by","required":false,"schema":{"type":"string"}},{"name":"filter","in":"query","description":"`dim:op:value`, repeatable. `op` is `is`, `is_not`, `contains` or `matches`","required":false,"schema":{"type":"string"}},{"name":"compare","in":"query","description":"`previous`, `year`, or a period","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Most rows wanted","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"goal","in":"query","description":"For the goal metrics","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/stats.csv":{"get":{"tags":["api"],"summary":"The same answer as comma-separated text: any panel as a file (RP-04).\nWho took what out is written down.","operationId":"stats_csv","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/csv":{"schema":{"type":"string"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/stores":{"get":{"tags":["api"],"summary":"Every table that holds anything about a site, and what is never kept.","operationId":"site_stores","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoresView"}}}}}}},"/api/v1/sites/{site}/stream":{"get":{"tags":["stream"],"summary":"The stream for one site.","operationId":"stream","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"text/event-stream: `hit` and `live` events","content":{"text/event-stream":{}}}}}},"/api/v1/sites/{site}/stretches":{"get":{"tags":["api"],"summary":"The stretches of a site left out of comparisons, newest first, the\nundone among them.","operationId":"list_stretches","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StretchView"}}}}}}},"post":{"tags":["api"],"summary":"Leave a stretch out of comparisons: its views stay counted, and what\nis usual is worked out without them.","operationId":"add_stretch","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StretchCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StretchView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/stretches/{id}":{"delete":{"tags":["api"],"summary":"Undo it: it counts in comparisons again. It stays in the list.","operationId":"undo_stretch","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"The stretch","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/views":{"get":{"tags":["more"],"operationId":"get_views","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SavedView"}}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["more"],"operationId":"post_view","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedViewCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/visitors":{"get":{"tags":["hard_api"],"summary":"Visitors who agreed, last seen first.","operationId":"visitors","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"period","in":"query","description":"30d when left out","required":false,"schema":{"type":"string"}},{"name":"min_visits","in":"query","description":"Only visitors with this many visits","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"find","in":"query","description":"A visitor ID or the site's own user ID","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"25 when left out","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"offset","in":"query","description":"How many to skip","required":false,"schema":{"type":"integer","format":"int32","minimum":0}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorsResponse"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/visitors-export":{"get":{"tags":["hard_api"],"summary":"Every visitor's record, a line of JSON each (IO-06). Only those who\nagreed are in it: nobody else has a record.","operationId":"visitors_export","parameters":[{"name":"site","in":"path","description":"The site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/x-ndjson":{"schema":{"type":"string"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/visitors/{visitor}":{"get":{"tags":["hard_api"],"summary":"Everything held about one visitor.","operationId":"visitor","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"visitor","in":"path","description":"The visitor's ID, v_ and 32 digits","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorDetail"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["hard_api"],"summary":"Delete everything held about a visitor. Typed to confirm: their ID.","operationId":"delete_visitor","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"visitor","in":"path","description":"The visitor's ID","required":true,"schema":{"type":"string"}},{"name":"confirm","in":"query","description":"The visitor's ID again","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemovedView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/visitors/{visitor}/export":{"get":{"tags":["hard_api"],"summary":"A copy of everything held about a visitor, for them.","operationId":"visitor_export","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"visitor","in":"path","description":"The visitor's ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorExport"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/sites/{site}/when":{"get":{"tags":["api"],"summary":"When in the week readers come: each hour of each weekday.","operationId":"when","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}},{"name":"period","in":"query","description":"The period averaged over; four weeks unless given","required":false,"schema":{"type":"string"}},{"name":"metrics","in":"query","description":"`visitors` (the default) or `views`","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhenResponse"}}}}}}},"/api/v1/sites/{site}/why":{"get":{"tags":["api"],"summary":"How a figure was made: what arrived, what was left out and why, what\nwas counted without a key.","operationId":"why","parameters":[{"name":"site","in":"path","description":"A site's id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhyResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/team":{"get":{"tags":["team"],"operationId":"get_team","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/team/invitations":{"post":{"tags":["team"],"operationId":"post_invitation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invite"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invited"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/team/invitations/{id}":{"delete":{"tags":["team"],"operationId":"delete_invitation","responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/team/invitations/{id}/resend":{"post":{"tags":["team"],"operationId":"resend_invitation","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invited"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/team/members/{id}":{"put":{"tags":["team"],"operationId":"put_member","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberChange"}}},"required":true},"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["team"],"operationId":"delete_member","responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/team/owner":{"post":{"tags":["team"],"operationId":"post_owner","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandOver"}}},"required":true},"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/team/second-step":{"put":{"tags":["signin"],"operationId":"put_required","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnOff"}}},"required":true},"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/texts/{id}":{"get":{"tags":["about"],"summary":"One published text: its title and its blocks.","operationId":"get_text","parameters":[{"name":"id","in":"path","description":"terms, privacy, dpa, subprocessors, company or accessibility","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/tokens":{"get":{"tags":["routes"],"operationId":"tokens","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TokenView"}}}}}}},"post":{"tags":["routes"],"operationId":"create_token","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenCreated"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/tokens/about":{"get":{"tags":["team"],"operationId":"get_token_about","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenAbout"}}}}}}},"/api/v1/tokens/{id}":{"delete":{"tags":["routes"],"operationId":"revoke_token","responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/views/{id}":{"delete":{"tags":["more"],"operationId":"delete_view","responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"About":{"type":"object","required":["texts","cli"],"properties":{"cli":{"type":"boolean","description":"Customers are offered the command line (CL-09)."},"contact":{"type":["string","null"],"description":"The address to write to, where one was given."},"texts":{"type":"array","items":{"$ref":"#/components/schemas/TextLink"},"description":"The texts this deployment publishes, in the order they are listed."}}},"AccountChoice":{"type":"object","description":"Which of one's accounts to act in from now on.","required":["account"],"properties":{"account":{"type":"string","format":"uuid"}}},"AccountRename":{"type":"object","description":"What an account is called (doc/launch.md, 2.4).","required":["name"],"properties":{"name":{"type":"string"}}},"AccountView":{"type":"object","description":"What an account is, to its members.","required":["id","name","delete_days"],"properties":{"delete_days":{"type":"integer","format":"int32","description":"How many days an owner's own wish to delete waits.","minimum":0},"deletion":{"oneOf":[{"$ref":"#/components/schemas/Deletion","description":"Set while the account is on its way to being deleted."},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"instance":{"type":"boolean","description":"The account of whoever runs this tidekeeper. It is not deleted\nfrom here: it goes when the instance does."},"name":{"type":"string"},"pending":{"type":"boolean","description":"It is new and waits for whoever runs this tidekeeper to approve\nit: nothing is counted until then."},"support":{"oneOf":[{"$ref":"#/components/schemas/SupportView","description":"Set while tidekeeper's support has asked to see the account's\nfigures, or has been let."},{"type":"null"}]},"suspended":{"oneOf":[{"$ref":"#/components/schemas/Suspended","description":"Set while an operator has suspended it: nothing is counted."},{"type":"null"}]}}},"AdminAccount":{"type":"object","required":["row","members","sites","plan","events","invoices","audit","log","notes","suspended_why","deletion_by","plans","now"],"properties":{"audit":{"type":"array","items":{"$ref":"#/components/schemas/AdminLine"},"description":"What its members did, newest first."},"deletion_by":{"type":"string"},"events":{"type":"array","items":{"$ref":"#/components/schemas/AdminEvent"},"description":"The provider's events about it, newest first."},"invoices":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceView"}},"limits":{"oneOf":[{"$ref":"#/components/schemas/AdminLimits"},{"type":"null"}]},"log":{"type":"array","items":{"$ref":"#/components/schemas/AdminLine"},"description":"What operators did to it, newest first."},"members":{"type":"array","items":{"$ref":"#/components/schemas/AdminMember"}},"notes":{"type":"array","items":{"$ref":"#/components/schemas/AdminNote"}},"now":{"type":"integer","format":"int64"},"plan":{"$ref":"#/components/schemas/PlanView","description":"The plan as it applies to this account: its own limits in place."},"plans":{"type":"array","items":{"$ref":"#/components/schemas/PlanView"}},"row":{"$ref":"#/components/schemas/AdminAccountRow"},"sites":{"type":"array","items":{"$ref":"#/components/schemas/AdminSite"}},"subscription":{"oneOf":[{"$ref":"#/components/schemas/AdminSubscription"},{"type":"null"}]},"support":{"oneOf":[{"$ref":"#/components/schemas/SupportView"},{"type":"null"}]},"suspended_why":{"type":"string"}}},"AdminAccountRow":{"type":"object","description":"One account, as a row of the list.","required":["id","name","created","owner","members","sites","plan","plan_name","state","events","limit","suspended","held","stage","own_limits"],"properties":{"created":{"type":"integer","format":"int64"},"deletion":{"type":["integer","null"],"format":"int64","description":"The day it is to be deleted."},"events":{"type":"integer","format":"int64","description":"This month's events, and the limit they are held to. Zero is none.","minimum":0},"held":{"type":"boolean","description":"Hits are being left out: unpaid past its grace, over its plan past\nits grace, ended, or suspended."},"id":{"type":"string","format":"uuid"},"instance":{"type":"boolean","description":"The account of whoever runs this tidekeeper."},"last_seen":{"type":["integer","null"],"format":"int64","description":"When any member was last here."},"limit":{"type":"integer","format":"int64","minimum":0},"members":{"type":"integer","format":"int32","minimum":0},"name":{"type":"string"},"own_limits":{"type":"boolean","description":"Its limits are its own, not its plan's."},"owner":{"type":"string","description":"Its first owner's address."},"pending":{"type":"boolean","description":"New, and waiting to be approved: resuming it approves it."},"plan":{"type":"string"},"plan_name":{"type":"string"},"sites":{"type":"integer","format":"int32","minimum":0},"stage":{"type":"string","description":"How far it got: `confirmed`, `site`, `counted` or `paying`."},"state":{"type":"string","description":"`none`, `trialing`, `active`, `past_due`, `unpaid`, `cancelling`,\n`ended`, or `comp` for a plan given without payment."},"suspended":{"type":"boolean"}}},"AdminAccounts":{"type":"object","required":["rows","total","plans","now"],"properties":{"now":{"type":"integer","format":"int64"},"plans":{"type":"array","items":{"$ref":"#/components/schemas/PlanView"}},"rows":{"type":"array","items":{"$ref":"#/components/schemas/AdminAccountRow"}},"total":{"type":"integer","format":"int32","description":"How many there are before the search and the filters.","minimum":0}}},"AdminDeletion":{"type":"object","required":["days","reason"],"properties":{"days":{"type":"integer","format":"int32","description":"In how many days. Never fewer than seven.","minimum":0},"reason":{"type":"string"}}},"AdminEvent":{"type":"object","required":["provider","id","kind","received","says"],"properties":{"applied":{"type":["integer","null"],"format":"int64"},"id":{"type":"string"},"kind":{"type":"string"},"provider":{"type":"string"},"received":{"type":"integer","format":"int64"},"says":{"type":"string"}}},"AdminLimits":{"type":"object","description":"Limits set for one account in place of its plan's. A field left out\nleaves the plan's; zero is no limit.","properties":{"api_requests":{"type":["integer","null"],"format":"int32","minimum":0},"events":{"type":["integer","null"],"format":"int64","minimum":0},"history_months":{"type":["integer","null"],"format":"int32","minimum":0},"jobs":{"type":["integer","null"],"format":"int32","minimum":0},"members":{"type":["integer","null"],"format":"int32","minimum":0},"set":{"type":"integer","format":"int64"},"set_by":{"type":"string"},"sites":{"type":["integer","null"],"format":"int32","minimum":0},"until":{"type":["integer","null"],"format":"int64","description":"When they stop applying. Left out: until changed."},"why":{"type":"string","description":"Why, and who set them and when: filled in an answer."}}},"AdminLimitsSet":{"allOf":[{"$ref":"#/components/schemas/AdminLimits"},{"type":"object","required":["reason"],"properties":{"reason":{"type":"string"}}}]},"AdminLine":{"type":"object","description":"A line of a log: the members' own, or the operators'.","required":["ts","who","what"],"properties":{"account":{"type":["string","null"],"format":"uuid","description":"The account it was about, in the log of everything."},"account_name":{"type":"string"},"reason":{"type":"string","description":"The reason an operator gave. Empty in a members' log."},"ts":{"type":"integer","format":"int64"},"what":{"type":"string"},"who":{"type":"string"}}},"AdminLog":{"type":"object","required":["lines"],"properties":{"lines":{"type":"array","items":{"$ref":"#/components/schemas/AdminLine"}}}},"AdminMember":{"type":"object","required":["email","role"],"properties":{"email":{"type":"string"},"last_seen":{"type":["integer","null"],"format":"int64"},"role":{"type":"string"}}},"AdminNote":{"type":"object","required":["ts","by","text"],"properties":{"by":{"type":"string"},"text":{"type":"string"},"ts":{"type":"integer","format":"int64"}}},"AdminNoteNew":{"type":"object","required":["text"],"properties":{"text":{"type":"string"}}},"AdminOverview":{"type":"object","required":["now","accounts","signups","funnel","unconfirmed","needs","stray","money","provider"],"properties":{"accounts":{"type":"integer","format":"int32","minimum":0},"approval":{"type":"boolean","description":"New accounts wait for an operator's approval here."},"funnel":{"type":"array","items":{"$ref":"#/components/schemas/Stage"},"description":"The same accounts as a funnel, with those who never confirmed on top."},"money":{"$ref":"#/components/schemas/Money"},"needs":{"type":"array","items":{"$ref":"#/components/schemas/Needs"}},"now":{"type":"integer","format":"int64"},"provider":{"type":"string","description":"Whether a provider that takes payment is connected, and its name."},"signups":{"type":"array","items":{"$ref":"#/components/schemas/SignupDay"},"description":"The last thirty days, newest first. Days nobody signed up on are\nleft out."},"stray":{"type":"array","items":{"$ref":"#/components/schemas/StrayEvent"}},"test_mode":{"type":"boolean","description":"It takes no real payment: its keys are test keys."},"unconfirmed":{"type":"array","items":{"$ref":"#/components/schemas/Unconfirmed"}}}},"AdminPlan":{"type":"object","required":["plan","reason"],"properties":{"plan":{"type":"string"},"reason":{"type":"string"}}},"AdminResend":{"type":"object","description":"Which mail to send again where it still applies: `trial_ending`,\n`trial_ended`, `payment_failed`, `held`, `cancelling`, `ended`,\n`card_expiring`.","required":["what","reason"],"properties":{"reason":{"type":"string"},"what":{"type":"string"}}},"AdminSite":{"type":"object","description":"A site as an operator sees it: that it is there. No figure.","required":["name","mode","paused","seen"],"properties":{"mode":{"type":"string","description":"`easy` or `hard`."},"name":{"type":"string"},"paused":{"type":"boolean"},"seen":{"type":"boolean","description":"Whether its script has ever sent anything."}}},"AdminSubscription":{"type":"object","required":["provider","state","says","yearly","told"],"properties":{"cancel_at":{"type":["integer","null"],"format":"int64"},"held_on":{"type":["integer","null"],"format":"int64"},"period_end":{"type":["integer","null"],"format":"int64"},"provider":{"type":"string"},"says":{"type":"string"},"state":{"type":"string"},"told":{"type":"array","items":{"$ref":"#/components/schemas/Told"},"description":"What its owners were mailed, and when."},"trial_ends":{"type":["integer","null"],"format":"int64"},"yearly":{"type":"boolean"}}},"AdminTrial":{"type":"object","required":["days","reason"],"properties":{"days":{"type":"integer","format":"int32","description":"How many more days.","minimum":0},"reason":{"type":"string"}}},"AnnotationCreate":{"type":"object","required":["day","note"],"properties":{"day":{"type":"string"},"note":{"type":"string"}}},"AnnotationView":{"type":"object","required":["id","day","note","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"day":{"type":"string","description":"`2026-10-08`, in the site's time zone."},"id":{"type":"string","format":"uuid"},"note":{"type":"string"}}},"ApiError":{"type":"object","description":"Every error body. `code` is stable and machine-readable; `message` is for\npeople.","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"AroundResponse":{"type":"object","description":"Where readers of a page came from inside the site and went next.","required":["before","after"],"properties":{"after":{"type":"array","items":{"$ref":"#/components/schemas/Counted"}},"before":{"type":"array","items":{"$ref":"#/components/schemas/Counted"}}}},"AskAccess":{"type":"object","description":"The page someone wanted when they were told they have no access.","properties":{"page":{"type":"string"}}},"Attention":{"type":"object","description":"Problems with counting and news about traffic, on any site (AL-07).","required":["open","recovered","muted","watches"],"properties":{"muted":{"type":"array","items":{"$ref":"#/components/schemas/AttentionItem"},"description":"Open, and someone asked not to hear of it for now."},"open":{"type":"array","items":{"$ref":"#/components/schemas/AttentionItem"}},"plan":{"oneOf":[{"$ref":"#/components/schemas/PlanNotice","description":"The account is near its plan's events, past them, or held (AL-06)."},{"type":"null"}]},"recovered":{"type":"array","items":{"$ref":"#/components/schemas/AttentionItem"},"description":"Over, within the last week."},"requests":{"type":"array","items":{"$ref":"#/components/schemas/OpenRequest"},"description":"Visitors' requests about their data that are still open, soonest\ndeadline first (DS-05)."},"watches":{"type":"array","items":{"$ref":"#/components/schemas/WatchDef"},"description":"What tidekeeper watches for."}}},"AttentionItem":{"type":"object","description":"One thing that is, or was, true about a site (AL-07).","required":["id","site","kind","label","todo","todo_label","about_counting","summary","numbers","since","opened_at","told"],"properties":{"about_counting":{"type":"boolean","description":"A problem with counting, not a change in traffic (IV-10)."},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","description":"`silent`, `quiet`, `never_seen`, `spike`, …"},"label":{"type":"string"},"muted_until":{"type":["string","null"],"format":"date-time"},"numbers":{"type":"array","items":{"$ref":"#/components/schemas/Labelled"},"description":"The numbers behind it (AL-09)."},"opened_at":{"type":"string","format":"date-time"},"recovered_at":{"type":["string","null"],"format":"date-time"},"since":{"type":"string","description":"When it began: for a silent site, its last view."},"since_local":{"type":"string","description":"When it began and, if it is over, when it ended, in the site's own\ntime and as a stretch is written (`2026-10-08T15:04`): what a\nspike that ended is left out of comparisons with."},"site":{"type":"string"},"summary":{"type":"string","description":"One line with the number in it: `No views for 26 hours`."},"todo":{"type":"string","description":"What to do about it: `put_the_script_back`, `put_the_script_on`,\n`decide`, `look`, `know`."},"todo_label":{"type":"string"},"told":{"type":"integer","format":"int32","description":"How many times someone was told.","minimum":0},"until_local":{"type":["string","null"]}}},"Away":{"type":"object","description":"A page of the payment provider's to go to.","required":["url"],"properties":{"url":{"type":"string"}}},"BannerView":{"type":"object","required":["version","state","config","rules","publishable","asks_again","created_at"],"properties":{"asks_again":{"type":"boolean","description":"For a draft: publishing it asks everyone again. For a published\nversion: it did."},"config":{"type":"object"},"created_at":{"type":"integer","format":"int64","description":"Unix seconds."},"publishable":{"type":"boolean"},"published_at":{"type":["integer","null"],"format":"int64"},"rules":{"type":"array","items":{"type":"object"},"description":"The rules, each with what was found (CB-02, CB-03, CB-13)."},"state":{"type":"string","description":"`draft`, `live` or `retired`."},"version":{"type":"integer","format":"int32"}}},"BannersView":{"type":"object","required":["site","versions","starting","own_tool"],"properties":{"draft":{"oneOf":[{"$ref":"#/components/schemas/BannerView"},{"type":"null"}]},"live":{"oneOf":[{"$ref":"#/components/schemas/BannerView"},{"type":"null"}]},"own_tool":{"type":"boolean","description":"The site asks with its own tool: no banner of ours is shown."},"site":{"type":"string"},"starting":{"type":"object","description":"What a new draft starts from."},"versions":{"type":"array","items":{"$ref":"#/components/schemas/BannerView"},"description":"Every version that was shown, newest first (CR-03)."}}},"BillingDetails":{"type":"object","properties":{"address":{"type":"string"},"billing_email":{"type":"string"},"vat":{"type":"string"}}},"BillingView":{"type":"object","required":["unset","plan","plans","month","month_label","resets","events","limit","standing","by_site","sites","members","trial_days","grace_days","read_only_days","region","billing_email","vat","address","dpa_by","provider","now"],"properties":{"address":{"type":"string"},"billing_email":{"type":"string"},"by_site":{"type":"array","items":{"$ref":"#/components/schemas/SiteUse"}},"cancelled":{"type":["integer","null"],"format":"int64"},"dpa":{"type":["integer","null"],"format":"int64","description":"When the data processing agreement was accepted, and by whom."},"dpa_by":{"type":"string"},"events":{"type":"integer","format":"int64","description":"Views and events received this month, across every site. Bots,\nspam and rejected hits are not in it, and neither is anything\nimported.","minimum":0},"grace_days":{"type":"integer","format":"int32","minimum":0},"history":{"oneOf":[{"$ref":"#/components/schemas/HistoryNotice","description":"Set while history is about to get shorter."},{"type":"null"}]},"instance":{"type":"boolean","description":"This is the account of whoever runs this tidekeeper: its plan is\nits own, limits nothing, costs nothing and is offered to nobody."},"invoices":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceView"},"description":"The provider's invoices, newest first."},"limit":{"type":"integer","format":"int64","minimum":0},"members":{"type":"integer","format":"int32","minimum":0},"month":{"type":"string","description":"`2026-10`, and the stretch of it so far in words."},"month_label":{"type":"string"},"now":{"type":"integer","format":"int64"},"own_limits":{"oneOf":[{"$ref":"#/components/schemas/OwnLimits","description":"Set where the limits shown under `plan` were set for this account\nin place of the plan's."},{"type":"null"}]},"passes_on":{"type":["string","null"],"description":"The day the limit is passed if the month goes on as it has."},"pays":{"type":"boolean","description":"A provider that takes payment is connected: a plan with a price is\npaid for on its pages, not chosen here."},"plan":{"$ref":"#/components/schemas/PlanView"},"plans":{"type":"array","items":{"$ref":"#/components/schemas/PlanView"}},"provider":{"type":"boolean","description":"Whether a payment provider is connected. Without one there are no\ninvoices and no card, and a plan is changed by choosing it."},"read_only_days":{"type":"integer","format":"int32","minimum":0},"region":{"type":"string"},"renews":{"type":["integer","null"],"format":"int64"},"resets":{"type":"string","description":"The first day of the next month."},"sites":{"type":"integer","format":"int32","minimum":0},"standing":{"type":"object"},"subscription":{"oneOf":[{"$ref":"#/components/schemas/SubscriptionView","description":"What the account pays for, as the provider has it. None for an\naccount that has never been on trial and never paid."},{"type":"null"}]},"test_mode":{"type":"boolean","description":"The provider takes no real payment: its keys are test keys."},"trial_days":{"type":"integer","format":"int32","description":"The days of trial a card starts, for an account that has not given one.","minimum":0},"unset":{"type":"boolean"},"vat":{"type":"string"}}},"BucketRow":{"type":"object","required":["label","orders"],"properties":{"label":{"type":"string"},"orders":{"type":"integer","format":"int64","minimum":0},"share":{"type":["number","null"],"format":"double"}}},"CaveatView":{"type":"object","description":"Something a reader has to know to read a figure honestly (ME-14).","required":["code","text"],"properties":{"code":{"type":"string"},"text":{"type":"string"}}},"ChangedGroup":{"type":"object","description":"What moved by one dimension, largest first: the rows shown, and how\nmany rose and fell in all.","required":["dim","rose","fell","up","down"],"properties":{"dim":{"type":"string","description":"`page` or `source`."},"down":{"type":"array","items":{"$ref":"#/components/schemas/ChangedRow"}},"fell":{"type":"integer","format":"int32","minimum":0},"rose":{"type":"integer","format":"int32","minimum":0},"up":{"type":"array","items":{"$ref":"#/components/schemas/ChangedRow"}}}},"ChangedResponse":{"type":"object","description":"What changed between a period and the one before it.","required":["site","period","compare","metric","floor","part","groups","caveats"],"properties":{"before":{"type":["number","null"],"format":"double"},"caveats":{"type":"array","items":{"$ref":"#/components/schemas/CaveatView"}},"compare":{"$ref":"#/components/schemas/PeriodView"},"floor":{"type":"integer","format":"int32","description":"A row is listed when it moved by at least `floor`, and by at least\none part in `part` of what it was.","minimum":0},"groups":{"type":"array","items":{"$ref":"#/components/schemas/ChangedGroup"}},"metric":{"type":"string","description":"`visitors` or `views`."},"now":{"type":["number","null"],"format":"double"},"part":{"type":"integer","format":"int32","minimum":0},"period":{"$ref":"#/components/schemas/PeriodView"},"site":{"type":"string"}}},"ChangedRow":{"type":"object","description":"One page or one source that moved: what it counted in the period and\nin the one before. Nothing before is new; nothing now is gone.","required":["key","label","before","now"],"properties":{"before":{"type":"number","format":"double"},"key":{"type":"string"},"label":{"type":"string"},"now":{"type":"number","format":"double"}}},"ChannelCreate":{"type":"object","required":["kind","name","config"],"properties":{"config":{"type":"object","description":"The kind's own settings: `{\"to\": [\"me@example.org\"]}` for email,\n`{\"url\": \"…\", \"secret\": \"…\"}` for a webhook, `{\"topic\": \"…\"}` for\nntfy."},"kind":{"type":"string"},"kinds":{"type":["array","null"],"items":{"type":"string"},"description":"Left out, the kinds a new channel is told about by default."},"name":{"type":"string"}}},"ChannelRule":{"type":"object","required":["matches","source","channel"],"properties":{"channel":{"type":"string"},"matches":{"type":"string","description":"What is matched: a referring host, or a tag."},"source":{"type":"string","description":"The source's name."}}},"ChannelUpdate":{"type":"object","properties":{"config":{"type":["object","null"]},"disabled":{"type":["boolean","null"]},"kinds":{"type":["array","null"],"items":{"type":"string"}},"name":{"type":["string","null"]}}},"ChannelView":{"type":"object","description":"Somewhere alerts go. Its secrets are never sent back: `target` says\nwhere it points with them left out.","required":["id","kind","name","target","kinds","declared","disabled","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"declared":{"type":"boolean","description":"From the instance's configuration: not edited here."},"disabled":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","description":"`alertmanager`, `email`, `webhook`, `ntfy`, `discord`, `slack`,\n`telegram`."},"kinds":{"type":"array","items":{"type":"string"},"description":"The alerts this channel is told about: its row of the matrix."},"name":{"type":"string"},"target":{"type":"string"}}},"CheckRequest":{"type":"object","properties":{"url":{"type":["string","null"],"description":"The page to look at. Left out, the site's front page."}}},"CheckView":{"type":"object","description":"What tidekeeper found when it looked at a page (the CLI's `check`).","required":["url","site","bytes","millis","tag","script_answers","advice","install"],"properties":{"advice":{"type":"string","description":"What to do, in a line."},"bytes":{"type":"integer","format":"int64","minimum":0},"error":{"type":["string","null"],"description":"Why the page could not be fetched, in words."},"install":{"type":"string","description":"The tag for this site, to paste."},"last_hit":{"type":["string","null"],"description":"When the site last had a counted view."},"millis":{"type":"integer","format":"int64","minimum":0},"script_answers":{"type":"boolean","description":"Whether `/t.js` answers on the page's host."},"site":{"type":"string"},"status":{"type":["integer","null"],"format":"int32","description":"The page's status, when it answered.","minimum":0},"tag":{"type":"string","description":"`found`, `not_found`, `other_site` or `unreachable`."},"tag_site":{"type":["string","null"],"description":"The site the tag names, when it is another one."},"url":{"type":"string"}}},"CodeUse":{"type":"object","description":"A link's own token, or the address it went to with its six digits.","properties":{"code":{"type":["string","null"]},"email":{"type":["string","null"]},"second":{"type":["string","null"],"description":"The second step, when the member has one."},"token":{"type":["string","null"]}}},"CohortRow":{"type":"object","required":["from","to","visitors","back","so_far"],"properties":{"back":{"type":"array","items":{"type":["number","null"],"format":"double"},"description":"Percent back in period 1, 2, …; null where it is not over yet."},"from":{"type":"string"},"so_far":{"type":"boolean","description":"The cohort is still gathering visitors."},"to":{"type":"string"},"visitors":{"type":"integer","format":"int64","minimum":0}}},"ConsentDay":{"type":"object","required":["day","asked","agreed"],"properties":{"agreed":{"type":"integer","format":"int64","minimum":0},"asked":{"type":"integer","format":"int64","minimum":0},"day":{"type":"string"},"rate":{"type":["number","null"],"format":"double","description":"Null on a day nobody was asked: a gap, not a zero."}}},"ConsentSplit":{"type":"object","required":["key","asked","agreed"],"properties":{"agreed":{"type":"integer","format":"int64","minimum":0},"asked":{"type":"integer","format":"int64","minimum":0},"key":{"type":"string"},"rate":{"type":["number","null"],"format":"double"}}},"ConsentSummary":{"type":"object","description":"The consent log's figures (CR-06).","required":["site","period","asked","agreed","declined","unanswered","gpc","withdrew","days","by_language","by_device","by_version"],"properties":{"agreed":{"type":"integer","format":"int64","minimum":0},"asked":{"type":"integer","format":"int64","description":"The banner was shown.","minimum":0},"by_device":{"type":"array","items":{"$ref":"#/components/schemas/ConsentSplit"}},"by_language":{"type":"array","items":{"$ref":"#/components/schemas/ConsentSplit"}},"by_version":{"type":"array","items":{"$ref":"#/components/schemas/ConsentSplit"}},"days":{"type":"array","items":{"$ref":"#/components/schemas/ConsentDay"}},"declined":{"type":"integer","format":"int64","minimum":0},"gpc":{"type":"integer","format":"int64","description":"Never asked: the browser sent Global Privacy Control.","minimum":0},"period":{"$ref":"#/components/schemas/PeriodView"},"site":{"type":"string"},"unanswered":{"type":"integer","format":"int64","description":"Shown, and neither answer given. Treated as a no.","minimum":0},"withdrew":{"type":"integer","format":"int64","minimum":0}}},"Counted":{"type":"object","required":["key","count"],"properties":{"count":{"type":"integer","format":"int64","minimum":0},"key":{"type":"string"}}},"Coverage":{"type":"object","description":"Who a hard-mode figure covers.","required":["visitors","asked","agreed","says"],"properties":{"agreed":{"type":"integer","format":"int64","description":"Of those, how many agreed.","minimum":0},"asked":{"type":"integer","format":"int64","description":"Visitors the banner was shown to in the period.","minimum":0},"says":{"type":"string","description":"The sentence shown with every report."},"share":{"type":["number","null"],"format":"double","description":"`agreed / asked`, in percent. Null when nobody was asked: a site\nthat asks with its own tool, or a period with no new visitor."},"visitors":{"type":"integer","format":"int64","description":"Consenting visitors seen in the period.","minimum":0}}},"CreditRow":{"type":"object","required":["source","first_orders","first_minor","last_orders","last_minor","same_orders"],"properties":{"first_minor":{"type":"integer","format":"int64"},"first_orders":{"type":"integer","format":"int64","minimum":0},"last_minor":{"type":"integer","format":"int64"},"last_orders":{"type":"integer","format":"int64","minimum":0},"same_orders":{"type":"integer","format":"int64","minimum":0},"source":{"type":"string"}}},"DayCount":{"type":"object","required":["day","count"],"properties":{"count":{"type":"integer","format":"int64","minimum":0},"day":{"type":"string"}}},"DefinitionLine":{"type":"object","required":["label","text"],"properties":{"label":{"type":"string"},"text":{"type":"string"}}},"Definitions":{"type":"object","description":"Everything tidekeeper's figures mean, in one place (ME-11): the same text\nthe UI, the CLI and the emails show.","required":["metrics","dimensions","reasons","channels","caveats","fields"],"properties":{"caveats":{"type":"array","items":{"$ref":"#/components/schemas/CaveatView"}},"channels":{"type":"array","items":{"$ref":"#/components/schemas/ChannelRule"}},"dimensions":{"type":"array","items":{"type":"string"}},"fields":{"type":"array","items":{"$ref":"#/components/schemas/FieldDef"},"description":"What the script sends: the whole list (SC-16)."},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricDef"}},"reasons":{"type":"array","items":{"$ref":"#/components/schemas/ReasonDef"}}}},"Deletion":{"type":"object","required":["on","by","plan_ended"],"properties":{"by":{"type":"string","description":"Who asked: an address, or `plan ended`."},"on":{"type":"integer","format":"int64","description":"The day it happens."},"plan_ended":{"type":"boolean","description":"Because the plan ended: paying again stops it, and nothing else does."}}},"DeletionAsk":{"type":"object","description":"The account's name, typed to say that deleting it is meant.","required":["name"],"properties":{"name":{"type":"string"}}},"DeliveryView":{"type":"object","description":"One message to one channel: its attempts and its last error (NC-09).","required":["id","channel","what","state","attempts","title","error","created_at","not_before"],"properties":{"attempts":{"type":"integer","format":"int32","minimum":0},"channel":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"done_at":{"type":["string","null"],"format":"date-time"},"error":{"type":"string"},"id":{"type":"string","format":"uuid"},"not_before":{"type":"string","format":"date-time","description":"Not sent before this: quiet hours, or the wait before a retry."},"state":{"type":"string","description":"`pending`, `sent`, `failed` or `dropped`."},"title":{"type":"string"},"what":{"type":"string","description":"`alert`, `recovery` or `test`."}}},"EmailChange":{"type":"object","description":"A new address to sign in with: a link goes to it, and the change is\nmade when it is opened (doc/launch.md, 2.5).","required":["email"],"properties":{"email":{"type":"string"}}},"EmailOnly":{"type":"object","required":["email"],"properties":{"email":{"type":"string"}}},"EventIn":{"type":"object","description":"An event sent from a backend (IN-09), counted on the same model as one\nthe script sends.","required":["url"],"properties":{"currency":{"type":["string","null"]},"name":{"type":["string","null"],"description":"The event's name. Leave it out to count a view."},"props":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"referrer":{"type":["string","null"]},"url":{"type":"string","description":"The page it happened on: a full address on one of the site's hostnames."},"value":{"type":["number","null"],"format":"double","description":"An amount with its currency: `{ \"amount\": 29.0, \"currency\": \"EUR\" }`."},"visitor":{"oneOf":[{"$ref":"#/components/schemas/EventVisitor","description":"Without it the event is counted and belongs to no visitor."},{"type":"null"}]}}},"EventTaken":{"type":"object","required":["outcome"],"properties":{"outcome":{"type":"string","description":"`counted`, `left_out` with why, or `repeated` for a key seen before."},"why":{"type":["string","null"]}}},"EventVisitor":{"type":"object","description":"The visitor an event is about, as the backend saw them. Used to work\nout the same daily key the script's views get, and then dropped: the\naddress and the browser string are not stored, from here either.","properties":{"ip":{"type":["string","null"]},"language":{"type":["string","null"]},"user_agent":{"type":["string","null"]}}},"EventsTaken":{"type":"object","description":"What became of a batch of events.","required":["counted","left_out","why","repeated"],"properties":{"counted":{"type":"integer","format":"int32","minimum":0},"left_out":{"type":"integer","format":"int32","minimum":0},"repeated":{"type":"boolean","description":"The whole batch was sent before under the same key, and counts nothing."},"why":{"type":"object","description":"Why, and how many for each reason.","additionalProperties":{"type":"integer","format":"int32","minimum":0},"propertyNames":{"type":"string"}}}},"ExportHit":{"type":"object","required":["ts","kind","page","event","properties"],"properties":{"currency":{"type":["string","null"]},"event":{"type":"string"},"kind":{"type":"string","description":"`view` or `event`."},"page":{"type":"string"},"properties":{"type":"object"},"ts":{"type":"integer","format":"int64"},"value_minor":{"type":["integer","null"],"format":"int64"}}},"ExportVisit":{"type":"object","required":["n","start","end","source","country","device","hits"],"properties":{"country":{"type":"string"},"device":{"type":"string"},"end":{"type":"integer","format":"int64"},"hits":{"type":"array","items":{"$ref":"#/components/schemas/ExportHit"}},"n":{"type":"integer","format":"int32"},"source":{"type":"string"},"start":{"type":"integer","format":"int64"}}},"FeatureSet":{"type":"object","required":["personal","signup","billing"],"properties":{"billing":{"type":"boolean"},"personal":{"type":"boolean"},"signup":{"type":"boolean"}}},"FieldDef":{"type":"object","required":["name","what","strict"],"properties":{"name":{"type":"string"},"strict":{"type":"boolean","description":"Sent by the strict variant too."},"what":{"type":"string"}}},"FrameAt":{"type":"object","description":"Where a copy's frame is, for the next hour.","required":["url","expires","width"],"properties":{"expires":{"type":"integer","format":"int64"},"url":{"type":"string"},"width":{"type":"integer","format":"int32","description":"How wide the frame is for this device, in pixels.","minimum":0}}},"FunnelCreate":{"type":"object","required":["name","spec"],"properties":{"name":{"type":"string"},"spec":{"type":"object"}}},"FunnelReport":{"type":"object","description":"A funnel across visits, for visitors who agreed (AN-01), and the same\nsteps inside one visit for everyone (AN-05). The two answer different\nquestions and are never added.","required":["site","period","funnel","coverage","steps","finished","in_one_visit","by","split","easy","easy_says"],"properties":{"by":{"type":"string","description":"`source`, `country` or `device`: by what the visitor first came with."},"coverage":{"$ref":"#/components/schemas/Coverage"},"easy":{"type":"array","items":{"type":"integer","format":"int64","minimum":0},"description":"The easy way: visits that reached each step inside one visit. Null\nfor a day whose visits were counted before the funnel existed."},"easy_says":{"type":"string"},"finished":{"type":"integer","format":"int64","minimum":0},"finished_share":{"type":["number","null"],"format":"double"},"funnel":{"$ref":"#/components/schemas/FunnelView"},"in_one_visit":{"type":"integer","format":"int64","minimum":0},"median_seconds":{"type":["integer","null"],"format":"int64","description":"Median seconds from the first step to the last."},"period":{"$ref":"#/components/schemas/PeriodView"},"site":{"type":"string"},"split":{"type":"array","items":{"$ref":"#/components/schemas/FunnelSplit"}},"steps":{"type":"array","items":{"$ref":"#/components/schemas/FunnelStep"}}}},"FunnelSplit":{"type":"object","required":["key","landed","finished"],"properties":{"finished":{"type":"integer","format":"int64","minimum":0},"key":{"type":"string"},"landed":{"type":"integer","format":"int64","minimum":0},"rate":{"type":["number","null"],"format":"double"}}},"FunnelStep":{"type":"object","required":["label","visitors","dropped"],"properties":{"dropped":{"type":"integer","format":"int64","description":"Went no further than this step.","minimum":0},"label":{"type":"string"},"share":{"type":["number","null"],"format":"double","description":"Of those who did the first step, in percent."},"visitors":{"type":"integer","format":"int64","minimum":0}}},"FunnelView":{"type":"object","required":["id","name","spec","steps"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"spec":{"type":"object"},"steps":{"type":"array","items":{"type":"string"},"description":"Each step in words."}}},"GoalCreate":{"type":"object","required":["name","spec"],"properties":{"name":{"type":"string"},"spec":{"type":"object"}}},"GoalTest":{"type":"object","description":"What a goal would have counted, before it is saved (EV-09).","required":["days","period","times","by_day","note"],"properties":{"by_day":{"type":"array","items":{"type":["number","null"],"format":"double"},"description":"By the day, for a small chart. `null` is a day nothing was counted."},"days":{"type":"integer","format":"int32","minimum":0},"note":{"type":"string","description":"What cannot be tested this way, in a sentence. Empty when all of it was."},"period":{"$ref":"#/components/schemas/PeriodView"},"times":{"type":"number","format":"double","description":"Times it would have been reached."}}},"GoalUpdate":{"type":"object","description":"Change a goal. A new `spec` makes a new version; conversions already\ncounted keep the version they were counted under.","properties":{"name":{"type":["string","null"]},"note":{"type":["string","null"],"description":"Why the definition changed, shown beside the version."},"paused":{"type":["boolean","null"]},"spec":{"type":["object","null"]}}},"GoalVersionView":{"type":"object","required":["version","spec","lines","note","created_at"],"properties":{"by":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/DefinitionLine"},"description":"The definition as labelled lines, the form a diff is shown in."},"note":{"type":"string"},"spec":{"type":"object"},"version":{"type":"integer","format":"int32","minimum":0}}},"GoalView":{"type":"object","required":["id","site_id","name","version","spec","summary","paused","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"paused":{"type":"boolean"},"site_id":{"type":"string","format":"uuid"},"spec":{"type":"object"},"summary":{"type":"string","description":"`event install-copy`, `page /thanks*`."},"version":{"type":"integer","format":"int32","description":"The version in force. Each conversion records the one it was\ncounted under (EV-06).","minimum":0}}},"HandOver":{"type":"object","description":"Typed to confirm: the address of the member who becomes the owner.","required":["to","confirm"],"properties":{"confirm":{"type":"string"},"to":{"type":"string","format":"uuid"}}},"HardOff":{"type":"object","required":["choice","confirm"],"properties":{"choice":{"type":"string"},"confirm":{"type":"string","description":"The site's name, typed."}}},"HardOn":{"type":"object","required":["responsible"],"properties":{"responsible":{"type":"boolean","description":"\"I am responsible for this data\": must be true."}}},"HardView":{"type":"object","description":"A site's mode and what turning hard mode on still needs (MO-02).","required":["site","mode","reading","settings","checklist","ready","policy_text","compare","holds"],"properties":{"banner":{"type":["integer","null"],"format":"int32","description":"The banner version being shown, if one is."},"checklist":{"type":"array","items":{"type":"object"}},"compare":{"type":"array","items":{"$ref":"#/components/schemas/ModeLine"},"description":"What each mode does, line by line (MO-07)."},"holds":{"type":"array","items":{"$ref":"#/components/schemas/Held"},"description":"Rows hard mode holds for the site, table by table."},"mode":{"type":"string","description":"`easy` or `hard`."},"policy_text":{"type":"string","description":"The paragraph for the site's privacy policy."},"reading":{"type":"string","description":"The reading of the law the site is set up for: `strict` or `cnil`."},"ready":{"type":"boolean","description":"Every step but the last is done: it can be turned on."},"settings":{"type":"object"},"site":{"type":"string"}}},"Health":{"type":"object","description":"`GET /api/v1/health`: what this server is, without signing in.","required":["version","store","features","sso"],"properties":{"features":{"$ref":"#/components/schemas/FeatureSet"},"sso":{"type":"boolean","description":"Whether instance single sign-on is configured."},"store":{"type":"string","description":"`sqlite` or `postgres`."},"version":{"type":"string"}}},"Held":{"type":"object","required":["table","rows"],"properties":{"rows":{"type":"integer","format":"int64","minimum":0},"table":{"type":"string"}}},"HistoryNotice":{"type":"object","description":"History that is about to get shorter, and when.","required":["months","shorter","on"],"properties":{"months":{"type":"integer","format":"int32","description":"Months kept until then. Zero is everything.","minimum":0},"on":{"type":"integer","format":"int64"},"shorter":{"type":"integer","format":"int32","description":"Months kept from then on.","minimum":0}}},"ImportLine":{"type":"object","description":"One thing in the file, what it becomes, and what is lost or changed.","required":["in_file","becomes","note"],"properties":{"becomes":{"type":"string"},"in_file":{"type":"string"},"note":{"type":"string"}}},"ImportMonth":{"type":"object","description":"A month of \"how it will look\": views that would be imported, and views\ntidekeeper counted itself.","required":["month","imported","counted"],"properties":{"counted":{"type":"integer","format":"int64"},"imported":{"type":"integer","format":"int64"},"month":{"type":"string","description":"`2025-01`."}}},"ImportPreview":{"type":"object","description":"What an import would do, worked out without writing anything (IO-03).","required":["source","source_label","file","files","bytes","from","to","days","lines","notes","will_days","views","visitors","months","problems"],"properties":{"bytes":{"type":"integer","format":"int64","minimum":0},"counted_from":{"type":["string","null"],"description":"The first day tidekeeper counted itself, if it has counted any."},"days":{"type":"integer","format":"int32","minimum":0},"file":{"type":"string"},"files":{"type":"integer","format":"int32","minimum":0},"from":{"type":"string","description":"The first and last day in the file."},"lines":{"type":"array","items":{"$ref":"#/components/schemas/ImportLine"}},"months":{"type":"array","items":{"$ref":"#/components/schemas/ImportMonth"}},"notes":{"type":"array","items":{"type":"string"},"description":"What was found while reading: a day that appears twice, rows left out."},"problems":{"type":"array","items":{"type":"string"},"description":"Why it cannot be imported as it is. Empty when it can."},"source":{"type":"string"},"source_label":{"type":"string"},"to":{"type":"string"},"views":{"type":"integer","format":"int64"},"visitors":{"type":"integer","format":"int64"},"will_days":{"type":"integer","format":"int32","minimum":0},"will_from":{"type":["string","null"],"description":"The stretch that would be imported: the file's days before tidekeeper's\nown begin, and before today. `null` when nothing is left."},"will_to":{"type":["string","null"]}}},"ImportSource":{"type":"object","description":"A tool tidekeeper reads an export of.","required":["id","label","accepts"],"properties":{"accepts":{"type":"string","description":"What to upload."},"id":{"type":"string"},"label":{"type":"string"}}},"ImportView":{"type":"object","required":["id","source","source_label","file","from","to","days","views","visitors","dims","notes","imported","by","removable"],"properties":{"by":{"type":"string"},"days":{"type":"integer","format":"int32","minimum":0},"dims":{"type":"array","items":{"type":"string"},"description":"The dimensions it filled, by name."},"file":{"type":"string"},"from":{"type":"string"},"id":{"type":"string","format":"uuid"},"imported":{"type":"integer","format":"int64"},"notes":{"type":"array","items":{"type":"string"}},"removable":{"type":"boolean","description":"Whether it can still be taken out with one click."},"removed":{"type":["integer","null"],"format":"int64"},"source":{"type":"string"},"source_label":{"type":"string"},"to":{"type":"string"},"views":{"type":"integer","format":"int64"},"visitors":{"type":"integer","format":"int64"}}},"ImportsView":{"type":"object","required":["site","imports","sources","now"],"properties":{"counted_from":{"type":["string","null"]},"imports":{"type":"array","items":{"$ref":"#/components/schemas/ImportView"}},"now":{"type":"integer","format":"int64"},"site":{"type":"string"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/ImportSource"}}}},"InstallView":{"type":"object","description":"Everything the install page shows (SC-18).","required":["site","tag","tag_direct","gzipped","ceiling","version","integrity","csp","nginx","caddy","fields"],"properties":{"caddy":{"type":"string"},"ceiling":{"type":"integer","format":"int32","description":"It is never over this: a build that grows it fails.","minimum":0},"csp":{"type":"array","items":{"type":"string"},"description":"The content policy lines a page needs."},"fields":{"type":"array","items":{"$ref":"#/components/schemas/FieldDef"},"description":"What the script sends, all of it."},"gzipped":{"type":"integer","format":"int32","description":"The script's size as a browser receives it.","minimum":0},"integrity":{"type":"string","description":"For the tag's `integrity` attribute, for this site's switches."},"nginx":{"type":"string","description":"The two locations for nginx."},"nix":{"type":["string","null"],"description":"The declaration for our own NixOS module. Only on an instance of\nour own: customers never see it."},"site":{"type":"string"},"tag":{"type":"string","description":"The one line for the head of every page, served from the site's\nown domain."},"tag_direct":{"type":"string","description":"The same, loading the script from tidekeeper directly."},"version":{"type":"string"}}},"InstanceView":{"type":"object","description":"What this instance runs with, for whoever runs it (the \"This instance\"\ncard). Answered only to the instance's own account.","required":["version","store","store_bytes","salt_day","salt_on_disk","country_lookup","datacentre_ranges","spam_hosts","lists_from_files","calls","check","check_sites"],"properties":{"calls":{"type":"array","items":{"type":"string"},"description":"Everything outside itself this instance calls, each in a line.\nNone of them is tidekeeper's maker: it calls nobody home."},"check":{"$ref":"#/components/schemas/NightlyView","description":"The nightly check, as it last ran."},"check_sites":{"type":"integer","format":"int32","description":"How many sites its scan found something in, among what their own\npages sent.","minimum":0},"country_built":{"type":["integer","null"],"format":"int64","description":"When that database was built."},"country_lookup":{"type":"string","description":"How a country is found: `none`, `local database` or `table`."},"datacentre_ranges":{"type":"integer","format":"int32","minimum":0},"lists_from_files":{"type":"boolean","description":"The lists were read from files given at start."},"salt_day":{"type":"string","description":"The UTC day the salt in use was made for."},"salt_on_disk":{"type":"boolean","description":"The salt is a file in the service's state directory. Otherwise it\nis in memory, and a restart starts a new one."},"spam_hosts":{"type":"integer","format":"int32","minimum":0},"store":{"type":"string","description":"`sqlite` or `postgres`."},"store_away_since":{"type":["integer","null"],"format":"int64","description":"Since when the store has refused what is written, if it does now."},"store_bytes":{"type":"integer","format":"int64","minimum":0},"version":{"type":"string"}}},"InvitationAccept":{"type":"object","required":["token"],"properties":{"name":{"type":"string"},"password":{"type":"string","description":"Empty from someone who already signs in here and is signed in."},"token":{"type":"string"}}},"InvitationShown":{"type":"object","description":"What an invitation is to, shown to whoever holds its link.","required":["email","account","role","may_visitors","expires"],"properties":{"account":{"type":"string"},"email":{"type":"string"},"expires":{"type":"integer","format":"int64"},"known":{"type":"boolean","description":"This address already signs in here: the invitation is accepted by\nsigning in with it, and asks for no name and no password."},"may_visitors":{"type":"boolean"},"role":{"type":"string"},"sites":{"type":["array","null"],"items":{"type":"string"},"description":"Names. `null` is every site."}}},"InvitationView":{"type":"object","required":["id","email","role","may_visitors","invited","expires"],"properties":{"email":{"type":"string"},"expires":{"type":"integer","format":"int64","description":"When the link stops working, unix seconds."},"id":{"type":"string","format":"uuid"},"invited":{"type":"integer","format":"int64"},"may_visitors":{"type":"boolean"},"role":{"type":"string"},"sites":{"type":["array","null"],"items":{"$ref":"#/components/schemas/SiteRef"}}}},"Invite":{"type":"object","required":["email","role"],"properties":{"email":{"type":"string"},"may_visitors":{"type":"boolean"},"role":{"type":"string","description":"`admin` or `viewer`. An owner is made by handing the account over."},"sites":{"type":["array","null"],"items":{"type":"string"},"description":"Site ids or names. `null` is every site."}}},"Invited":{"type":"object","required":["invitation","link","emailed"],"properties":{"emailed":{"type":"boolean","description":"Whether it was also sent by email."},"invitation":{"$ref":"#/components/schemas/InvitationView"},"link":{"type":"string","description":"The link, shown once: tidekeeper keeps only a hash of it."}}},"InvoiceView":{"type":"object","description":"One of the provider's invoices: a line and a link.","required":["number","issued","total_minor","currency","state","url"],"properties":{"currency":{"type":"string"},"issued":{"type":"integer","format":"int64"},"number":{"type":"string"},"state":{"type":"string","description":"`open`, `paid`, `void` or `uncollectible`."},"total_minor":{"type":"integer","format":"int64","description":"In the currency's smallest unit."},"url":{"type":"string"}}},"JoinView":{"type":"object","required":["ts","joined","user_id"],"properties":{"joined":{"type":"string"},"ts":{"type":"integer","format":"int64"},"user_id":{"type":"string"}}},"Labelled":{"type":"object","required":["label","value"],"properties":{"label":{"type":"string"},"value":{"type":"string"}}},"Labelled2":{"type":"object","required":["id","label"],"properties":{"id":{"type":"string"},"label":{"type":"string"}}},"LeftOutView":{"type":"object","required":["reason","label","count","bot"],"properties":{"bot":{"type":"boolean","description":"One of the kinds the UI adds up as \"bots\"."},"count":{"type":"integer","format":"int64","minimum":0},"label":{"type":"string"},"reason":{"type":"string"}}},"LiveResponse":{"type":"object","description":"Who is on a site now, by page. Never by reader (RT-02).","required":["current","minutes","pages","sources","countries"],"properties":{"countries":{"type":"array","items":{"$ref":"#/components/schemas/Counted"}},"current":{"type":"integer","format":"int32","description":"Visitors seen in the last five minutes.","minimum":0},"last_hit":{"type":["string","null"],"description":"When the site last had a counted hit."},"minutes":{"type":"array","items":{"type":"integer","format":"int32","minimum":0},"description":"Views in each of the last thirty minutes, oldest first."},"pages":{"type":"array","items":{"$ref":"#/components/schemas/Counted"}},"sources":{"type":"array","items":{"$ref":"#/components/schemas/Counted"}}}},"LogLineView":{"type":"object","required":["ts","who","what"],"properties":{"ts":{"type":"integer","format":"int64"},"what":{"type":"string"},"who":{"type":"string"}}},"Login":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string"},"password":{"type":"string"},"second":{"type":["string","null"],"description":"The six digits of the second step, when the member has one."}}},"MatomoFetch":{"type":"object","description":"Which Matomo to ask for its reports, and for which days. The token is\nused for the one request this is and is never kept.","properties":{"id_site":{"type":"integer","format":"int32","description":"Matomo's number for the site: `idSite` in its address.","default":0,"minimum":0},"since":{"type":["string","null"],"description":"The first day, `2025-01-03`. Left out: a year before the last.","default":null},"token":{"type":"string","description":"A token of Matomo's with view access to that site.","default":""},"until":{"type":["string","null"],"description":"The last day. Left out: yesterday.","default":null},"url":{"type":"string","description":"Where Matomo answers: `https://matomo.example.org`.","default":""}}},"Me":{"type":"object","required":["user_id","email","role","account_id","account_name","features"],"properties":{"account_id":{"type":"string","format":"uuid"},"account_name":{"type":"string"},"accounts":{"type":"array","items":{"$ref":"#/components/schemas/MeAccount"},"description":"Every account they are in. One is the account this answer is\nabout; a person in one account has one here."},"email":{"type":"string"},"features":{"$ref":"#/components/schemas/FeatureSet"},"may":{"type":"array","items":{"type":"string"},"description":"What this request may do: `read`, `events`, `manage`, `visitors`,\n`own`. A page hides what would be refused."},"name":{"type":"string","description":"What they are called. Empty until they say."},"operator":{"type":"boolean","description":"Whoever runs this tidekeeper: the operator's console is theirs."},"role":{"type":"string"},"second_step_missing":{"type":"boolean","description":"The account's owner asked that every member has a second step at\nsign-in, and this member has not set one up."},"some_sites":{"type":"boolean","description":"Given some of the account's sites, not all."},"user_id":{"type":"string","format":"uuid"}}},"MeAccount":{"type":"object","description":"An account someone is in, and what they are in it.","required":["id","name","role","acting"],"properties":{"acting":{"type":"boolean","description":"The one they are acting in."},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"role":{"type":"string"}}},"MemberChange":{"type":"object","required":["role"],"properties":{"may_visitors":{"type":"boolean"},"role":{"type":"string"},"sites":{"type":["array","null"],"items":{"type":"string"}}}},"MemberView":{"type":"object","required":["id","email","name","role","may_visitors","you"],"properties":{"email":{"type":"string"},"id":{"type":"string","format":"uuid"},"last_seen":{"type":["integer","null"],"format":"int64","description":"Unix seconds. `null` is never."},"may_visitors":{"type":"boolean","description":"May open a visitor's record and answer visitors' requests. Kept\napart from the role on purpose."},"name":{"type":"string","description":"What they are called. Empty until they say."},"role":{"type":"string","description":"`owner`, `admin` or `viewer`."},"second_step":{"type":"boolean","description":"Has a second step at sign-in."},"sites":{"type":["array","null"],"items":{"$ref":"#/components/schemas/SiteRef"},"description":"The sites they were given. `null` is every site of the account."},"you":{"type":"boolean","description":"The member who is asking."}}},"MetricDef":{"type":"object","required":["name","label","definition","ratio"],"properties":{"definition":{"type":"string"},"label":{"type":"string"},"name":{"type":"string"},"ratio":{"type":"boolean","description":"A share or an average, which cannot be added up across rows."}}},"ModeLine":{"type":"object","required":["what","easy","hard"],"properties":{"easy":{"type":"string"},"hard":{"type":"string"},"what":{"type":"string"}}},"Money":{"type":"object","description":"What comes in, worked out from the subscriptions and the plans'\nprices as written. A plan whose price does not read as an amount is\ncounted in `unpriced` and left out of the sums.","required":["currency","monthly_minor","yearly_minor","by_plan","unpriced","new","up","down","gone"],"properties":{"by_plan":{"type":"array","items":{"$ref":"#/components/schemas/PlanMoney"}},"currency":{"type":"string"},"down":{"type":"integer","format":"int32","minimum":0},"gone":{"type":"integer","format":"int32","minimum":0},"monthly_minor":{"type":"integer","format":"int64"},"new":{"type":"integer","format":"int32","description":"This month: started paying, moved to a larger plan, to a smaller\none, and ended.","minimum":0},"unpriced":{"type":"integer","format":"int32","minimum":0},"up":{"type":"integer","format":"int32","minimum":0},"yearly_minor":{"type":"integer","format":"int64"}}},"Mute":{"type":"object","properties":{"days":{"type":["integer","null"],"format":"int32","description":"For how many days. 7 when left out.","minimum":0}}},"NameChange":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"Needs":{"type":"object","description":"An account that needs someone, and why, in a line.","required":["id","name","why","says"],"properties":{"at":{"type":["integer","null"],"format":"int64","description":"The time it is about, where there is one."},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"says":{"type":"string"},"why":{"type":"string","description":"`trial_ending`, `payment_failed`, `over`, `held`, `deletion`,\n`support`."}}},"NewAccount":{"type":"object","description":"Another account, made by someone who has one, and theirs to own.","required":["name"],"properties":{"name":{"type":"string"}}},"NightlyLine":{"type":"object","required":["name","label","passed","live","says"],"properties":{"label":{"type":"string"},"live":{"type":"boolean","description":"Run here every night. False: proved when the version was built,\nand not counted among those that passed tonight."},"name":{"type":"string","description":"`scan`, `browser`, `two_days` or `two_sites`."},"passed":{"type":"boolean"},"says":{"type":"string","description":"What it did and what it found. A find is where and how many,\nnever the value."}}},"NightlyView":{"type":"object","description":"The nightly check (the Stores board): what each check found the last\ntime it ran here.","required":["version","passed","of","checks","next"],"properties":{"checks":{"type":"array","items":{"$ref":"#/components/schemas/NightlyLine"}},"next":{"type":"integer","format":"int64","description":"When it runs next."},"of":{"type":"integer","format":"int32","minimum":0},"passed":{"type":"integer","format":"int32","description":"Of the checks that run here, how many passed, and how many there are.","minimum":0},"ran":{"type":["integer","null"],"format":"int64","description":"When it last ran. None: not yet, on this tidekeeper."},"version":{"type":"string","description":"The version that ran it."}}},"OfferSite":{"type":"object","description":"Typed to confirm: the site's name.","required":["confirm"],"properties":{"confirm":{"type":"string"}}},"OnOff":{"type":"object","required":["on"],"properties":{"on":{"type":"boolean"}}},"OpenRequest":{"type":"object","description":"A request waiting for an answer, and the site it is about.","required":["site","request"],"properties":{"request":{"$ref":"#/components/schemas/RequestView"},"site":{"type":"string"}}},"OverlayDepth":{"type":"object","description":"How many readers got as far as a place on the page.","required":["at"],"properties":{"at":{"type":"integer","format":"int32","description":"How far down, as a percentage of the page's height.","minimum":0},"share":{"type":["number","null"],"format":"double","description":"The share of the views that said how far they were read. None\nwhen none said."}}},"OverlayLink":{"type":"object","description":"One thing on a page and the clicks it got.","required":["n","kind","label","selector","clicks","outbound","same"],"properties":{"clicks":{"type":"integer","format":"int64","minimum":0},"event":{"type":["string","null"],"description":"For something the page marks as an event: the event's name."},"kind":{"type":"string","description":"`link`, `event`, `button`, `field` or `element`."},"label":{"type":"string"},"n":{"type":"integer","format":"int32","description":"Its number on the copy.","minimum":0},"outbound":{"type":"boolean"},"pick_id":{"type":["string","null"],"format":"uuid"},"picked":{"type":["string","null"],"description":"What a click on it is counted as, where it was picked:\n`install-copy · method from data-method`."},"same":{"type":"integer","format":"int32","description":"How many things on the page share this count: links to one place\ncannot be told apart.","minimum":0},"selector":{"type":"string"},"share":{"type":["number","null"],"format":"double","description":"Clicks to views of the page."},"to":{"type":["string","null"],"description":"For a link: the path it leads to, or the host and path elsewhere."},"would_be":{"type":["object","null"],"description":"What \"Make this a goal\" would make of it."}}},"OverlayView":{"type":"object","description":"The page overlay (AE-07, AE-08, ME-07): a stored copy of a page, the\nclicks each thing on it got, and how far down readers got.","required":["site","path","device","show","available","reason","links_on","depth_on","views","links","depth","depth_views"],"properties":{"available":{"type":"boolean","description":"This tidekeeper has somewhere to show a copy."},"copy":{"oneOf":[{"$ref":"#/components/schemas/SnapshotView","description":"The copy this is drawn on. None: this page has none yet."},{"type":"null"}]},"depth":{"type":"array","items":{"$ref":"#/components/schemas/OverlayDepth"},"description":"How many readers reached each quarter of the page's height."},"depth_on":{"type":"boolean","description":"The site's pages say how far down they were read."},"depth_views":{"type":"integer","format":"int64","description":"How many views said how far down they were read.","minimum":0},"device":{"type":"string"},"frame":{"oneOf":[{"$ref":"#/components/schemas/FrameAt"},{"type":"null"}]},"links":{"type":"array","items":{"$ref":"#/components/schemas/OverlayLink"},"description":"Everything on the page with a count, most clicked first."},"links_on":{"type":"boolean","description":"The site counts clicks on its own links."},"path":{"type":"string"},"period":{"oneOf":[{"$ref":"#/components/schemas/PeriodView"},{"type":"null"}]},"reason":{"type":"string"},"selected":{"type":["integer","null"],"format":"int32","minimum":0},"show":{"type":"string"},"site":{"type":"string"},"views":{"type":"integer","format":"int64","description":"Views of the page in the period.","minimum":0}}},"Overview":{"type":"object","required":["period","sites"],"properties":{"all_views":{"type":["number","null"],"format":"double"},"all_visitors":{"type":["number","null"],"format":"double","description":"Every site added up (SI-07). Daily visitors of each site, summed:\nsomeone who read two of them is counted by each."},"archived":{"type":"integer","format":"int32","description":"How many sites are put away and not in the list.","minimum":0},"period":{"$ref":"#/components/schemas/PeriodView"},"sites":{"type":"array","items":{"$ref":"#/components/schemas/SiteOverview"}}}},"OwnLimits":{"type":"object","description":"That this account's limits are its own and not its plan's.","properties":{"until":{"type":["integer","null"],"format":"int64","description":"When the plan's are back. None: until someone changes them."}}},"PageCount":{"type":"object","required":["path","views","text"],"properties":{"path":{"type":"string"},"text":{"type":"string","description":"\"read 4,730 times\"."},"views":{"type":"integer","format":"int64","minimum":0}}},"PanelView":{"type":"object","required":["panel","label","on"],"properties":{"label":{"type":"string"},"on":{"type":"boolean"},"panel":{"type":"string"}}},"PasskeyView":{"type":"object","required":["id","name","made"],"properties":{"id":{"type":"string","format":"uuid"},"last_used":{"type":["integer","null"],"format":"int64"},"made":{"type":"integer","format":"int64"},"name":{"type":"string"}}},"PasswordChange":{"type":"object","required":["new"],"properties":{"current":{"type":"string"},"new":{"type":"string"}}},"PathRow":{"type":"object","required":["steps","visitors"],"properties":{"share":{"type":["number","null"],"format":"double"},"steps":{"type":"array","items":{"type":"string"},"description":"Nearest first: what came right before (or after), then what came\nbefore that."},"visitors":{"type":"integer","format":"int64","minimum":0}}},"PathsReport":{"type":"object","required":["site","period","coverage","from","reach","steps","visitors","before","after","routes","choices"],"properties":{"after":{"type":"array","items":{"$ref":"#/components/schemas/PathRow"}},"before":{"type":"array","items":{"$ref":"#/components/schemas/PathRow"}},"choices":{"type":"array","items":{"type":"string"},"description":"Things paths can start from: the site's busiest pages and events."},"coverage":{"$ref":"#/components/schemas/Coverage"},"from":{"type":"string","description":"What the paths start from, in words."},"period":{"$ref":"#/components/schemas/PeriodView"},"reach":{"type":"string","description":"`visit` or `visitor`."},"routes":{"type":"array","items":{"$ref":"#/components/schemas/RouteRow"},"description":"The commonest whole routes to it."},"site":{"type":"string"},"steps":{"type":"integer","format":"int32","minimum":0},"visitors":{"type":"integer","format":"int64","description":"Visitors who did it in the period.","minimum":0}}},"PeriodView":{"type":"object","description":"The days a question covered, as the server resolved them.","required":["from","to","days","label","time_zone"],"properties":{"days":{"type":"integer","format":"int32","minimum":0},"from":{"type":"string","description":"The first day, `2026-10-05`."},"label":{"type":"string","description":"`5 to 11 Oct`."},"time_zone":{"type":"string","description":"The time zone the days are in: the site's."},"to":{"type":"string","description":"The last day, inclusive."}}},"PickCreate":{"type":"object","description":"Pick an element: count a click on what a selector matches as an event.","properties":{"attr":{"type":["string","null"],"description":"The attribute of the element the property's value is read from.","default":null},"event":{"type":"string","description":"The event a click is counted as. One that exists already is added to.","default":""},"goal":{"type":["string","null"],"description":"Make a goal of the event as well, with this name.","default":null},"path":{"type":["string","null"],"description":"The one path it counts on. Left out: every page where it matches.","default":null},"prop":{"type":["string","null"],"default":null},"selector":{"type":"string","default":""},"value":{"type":["string","null"],"description":"Or the value it always has.","default":null}}},"PickMatch":{"type":"object","required":["path","count"],"properties":{"count":{"type":"integer","format":"int32","minimum":0},"path":{"type":"string"}}},"PickSelected":{"type":"object","description":"The thing that is selected on the copy.","required":["kind","label","selector","valid","trail","attrs","here","on_site","matches"],"properties":{"attrs":{"type":"array","items":{"$ref":"#/components/schemas/Labelled"},"description":"Its attributes a value can be read from."},"here":{"type":"integer","format":"int32","description":"How many things the selector matches on this copy, and on every\nstored copy of the site for this device.","minimum":0},"kind":{"type":"string","description":"`link`, `button`, `field`, `event` or `element`."},"label":{"type":"string"},"matches":{"type":"array","items":{"$ref":"#/components/schemas/PickMatch"}},"n":{"type":["integer","null"],"format":"int32","description":"Its number on the copy. None: a selector written with nothing\nchosen, as the terminal asks.","minimum":0},"on_site":{"type":"integer","format":"int32","minimum":0},"picked":{"oneOf":[{"$ref":"#/components/schemas/PickedView","description":"What a click on it is counted as already, if it was picked."},{"type":"null"}]},"selector":{"type":"string","description":"The selector that is counted: its own, or the one written by hand."},"trail":{"type":"array","items":{"type":"string"},"description":"Where it is: what is around it, outermost first, itself last."},"up":{"type":["integer","null"],"format":"int32","description":"The nearest thing around it that can be picked too.","minimum":0},"valid":{"type":"boolean","description":"Whether that is a selector at all."}}},"PickView":{"type":"object","description":"The picker (AE-06): a stored copy of a page with everything on it\nthat can be picked marked, and the one that is selected.","required":["site","path","device","available","reason","pages","picks","events"],"properties":{"available":{"type":"boolean"},"copy":{"oneOf":[{"$ref":"#/components/schemas/SnapshotView"},{"type":"null"}]},"device":{"type":"string"},"events":{"type":"array","items":{"type":"string"},"description":"The names of the events the site has sent lately: a click counted\nas one of them is added to it."},"frame":{"oneOf":[{"$ref":"#/components/schemas/FrameAt"},{"type":"null"}]},"pages":{"type":"array","items":{"type":"string"},"description":"The pages of the site that have a stored copy."},"path":{"type":"string"},"picks":{"type":"array","items":{"$ref":"#/components/schemas/PickedView"},"description":"What is picked on this site already."},"reason":{"type":"string"},"selected":{"oneOf":[{"$ref":"#/components/schemas/PickSelected"},{"type":"null"}]},"site":{"type":"string"}}},"PickedView":{"type":"object","description":"An element picked on a stored copy of a page (the Picker board): a\nclick on what its selector matches is an event.","required":["id","selector","event","says","by","made"],"properties":{"attr":{"type":["string","null"]},"by":{"type":"string"},"event":{"type":"string"},"id":{"type":"string","format":"uuid"},"made":{"type":"integer","format":"int64"},"path":{"type":["string","null"],"description":"The one path it counts on. None: every page where it matches."},"prop":{"type":["string","null"],"description":"A property sent with it, and where its value comes from: one of\nthe element's attributes, or a fixed text."},"says":{"type":"string","description":"What it sends, in a line."},"selector":{"type":"string"},"value":{"type":["string","null"]}}},"PlanChoice":{"type":"object","required":["plan"],"properties":{"plan":{"type":"string"},"yearly":{"type":"boolean","description":"Paid by the year, where a provider takes payment."}}},"PlanEvent":{"type":"object","description":"What a payment provider's relay tells tidekeeper: an account's plan as\nit now is. Signed with the deployment's secret.","required":["account","plan"],"properties":{"account":{"type":"string","format":"uuid"},"cancelled":{"type":["integer","null"],"format":"int64"},"plan":{"type":"string"},"renews":{"type":["integer","null"],"format":"int64"}}},"PlanMoney":{"type":"object","required":["plan","name","accounts","paying","monthly_minor"],"properties":{"accounts":{"type":"integer","format":"int32","description":"Accounts on it, paying or not.","minimum":0},"monthly_minor":{"type":"integer","format":"int64","description":"What those bring in a month, in the currency's smallest unit."},"name":{"type":"string"},"paying":{"type":"integer","format":"int32","minimum":0},"plan":{"type":"string"}}},"PlanNotice":{"type":"object","description":"Where an account stands against its plan, for \"Needs attention\".","required":["state","text"],"properties":{"snoozable":{"type":"boolean","description":"It can be put off with \"Remind me later\": nothing is being left\nout yet. Once hits are held back, or a payment is owed, it cannot."},"state":{"type":"string","description":"`near`, `over` or `held`."},"text":{"type":"string"}}},"PlanView":{"type":"object","required":["id","name","says","events","sites","members","history_months","price_month","price_year","has"],"properties":{"api_requests":{"type":"integer","format":"int32","description":"Requests an hour for each API token. Zero is the deployment's own\nnumber.","minimum":0},"events":{"type":"integer","format":"int64","description":"Events a month. Zero is no limit.","minimum":0},"has":{"type":"array","items":{"type":"string"}},"history_months":{"type":"integer","format":"int32","minimum":0},"id":{"type":"string"},"jobs":{"type":"integer","format":"int32","description":"Exports and imports running at once. Zero is any number.","minimum":0},"members":{"type":"integer","format":"int32","minimum":0},"name":{"type":"string","description":"Empty until someone writes the plans."},"price_month":{"type":"string"},"price_year":{"type":"string"},"says":{"type":"string"},"sites":{"type":"integer","format":"int32","description":"Sites and members. Zero is any number.","minimum":0}}},"PlansView":{"type":"object","description":"What a deployment offers, for the pricing page.","required":["plans","unset","grace_days","read_only_days","trial_days","region"],"properties":{"grace_days":{"type":"integer","format":"int32","minimum":0},"plans":{"type":"array","items":{"$ref":"#/components/schemas/PlanView"}},"read_only_days":{"type":"integer","format":"int32","minimum":0},"region":{"type":"string"},"trial_days":{"type":"integer","format":"int32","minimum":0},"unset":{"type":"boolean","description":"Nobody has written the plans yet: every name, price and limit is\na placeholder, and no account is held to anything."}}},"Point":{"type":"object","required":["key","values"],"properties":{"imported":{"type":"boolean","description":"The day came from another tool: drawn hatched and said so (IO-02)."},"key":{"type":"string","description":"A day (`2026-10-05`) or an hour (`13`)."},"partial":{"type":"boolean","description":"The day or hour is not over yet, so the figure will still grow."},"values":{"type":"array","items":{"type":["number","null"],"format":"double"}}}},"PolicyConfirm":{"type":"object","description":"The owner says the policy has the paragraph. tidekeeper looks for itself\ntoo and says what it found, but the confirmation is the owner's.","required":["url"],"properties":{"url":{"type":"string"}}},"PolicyFound":{"type":"object","required":["url","found","says"],"properties":{"found":{"type":"boolean","description":"Whether the page could be read and names tidekeeper."},"says":{"type":"string"},"url":{"type":"string"}}},"ProductRow":{"type":"object","required":["value","orders","minor"],"properties":{"minor":{"type":"integer","format":"int64"},"orders":{"type":"integer","format":"int64","minimum":0},"value":{"type":"string"}}},"PropView":{"type":"object","required":["key","value"],"properties":{"key":{"type":"string"},"value":{"type":"string"}}},"PushDeviceView":{"type":"object","required":["id","name","by","mine","made","error"],"properties":{"by":{"type":"string","description":"The member whose device it is."},"error":{"type":"string","description":"What its push service said the last time it refused. Empty: nothing."},"id":{"type":"string","format":"uuid"},"last_sent":{"type":["integer","null"],"format":"int64"},"made":{"type":"integer","format":"int64"},"mine":{"type":"boolean","description":"It is the asking member's own."},"name":{"type":"string","description":"What its owner sees it as: `Firefox on Linux`."}}},"PushSubscribe":{"type":"object","description":"What a browser gave when it subscribed.","properties":{"auth":{"type":"string","default":""},"endpoint":{"type":"string","default":""},"name":{"type":["string","null"],"description":"A name for the device. Left out: what its browser says it is.","default":null},"p256dh":{"type":"string","default":""}}},"PushView":{"type":"object","description":"Web push (NC-05): the devices of an account's members that take an\nalert's title, and what a browser needs to become one.","required":["key","worker","devices"],"properties":{"channel":{"type":["string","null"],"format":"uuid","description":"The account's push channel: its column of \"Where alerts go\". None\nuntil the first device is added."},"devices":{"type":"array","items":{"$ref":"#/components/schemas/PushDeviceView"}},"key":{"type":"string","description":"The instance's public key, as a browser takes it to subscribe."},"worker":{"type":"string","description":"Where the worker is that the browser runs for it."}}},"Reason":{"type":"object","description":"Every action of an operator's says why.","required":["reason"],"properties":{"reason":{"type":"string"}}},"ReasonDef":{"type":"object","required":["name","label","bot"],"properties":{"bot":{"type":"boolean"},"label":{"type":"string"},"name":{"type":"string"}}},"RecordDetail":{"type":"object","description":"One record with what the visitor was shown, word for word (CR-03).","required":["record","question","meaning","yes","no","choose","kept_until"],"properties":{"answered_after":{"type":["number","null"],"format":"double","description":"Seconds from the banner appearing to the answer."},"choose":{"type":"string"},"kept_until":{"type":"string"},"meaning":{"type":"string"},"no":{"type":"string"},"question":{"type":"string"},"record":{"$ref":"#/components/schemas/RecordView"},"yes":{"type":"string"}}},"RecordView":{"type":"object","required":["id","short","ts","kind","label","allows","version","lang","how","gpc","proof"],"properties":{"allows":{"type":"array","items":{"type":"string"},"description":"What is allowed after it: `recognise`, `purchases`."},"gpc":{"type":"boolean"},"how":{"type":"string","description":"The control that was used, in the banner's own words where it has\nthem: `\"Yes, that is fine\"`."},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","description":"`agreed`, `declined`, `gpc`, `withdrew`, `changed`."},"label":{"type":"string"},"lang":{"type":"string"},"proof":{"type":"boolean","description":"Kept as proof after the visitor's data was deleted."},"short":{"type":"string","description":"`c_91ab04`."},"ts":{"type":"integer","format":"int64","description":"Unix seconds."},"version":{"type":"integer","format":"int32"},"visitor":{"type":["string","null"],"description":"The visitor, for a yes, a change and a withdrawal. A no keeps no ID."}}},"RemovedView":{"type":"object","required":["visitors","visits","hits"],"properties":{"hits":{"type":"integer","format":"int64","minimum":0},"visitors":{"type":"integer","format":"int64","minimum":0},"visits":{"type":"integer","format":"int64","minimum":0}}},"ReportSetting":{"type":"object","description":"Who is sent a site's report, or the digest of every site, and how often.","required":["every"],"properties":{"every":{"type":"string","description":"`off`, `weekly` or `monthly`."},"sends":{"type":"string","description":"When it goes out, in words. Set by the server."},"to":{"type":"array","items":{"type":"string"}}}},"RequestCreate":{"type":"object","required":["subject","kind"],"properties":{"kind":{"type":"string","description":"`copy` or `deletion`."},"subject":{"type":"string","description":"A visitor ID (`v_…`, whole or its first eight digits) or the site's\nown user ID."}}},"RequestDone":{"type":"object","properties":{"confirm":{"type":"string","description":"For a deletion: the visitor's ID, typed."},"outcome":{"type":"string","description":"For closing without doing: why."}}},"RequestView":{"type":"object","required":["id","number","kind","label","subject","asked","asked_how","deadline","days_left","state","outcome","log"],"properties":{"asked":{"type":"integer","format":"int64"},"asked_how":{"type":"string"},"days_left":{"type":"integer","format":"int64","description":"Days left to answer; negative when it is late."},"deadline":{"type":"integer","format":"int64"},"done":{"type":["integer","null"],"format":"int64"},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","description":"`copy` or `deletion`."},"label":{"type":"string"},"log":{"type":"array","items":{"$ref":"#/components/schemas/LogLineView"}},"number":{"type":"string","description":"`R-0031`."},"outcome":{"type":"string"},"state":{"type":"string","description":"`open`, `done` or `closed`."},"subject":{"type":"string"},"visitor":{"type":["string","null"],"description":"The visitor it is about, while they are held."},"will_delete":{"type":["string","null"],"description":"For an open deletion: what will go and what will stay."}}},"RequestsView":{"type":"object","required":["site","mode","requests","open","easy_answer"],"properties":{"easy_answer":{"type":"string","description":"In easy mode there is nothing to find, and this is why (DS-08)."},"mode":{"type":"string","description":"`easy` or `hard`."},"open":{"type":"integer","format":"int64","minimum":0},"requests":{"type":"array","items":{"$ref":"#/components/schemas/RequestView"}},"site":{"type":"string"}}},"ResetDone":{"type":"object","required":["signed_out"],"properties":{"signed_out":{"type":"integer","format":"int32","description":"How many other sessions were signed out.","minimum":0}}},"ResetFinish":{"type":"object","required":["token","password"],"properties":{"everywhere":{"type":"boolean","description":"Sign out everywhere else."},"password":{"type":"string"},"token":{"type":"string"}}},"ResetOpen":{"type":"object","required":["email"],"properties":{"email":{"type":"string"}}},"RetentionReport":{"type":"object","required":["site","coverage","grain","what","cohorts","back_first_cohorts","back_fourth_cohorts","by_source"],"properties":{"back_first":{"type":["number","null"],"format":"double","description":"Back in the first period after the one they were first seen in:\nthe mean over the cohorts old enough to say, and how many those are."},"back_first_cohorts":{"type":"integer","format":"int32","minimum":0},"back_fourth":{"type":["number","null"],"format":"double","description":"Still coming in the fourth period."},"back_fourth_cohorts":{"type":"integer","format":"int32","minimum":0},"by_source":{"type":"array","items":{"$ref":"#/components/schemas/RetentionSplit"}},"cohorts":{"type":"array","items":{"$ref":"#/components/schemas/CohortRow"}},"coverage":{"$ref":"#/components/schemas/Coverage"},"days_to_return":{"type":["number","null"],"format":"double","description":"Median days until a visitor's second day."},"grain":{"type":"string","description":"`week` or `month`."},"site":{"type":"string"},"what":{"type":"string","description":"`visit`, or a goal's name."}}},"RetentionSplit":{"type":"object","required":["key","visitors"],"properties":{"back":{"type":["number","null"],"format":"double"},"key":{"type":"string"},"visitors":{"type":"integer","format":"int64","minimum":0}}},"RevenueReport":{"type":"object","description":"Revenue in one currency. Money keeps the currency it was charged in and\nis never converted (RV-04).","required":["site","period","coverage","currency","currencies","all_orders","all_minor","known_orders","known_minor","credit","buckets","by_property","says"],"properties":{"all_minor":{"type":"integer","format":"int64"},"all_orders":{"type":"integer","format":"int64","description":"Every order, counted the easy way: an easy figure.","minimum":0},"buckets":{"type":"array","items":{"$ref":"#/components/schemas/BucketRow"}},"by_property":{"type":"array","items":{"$ref":"#/components/schemas/ProductRow"}},"coverage":{"$ref":"#/components/schemas/Coverage"},"credit":{"type":"array","items":{"$ref":"#/components/schemas/CreditRow"}},"currencies":{"type":"array","items":{"type":"string"},"description":"Every currency there are orders in."},"currency":{"type":"string"},"days_to_order":{"type":["number","null"],"format":"double","description":"Median days from a visitor's first visit to their order."},"known_minor":{"type":"integer","format":"int64"},"known_orders":{"type":"integer","format":"int64","description":"Orders by visitors who agreed: a hard figure, and a part of the\nfirst, never added to it.","minimum":0},"period":{"$ref":"#/components/schemas/PeriodView"},"property":{"type":["string","null"],"description":"Orders by one property of the event, when it has one."},"says":{"type":"string"},"site":{"type":"string"}}},"RoleView":{"type":"object","required":["role","label","means"],"properties":{"label":{"type":"string"},"means":{"type":"string"},"role":{"type":"string"}}},"RouteRow":{"type":"object","required":["stops","spread","visitors"],"properties":{"share":{"type":["number","null"],"format":"double"},"spread":{"type":"string","description":"`one visit`, or `two visits, 2 days apart`."},"stops":{"type":"array","items":{"type":"string"}},"visitors":{"type":"integer","format":"int64","minimum":0}}},"SavedView":{"type":"object","description":"A set of filters under a name (FI-03): the query string of the view,\nexactly as the address bar has it.","required":["id","name","page","query","by"],"properties":{"by":{"type":"string"},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"page":{"type":"string","description":"The page it was saved on: `sources`, `pages`, or empty for the overview."},"query":{"type":"string"}}},"SavedViewCreate":{"type":"object","required":["name","query"],"properties":{"name":{"type":"string"},"page":{"type":"string"},"query":{"type":"string"}}},"ScopeView":{"type":"object","description":"One thing a token may be made for.","required":["scope","label","hard","yours"],"properties":{"hard":{"type":"boolean","description":"Only means something on a site in hard mode."},"label":{"type":"string"},"scope":{"type":"string"},"yours":{"type":"boolean","description":"Whether the member asking may give it: a token never does more\nthan the member who made it."}}},"ScriptState":{"type":"string","description":"Whether hits are arriving, worked out from when the last one did.","enum":["never_seen","receiving","quiet","silent","paused"]},"SecondStepStart":{"type":"object","description":"A second step being set up: the secret for an authenticator app.","required":["secret","url"],"properties":{"secret":{"type":"string","description":"The secret, in the letters an app takes when typed."},"url":{"type":"string","description":"The same as an address an app opens."}}},"Security":{"type":"object","description":"How the member who is asking signs in.","required":["email","has_password","second_step","second_step_required","passkeys","own_sign_in","passkeys_offered"],"properties":{"email":{"type":"string"},"has_password":{"type":"boolean"},"own_sign_in":{"type":"boolean","description":"Whether this tidekeeper signs people in itself at all."},"passkeys":{"type":"array","items":{"$ref":"#/components/schemas/PasskeyView"}},"passkeys_offered":{"type":"boolean"},"second_step":{"type":"boolean"},"second_step_required":{"type":"boolean","description":"The owner asked that every member has a second step."}}},"Sent":{"type":"object","description":"The same answer whoever asked and whatever was found: a page that\nsends a link cannot be used to learn who has an account.","required":["sent","minutes","again_in"],"properties":{"again_in":{"type":"integer","format":"int32","description":"How long before another can be asked for, in seconds.","minimum":0},"minutes":{"type":"integer","format":"int32","description":"How long the link works, in minutes.","minimum":0},"sent":{"type":"boolean"}}},"SeriesResponse":{"type":"object","required":["site","period","grain","metrics","points","totals","caveats","annotations"],"properties":{"annotations":{"type":"array","items":{"$ref":"#/components/schemas/AnnotationView"},"description":"Notes on the chart that fall in the period."},"caveats":{"type":"array","items":{"$ref":"#/components/schemas/CaveatView"}},"compare":{"oneOf":[{"$ref":"#/components/schemas/PeriodView"},{"type":"null"}]},"grain":{"type":"string","description":"`day` or `hour`."},"metrics":{"type":"array","items":{"type":"string"}},"period":{"$ref":"#/components/schemas/PeriodView"},"points":{"type":"array","items":{"$ref":"#/components/schemas/Point"},"description":"One point for every day or hour of the period. A point with `null`\nvalues is a time nothing was being counted: a gap, not a zero."},"previous":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Point"}},"previous_totals":{"type":["array","null"],"items":{"type":["number","null"],"format":"double"}},"site":{"type":"string"},"totals":{"type":"array","items":{"type":["number","null"],"format":"double"}}}},"SessionView":{"type":"object","required":["id","what","since","this"],"properties":{"id":{"type":"string","description":"The start of the session's hash: enough to name it, not to use it."},"last_seen":{"type":["integer","null"],"format":"int64"},"since":{"type":"integer","format":"int64"},"this":{"type":"boolean","description":"The session that is asking."},"what":{"type":"string","description":"\"Firefox on Linux\". The browser's own string is not kept."}}},"ShareAdmin":{"type":"object","description":"What the Sharing screen shows and changes.","required":["site","settings","floor","panels","address","links","never","now"],"properties":{"address":{"type":"string","description":"Where the public dashboard is, on or off."},"floor":{"type":"integer","format":"int32","description":"A row with fewer visitors than this is folded into \"other\".","minimum":0},"links":{"type":"array","items":{"$ref":"#/components/schemas/ShareLinkView"}},"never":{"type":"array","items":{"type":"string"},"description":"What is never in a shared view, whatever is ticked."},"now":{"type":"integer","format":"int64"},"panels":{"type":"array","items":{"$ref":"#/components/schemas/PanelView"}},"settings":{"type":"object"},"site":{"type":"string"}}},"ShareChange":{"type":"object","required":["settings"],"properties":{"floor":{"type":["integer","null"],"format":"int32","minimum":0},"settings":{"type":"object"}}},"ShareFigure":{"type":"object","required":["name","label"],"properties":{"label":{"type":"string"},"name":{"type":"string"},"previous":{"type":["number","null"],"format":"double"},"value":{"type":["number","null"],"format":"double"}}},"ShareGoal":{"type":"object","required":["name","conversions"],"properties":{"conversions":{"type":"number","format":"double"},"name":{"type":"string"},"rate":{"type":["number","null"],"format":"double","description":"Percent of visitors who reached it. `null` when too few to say."}}},"ShareLinkCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"password":{"type":["string","null"]}}},"ShareLinkView":{"type":"object","required":["id","name","has_password","made","opened","url"],"properties":{"has_password":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"last_opened":{"type":["integer","null"],"format":"int64"},"made":{"type":"integer","format":"int64"},"name":{"type":"string","description":"Who it is for, in the owner's words."},"opened":{"type":"integer","format":"int64"},"url":{"type":"string","description":"The address that opens it."}}},"SharePanel":{"type":"object","description":"One list of a shared view. Rows under the floor are not in `rows`:\nthey are counted in `others` and added up in `other`.","required":["rows","others","total"],"properties":{"other":{"type":["number","null"],"format":"double","description":"Their sum. `null` when saying it would point at one row."},"others":{"type":"integer","format":"int32","description":"How many rows were folded.","minimum":0},"rows":{"type":"array","items":{"$ref":"#/components/schemas/ShareRow"}},"total":{"type":"number","format":"double"}}},"ShareRow":{"type":"object","required":["key","label","value"],"properties":{"key":{"type":"string","description":"What a filter takes."},"label":{"type":"string"},"value":{"type":"number","format":"double"}}},"ShareShare":{"type":"object","required":["label","share"],"properties":{"label":{"type":"string"},"share":{"type":"number","format":"double","description":"Percent of visitors."}}},"ShareUnlock":{"type":"object","required":["key","password"],"properties":{"key":{"type":"string"},"password":{"type":"string"}}},"ShareUnlocked":{"type":"object","required":["pass"],"properties":{"pass":{"type":"string","description":"Goes in the address as `pass`. Good until the end of tomorrow, UTC."}}},"ShareView":{"type":"object","description":"Everything a shared view shows, and nothing it does not: the parts its\nowner ticked, from the figures every visitor is in, with small rows\nfolded. No figure here is about a recognised visitor.","required":["site","period","panels","figures","grain","points","notes","systems","browsers","floor","too_few","credit","follow_theme","caveats"],"properties":{"browsers":{"type":"array","items":{"$ref":"#/components/schemas/ShareShare"}},"caveats":{"type":"array","items":{"$ref":"#/components/schemas/CaveatView"},"description":"How the visitors were counted, in words."},"compare":{"oneOf":[{"$ref":"#/components/schemas/PeriodView"},{"type":"null"}]},"countries":{"oneOf":[{"$ref":"#/components/schemas/SharePanel"},{"type":"null"}]},"credit":{"type":"boolean"},"devices":{"oneOf":[{"$ref":"#/components/schemas/SharePanel"},{"type":"null"}]},"figures":{"type":"array","items":{"$ref":"#/components/schemas/ShareFigure"}},"filter":{"type":["string","null"],"description":"The row looked at alone, as words."},"floor":{"type":"integer","format":"int32","description":"Rows with fewer visitors than this were folded. 0 when its owner\nturned that off.","minimum":0},"follow_theme":{"type":"boolean"},"goals":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ShareGoal"}},"grain":{"type":"string"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/AnnotationView"}},"now":{"type":["integer","null"],"format":"int32","description":"People on the site now. `null` when not shared, or too few to say.","minimum":0},"pages":{"oneOf":[{"$ref":"#/components/schemas/SharePanel"},{"type":"null"}]},"panels":{"type":"array","items":{"type":"string"},"description":"The parts shown."},"period":{"$ref":"#/components/schemas/PeriodView"},"points":{"type":"array","items":{"$ref":"#/components/schemas/Point"}},"previous":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Point"}},"site":{"type":"string"},"sources":{"oneOf":[{"$ref":"#/components/schemas/SharePanel"},{"type":"null"}]},"systems":{"type":"array","items":{"$ref":"#/components/schemas/ShareShare"}},"too_few":{"type":"boolean","description":"The filter would show fewer visitors than the floor: nothing is shown."}}},"SignupDay":{"type":"object","description":"A day of sign-ups, and how far the accounts made that day have got.","required":["day","confirmed","site","counted","paying"],"properties":{"confirmed":{"type":"integer","format":"int32","minimum":0},"counted":{"type":"integer","format":"int32","minimum":0},"day":{"type":"string","description":"`2026-10-13`."},"paying":{"type":"integer","format":"int32","minimum":0},"site":{"type":"integer","format":"int32","minimum":0}}},"SignupStart":{"type":"object","required":["email"],"properties":{"accept":{"type":"boolean","description":"The terms and the data processing agreement, where this deployment\npublishes either; where it publishes neither, nothing is asked."},"account":{"type":["string","null"],"description":"What the account is called. Without one it is called after its\nfirst site, and without that after the address."},"email":{"type":"string"},"how":{"type":"string","description":"`password`, `link` or `passkey`: how they mean to sign in."},"password":{"type":["string","null"]},"site":{"type":["string","null"],"description":"A first site, by its domain."}}},"SiteChangeView":{"type":"object","description":"One change to a site's settings (SI-08).","required":["at","what","old","new"],"properties":{"at":{"type":"string","format":"date-time"},"by":{"type":["string","null"],"description":"Who changed it. `null` when the instance's configuration did."},"new":{"type":"string"},"old":{"type":"string"},"what":{"type":"string"}}},"SiteCreate":{"type":"object","required":["name"],"properties":{"hostnames":{"type":["array","null"],"items":{"type":"string"},"description":"Left out, the name is the one hostname."},"name":{"type":"string","description":"Usually the domain: `eza.rocks`."},"settings":{"type":["object","null"]},"time_zone":{"type":["string","null"],"description":"An IANA name. Left out, `UTC`."}}},"SiteHolds":{"type":"object","description":"What deleting a site would take with it (the Dialogs board), said\nbefore anyone is asked to type its name.","required":["site","rows","months","imported","goals","notes","snapshots","links","public"],"properties":{"copies_days":{"type":["integer","null"],"format":"int32","description":"Copies of the database are kept this many days: that long after a\ndeletion it is gone from every copy. None: not said for this\ninstance.","minimum":0},"first_day":{"type":["string","null"],"description":"The first day there is a figure for, counted or brought in."},"goals":{"type":"integer","format":"int32","minimum":0},"imported":{"type":"boolean","description":"Days brought from another tool are among its totals."},"links":{"type":"integer","format":"int32","description":"Private links that still open.","minimum":0},"months":{"type":"integer","format":"int32","description":"How many months that is, to today.","minimum":0},"notes":{"type":"integer","format":"int32","minimum":0},"public":{"type":"boolean","description":"Its public dashboard is on."},"rows":{"type":"integer","format":"int64","description":"Views and events tidekeeper counted itself, one row each.","minimum":0},"site":{"type":"string"},"snapshots":{"type":"integer","format":"int32","description":"Stored copies of its pages.","minimum":0}}},"SiteOffered":{"type":"object","required":["code","expires"],"properties":{"code":{"type":"string","description":"Shown once. Whoever types it into their account takes the site."},"expires":{"type":"integer","format":"int64"}}},"SiteOverview":{"type":"object","description":"One row of the overview of every site (SI-02).","required":["site","state","current","spark"],"properties":{"current":{"type":"integer","format":"int32","description":"Visitors seen in the last five minutes.","minimum":0},"hours_since":{"type":["integer","null"],"format":"int32","description":"Hours since then, when that is what the state is about.","minimum":0},"last_hit":{"type":["string","null"],"description":"When the last counted hit arrived."},"previous_visitors":{"type":["number","null"],"format":"double","description":"The same over the period before, to compare."},"site":{"$ref":"#/components/schemas/SiteView"},"spark":{"type":"array","items":{"type":["number","null"],"format":"double"},"description":"Visitors for each day of the period, for the small chart. `null` is\na day nothing was being counted."},"state":{"$ref":"#/components/schemas/ScriptState"},"views":{"type":["number","null"],"format":"double"},"visitors":{"type":["number","null"],"format":"double","description":"Daily visitors, summed over the period. `null` before any hit."}}},"SiteRef":{"type":"object","description":"A site by both of its names: the one the API takes and the one people read.","required":["id","name"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"SiteUpdate":{"type":"object","description":"Change a site. Whatever is left out stays as it is.","properties":{"hostnames":{"type":["array","null"],"items":{"type":"string"}},"paused":{"type":["boolean","null"]},"resume":{"type":["string","null"],"description":"With `paused: true`: when counting starts again by itself. `hour`\nis in an hour, `tomorrow` is 09:00 the next day in the site's own\ntime. Left out, it stays paused until someone says otherwise."},"settings":{"type":["object","null"]},"time_zone":{"type":["string","null"]}}},"SiteUse":{"type":"object","required":["site","events"],"properties":{"events":{"type":"integer","format":"int64","minimum":0},"site":{"type":"string"}}},"SiteView":{"type":"object","required":["id","name","hostnames","time_zone","mode","reading","settings","declared","paused","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"declared":{"type":"boolean","description":"Declared in the instance's configuration: read-only here, pausable."},"hostnames":{"type":"array","items":{"type":"string"},"description":"Hostnames allowed to send hits for this site."},"id":{"type":"string","format":"uuid"},"mode":{"type":"string","description":"`easy` or `hard`."},"name":{"type":"string","description":"The name the tag carries (`data-site`)."},"paused":{"type":"boolean"},"reading":{"type":"string","description":"`strict` or `cnil`."},"settings":{"type":"object"},"time_zone":{"type":"string"}}},"SixDigits":{"type":"object","required":["code"],"properties":{"code":{"type":"string"}}},"SnapshotFrame":{"type":"object","description":"Where a copy can be shown for the next hour.","required":["url","expires","width","copy"],"properties":{"copy":{"$ref":"#/components/schemas/SnapshotView"},"expires":{"type":"integer","format":"int64"},"url":{"type":"string","description":"An address on the other origin, for a frame."},"width":{"type":"integer","format":"int32","description":"How wide the frame is for this device, in pixels.","minimum":0}}},"SnapshotRemoved":{"type":"object","description":"What was taken out of a page when it was stored, counted.","required":["scripts","frames","handlers","forms","elsewhere","styles","other"],"properties":{"elsewhere":{"type":"integer","format":"int32","description":"Addresses that are not on one of the site's own hostnames.","minimum":0},"forms":{"type":"integer","format":"int32","description":"Where a form would have gone.","minimum":0},"frames":{"type":"integer","format":"int32","description":"Frames, objects and embeds.","minimum":0},"handlers":{"type":"integer","format":"int32","description":"`on…` attributes.","minimum":0},"other":{"type":"integer","format":"int32","minimum":0},"scripts":{"type":"integer","format":"int32","minimum":0},"styles":{"type":"integer","format":"int32","description":"Stylesheets that could not be put in.","minimum":0}}},"SnapshotTake":{"type":"object","description":"Store a copy of a page of the site.","properties":{"path":{"type":"string","description":"A path of the site: `/install`.","default":""},"url":{"type":["string","null"],"description":"Or the page's whole address, for a site that is not reached at\n`https://` and its first hostname. One of the site's own hostnames.","default":null}}},"SnapshotView":{"type":"object","description":"One stored copy of a page: as a desktop was sent it, or a phone.","required":["id","path","device","taken","by","url","bytes","pickable","removed"],"properties":{"by":{"type":"string"},"bytes":{"type":"integer","format":"int64","description":"The page as it was fetched.","minimum":0},"device":{"type":"string","description":"`desktop` or `phone`."},"id":{"type":"string","format":"uuid"},"path":{"type":"string"},"pickable":{"type":"integer","format":"int32","description":"How many things on it can be picked.","minimum":0},"removed":{"$ref":"#/components/schemas/SnapshotRemoved"},"taken":{"type":"integer","format":"int64"},"url":{"type":"string","description":"Where it was fetched from in the end."}}},"SnapshotsView":{"type":"object","description":"The stored copies of a site's pages (the page overlay and the picker\nare drawn on them).","required":["available","reason","most","copies"],"properties":{"available":{"type":"boolean","description":"This tidekeeper has somewhere to show a copy."},"copies":{"type":"array","items":{"$ref":"#/components/schemas/SnapshotView"}},"most":{"type":"integer","format":"int32","description":"How many pages of a site are kept.","minimum":0},"reason":{"type":"string","description":"Why not, when not."}}},"Snooze":{"type":"object","description":"\"Remind me later\": do not show something again for some days.","required":["what","days"],"properties":{"days":{"type":"integer","format":"int32","description":"1 to 14.","minimum":0},"what":{"type":"string","description":"What: `plan`, the notice that the plan's events are nearly or\nwholly used."}}},"Stage":{"type":"object","required":["name","label","n"],"properties":{"label":{"type":"string"},"n":{"type":"integer","format":"int32","minimum":0},"name":{"type":"string"}}},"StatRow":{"type":"object","required":["key","label","values"],"properties":{"key":{"type":"string","description":"The group's value as stored: a path, a source, a country code."},"label":{"type":"string","description":"The same for people: `Search` for the channel, `Phone` for the\ndevice. Equal to `key` where there is nothing to translate."},"previous":{"type":["array","null"],"items":{"type":["number","null"],"format":"double"},"description":"The same row in the period compared with, when one was asked for."},"values":{"type":"array","items":{"type":["number","null"],"format":"double"},"description":"One per metric asked for, in order. `null` is \"no figure\", which is\nnever the same as zero."}}},"StatsResponse":{"type":"object","required":["site","period","metrics","rows","totals","caveats"],"properties":{"by":{"type":["string","null"]},"caveats":{"type":"array","items":{"$ref":"#/components/schemas/CaveatView"}},"compare":{"oneOf":[{"$ref":"#/components/schemas/PeriodView"},{"type":"null"}]},"metrics":{"type":"array","items":{"type":"string"}},"period":{"$ref":"#/components/schemas/PeriodView"},"previous_totals":{"type":["array","null"],"items":{"type":["number","null"],"format":"double"}},"rows":{"type":"array","items":{"$ref":"#/components/schemas/StatRow"}},"site":{"type":"string"},"totals":{"type":"array","items":{"type":["number","null"],"format":"double"}}}},"StoreTable":{"type":"object","description":"One table that holds something about a site.","required":["name","holds","kept_for","rows","person"],"properties":{"holds":{"type":"string"},"kept_for":{"type":"string"},"name":{"type":"string"},"person":{"type":"string","description":"Does a row point at a person? The answer, in words."},"rows":{"type":"integer","format":"int64","minimum":0}}},"StoresView":{"type":"object","description":"Every table that holds anything about a site, and what is never kept\n(the Stores board).","required":["site","tables","never","statement"],"properties":{"never":{"type":"array","items":{"type":"string"}},"site":{"type":"string"},"statement":{"type":"string","description":"What to tell a visitor who asks what is held about them."},"tables":{"type":"array","items":{"$ref":"#/components/schemas/StoreTable"}}}},"StrayEvent":{"type":"object","description":"A provider's event that was stored and could not be applied.","required":["provider","id","kind","received","says"],"properties":{"id":{"type":"string"},"kind":{"type":"string"},"provider":{"type":"string"},"received":{"type":"integer","format":"int64"},"says":{"type":"string"}}},"StretchCreate":{"type":"object","description":"Leave a stretch out of comparisons. What is left out of the request is\nempty, and is refused as that: after it is known that the site is\nthe asker's to change.","properties":{"from":{"type":"string","description":"`2026-10-08T15:00`, in the site's own time.","default":""},"until":{"type":"string","default":""},"why":{"type":"string","description":"1 to 280 characters. Shown on the chart with who said it.","default":""}}},"StretchView":{"type":"object","description":"A stretch left out of comparisons (the Dialogs board). Its views stay\ncounted and on the chart; what is usual is worked out without them.","required":["id","from","until","says","why","by","made","undone_by"],"properties":{"by":{"type":"string","description":"Who vouched for it."},"from":{"type":"integer","format":"int64","description":"Unix seconds."},"id":{"type":"string","format":"uuid"},"made":{"type":"integer","format":"int64"},"says":{"type":"string","description":"From when to when, in words, in the site's own time."},"undone":{"type":["integer","null"],"format":"int64","description":"When it was undone, if it was. It counts again from then."},"undone_by":{"type":"string"},"until":{"type":"integer","format":"int64"},"why":{"type":"string"}}},"SubscriptionView":{"type":"object","description":"A subscription as its owners see it.","required":["state","says","yearly","held","portal"],"properties":{"cancel_at":{"type":["integer","null"],"format":"int64"},"held":{"type":"boolean","description":"Hits are being held now, and counted as held."},"held_on":{"type":["integer","null"],"format":"int64","description":"When counting stops if nothing is paid: the end of the grace."},"paid":{"type":"boolean","description":"Paid for at a provider: the plan is changed there. Not so on\ntrial, nor on a plan given without payment."},"period_end":{"type":["integer","null"],"format":"int64"},"portal":{"type":"boolean","description":"Whether the provider has a page of its own for the card and the\ninvoices to send the owner to."},"says":{"type":"string","description":"Where it stands, in a sentence."},"state":{"type":"string","description":"`trialing`, `active`, `past_due`, `unpaid`, `cancelling`, `ended`."},"trial_ends":{"type":["integer","null"],"format":"int64"},"yearly":{"type":"boolean"}}},"SupportGrantAsk":{"type":"object","description":"For how long an owner lets support see the account's figures.","required":["days"],"properties":{"days":{"type":"integer","format":"int32","description":"One to thirty.","minimum":0}}},"SupportView":{"type":"object","description":"Access to an account's figures for support.","required":["asked_by","why","granted_by","live"],"properties":{"asked":{"type":["integer","null"],"format":"int64"},"asked_by":{"type":"string"},"granted_by":{"type":"string"},"live":{"type":"boolean","description":"Granted and not over."},"until":{"type":["integer","null"],"format":"int64","description":"Set once an owner granted it: when it ends by itself."},"why":{"type":"string"}}},"Suspended":{"type":"object","required":["since","why"],"properties":{"since":{"type":"integer","format":"int64"},"why":{"type":"string"}}},"TakeSite":{"type":"object","required":["code"],"properties":{"code":{"type":"string"}}},"TeamView":{"type":"object","required":["members","invitations","roles","sites","can_invite","can_change","log","now"],"properties":{"can_change":{"type":"boolean","description":"Whether the member asking may change the others."},"can_invite":{"type":"boolean","description":"Whether this tidekeeper can invite: it needs its own sign-in, which a\npersonal instance leaves to its single sign-on."},"invitations":{"type":"array","items":{"$ref":"#/components/schemas/InvitationView"}},"log":{"type":"array","items":{"$ref":"#/components/schemas/LogLineView"},"description":"What members did lately, newest first."},"members":{"type":"array","items":{"$ref":"#/components/schemas/MemberView"}},"now":{"type":"integer","format":"int64","description":"The server's clock, unix seconds: what \"last here\" is counted from."},"roles":{"type":"array","items":{"$ref":"#/components/schemas/RoleView"}},"second_step_required":{"type":"boolean","description":"Everyone needs a second step at sign-in."},"sites":{"type":"array","items":{"$ref":"#/components/schemas/SiteRef"},"description":"Every site of the account, to choose from."},"support":{"oneOf":[{"$ref":"#/components/schemas/SupportView","description":"Set while tidekeeper's support has asked to see the account's\nfigures, or has been let: who, why, and until when."},{"type":"null"}]}}},"TestResult":{"type":"object","description":"How \"Test\" on a channel went (NC-08).","required":["sent"],"properties":{"error":{"type":["string","null"]},"sent":{"type":"boolean"}}},"TextBlock":{"type":"object","required":["kind","text"],"properties":{"kind":{"type":"string","description":"`h` a heading, `p` a paragraph, `li` an item of a list."},"text":{"type":"string"}}},"TextLink":{"type":"object","required":["id","title"],"properties":{"id":{"type":"string","description":"`terms`, `privacy`, `dpa`, `subprocessors`, `company` or\n`accessibility`: its address is `/<id>`."},"title":{"type":"string"}}},"TextView":{"type":"object","description":"A published text, as blocks the page draws: nothing in it is markup.","required":["id","title","blocks"],"properties":{"blocks":{"type":"array","items":{"$ref":"#/components/schemas/TextBlock"}},"id":{"type":"string"},"title":{"type":"string"}}},"TokenAbout":{"type":"object","description":"What the API tokens screen needs beside the tokens themselves.","required":["scopes","sites","per_hour","url","now"],"properties":{"now":{"type":"integer","format":"int64"},"per_hour":{"type":"integer","format":"int32","description":"Requests an hour one token may make.","minimum":0},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/ScopeView"}},"sites":{"type":"array","items":{"$ref":"#/components/schemas/SiteRef"},"description":"The sites a token of this member's could be held to."},"url":{"type":"string","description":"Where this tidekeeper is reached, for the example."}}},"TokenCreate":{"type":"object","required":["name"],"properties":{"expires_days":{"type":["integer","null"],"format":"int32","description":"Days until it stops working. Left out, it does not.","minimum":0},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"},"description":"`read`, `events`, `manage`, `visitors`."},"sites":{"type":"array","items":{"type":"string"},"description":"Site ids or names it is held to. Empty is every site its maker may open."}}},"TokenCreated":{"type":"object","description":"The only time a token's secret is shown.","required":["secret","token"],"properties":{"secret":{"type":"string"},"token":{"$ref":"#/components/schemas/TokenView"}}},"TokenView":{"type":"object","required":["id","name","scopes","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"expires":{"type":["integer","null"],"format":"int64","description":"Unix seconds after which it no longer works."},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":["string","null"],"format":"date-time"},"last_used_by":{"type":["string","null"],"description":"What last used it, in a word: `CLI`, `curl`."},"made_by":{"type":"string","description":"The member who made it. It never does more than they may."},"name":{"type":"string"},"revoked_at":{"type":["string","null"],"format":"date-time"},"scopes":{"type":"array","items":{"type":"string"}},"sites":{"type":"array","items":{"type":"string"},"description":"The sites it is held to, by name. Empty is every site."}}},"Told":{"type":"object","required":["what","ts"],"properties":{"ts":{"type":"integer","format":"int64"},"what":{"type":"string"}}},"Unconfirmed":{"type":"object","description":"An address that asked to sign up and has not confirmed.","required":["email","asked"],"properties":{"asked":{"type":"integer","format":"int64"},"email":{"type":"string"}}},"VisitView":{"type":"object","required":["n","start","seconds","source","route","reached","campaign"],"properties":{"campaign":{"type":"string","description":"Campaign tags it arrived with."},"n":{"type":"integer","format":"int32"},"reached":{"type":"array","items":{"type":"string"},"description":"Goals reached in it."},"route":{"type":"array","items":{"type":"string"},"description":"The pages of the visit in order, and the events on them."},"seconds":{"type":"integer","format":"int64"},"source":{"type":"string"},"start":{"type":"integer","format":"int64"}}},"VisitorDetail":{"type":"object","description":"Everything held about one visitor (VI-06).","required":["site","visitor","state","visits","records","props","refused","device","deleted_on","requests","joined","note"],"properties":{"deleted_on":{"type":"string","description":"The day their data is deleted if they do not come back."},"device":{"type":"string"},"joined":{"type":"array","items":{"$ref":"#/components/schemas/JoinView"},"description":"IDs that were joined to this one, with when (VI-04)."},"note":{"type":"string","description":"Their first views, before they answered, are not here."},"props":{"type":"array","items":{"$ref":"#/components/schemas/PropView"}},"records":{"type":"array","items":{"$ref":"#/components/schemas/RecordView"}},"refused":{"type":"array","items":{"type":"string"},"description":"Properties the site sent that it had not declared."},"requests":{"type":"array","items":{"$ref":"#/components/schemas/RequestView"}},"site":{"type":"string"},"state":{"type":"string","description":"`agreed` or `withdrew`."},"visitor":{"$ref":"#/components/schemas/VisitorRow"},"visits":{"type":"array","items":{"$ref":"#/components/schemas/VisitView"}}}},"VisitorExport":{"type":"object","description":"Everything held about a visitor, as JSON for them (DS-02).","required":["site","exported_at","visitor","consent","properties","visits","note"],"properties":{"consent":{"type":"array","items":{"$ref":"#/components/schemas/RecordView"}},"exported_at":{"type":"integer","format":"int64"},"note":{"type":"string"},"properties":{"type":"array","items":{"$ref":"#/components/schemas/PropView"}},"site":{"type":"string"},"visitor":{"$ref":"#/components/schemas/VisitorRow"},"visits":{"type":"array","items":{"$ref":"#/components/schemas/ExportVisit"}}}},"VisitorRow":{"type":"object","required":["id","short","first_seen","last_seen","visits","first_source","country","reached"],"properties":{"country":{"type":"string"},"first_seen":{"type":"integer","format":"int64"},"first_source":{"type":"string"},"id":{"type":"string","description":"`v_` and 32 digits."},"last_seen":{"type":"integer","format":"int64"},"reached":{"type":"array","items":{"type":"string"},"description":"Goals this visitor reached, by name."},"short":{"type":"string"},"user_id":{"type":["string","null"]},"visits":{"type":"integer","format":"int64","minimum":0}}},"VisitorsResponse":{"type":"object","required":["site","period","coverage","came_back","signed_in","rows","total","weeks","keep_days"],"properties":{"came_back":{"type":"integer","format":"int64","minimum":0},"coverage":{"$ref":"#/components/schemas/Coverage"},"days_between":{"type":["number","null"],"format":"double","description":"Median days between one visit and the next."},"keep_days":{"type":"integer","format":"int32","description":"How long a visitor is remembered: the site's setting.","minimum":0},"period":{"$ref":"#/components/schemas/PeriodView"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/VisitorRow"}},"signed_in":{"type":"integer","format":"int64","minimum":0},"site":{"type":"string"},"total":{"type":"integer","format":"int64","description":"How many match in all.","minimum":0},"visits_mean":{"type":["number","null"],"format":"double"},"visits_median":{"type":["number","null"],"format":"double"},"weeks":{"type":"array","items":{"$ref":"#/components/schemas/WeekCount"}}}},"WatchDef":{"type":"object","required":["kind","label","means","about_counting"],"properties":{"about_counting":{"type":"boolean"},"kind":{"type":"string"},"label":{"type":"string"},"means":{"type":"string"}}},"Ways":{"type":"object","description":"The ways into this tidekeeper, for the sign-in page.","required":["password","passkey","social","sso","from"],"properties":{"from":{"type":"string","description":"The address its emails come from, to look for."},"passkey":{"type":"boolean"},"password":{"type":"boolean","description":"Email and password, and a link by email."},"social":{"type":"array","items":{"$ref":"#/components/schemas/Labelled2"},"description":"Other services people can sign in through: (id, name)."},"sso":{"type":"boolean","description":"The instance's own single sign-on."},"sso_at":{"type":"string","description":"Where that single sign-on is: the host people are sent to and back."}}},"WeekCount":{"type":"object","required":["from","to","new","returning"],"properties":{"from":{"type":"string"},"new":{"type":"integer","format":"int64","minimum":0},"returning":{"type":"integer","format":"int64","minimum":0},"to":{"type":"string"}}},"WhenCell":{"type":"object","description":"One hour of one weekday.","required":["weekday","hour","value"],"properties":{"hour":{"type":"integer","format":"int32","description":"0 to 23, in the site's time zone.","minimum":0},"value":{"type":"number","format":"double"},"weekday":{"type":"string"}}},"WhenResponse":{"type":"object","description":"When in the week readers come.","required":["site","period","metric","rows","by_hour"],"properties":{"busiest":{"oneOf":[{"$ref":"#/components/schemas/WhenCell"},{"type":"null"}]},"by_hour":{"type":"array","items":{"type":["number","null"],"format":"double"},"description":"Each hour of the day, averaged over every day."},"caveats":{"type":"array","items":{"$ref":"#/components/schemas/CaveatView"},"description":"What these averages say of themselves: a stretch someone left out\nof comparisons is in none of them."},"metric":{"type":"string","description":"`visitors` (counted once in each hour they came) or `views`."},"period":{"$ref":"#/components/schemas/PeriodView"},"quietest":{"oneOf":[{"$ref":"#/components/schemas/WhenCell"},{"type":"null"}]},"rows":{"type":"array","items":{"$ref":"#/components/schemas/WhenRow"},"description":"Seven rows, from the day the site's week starts on."},"site":{"type":"string"}}},"WhenRow":{"type":"object","description":"A weekday: its 24 hours, each the average over the period's days of\nthat weekday. No figure where the period holds no such hour yet.","required":["weekday","hours"],"properties":{"a_day":{"type":["number","null"],"format":"double","description":"What such a day adds up to."},"hours":{"type":"array","items":{"type":["number","null"],"format":"double"}},"weekday":{"type":"string"}}},"WhyResponse":{"type":"object","description":"How a figure was made (ME-12).","required":["site","period","metric","label","definition","received","left_out","left_out_is_site_wide","views","events","no_key_views","visitors","daily_visitors","imported_views","caveats"],"properties":{"caveats":{"type":"array","items":{"$ref":"#/components/schemas/CaveatView"}},"daily_visitors":{"type":"array","items":{"$ref":"#/components/schemas/DayCount"},"description":"The visitor figure day by day: it is their sum."},"definition":{"type":"string","description":"The metric's one definition, in the words shown everywhere."},"events":{"type":"integer","format":"int64","minimum":0},"imported_views":{"type":"integer","format":"int64","description":"Views that came from an import (IV-12).","minimum":0},"label":{"type":"string"},"left_out":{"type":"array","items":{"$ref":"#/components/schemas/LeftOutView"}},"left_out_is_site_wide":{"type":"boolean","description":"The left-out counts are for the whole site, not for the filtered\nslice: they are kept per site and day only."},"metric":{"type":"string"},"no_key_views":{"type":"integer","format":"int64","description":"Views counted without a visitor key (VC-13).","minimum":0},"period":{"$ref":"#/components/schemas/PeriodView"},"received":{"type":"integer","format":"int64","description":"Hits received in the period: counted plus left out.","minimum":0},"site":{"type":"string"},"value":{"type":["number","null"],"format":"double","description":"The figure itself."},"views":{"type":"integer","format":"int64","minimum":0},"visitors":{"type":"integer","format":"int64","minimum":0}}}}}}