Legal
Privacy Policy
Version 1.0, last updated .
Who we are. BotShark is run by ASOK, of 80 Darby Road, Liverpool, L19 9AW, who is the controller of the personal data this page describes. Contact: [email protected].
What we store. When you scan an account we may persist: the handle, score, tier, confidence, generated report JSON, optional snapshot data (bios, post text samples, avatar references, follower/following samples), feedback labels you submit, and your account email if you register.
Why. Stored runs power history charts, library search, corpus coordination detection across accounts you have scanned, and rule tuning from feedback. Snapshots on disk support re-scoring without re-fetching when data is still fresh.
Lawful basis. We rely on legitimate interests: scoring public posting behaviour when someone asks us to check an account, and showing the checks behind that score. That interest does not override a person’s right to object.
Where the data comes from. We scan X accounts. Their profiles and posts are public data, supplied by Sorsa. The verification badge comes from a second vendor, twitterapi.io. We send each vendor the handle we are asked to check. We add another platform only when we enable it. Reports on Bluesky accounts are built from Bluesky’s public API.
AI checks. Some checks, and the wording of a report’s summary, use a language model that Cloudflare Workers AI runs for us. For those checks we send Cloudflare text from the scan: a sample of the account’s posts and replies, the posts it replied to, its bio, posts by other accounts that repeat its wording, the places its followers typed in their profiles, and the facts in the report. The model sends back labels, such as whether a reply fits the post it answers, and the summary’s wording. We keep those answers with the report, for as long as the report is kept, so that a score can be explained and checked later. We keep a copy of the text we sent and of the model’s reply for 14 days, with email and network addresses masked, to find and fix faults, and then delete it.
Engine checks. We keep a small set of reports as reference points and score them again every hour and after every change to our checks, so that a change cannot move a score without us seeing it; once a day, and after each change, we also scan one organisation’s public account for the same reason, without publishing anything. The reference reports’ scraped data and the model’s answers are kept while they are in that set; the result of each check, with the daily scan’s data, for 90 days. Email [email protected] to have an account taken out of it.
Who processes data for us. These companies handle personal data for us, on our instructions and under data processing terms. Railway hosts our servers, database and logs. Cloudflare runs the network in front of botshark.io, which every request passes through, and Workers AI. Sentry receives error reports. Stripe takes payments: you type your card details on Stripe’s own page and they never reach us. Stripe is also a controller in its own right for its own duties, such as preventing fraud. Resend sends our emails. Loops runs our mailing list.
Others we send data to. If you choose to sign in with Google or X, that company tells us your account id there, and Google also tells us your email address. We keep them with your account. For the posts a saved report quotes, we ask the Internet Archive’s Wayback Machine to save a public copy, so that the example can still be read if the post is deleted. The Archive keeps its copies under its own rules.
Transfers outside the UK. The companies that process data for us are based in the United States, as are Google, X and the Internet Archive. A transfer to one of them relies on the UK’s adequacy regulations (the UK–US data bridge) where the company is certified under it, and otherwise on the International Data Transfer Addendum to the EU standard contractual clauses in its data processing terms. Sorsa and twitterapi.io receive the handle we are asked to check. Plausible, our analytics service, keeps its data in the EU.
Objecting. Email [email protected] and say you object. We answer within one month.
The ICO. You can complain to the Information Commissioner’s Office atico.org.uk/make-a-complaint.
Data-protection complaints. Email [email protected] or use thedispute form. We acknowledge a data-protection complaint within 30 days. A subject response on a report is still acknowledged within 7 days.
Watchlists and phrases. We store the handles on your watchlist. A daily check reads the public profile of each X account on that list, up to your plan’s limit, and does not score them. We store the phrases you ask us to watch for, up to your plan’s limit. A scan alerts you when an account posts one. Saved phrases do not change the score.
Case folders. We store the folder names, the accounts you put in them, and the notes you write. A note is visible to you and to anyone you share that folder with. It is not part of the public report and it does not change the score.
Private scans. A Pro scan can stay off the public report for the hold you choose. It publishes on its own when that hold ends, or sooner if you publish it.
Retention. A public report stays listed while the latest run is less than 180 days old, or for 180 days after we review and restore it. After that, with no newer run, we unlist it (status expired). It is listed again once a newer run is public: a new scan, or a private scan when it publishes. Guest free-scan claims older than 90 days are deleted. A free-scan claim or a dispute keeps a keyed hash of the network address it came from, not the address. We do not sell scanned account data.
Server logs. Each request to the BotShark app or its API writes one log line: the address requested (with any email, network address or key in it masked), the answer, how long it took, your account id if you are signed in, and the network address the request came from. Our other log lines replace email and network addresses with keyed codes, apart from the addresses a request passed through when we record a fault in how it reached us, and mask passwords, keys, tokens and the text of emails. Railway, our host, keeps these logs for up to 30 days. We read them to keep the service running and secure.
Error reports. When something fails on our servers, a report goes to Sentry, our error-tracking service: what failed, where in our code and the values it was working with, the version and server that were running, the log lines just before it, and the address and headers of the request that failed. A report is masked as our logs are, with cookies and sign-in tokens removed, and never includes the body of a request, so what you type into a form stays out. Sentry keeps reports only for a limited period, set by our plan with them. We read them to find and fix faults. Sentry also hears when each of our scheduled jobs starts and how it ended, and checks that our site and app answer; neither carries anything about you.
Browser error reports. When a page of the app, or our browser extension, fails in your browser, it sends us a report: the error's type, message and stack trace, the page's pattern rather than its address (/u/:handle, not the handle), the version of our code, how many times it happened, your browser's name and major version, and for a failed request to our servers its status and our request id. Every web address in a report loses its query; in a report from the extension, an X or Bluesky address keeps only its page type and the extension's install id is removed. A report is sent without your session or API key and is not linked to your account. The extension sends reports only while its telemetry switch is on, and on Firefox only if you allowed technical data. We keep them in our records for 90 days (deleted a week at a time, so none is kept longer than 97 days), with any email or network address replaced by a keyed code, and read them to find and fix faults.
Security records. Separately from the logs, we keep a record of what happens on our servers for 90 days: warnings and errors, failed requests, scans moving through the queue, payment events from Stripe, changes our team makes, how many layout-drift reports the browser extension sent (not the pages), and security events on your account (a refused sign-in or authenticator code, a password reset or change, turning the authenticator on or off, API keys created or revoked, a download of your data, and a support session our team opened on your account). A record holds when and what happened and your account id; an email or network address in it is replaced with a keyed code, including the email typed into a refused sign-in. Your data download includes your account's security records, and deleting your account removes your account id from every record. Records are deleted a week at a time once they are 90 days old, so none is kept longer than 97 days. We read them to keep the service running and secure.
Messages we send. We keep a record of each email, webhook and Slack message we send: when, what kind of message it was (a password reset, a receipt, an alert you set up), your account id, whether it went out, and our email provider's reference for it. The address it went to is kept only as a keyed code, and a webhook or Slack address only as its site; the message itself is not kept. Your data download includes this record, and deleting your account removes your account id, the code and the provider's reference from it. A record is deleted once it is 90 days old, with the rest of its month, so it is kept 90 to about 120 days. We read them to check that messages reach you.
Scan records. For each scan we keep a technical record for 90 days, deleted within a month after that: the account scanned, when, how it ended and how long each step took, which requests to our data vendors failed and why, and any error, masked as our logs are. For 30 days we keep the timing of each step of some scans, and a record of each request to the AI model: its size, cost, timing and outcome. When a data vendor’s request fails, we keep its reply for 7 days. We read these records to find out why a scan failed or was slow; they are then deleted.
Product updates. If you ask for product updates with a free scan, your email joins our mailing list at Loops. That consent is separate from the free-scan claim: it stays after the claim is deleted, until you unsubscribe with the link in any update, email us, or delete an account registered and verified with that email.
Disputes. If you own or represent a scanned account, submit a response at/u/:handle/dispute or /dispute. We acknowledge within 7 days at [email protected]. A subject dispute keeps the public report up and adds your statement as a banner, which stays unless we remove it after review. A dispute does not bring back a report we have taken down; if we restore one, your statement shows on it.
Your data and deletion. In Settings you can download a copy of your account data and delete your account, or email [email protected]. Deleting it removes your account, sessions, API keys, usage, subscription, watchlist, phrases, notifications, the case folders you own, your private runs and, once your email is verified, the free-scan claim made with it. Public reports you ran stay addressable by handle, without your account. A note you left in someone else’s folder stays there without your name, and a subject dispute you sent stays with its report. When we delete an account on request, our record of operator actions keeps a line saying so. Once your email is verified, deleting the account also removes it from our mailing list at Loops; if Loops cannot be reached we keep trying until it confirms.
Cookies. Authenticated sessions use an HTTP-only session cookie. If you sign in with Google or X and then enter an authenticator code, a second sign-in cookie lasts up to 5 minutes. Both are strictly necessary, so we do not ask for consent to them. Site analytics is Plausible: cookieless pageviews, referrers, and country at aggregate level, hosted in the EU — not a profile of you, and not used for ads. We do not use third-party advertising trackers. On signed-in report pages we may load X or Bluesky embed scripts so live posts appear automatically. On the public /u/:handle page those scripts load only after you choose “Show the live post”. The widgets can set their own cookies; snapshot cards never load them.