Free AI for my Chrome extension's users, with no API key and no surprise bill A developer behind the Groupify Chrome tab organizer built a Cloudflare Worker that gives extension users AI-powered tab grouping without requiring an API key, running on Workers AI's free daily allocation so requests simply fail rather than bill once the quota is exhausted. The Worker identifies the extension via CORS, caps requests per IP per minute, sends only tab titles and site names (never full URLs), and stores no data, while the extension tries on-device AI first, then the cloud, then date-based naming. The developer also implemented a 15-second "ownChangesUntil" window so the extension's automatic sorting never overrides groups users created by hand. TL;DR I wanted my tab extension to name and sort tab groups with AI. Chrome's built-in AI isn't on most computers, and nobody wants to paste an API key into a tab tool. So I put a tiny Worker on Cloudflare in between, running on the free Workers AI allocation: when it runs out it simply stops, and nothing is billed. Users without on-device AI flip one switch in Settings and get AI names. Groupify is my Chrome tab organizer. When I start a new project I usually have Pinterest, the Next.js docs, Cloudflare and Vercel open at once, and grouping by website just splits them apart. What I wanted was one click to put those tabs in one group, with a sensible name such as “Website deploy”. That needs AI. The question was which AI. I wanted a free allocation that stops when it's used up, like the Azure speech free tier I use in another extension. Workers AI gives every account a free daily allocation. On the Workers Free plan, requests past it fail instead of being charged, so the most it can ever cost me is nothing. I only needed a tiny Worker in the middle that does three things: recognise my extension, limit how much each person can use, and turn the tabs into a prompt. One endpoint names a set of tabs; the other sorts a pile of tabs into groups by task. The Worker stores nothing and logs nothing, so it never remembers what anyone sent. The extension sends each tab's title and site name, never the full address, because addresses often carry tokens or private parameters. At most 40 tabs go in one request, and long titles are cut short. The Worker answers only my extension's origins the store build and my development build through CORS. That means the extension needs no new permission, so users see no new warning when it updates. An origin can be faked, so there's also a per-IP limit per minute on top of the free allocation's hard cap. The worst case is a day without AI. Most of my users read Traditional Chinese, so I picked a cheap open model that handles Chinese well and told it to skip its thinking output to save allocation. Naming a group uses very little, and at my current number of users the free allocation goes a long way. Cloud AI is a switch in Settings, off by default, with a line saying tab titles and site names go to my server and nothing is kept. The extension always tries on-device AI first, then the cloud, then names by date, so whichever step fails, users never see an error. Once Groupify could sort tabs automatically, I hit a problem: automatic sorting must not pull apart groups I made by hand. If I put my own blog's tabs in a group called “Me”, sorting by purpose shouldn't move them into “Reading”. But Chrome doesn't record who changed a tab or a group, only how things are now. So the extension has to tell for itself. Before it changes any group, it writes down “the next few seconds of changes are mine”. A background worker listens to Chrome's tab and group events, and treats anything outside that window as the user's decision, including dragging tabs and renaming groups in Chrome's own tab bar. // The extension's own changes are wrapped, so they never count as the user's async function asExtension