Printed-link watch
A daily check of up to 25 printed links: QR codes and short links on menus, flyers, posters and packaging, from any vendor. Start one on the tool page, with one API call or from an assistant over MCP. No account needed.
What counts as a problem
- Dead: DNS fails, TLS fails, no answer in 15 seconds, or a 4xx/5xx, on two checks at least 6 hours apart.
- Lands somewhere new: the final site or path differs from the first good check (the baseline).
- Deactivated page: the chain ends on a QR or short-link vendor's own domain or a parking service, or the first 32 KB of the page match phrases such as “QR code deactivated” or “this domain is for sale”.
- Redirect changed: 301/308 ↔ 302/307, a hop added or removed, a meta refresh appeared.
- Certificate expiring: the final site's TLS certificate ends within 14 days.
Result page and manage link
Every watch has a page at b59.link/w/<slug>: one line per link with its state, final address and hops, the full redirect chain on a click, and a 30-day strip. It works without JavaScript. Unlisted (the default) means anyone with the address can open it; public pages can be found by search engines; private pages open only with the manage link.
The manage link (?manage=<token>) is shown once, when the watch is made. We keep only a hash of the token, so a lost manage link can't be sent again. Over the API, send the token in the X-Manage-Token header.
Email alerts
Give an address when you start the watch, or add one from the manage link. We send a 6-digit code; until it is entered, that code is the only email the address gets. After that you get at most one email a day per watch, and only when a link's state changes. Every alert has a link to stop them; it opens a page with a button, so a mail filter opening the link changes nothing. A watch with a confirmed address doesn't expire.
API
| Call | What | Needs |
|---|---|---|
| POST /api/watch | {links: [{url, label?}], email?, visibility?} → slug, page_url, manage_url, manage_token and the first check's results | none (a session key ties it to your account) |
| GET /api/watch/<slug> | every link's state, what changed since its first check, the last chain and the last 30 days | none for unlisted and public watches; the manage token for private ones |
| POST /api/watch/<slug>/check | check every link now | manage token or the owner's session key; once an hour |
| PATCH /api/watch/<slug> | {add?, remove?, labels?, email?, visibility?, paused?} | manage token or the owner's session key |
| DELETE /api/watch/<slug> | the watch and all its history | manage token or the owner's session key |
| POST /api/watch/<slug>/email | {} emails a 6-digit code to the watch's address; {code} confirms it | manage token or the owner's session key |
curl -X POST https://b59.link/api/watch -H "Content-Type: application/json" \
-d '{"links": [{"url": "https://qrco.de/abc123", "label": "menu table card"}], "email": "you@example.com"}'
curl https://b59.link/api/watch/<slug>Errors are plain JSON: {"error": "...", "limit": 25}. Limits that pass with time answer 429 with Retry-After; requests that have to change answer 400. The full schema is at /api-docs.
MCP
On https://b59.link/api/mcp (no key needed): watch_printed_links {links: [{url, label?}], email?} starts a watch and returns the first results and the result page to hand to the person; get_watch_report {slug} reads it back. Check now is not an MCP tool. Setup for each client is on the MCP page.
Limits
| Links in one watch | 25 |
| New watches without a confirmed email or account | 2 a day from one connection (429 with Retry-After until midnight UTC) |
| With a confirmed email or an account | 3 watches and 100 links in all |
| Checks | once a day per link, at its own time of day; a link that failed is checked again 6 hours later |
| Check now | once an hour per watch, API only (not an MCP tool) |
| Watch without an email or account | ends 30 days after its manage link was last opened |
| Confirm codes | 15 minutes each, 5 tries, 3 codes per 15 minutes per address |
| Alert emails | at most one a day per watch, only when a link's state changes |
| Check history | 90 days |
| Requests | 10 a minute per connection on POST /api/watch and the MCP tool calls |
Free for everyone. If the watch gets more use than we planned for, new watches may be refused for a while; watches that already run keep running.
How the links are checked
From our server, once a day per link, at most one request every 2 seconds to any one site, up to 10 redirects, public addresses only, reading only the first 32 KB of the final page. The user agent is Mozilla/5.0 (compatible; b59.link printed-link watch; +https://b59.link/tools/printed-link-watch). If you run a site we check and want us to stop, write to us.