Skip to main content
Every change that ships gets a receipt. It is the proof of one change: what was changed, where, when, what AI answers said before it, the checks that read them again afterwards, and what those checks found. You find them on app.attensira.com/receipt under Did each change work?, one row per shipped change. Opening a row opens that change’s receipt as its own page, with a back button, at any screen width.

What a receipt shows

In this order:
  1. The change and where it is. Its title, its stage (Live, Shipping, Undone and so on), the day it shipped, and the page it lives on.
  2. Questions, engines and market. The tracked questions the change was meant to move, and the AI engines the checks read. A question you have stopped tracking is shown as such. When your workspace reads more than one market, the receipt also names the market the checks read and why, for example “The page lives under /de/, so only answers in DE count.” See which market a change is measured in.
  3. Before. A verbatim excerpt of a stored answer from before the change, with its engine and date, and whether it names you.
  4. What changed. A summary of the edit, the old and new text when the change wrote a field (shortened when long), and a link to the pull request when it shipped as one.
  5. Checks. One row per check at +7, +14 and +30 days, each with a verdict, or Checking and the date it will be read.
  6. Verdict. The change’s current verdict and the sentence behind it, with the counts it rests on.
  7. After. Once a check has decided, a verbatim excerpt of an answer from the week that check measured, from the same question and engine as the excerpt before.
For the first 30 days most receipts are waiting on checks. That is the normal view: the timeline with the next check date (“Next check Oct 23”), never an empty page.

The checks

A check is a re-measure of the change’s questions: a week of answers before the change against a week of answers around the check date. Checks are booked when the change goes live, read about 4 days after their date once the measured week is over, and decided by a significance test. Before and after explains the windows, the live-page test and what happens when a check cannot be read. The check timeline always lists +7, +14 and +30. A check that was never booked (the change is not live yet) says so; one that was called off (the change was stopped or undone) says that instead, and neither is a verdict.

The verdicts

The rules behind them:
  • Inside the noise is not a change. A difference the test cannot separate from sampling noise is Too close to call, however large it looks. It is never shown as Moved, never in green, and never announced.
  • The latest check decides. The verdict comes from the latest check that reached one, +30 over +14 over +7, because a later check has more answers behind it. A change that read Moved at +7 and Too close to call at +14 reads Too close to call.
  • An early look never decides. A check earlier than +7 can show on the timeline; it never sets the verdict.
  • Every number carries its sample. Counts read “named in 3 of 10 answers”, never a percentage on its own.
  • Moved is observed, not proven cause. The answers moved after the change shipped; other things can move them too, and the receipt says so.
The receipt, the analytics glance and the question page read the same checks, so they cannot disagree about whether a change moved or fell. One difference: when a check finds the change missing from the live page and a later check is still booked, the receipt shows Not live on your site, because that needs you, while the glance still counts the change as too early to call.

Engine-wide changes

An AI engine can change how it answers for everyone at once: a new model, a new search index. A change measured across that week could read as Moved or Fewer mentions when the change had nothing to do with it. To catch that, Attensira keeps a control panel: a few of our own workspaces, one per category, whose tracked questions no change ever touches. They are read on the normal daily schedule like any workspace. Once a day we compare the panel’s last week with the week before, on each engine, the same way a check compares a change’s weeks. A fortnight is flagged as an engine-wide change on an engine when all of these hold:
  • each week has at least 30 successful panel answers on that engine;
  • the difference passes the same significance test a check uses;
  • the panel’s named rate moved by at least 10 points, up or down;
  • most of the panel’s workspaces moved the same way, so one category’s own news is not taken for the engine.
A receipt whose deciding check compared days inside a flagged fortnight, on an engine the check read, says so:
  • engine_shift is set to {engines, from, to, sentence}: the engines the panel moved on, the flagged days (UTC), and the flag in words. It is null on every other receipt.
  • The verdict reason leads with that sentence, for example “Engine-wide change: the answers to our own control questions, which no change touches, shifted on ChatGPT between 1 September 2026 and 14 September 2026, inside the days this check compared. This verdict cannot be told apart from that, so it is not counted for this change.”
  • The verdict itself is still what the checks measured. A receipt still being checked is never flagged.
  • The change is left out of the playbook win rates and of the model agents use to choose playbooks.
