Privacy
This page describes what Timbuktu stores, where it goes, and how long it is kept. It is written to be accurate rather than reassuring: where something leaves our own infrastructure, it says so.
Who is responsible
Jodok Batlogg operates Timbuktu as a private service for a named household — two people, one shared set of books, no sign-up — and is responsible for the data in it. Contact for any data question: [email protected].
What is stored
- Receipt documents — the original photographs, images and PDFs, submitted by upload or by forwarding them to a private email address. Forwarded mail passes through Cloudflare Email Routing before it reaches the application.
- Extracted receipt metadata — date, merchant, amount, currency, tax total, payment method and, where the receipt shows it, the last four digits of the card.
- Bank and card transactions — retrieved from the connected account, or imported from a statement file.
- Account and session data — the Google account email used to sign in, and the tokens for the signed-in device.
Where it is stored
Original documents are stored in Cloudflare R2. Extracted metadata, transactions and all other application state are stored in PostgreSQL on servers operated by the controller at Hetzner, in the EU. Documents are backed up to a second R2 bucket held under its own credential, so that losing one copy does not lose both.
Credentials for a connected bank account are encrypted before they are written to the database, so a database copy alone does not yield access to the account.
What is sent to an AI model
Receipt images are sent to OpenRouter for extraction, which routes them to a vision model hosted in the United States. This is how a photographed receipt becomes structured data, and it means the extraction provider sees every receipt submitted. What is sent is a rendered image with EXIF metadata stripped, not the original file.
Transaction data is never sent to any model. No counterparty name, account number, IBAN or bank reference leaves our own infrastructure. The only thing derived from transactions that reaches the extraction step is the amounts of nearby transactions that still have no receipt, used as a hint for reading a blurred total.
Model output is treated as untrusted input: every field is validated before it is stored, and nothing extracted from a receipt is executed or used to build a query.
Google Drive
Exporting to Google Drive is optional and off unless it is connected. It uses the
drive.file scope only, which means the application can see and manage
exactly the files it created itself, and nothing else in the Drive. Disconnecting
revokes that access.
Bank access is read-only
The connection to a bank provides account information only — balances and transactions. No payment-initiation capability is requested or provisioned at any layer, so the credential cannot move money. Access is granted through the bank's own consent flow, expires (typically after 90 days) and must be renewed deliberately.
Who else receives data
The services named above — Cloudflare (R2 storage, email routing and the network edge), Hetzner (servers), OpenRouter (receipt extraction) and Google (sign-in, and Drive if connected) — are the only third parties that receive any of this data. There is no advertising, no third-party analytics, and nothing is sold. The only cookies set are the session and CSRF cookies needed to stay signed in.
How long it is kept
Indefinitely, by design. The data is the evidence trail for tax years, and the statutory retention period in the EU is seven years, so nothing expires on its own. There is no automatic deletion.
Deletion is always an explicit act. When a receipt is deleted it is first hidden, and a purge then removes the stored bytes — unless another receipt still references the same file — along with the exported copy in Drive.
Contact
Questions about this policy, about what is stored, or about deleting something: [email protected]. Security issues go to the same address rather than to a public issue tracker.