Change Requests¶
A change request lets someone from the shop or organisation send in an update in their own words, with photos ("we were called out to Kinder Scout on Saturday", "our new volunteer coordinator is Sam", "the summer fair is on 14 June"), and get back a draft page or blog post to check. Nothing is published until a signed-in admin approves it.
It's built for teams that have news to share but no time to build pages: a mountain rescue team, a charity shop, a law firm. The request works from a phone, which is how most of them are sent.
Switching it on¶
Change requests are off by default. Switch them on in Settings → Store → Change requests
(change-requests-enabled).
They need AI image tagging (ai-image-tagging-enabled, under the AI settings) to be on as well:
the description of each photo is what decides where it goes in the draft. Settings refuses to switch
change requests on while tagging is off (switch both on in one save), and refuses to switch tagging
off while change requests are on. If tagging is switched off some other way, the screens stay
readable but say why a new request or reply can't be sent.
| Key | Default | What it does |
|---|---|---|
change-requests-enabled |
false |
Shows Content → Change requests and lets admins send requests. |
change-request-default-blog |
blank | The blog (its address name, for example news) a news post goes in when the request doesn't say which. |
change-request-model |
anthropic:claude-sonnet-5-5 |
The AI model that writes drafts, as provider:model. Set by Badger; not shown to shop admins. |
change-request-monthly-limit |
0 (no limit) |
How many drafts can be written in a calendar month. Set by Badger; not shown to shop admins. |
Change request settings are tied to the site: a site import never switches them on elsewhere.
Who can use it¶
Anyone with the Content editor, Admin or Superadmin role. The same person can send a request and later approve the draft (small organisations often have one admin).
Sending a request¶
Content → Change requests → New change request (/admin/change-requests/new), or New change
request from the command palette.
- Write what you want changed or added, the way you'd tell a colleague: what happened or what's coming up, who was involved, and anything people should do.
- Add up to 10 photos: JPEG, PNG, GIF or WebP, up to 10 MB each. Each file is checked by its content, not its name, and the whole request is refused (nothing is stored) if any file can't be accepted.
- The text and photos are sent together. Photos are stored in the media library under the
change-requests/<request id>folder and taggedchange-request, so they can be found and reused later; their titles and alt text are left blank for tagging to fill.
Each request gets a number per site, shown as CR-1, CR-2 and so on.
Photos are described as content¶
AI image tagging normally describes a photo as a product (type, colour, material). Photos sent with a change request are marked as content, so tagging describes the scene instead: the setting, what is happening, notable objects, and how many people are in it, with alt text written for an article. It never identifies anyone or guesses personal traits such as age.
Following a request¶
The list (/admin/change-requests) has three tabs:
| Tab | Shows |
|---|---|
| Open | Everything not finished yet, including requests ready for review |
| Ready for review | Drafts waiting for someone to approve, ask for changes or reject |
| Done | Published, rejected, failed and cancelled requests |
A request's page shows the conversation on the left, with each photo's thumbnail and what tagging made of it, and its progress on the right: Submitted → Preparing → Writing → Ready → Published. While the request is open the page checks for changes every few seconds and refreshes itself (unless you're part-way through typing a reply).
| Status | Meaning |
|---|---|
| Queued | Received, waiting to be worked on |
| Preparing | Waiting for the photos to be described |
| Writing | The draft is being written |
| Ready for review | A draft is ready to check |
| Revising | The draft is being rewritten after a request for changes |
| Published | Approved and live |
| Failed | No draft could be written; Try again queues it again |
| Rejected, Cancelled | Finished without publishing |
Replying¶
Add to this request adds more detail, a correction or more photos to an open request. A reply needs some text or at least one photo. A reply sent while a draft is being written is still acted on: once that draft is ready, the request goes straight on to Revising and the draft is written again with the reply.
Cancelling¶
Cancel request stops an open request. Its draft page is deleted if it hasn't been published, and its photos stay in the media library. A request cancelled while its draft is being written is dropped when the writer finishes, and the draft it wrote is deleted.
How a request is worked on¶
Requests are worked on in the background, a few seconds after they're sent:
- Preparing. The writer waits for every photo to be described by image tagging, for at most two minutes; a photo still undescribed after that is used without its description.
- Writing. One call to the AI model writes the draft (usually under a minute), and Badger checks it and saves it as a draft page.
- Ready for review. The draft writer adds a message to the conversation with what the draft does and any questions it has (a detail the request didn't give, for example), and the request takes the draft's title.
A draft that can't be written (the model's answer can't be used, or the provider is busy) is tried once more. After two failed tries, or straight away when the model declines the request or the site has no AI model or key set up, the request is Failed with a message saying why. Once that's put right, Try again on the request's page queues it to be written again with the same text and photos, so nothing needs sending twice. Tries that never reached a model don't count towards the monthly limit; the others do.
When it's a revision that can't be written (or the monthly limit stops it), the request isn't failed: it goes back to Ready for review with the previous version of the draft unchanged and a message saying why, so it can still be approved, rejected or revised again.
Reviewing a draft¶
When a draft is ready, the request's page shows it above the conversation:
- the summary of what the draft does, and the writer's questions;
- a live preview of the draft page, exactly as it will look once published, with Open in new tab and Copy link (the same preview link the page editor gives: anyone with it can see the draft for 14 days, and it stays the same through every revision);
- the actions.
| Action | What happens |
|---|---|
| Approve and publish | The page goes live now. Its published date is the approval time, and the approver is recorded on the page and the request. |
| Request changes | Say what to change, with more photos if needed. The request goes to Revising and the same draft page is rewritten, keeping everything you didn't ask to change. |
| Reject | The draft page is deleted and nothing is published. The photos stay in the media library. |
| Go back (under Versions) | Rewrites the draft from an earlier version, which becomes the newest version. |
The draft is an ordinary draft page, so it can also be edited by hand in the page editor. The review panel warns when that has happened: asking for changes or going back to another version rewrites the blocks the writer made, so hand edits to those blocks may be lost (blocks added by hand are kept).
Only a draft that is ready for review can be approved, rejected or rewritten, and a page that has been published is never rewritten or deleted.
Limits¶
- A site has at most three requests being written at once; others wait their turn.
change-request-monthly-limitcaps the drafts written in a calendar month, counted in the shop's time zone; every call to the model counts, including retries and revisions. When the limit is reached, a request that would need a first draft is Failed with a message saying the monthly limit was reached (a revision keeps its previous draft for review instead).0means no limit.- Superadmins see the month's count against the limit on each request's page.
How a draft is built¶
The AI model never writes to the site. It reads the request (its messages, and each photo with the description tagging wrote) and answers with structured content: one of three page recipes, a title and a short list of blocks. Badger checks that answer and builds the draft page from it.
Photos from the media library¶
Alongside the request's own photos, the writer is offered up to 12 photos already in the site's media library that match the words of the request ("burger", "grill", "Shoreditch"): those whose title, description, alt text or tags contain the most of them. Only photos image tagging has described are offered, only from this site, and only their descriptions are sent, never the photos themselves, so the request costs barely more. The writer uses the request's own photos first and a library photo only when the request asks for one or has no photo that fits, and the draft's summary says which library photo it used. On a revision the writer may keep a library photo the previous draft used.
| Recipe | Page | Top of the page | Body | Call to action |
|---|---|---|---|---|
| News post | A post in one of the site's blogs | The blog masthead, with the lead photo, the title, the excerpt and the byline | The blocks in order, then related posts | A panel in the right-hand column |
| Profile page | A page about one person | A hero with their photo beside their name and role | The blocks in order | A strip at the end of the body |
| Event page | A page about one event | A centered hero with the date, the title and a booking button, the lead photo behind | The blocks in order | A full-width band under the page |
| Block | Becomes |
|---|---|
| Prose | Markdown text; consecutive prose is one block. Long-form writing only. |
| Quote | A quotation with the speaker's name and role |
| Photos | One photo, two or three side by side, or a carousel for four or more, with the alt text image tagging wrote and an optional caption |
| Key facts | A row of icon, heading and line (date, time, place) |
| Questions | An FAQ block |
| Call to action | A heading, a line and a button, placed as the recipe says |
Before anything is written, Badger refuses an answer that:
- uses a photo that wasn't sent with this request or offered from the library;
- posts to a blog the site doesn't have (it falls back to
change-request-default-blogfirst); - links a button anywhere but a page (
/p/...) or collection (/collection/...) on this site; - uses an icon the page builder doesn't draw, or a question without its answer;
- is longer than the layout allows (title 120 characters, search description 160, excerpt 300, prose 20,000, at most 12 photos, facts or questions in one block).
Prose is cleaned before it is stored: HTML is removed, links other than web, email and site links lose their link (keeping their text), and an image other than one of the request's photos (or the library photos offered) is reduced to its description. Question and answer text is shown as plain text.
The draft is saved as an unpublished draft page with a unique address (a
taken address gets -2, -3 and so on). When the reviewer asks for changes, the same draft page is
rewritten, so its preview link stays the same: only the blocks the writer added are replaced, and
anything someone added to the draft by hand is kept. A draft that has been published is never
rewritten.
Models¶
Drafts are written by one call to the model set in change-request-model, as provider:model.
Anthropic (Claude) and OpenAI models can both be used, so models can be compared on the same
requests; each call uses the site's own key for that provider, or the platform's. The site's rules
and details are sent first so the provider can cache them across a site's requests. With Claude,
a request a safety check declines is retried on Anthropic's recommended fallback model, and the
model that actually answered is recorded.
Each call's tokens are recorded (new input, cached input, cache writes and output) with a cost from Badger's price list. A model with no listed price records no cost rather than a guess.
Models are compared on a fixed set of real-style requests before the default changes: see Comparing change request models.
Each attempt also records when it started and finished and, when it failed, a short reason code
(for example invalid_json, refusal, or the problems Badger found, such as
MEDIA_FOREIGN@leadMediaId): never the model's text.
Safety and privacy¶
- Nothing goes live without a person. The model only ever returns structured content; Badger checks it and saves an unpublished draft. Publishing needs a signed-in admin to approve it.
- The request is treated as data. What staff write is passed to the model as the request to work from, not as instructions, so a request can at worst produce odd draft text, which the reviewer sees before anything is published.
- No request text in logs. The request text, photo descriptions and drafts are stored with the request and shown to the shop's admins. Logs carry only request ids, numbers, statuses, token counts and reason codes.
- Deleted with the site. Deleting a site deletes its change requests, along with its pages and media.
- Not exported. Change requests aren't included in a site export, and a draft page that is exported arrives on the other site without its link to the request.