The flag is a field on the receipt and its list row. There is no separate list of engine-wide changes over the API or MCP.

Is it still live?

A change whose verdict is Moved, or that a win sits after, is read again every week to check the shipped text is still on its page (see Keeping changes live). The receipt shows that read: live_status (live or no_longer_live, null before the first weekly read), last_live_check_at, and live_check with the page, whether the text was found, the sentence behind it and, when it was not, the re-ship change filed to put it back. The verdict is not rewritten by it: what the answers did after the change shipped stays what they did. A page we could not read never sets no_longer_live.

A review request’s receipt

A review request asks your customers for reviews rather than changing a page, so its receipt carries reviews on the receipt and its list row (absent on every other change):
  • platform and profile_url: the platform and the profile we read once a week.
  • sent_at: when you marked it sent, null before. The receipt counts from that day.
  • baseline: the last measured read on or before the day you marked it sent, or the first measured read after it when none came before. latest: the newest read, measured or not. Each read has read_at, status (measured or not_measurable), reason when it was not measurable, and review_count, average_rating, best_rating and last_review_at as the profile states them.
  • reviews_since and rating_change: the newest measured read minus the baseline, null until both are measured.
  • sentence: the same in words, for example “Reviews on G2: 11 on 8 October 2026, 19 on 29 October 2026 (+8 since it was sent on 8 October 2026).” When the newest read was not measurable, the sentence says why.
A profile we could not read is not_measurable, never zero reviews. A review request has no tracked question behind it, so it has no verdict from the checks: the review count is its receipt.

The receipt_verified event

When a change’s verdict becomes Moved, Attensira records one receipt_verified event for it. It is recorded once in the change’s life: a later check that agrees, or a check that is read again, does not record it a second time. A verdict of Too close to call, Fewer mentions, Not enough answers yet or an early look never records it. Like claim_wrong, it is not one of the events you can pick for an automation yet, in the dashboard, over MCP or over REST, so only an automation saved with an empty event list acts on it. As a webhook, it is sent as receipt.verified.

Crawled: hosted answer pages

When a change publishes a hosted answer page, we serve that page ourselves, so we can see which AI crawlers read it. Every request a known crawler’s user agent makes to a hosted site is logged with the page, the time, the status it got and the crawler it claims to be. A user agent is a claim anybody can make, so a fetch counts as crawled only when it is verified:
  • By published address. The request came from an address the crawler’s operator publishes for it: OpenAI (GPTBot, OAI-SearchBot, ChatGPT-User), Anthropic, Perplexity, Google and Bing each publish such a list. We re-read the lists every day; if one cannot be read, the last list we read is kept.
  • By reverse DNS. For Google and Bing, which document it, the address’s reverse name is theirs and resolves back to the same address.
A fetch that claims to be a crawler but passes neither check is kept, so a forgery can be seen, but it never counts. Requests from browsers and other visitors are not logged at all. The first verified read of the page by OpenAI, Anthropic, Perplexity or Google after the change went live records one change_crawled event for the change, once in its life. It carries the page’s address, the crawler, its operator, how it was verified and when. A read of robots.txt, sitemap.xml, llms.txt or the site’s index is not a read of the page, and a page that answered anything but 200 was not read. Bing is verified and logged but does not record change_crawled. Like receipt_verified, it is not one of the events you can pick for an automation yet, so only an automation saved with an empty event list acts on it.

Over the API and MCP

Over REST, GET /v1/receipts lists the receipts and GET /v1/receipts/{id} returns one, each with engine_shift and with target_market when the workspace reads more than one market; see the endpoint reference. The id is the change’s id. Over MCP a receipt is the receipt object type: get with attensira://{workspace}/receipt/{id}, or list with type receipt. Neither verb is listed to MCP clients yet; until it is, no listed MCP tool reads a receipt. Every receipt read is free and works when your balance is spent.