Privacy Policy
Last updated: September 28, 2026
1. What we collect, and why
- Your account: your email address, and, if you give them, a name, a use case and a stack. If you sign in with Google or GitHub, also the account id that provider gives us for you and the verified address it returns: we ask Google for your email and basic profile and GitHub for your profile and email addresses, and keep only the id and the one verified address. Used to run your account, sign you in and email you (section 5).
- Your API keys: we look a key up by a SHA-256 hash of it and show only its first and last characters. The key itself is not stored. With each key we keep its label, the address it was last used from, and each network it has been used from (for IPv6 the /64, for IPv4 the address itself), to email you when a key is used from a network it has not been seen from before.
- What your code sends: the preflight calls, usage records and steps your integration makes, with the ids you choose (agent, customer, job), the numbers (estimates, ceilings, units, tokens) and any metadata you attach to a record (at most 8 KB each). And the answer each refused call got, and a daily count of preflights the service could not decide (a 422, such as a new job sent with no ceiling), per account and reason, with nothing of the request in it. This is the service itself: the ceilings, the console and your usage.
- Public links you make: when you create a public link to your office, we store what the link shows, frozen at that moment (the staff count, who was at a desk and who was sent home, and agent names and dollar amounts only if you chose to show them), and the card image your browser drew for it. Anyone with the link can see them; search engines are asked not to index the page. Ending a link deletes the image and what the link showed at once, and the link answers 404 from then on.
- Page events: our marketing pages record a few page-level events in our own database (the demo being run, a click to the demo or through to the sign-up page, the sign-up page loading), stored with no cookie, no IP address and no identifier that outlives the tab.
- Which of our links you came from: some of our links carry a short label we wrote
ourselves (
?src=, for example the one in an ad). If you create an account after arriving on one, the account keeps that label, set once, so we can tell which of our links brought people. It is only our own label: never the page you came from, and nothing you typed. - How far setup got: in your console, whether the start screen was shown, which way in you picked, whether you named a client, and which of its samples or your key's lines you pressed Copy on, with how often and when. Never what you typed or copied: only that the step happened, so we can see where setup gets stuck.
- The request log: like any web server, ours logs each request with the IP address it came from, the path (never the query string, and never a sign-in or recovery token) and the time. The log is kept by our host, Fly.io, under its own retention; this service sets none.
- Cookies: signing in sets a session cookie for the console (
/app), and a short-lived one while a Google or GitHub sign-in is in progress. The marketing pages set no cookie of their own. The ad pixels in section 3 set theirs.
2. What the SDKs' wrap() sends, and never sends
wrap() in the Python and Node SDKs measures the model calls of a client you wrap. The call
itself goes from your process straight to your provider. Around it, wrap() sends AgentBill two requests,
and only these fields:
- Before the call, a preflight:
agent_id,customer_id,task_ref,task_ceiling,task_ceiling_usd,estimated_units,unit. - After it, a record:
customer_id,event_type,idempotency_key,units,success,task_ref,reservation_id,usage_missing,metadata. Theidempotency_keyis the provider's response id (a hash of it when it is longer than 128 characters, and a random key on a compatible endpoint), andunitsis the token total. - In the record's metadata:
provider,model,requested_model,tokens,service_tier,step,stream,duration_ms.tokensis the counts the provider reported: input, cache reads and writes, output, and reasoning where the provider says.
It never sends your prompts or messages, the model's answer, your provider API key, or the headers of your provider request. The requests carry your AgentBill key, as every call to the API does.
3. Who processes it
- Fly.io hosts the service and keeps its request log.
- Supabase hosts the database.
- Resend sends the emails in section 5, and receives mail sent to hello@agentbill.dev, which is forwarded to our own inbox.
- Polar takes payments on its own checkout page; we never see card details.
- Google and GitHub, only if you sign in with them.
- Google Fonts: our pages load their typefaces from fonts.googleapis.com and fonts.gstatic.com, so your browser sends Google its IP address when a page loads.
- Meta Pixel, on
/,/register,/pricingonly, to measure our ads (page views and sign-ups), with cookies set by that company. Never inside the console or the API. - Meta's Conversions API: when you create an account in a browser that already carries
the Meta Pixel's cookie (
_fbp, or_fbcafter an ad click), our server tells Meta a sign-up happened, with a SHA-256 hash of your email address and of your account id, the IP address and browser user agent of that request, and those cookie values. If your browser blocked the pixel, the server sends nothing. - Your own webhook, if you set one: an anomaly alert for your account is sent to the URL you gave.
4. How long it is kept
Once retention is on, a daily job removes each of these when its period ends. It is built and not yet switched on, so until then they are kept:
- An API key that was revoked or expired, with its label, the last address it was used from and the networks it was seen from: deleted 90 days after the day it was revoked or expired.
- The full address a key was first seen from on a new network (the network itself is kept while the key lives, for the new-network alert): cleared 90 days after the day the network was first seen.
- A preflight refusal and its snapshot: the answer your agent got, with the agent, customer and job ids in it: deleted 180 days after the refusal.
- The stored answer to a preflight sent with an idempotency_key, kept so a retry gets the same answer: deleted 30 days after the preflight.
- A reservation that was settled, released or reclaimed (the open ones are the live budget and are never touched): deleted 30 days after the day it closed.
- The metadata of a usage record (for wrap(): provider, model, token counts, duration, step); the record itself, its units and its list-price figure are kept: cleared 400 days after the record.
- A step recorded with POST /step (agent, step name, units), which the anomaly baseline reads the last 30 of: deleted 400 days after the step.
- A recovery link (stored as a hash) and when it was used: deleted 30 days after its expiry.
- An email sign-in link (stored as a hash) and the address it was sent to: deleted 30 days after its expiry.
- A first-party page event on the marketing pages (which event, a per-view id, the demo ceiling, a source label): deleted 180 days after the event.
Always, already: an MCP connection's authorization request is deleted 1 hour after it expires, and its codes and tokens 1 day after they expire.
Kept while your account exists, and deleted with it: the account, your sign-in identities, your live keys and the networks they have been used from, your customers, jobs and usage records, and the public links you have not ended. Kept on purpose, because they are the record of what was bought and paid: the plan and its history with Polar, the payment events Polar sent us, and the record of each quota email.
5. Email
We email you: a welcome when a sign-in creates your account, sign-in links you ask for, recovery links you ask for, an alert when one of your keys is used from a new network, and alerts when your account reaches 75% and 90% of its monthly quota and when the quota is spent, and an alert when one of your agents or customers spends three times its usual day, once per agent or customer per day. We, the operator, are emailed when an account is created (with its address), a periodic summary of accounts and their usage, and a note when one of your customer ids passes 800 units.
6. Deleting your account, and your rights
Email hello@agentbill.dev from the address on the account and we delete the account and everything stored under it: keys, customers, jobs, usage records, refusals, and your sign-in identity. Polar keeps its own records of any payment. The database host keeps backups on its own schedule, and a deleted account stays in those until they expire.
You can also ask for a copy of your data or to correct it, the same way. If you are in the EU/EEA or UK, these rights are backed by the GDPR.