1. What this is
UseShipReady is a production readiness scanner. Somebody enters a URL, and we run a fixed set of deterministic checks against what that URL serves publicly — security headers, exposed configuration, TLS, SEO and AI crawlability, email DNS records, accessibility, and performance — then report what the checks observed, with the evidence attached.
The bot that does the fetching identifies itself as UseShipReady-Scanner. It runs on-demand scans that a person explicitly requested. It is not a search crawler, it does not build an index, and it does not collect or resell data about your site. It visits because somebody asked it to look at one specific URL, and then it stops.
2. Why you are seeing this in your logs
Someone ran a UseShipReady scan against your site. In practice that is a site owner checking their own app before a launch, a developer checking something they just deployed, or an agency or freelancer checking a client’s site.
If you don't recognise why
We do not verify that the person who entered a URL owns it. That is a deliberate design decision, and the honest consequence is that a third party can scan your site without telling you. What they get is a report built from responses your server already gives to anybody who asks — nothing private, nothing authenticated.
A scan is a single burst of a minute or less, not sustained crawling. If you want it to stop, section 7 tells you how, and section 8 is a real address that reaches a human.
Scans are on-demand. A repeat visit means either somebody ran another scan, or an owner connected a repository and a push triggered a re-scan. We do not run a recurring crawl of sites on a schedule of our own.
3. What the scanner does
- Fetches public pages over HTTP(S). Up to 10 pages, no deeper than 2 path levels from the URL entered, and only on the same origin. Links pointing off that origin are not followed.
- Reads response headers and bodies. This is how most checks work — a header that is missing, a CORS policy that is too open, a secret left in a JavaScript bundle, a metadata tag that is absent or duplicated.
- Requests well-known paths to see if they are public.
/robots.txt,/sitemap.xml,/.env,/.git/HEAD,/.git/config,/docker-compose.yml,/.DS_Store,/admin,/debugand similar. This is the part that looks most like an attack in a log, so it is worth being plain about: these are plain GET requests, we are checking whether files that should never ship are being served, and a 404 is the answer we hope for. Nothing is exploited and nothing is written. - Sends one read-only GraphQL introspection query. A
POSTto/graphql,/api/graphqland/v1/graphqlasking the API to describe its own schema. It is the only non-GET request we make to your site, and it mutates nothing. - Looks up public DNS records. SPF, DKIM, DMARC, MX and similar, for email deliverability checks. These queries go to DNS resolvers, not to your web server, so they will not appear in your HTTP logs at all.
- Backs off when you push back. A
429or503doubles our delay to your host, and after three consecutive blocks we stop requesting from you entirely and mark the report as blocked. Rate-limiting us works, and it works within a single scan.
4. What the scanner does not do
No forms, no logins
It never submits a form, never attempts authentication, and never sends credentials, API keys or cookies of its own. Everything it sees is what an anonymous visitor sees.
No exploitation
Findings come from observation, not from proving an issue by attacking it. We do not attempt injection, we do not try to escalate, and we do not write to anything.
No personal data collection
The scanner is not scraping content, harvesting emails, or building a dataset about you. It reads pages to run checks and keeps the evidence for the resulting report.
No JavaScript execution
There is no headless browser. The scanner is a plain HTTP client, so client-side scripts on your pages are read as text and never run.
No off-origin requests
It stays on the origin that was entered. A scan of one site does not become a crawl of everything it links to.
No indefinite running
Every scan has a hard 65-second ceiling, after which it is cancelled whether it finished or not. There is no long-lived session against your host.
5. How much traffic to expect
These are the limits the scanner enforces on itself, so a scan does not read as an attack pattern or become a load test against somebody’s production site:
| Limit | Value |
|---|---|
| Pages fetched per scan | Up to 10, same origin, maximum depth 2 |
| Total requests per scan | Around 90, measured against a large site — pages plus their scripts and the well-known paths above |
| Concurrent requests to your host | Never more than 2 at a time, spaced at least 0.4s apart, regardless of how many scans are running |
| Duration of one scan | Up to 20s of page fetching, then up to 40s of checks; cancelled at 65s |
| Per-request timeout | 10 seconds |
| Redirects followed | Maximum 5 per request |
| Bytes read per response | Capped at 2 MB; longer responses are truncated |
| Frequency | On demand only. A re-scan happens when somebody runs one, or when a push lands on a repository the owner connected |
For scale: the suite is 197 deterministic checks, and all of them share the single request budget above rather than each getting their own.
6. How to allow-list the scanner
If a WAF, CDN or bot-protection layer sits in front of your site, it may challenge or block us. When that happens the scan still completes — it just reports your protection layer instead of your app, which is a wasted scan rather than an error. To let it through, match on the User-Agent substring:
Match this substring
UseShipReady-Scanner
Match the substring, not the full User-Agent string. The full value is UseShipReady-Scanner/1.0 (+https://useshipready.dev/about-our-scanner), and the /1.0 will change. A rule pinned to the whole string breaks silently on the next version bump; a rule matching UseShipReady-Scanner keeps working.
Cloudflare.Security → WAF → Custom rules, create a rule with expression http.user_agent contains "UseShipReady-Scanner" and action Skip→ all remaining custom rules plus Bot Fight Mode. A Cloudflare WAF Custom Rule is the reliable place for this; an IP Access Rule cannot express a User-Agent condition.
Generic WAF or reverse proxy. Add an allow or skip rule conditioned on the request User-Agent header containing UseShipReady-Scanner, ordered before your bot-mitigation and rate-limiting rules — after them, the block has already happened.
robots.txt will not help here. An Allow directive grants permission to crawlers that were already asking for it; it does not instruct a firewall to stop blocking. Allow-listing has to happen at the layer doing the blocking.
We do not publish IP ranges
Scanner traffic comes from a managed hosting platform with dynamic outbound addresses, so there is no stable IP list to allow-list against, and we would rather say that than publish a list that goes stale and locks you out. Match on the User-Agent instead.
If your security policy genuinely requires an IP-based rule, email us — see section 8 — and we will tell you what we can actually commit to rather than guess.
7. How to block the scanner
If you do not want your site scanned, you should be able to stop it, and here is how. Please read the first line carefully, because it is the one most people get wrong:
robots.txt will not block this scanner
We read your robots.txt — to discover sitemaps, and to run checks on its contents — but we do not treat it as an access control, because a scan is an action a person took against a specific URL rather than a crawler wandering in. A Disallow rule will not stop a scan, and we would rather tell you that than let you add a rule that quietly does nothing.
Block by User-Agent. This works, and it is the fastest route. Refuse requests whose User-Agent contains UseShipReady-Scanner at your WAF, CDN or web server. In Cloudflare that is a WAF Custom Rule with expression http.user_agent contains "UseShipReady-Scanner" and action Block. In nginx:
if ($http_user_agent ~* "UseShipReady-Scanner") {
return 403;
}A scan of a blocked site still runs, but every check reports that it was blocked rather than reporting anything about your app — which is exactly the outcome you want.
Rate-limit us. Also effective, and no configuration of ours is needed: return 429 or 503 and we slow down immediately, then stop asking after three consecutive refusals.
Ask us. Email hello@useshipready.dev from an address at the domain, with the domain in the subject. We do not ask why.
Separately: if your domain appears on our public rankings board and you want it off, that is the same address and the same one-line email. Removal is free, permanent, and needs no account.
8. Scanner name change
As of 15 September 2026 this scanner identifies as UseShipReady-Scanner (previously ShipReady-Scanner) as part of our rebrand. If you have an existing allow-list or block rule matching the old name, update it — and see section 6 on matching the substring so the next version bump does not break it again.
9. Contact
Questions about scanner traffic, opt-out requests, abuse reports, or anything on this page reach a person at:
hello@useshipready.devSee also: every check we run · Disclaimer · Acceptable Use · Privacy Policy