Privacy policy

Draft, not reviewed by counsel. Written by an agent from docs/ARCHITECTURE.md §10 and the database schema, so every number and table below is what the code actually does. It is not legal advice and it has not been read by a lawyer. Take it to one before it is published. Notes addressed to that lawyer are marked [For counsel].

Version: draft 1 · Written: 13 September 2026 · Counsel review: pending · Published at: https://honestfetch.dev/privacy, 13 September 2026


1. Who is responsible

HonestFetch is operated by HallinCreations, in Sweden. The same operator the bot page names, and the same one the Cloudflare Verified listing names.

[For counsel] The legal form is undecided (docs/adr/0006-business-setup.md). The beta runs without a registered entity because nothing is sold. Once a form is chosen, the legal name, the organisation number and a postal address belong in this section, and the same three belong on https://honestfetch.dev/bot.

Contact: bot@honestfetch.dev.

2. What HonestFetch is, in one paragraph

An agent sends a URL and an optional question. HonestFetch fetches that one page, checks the site's own rules first, and returns a short extract of the text. It signs every request so a site owner can tell who it was. It is a reading tool, not an archive.

3. The promise this policy exists to make

HonestFetch never stores the pages it fetches. Page content lives in memory for the length of one request and is never written anywhere: not to the database, not to a log, not to a cache, not to a file.

This is structural rather than a policy. The database schema has no column that could hold page content, and a test (no-content.integration.test.ts) asks the database directly and fails the build if content ever appears in one.

4. What is stored, and why

Six tables, and this is all of them.

Table What it holds Why
customers Account name, plan, an optional operator handle, when the account was created, and whether it has been disabled To know whose key it is
api_keys The first characters of a key, a SHA-256 hash of the whole key, and timestamps To authenticate. The key itself is never stored; only the hash
usage_events Customer id, destination host, an optional truncated path prefix, the decision, the status, the reason, byte and token counts, latency, and any quoted price Metering, and the accountable record §3 of the architecture requires, so abuse can be traced and cut off
usage_daily Customer, day, host, and three counts The same picture after the raw rows are deleted
domain_optouts A domain, the verification method, a keyed hash of the contact address, a hash of the DNS token, and timestamps The site-owner exclusion list
plans Pricing plans Limits and, later, billing

usage_events holds no URL. It holds the host, and at most a truncated path prefix. No query string, ever.

The contact address of a site owner is never written down. domain_optouts keeps a keyed HMAC-SHA256 hash of it and nothing else. The hash exists for one purpose: to recognise the same person if they write again. A copy of that table hands a reader no address, and because the hash is keyed with a secret held outside the database, it cannot be turned into a lookup table for "did this person write in".

5. Requested URLs are treated as personal data

A URL can identify a person. https://example.com/profile/anna-svensson is a name.

So the URL an agent sends is handled as personal data throughout: it is used to make the one request it was sent for, it is never written to the database in full, it never appears in a log line, and it is gone when the request ends.

For that URL, you are the controller and HonestFetch is your processor (ADR-0018). It arrives as your instruction and HonestFetch keeps none of it. The records HonestFetch does keep, and why, are in §4 and §11.

6. Logs

Two logs exist. Neither holds a fetched page, an API key, or a requested URL.

The web server log records the time, the status, the path called on HonestFetch's own API, and the address the call came from. Authorization, Proxy-Authorization and Cookie headers are deleted before the line is written. The path is safe to keep because the URL to read travels in the request body: an inbound line says /v1/read and nothing more.

The application log writes only fields from a fixed allow-list, and every value is capped in length. Request headers are never serialised at all, because redacting headers by name leaves the next one to be discovered.

The web server log is rotated every day and rotated files are deleted after 30 days, so the address a call came from is kept for at most 30 days, the same period as the raw usage records in section 7. The rotation is a file on the host (infra/logrotate.conf), installed with the web server's configuration.

7. How long things are kept

Data Kept for
Raw usage events 30 days
Daily aggregates 13 months
Opt-out requests that were never verified 30 days, then forgotten
Verified opt-outs Until the site owner asks for removal
Account and key records While the account exists
Fetched page content Not kept at all

A job deletes raw rows and rolls them into aggregates in one transaction, so nothing is lost on the way and nothing outlives its window.

8. Where it is stored

In the European Union. The server is a Hetzner Cloud machine in Helsinki, Finland. The database and the cache run on that machine. No data is transferred outside the EU.

9. Who else touches it

Who What they do Where
Hetzner Online GmbH Hosts the server, and takes encrypted backups of it Helsinki, Finland
Cloudflare DNS for the domain, and forwards mail sent to bot@honestfetch.dev Global

There is no analytics provider, no advertising network, and no third-party script on any page HonestFetch serves.

[For counsel] A payment provider joins this list before the first paid customer. docs/adr/0006-business-setup.md recommends Stripe with Stripe Tax.

10. Cookies

HonestFetch sets no cookies on any page it serves.

It also sends none: a cookie is stripped from every outbound request, and any cookie a site tries to set is stripped from the response. That is part of never logging in and never passing a paywall.

11. Your rights

Under the GDPR you may ask for access to your personal data, correction of it, erasure of it, restriction of processing, portability of it, or to object to processing. You may also complain to a supervisory authority; in Sweden that is Integritetsskyddsmyndigheten (IMY).

Write to bot@honestfetch.dev.

The legal basis for each thing HonestFetch keeps as controller (ADR-0018):

Data Basis
Account and API key records Contract, Art. 6(1)(b): the service cannot be provided without them
Usage events and daily aggregates Legitimate interest, Art. 6(1)(f): the accountable record that lets a site owner's complaint be answered with facts, and metering
The opt-out list Legitimate interest, Art. 6(1)(f): honouring a site owner's request, which is their interest as much as ours
Caller addresses in the web server log Legitimate interest, Art. 6(1)(f): security

For the URL and question you send, the basis is yours: HonestFetch processes them on your instruction (§5).

[For counsel] Confirm the bases, and whether the balancing test for the two legitimate interests should be written down here or kept internally.

12. Site owners

If you run a site and do not want HonestFetch to read it, you have four ways to say so, and HonestFetch obeys all of them: robots.txt, Content Signals, an RSL licence it cannot meet, and its own exclusion list at https://honestfetch.dev/bot.

An exclusion takes effect on the very next request, before HonestFetch asks your server anything at all, including for robots.txt. It covers every subdomain.

13. Changes

A change to this policy changes the version and the date at the top. Material changes are sent to customers at the address on their account.