Jul 28, 2026
An experiment to unlock better agentic commerce for theatres
WHAT WE FOUND
- AI found it in 50 minutes, with no announcement. ClaudeBot's first IP-verified fetch landed 50 minutes after the site went live, Bingbot at an hour, Googlebot at ninety minutes. The first organic answer-time fetch, someone asking ChatGPT a question that sent it here, arrived at 29.7 hours.
- It read almost all of it. Across 49 days, OpenAI, Anthropic and Perplexity agents fetched 269,421 distinct URLs, 81% of every address the site ever served successfully. Counting AI crawlers whose identity cannot be verified takes it to 96%.
- 430,113 AI requests, 45.9% of all traffic. More than conventional search crawlers, SEO tools and human visitors combined. OpenAI alone sent 255,298.
- Demand is event-driven. Answer-time fetches grew 20x in seven weeks, from roughly 50 a day to 2,099, with no promotion of any kind. One film release drove it: 82% of every seat map ChatGPT fetched, across the whole window, was for The Odyssey.
- It went straight for the deep pages. 54% of ChatGPT's fetches were the seat map for one specific screening: the data that was hardest to reach before and that isn't easily accessible to AI.
- Being read is not being visited, and search is no better. 17,270 answer-time fetches produced 48 human arrivals. Only 263 of the 5,208 hits carrying a Google referrer survive scrutiny; 87% are a scraper forging one. A site machines read 430,113 times, people visited roughly three hundred times.
- Format follows function. Half of GPTBot's fetches took the Markdown twin.
ChatGPT-User, same company, used it on 0.1% of requests. Googlebot has never fetched one.
Scope
One site, 49 days, 936,487 requests, read from CloudFront access logs we owned end to end. Every vendor claim below is checked against that vendor's published IP ranges before it is counted. This is the second experiment in a series: the first, the Calgary Stampede edition, ran for ten days on an event catalogue. This one runs seven weeks on a national dataset that updates continuously.
What it is not: a claim about the whole web, or a citation study. We measured what AI fetched, not what it said afterwards. Our companion report covers the same questions across twenty live customer knowledge bases.
What we opened up
Agentic commerce depends on a step that gets far less attention than the transaction itself: discovery. Before an assistant can help anyone buy anything, it has to find a catalogue it can read and match what is in that catalogue against what the person actually wants. Checkout plumbing does not help if the assistant cannot tell what is available in the first place.
That is where most of it breaks today. Catalogue data is built for a human with a browser: rendered by JavaScript, hidden behind filters, revealed one item at a time by a widget designed for a mouse. It is public in the sense that anyone can look at it, and unreadable in the sense that matters here. Almost none of it was written with AI as the audience, because until recently there was no reason to.
Going to the movies is a clean instance of the problem. If you want to know which seats are still free for a film tonight in Calgary, that information exists, inside Cineplex's booking flow, rendered by JavaScript, one screening at a time, behind a seat-picker built for a human with a mouse. It is public in the sense that anyone can look at it. It is not public in the sense that a machine can read it.
In June we changed that. opentheatreseats.com publishes Cineplex showtimes and point-in-time seat availability for theatres across Canada as flat, structured, addressable pages: one URL per theatre, per date, per screening, each with the seat map written out in a form an assistant can read in a single fetch.
The question is blunt: unlock a catalogue AI cannot reach today, and what does it do with it? Does anything come for it, how quickly, and which parts does it actually want?
| What it is | A catalogue of Canadian cinema showtimes and live seat availability, roughly 24,700 pages at any moment, one entity per page. |
| The hard part | Seat-level availability. Which specific seats are free for a specific screening, the thing that previously existed only inside a booking widget. |
| Every page, three ways | Human HTML, a plain-Markdown twin at the same path (/theatres/7130/2026-06-13.md), and schema.org JSON-LD. |
| Freshness | A full rebuild daily; near-term seat availability re-pulled every 15 minutes for today and tomorrow. |
| Discovery | Sharded sitemaps, llms.txt, and a tiered robots.txt that names the discovery, fetch and training crawlers separately. |
| Infrastructure | Static S3 behind CloudFront, no WAF and no bot challenge. A challenge silently breaks ChatGPT-User and Claude-User, which would have destroyed the measurement. |
Table 1. The published artefact. Because dated pages turn over with the calendar, the site served 331,486 distinct URLs across the 49 days, far more than exist at any one moment. A further 26,500 addresses were requested and never existed, most of them expired dates.
How we measured it
We host the site ourselves, so every request an AI system made landed in a log we control. No sampling, no analytics script, no third-party tag: 936,487 rows, parsed in full.
The discipline that makes the rest of the numbers worth reading is IP verification. A user-agent string is a claim, not a credential, and anyone can send any string they like. So for every vendor that publishes its ranges (OpenAI, Google, Perplexity, Anthropic), we resolved each request's source IP against the published list and counted the request only if it matched.1
The strings are forged in practice, not just in theory: ten IP addresses generated 479 requests here while each claiming four to eight different AI vendors, using the disguise to probe for /.env, /.git/config and /service-account.json. Nothing was exposed — the site is static behind Origin Access Control — but verification is what keeps that traffic out of the counts.
It cuts both ways. Verification clears agents that look suspicious: Googlebot resolves at 99.9% once checked against Google's current prefix list, which has moved and is easy to fetch stale. It also removes agents that look genuine: the earliest request presenting itself as GPTBot is an impostor, and the first verified one arrives a day and a half later, which changes the discovery timeline in the next chapter.
Vendors that publish no ranges at all (Bing, Apple, Amazon, Meta, Yandex, and the SEO crawlers) are reported by user-agent only and labelled as such throughout. Everything else in this report is checked against a prefix list fetched from the vendor at analysis time.
| Function | What it means | Requests |
|---|---|---|
| Training | Bulk corpus collection, unrelated to any query | 403,346 |
| Indexing | Building the index an assistant later cites from | 9,497 |
| Live retrieval | A person just asked something; fetching to answer | 17,270 |
| Search | Conventional search engine crawlers | 263,196 |
| SEO tools | Backlink and rank crawlers | 128,926 |
| Human | Browsers (see methodology, over-counted) | 94,231 |
Table 2. Every request sorted by what the agent was doing, not who made it. Grouping by function rather than by vendor is what makes the logs legible: the same company operates bots in three different rows.
First contact: 50 minutes
The site went live at 19:55 UTC on 10 June with no announcement, no inbound links, and no submission to anything. We pinged IndexNow and published a sitemap. That was the entire go-to-market.
Fifty minutes later ClaudeBot made the first IP-verified fetch. Bingbot arrived at one hour, Googlebot at ninety minutes. Inside two hours, three separate crawlers had found a site nobody had been told about.
Answer-time demand took a day longer. The first organic ChatGPT-User request, someone asking ChatGPT a question that sent it to this site, landed at 29.7 hours. OpenAI's training and indexing crawlers followed at 38.8 hours.
Figure 1. Vendors without published IP ranges are marked; their times are user-agent claims. Fetches our own testing triggered on launch night are excluded, so each agent is dated from its first organic request.
The ordering is the interesting part. Search and AI crawlers found the site within the hour; retrieval followed at just over a day; the training crawlers arrived last, GPTBot at 38.8 hours and Meta's nine and a half days. If you assume a page becomes answerable only after it has been absorbed into a training corpus, this is backwards. Retrieval got there first, because retrieval follows the search index, and the search index followed the sitemap within the hour.
A page can be answering someone's question a day after it exists, and still be waiting to enter a training set the day after that.
For anyone publishing structured data and wondering how long the feedback loop is: it is much shorter than the discourse suggests. You do not need to wait for a model to be retrained to be useful to one.
The funnel, and where it inverts
Sorting AI requests by function produces a funnel with a very steep top and a nearly flat bottom.
Figure 2. Every tier is IP-verified where the vendor publishes ranges. The bottom tier counts humans who arrived from an AI surface, measured by referrer.
Two things stand out. First the obvious one: the drop from 403,346 training fetches to 48 human arrivals is four orders of magnitude. Being read at enormous volume and being visited are unrelated quantities.
The second is easy to miss. Live retrieval is larger than AI indexing, 17,270 against 9,497. At the Stampede the tiers ran in the expected order, with indexing comfortably ahead of live fetching. Here they inverted, and we think the dataset explains why: an index built last week cannot answer a question about tonight's seats, so the assistant has to come back and look. Data that changes converts indexing demand into retrieval demand. If your content is genuinely live, you should expect more of the traffic that happens while a customer is waiting, and less of the traffic that happens on a crawler's schedule.
Who actually read it
Fourteen distinct bot families fetched the catalogue. Here is the full roster, with verification status attached to every claim.
| Agent | Function | Requests | Verified | Success |
|---|---|---|---|---|
| GPTBot | training | 231,114 | 100.0% | 99% |
| Googlebot | search | 96,804 | 99.9% | 23% |
| SemrushBot | SEO tool | 94,959 | — | 25% |
| YandexBot | search | 68,320 | — | 96% |
| Bingbot | search | 64,818 | — | 29% |
| meta-externalagent | training | 64,540 | — | 79% |
| ClaudeBot | training | 53,889 | 99.8% | 98% |
| Amazonbot | training | 53,627 | — | 62% |
| Applebot | search | 32,764 | — | 14% |
| ChatGPT-User | live retrieval | 17,027 | 98.4% | 77% |
| OAI-SearchBot | indexing | 7,157 | 99.0% | 80% |
| PerplexityBot | indexing | 2,329 | 96.8% | 92% |
| Claude-User | live retrieval | 162 | 59.3% | 71% |
| Perplexity-User | live retrieval | 13 | 23.1% | 23% |
Table 3. Every agent that fetched more than a handful of pages. A dash means the vendor publishes no IP ranges, so the identity is a user-agent claim only. Success is the share of that agent's requests returning 200.
OpenAI is the single largest consumer of this dataset at 255,298 requests across its three bots, more than Google, Bing and every human visitor combined. Anthropic is second among AI vendors at 54,067, almost entirely training. The spread of the success column is a story in itself, and chapter 10 is about that.
Claude-User deserves its own note, because it is the only agent that splits across two kinds of address. 59.3% of its requests come from Anthropic's own published range; the rest arrive from residential consumer IPs on Canadian and European ISPs. Both are legitimate — Claude in Chrome and Claude Desktop fetch from the user's own machine, so the request carries their address rather than a vendor's — which makes it the one agent where a low verification rate is not evidence of anything wrong. 59 of its 162 requests carried a claude-code CLI string across 15 different versions, developers pointing an agent at the site. Its page mix reflects that: it spent its time on /about/ and robots.txt, reading how the catalogue was built rather than what was playing.
Give AI what it wants, and it shows up
The experiment was built on a specific bet. Extracting seat-level availability was by far the hardest part of the build, and we did it because we believed that single fact was what AI actually needed: not a listing of what is on, but whether you can still get two seats together at 7:40 tonight. That is also the question a person asks before they decide to go.
The logs settle it. AI went straight to the bottom of the tree. For ChatGPT-User, 54% of all fetches were the seat map for one specific screening, and 73% targeted a specific theatre on a specific date. The pattern holds for the indexing crawlers too: 55% of OAI-SearchBot's fetches and 50% of PerplexityBot's were seat maps.
Figure 3. Every live-retrieval and AI-indexing request, 26,675 in total. Ribbon width is request volume. The right column is the outcome, and the failures are not spread evenly.
The navigational pages barely registered. The theatre directory, the now-playing list and the regional indexes took 4.3% of ChatGPT's fetches between them; the deep pages took seventeen times that.
The right-hand column of that figure is worth holding onto. Failure is not spread evenly across the site: the home page, the about page and the discovery files never failed once, while 27% of seat-map requests found nothing. The pages AI wanted most were the pages most likely to be gone, and chapter 10 is about why.
This is the finding with the most carry-over to anyone else publishing a knowledge base. The thing that was hardest to extract was the thing AI wanted most. The seat map was the least available anywhere else, and it drew more traffic than every navigational page on the site combined, several times over. Organising the catalogue did almost nothing; getting one hard fact into a readable form did everything.
Demand is also concentrated tightly. Of 13,479 ChatGPT requests aimed at a specific cinema, 34.9% went to one theatre, Cineplex Mississauga Square One, and 51.7% to just two. A national catalogue was consumed like a local one, which suggests depth in the busiest venues is worth more than coverage of the long tail.
The shape of a buying question
Everything so far describes what AI read. The paths describe what the person on the other end was trying to do, and three patterns point the same way: this looks like commerce, not research.
The question is almost always about tonight.
Every dated request carries a horizon: the gap between the day it was made and the day it asks about. A quarter are for today, another fifth for tomorrow, a sixth for the day after. Two thirds fall inside the three-day window the site publishes, and almost everything beyond it is a stale-index artefact rather than someone planning ahead.
Figure 4. ChatGPT-User requests for a dated page, by the gap between the request and the showtime it asks about. Gold is inside the published window, red is a date already past.
Nobody asks an assistant what is on at the cinema in three weeks. They ask what they can see in the next few hours, the moment a listing stops being reference material and becomes a purchase decision. That window is the one that matters, and it is unforgivingly short.
Demand went deeper, not wider.
Chapter 8 covers the twentyfold rise in answer-time traffic from 14 July. The paths show what changed underneath it, and it is not coverage. ChatGPT had already found essentially the whole catalogue before the inflection and barely added to it afterwards. What changed is how far into each theatre it went.
| Live retrieval | Before 14 Jul | After 14 Jul | Change |
|---|---|---|---|
| Requests per day | 62 | 998 | 16.1x |
| Distinct seat maps fetched | 298 | 1,710 | 5.7x |
| Distinct theatres reached | 84 | 87 | 1.04x |
Table 4. The inflection was a change in depth, not coverage. Only four theatres appear after 14 July that had not been reached before.
The catalogue was fully discovered within weeks, then sat lightly used until something on OpenAI's side started reaching into it. That is an uncomfortable finding for anyone planning to publish broadly and wait: breadth got us discovered, depth got us used.
A few URLs become the answer, and they outlive the showtime.
Seat-map demand follows a hard power law: 8.4% of the URLs ever fetched carry 64% of all seat-map traffic. A small set of screenings becomes, in effect, the answer to a recurring question.
The obvious explanation is a single client polling one screening for availability. It is not that. The median popular URL is fetched by 25 distinct IP addresses, with a 100% unique-IP share: essentially every request comes from a different address. The most-fetched single seat map drew 231 requests from 190 distinct IPs across 40 network blocks over twelve days. These are separate conversations landing on the same page.
Which is exactly why the next number matters. 29% of the fetches to those popular URLs arrive after the screening has already happened, and 26% return nothing at all. The association ChatGPT forms with a specific URL is durable, and it outlives the event the URL describes.
From the crawler's side, expiry is housekeeping: wasted budget, a rising 404 rate. From here it is a customer problem. Someone asked where to see a film tonight, the assistant sent them to a page that no longer existed, and nothing in that exchange told either party the answer was stale.
The structural lesson is about where you put the volatile data, not how fast you refresh it. We minted a URL per screening, which means the address itself expires along with the thing it describes. An assistant that has learned to reach for that address has learned something with a shelf life of hours.
Put perishable data on permanent addresses. A URL that always resolves and changes what it says can be cited indefinitely; a URL that exists only while its screening does stops existing exactly when an assistant has learned to recommend it.
The theatre-and-date page is the natural anchor here: it always exists for any date in the window, it carries every screening's seat counts, and it degrades into something useful rather than nothing when a specific showing has passed. Per-screening pages are still worth publishing, but they should be the leaf under a durable parent, not the thing AI is taught to cite.
Two smaller patterns, both thinner in evidence. Demand is not skewed toward premium formats: standard rooms took 8,714 fetches against 1,648 for VIP. And language-variant screenings are over-represented, with Spanish-dubbed, Hindi and Teochew-subtitled titles making up four of the ten most-fetched film pages after The Odyssey. The second is suggestive rather than established: film pages are only 648 fetches in total, so the absolute numbers are small.
ChatGPT dominates live retrieval
Of the 17,270 fetches that happened because a person had just asked something, 17,027 were ChatGPT. That is 98.6%, from 1,254 distinct IP addresses, on all 49 days.
Figure 5. Flat through June at roughly 50 a day, then a sustained climb from 14 July to a peak of 2,099 on 27 July, a 20x rise with no promotion of any kind.
Nothing happened on our side on 14 July. We did not launch anything, post anything, or change the site. The explanation is on the demand side, and it is a single film.
The Odyssey opened in the middle of July. Before 14 July it accounts for two of the 77 film-page fetches ChatGPT made. After, it accounts for 348 of 571, and it climbs every week to the end of the window. The seat-map traffic tells the same story far more sharply. Resolving all 9,157 of ChatGPT's seat-map requests back to a title, 82% are for The Odyssey: 7,503 requests for one film's seating, plus 350 more for its film page.
So the inflection is not the catalogue crossing some threshold of confidence in OpenAI's index. It is a tentpole release creating a wave of real questions — what is on, where, and can I still get a seat — at exactly the moment a site existed that could answer the third one. Demand for this data is event-driven.
That reframes the five-week lag. The gap between "AI can read this" and "AI reaches for this" was not five weeks of the model warming up to us; it was five weeks of waiting for a question big enough to ask. Publishing was necessary and nowhere near sufficient, and a team measuring at week two would have concluded the experiment had failed.
Two signatures mark this traffic as genuinely human-driven. It has a daily rhythm, peaking through the Eastern afternoon and falling away before dawn, which is what an audience deciding what to watch looks like. And 61.4% of its bursts are a single page: one question, one lookup, gone. Compare OAI-SearchBot, the same company's index crawler, which arrives in erratic scheduled batches of up to 49 pages with no daily rhythm at all.
Figure 6. Each series normalised to its own daily mean, on separate panels so the shapes can be compared. One follows people; the other follows a scheduler.
HTML or Markdown depends on the job, not the vendor
We published a Markdown twin of every page, on the theory that machines would rather read Markdown than parse HTML. The logs say that is true for exactly half the machines.
Figure 7. Markdown adoption tracks what the bot is for. Training crawlers take it; answer-time fetchers and search engines do not.
Half of everything GPTBot fetched was Markdown, at essentially 100% success. ClaudeBot, 48%. But ChatGPT-User, same company as GPTBot and a different job, used Markdown on 0.1% of its requests, and Googlebot has never fetched a single one in 96,804 visits.
So the split is by function, not by vendor. A crawler ingesting text at volume wants the cheapest clean representation. A fetcher answering a live question takes the canonical URL, which is the HTML. If you are deciding whether Markdown twins are worth building: they are, for training and indexing, and they will do nothing for the fetch that happens while a customer waits. Judging them on live traffic alone would tell you they were a waste.
One more note, on the discovery files. robots.txt was fetched 12,974 times and the sitemap XML 1,082. Every crawler that identified itself respected the Disallow: across 936,487 requests, not one identified AI or search crawler touched /data/ or /state/. The only agents that tried were curl and requests wearing spoofed mobile-browser strings. Whatever else is contested about crawler behaviour, on this property the robots protocol simply worked.
What the dashboard would not show you
Most teams would judge a site like this on two numbers: how many people arrived, and how much traffic it served. Both mislead here. Referral traffic says almost nobody came, while machines read the site 430,113 times. The traffic line climbs steadily, while by the last day 62% of requests were returning nothing at all.
Read constantly, visited never
Every AI surface combined sent 48 people to the site: 43 from ChatGPT, 5 from Perplexity. At face value search buries that, with 5,208 hits carrying a google.com referrer. That number does not survive contact with the logs.
86.9% of those hits came from a single browser fingerprint — Mozilla/5.0 (X11; Linux x86_64)… Chrome/149 — spread across 4,294 IP addresses at 1.05 hits per address. On one day, 1,308 of them arrived from 1,303 distinct IPs, nearly all targeting four specific URLs. That is a rotating-proxy scraper forging a search referrer, not people arriving from Google.
What sent the 5,208 google.com-referred hits | Hits | Share |
|---|---|---|
| One Linux/Chrome fingerprint across 4,294 rotating IPs | 4,525 | 86.9% |
| Google's own IPv6 infrastructure, not users | 287 | 5.5% |
| A single heavy IP address | 133 | 2.6% |
| Plausible human visits | 263 | 5.0% |
Table 5. The residue is the only part that behaves like people: 263 hits from 242 addresses at 1.09 pages each, spread over 47 days, and 68% mobile — the device mix you would expect from someone checking showtimes on a phone. The three discarded groups are 96% desktop.
That leaves 263 human arrivals from Google against 48 from AI: five to one, not the hundred to one the raw counts suggest. The AI referrals, checked the same way, are clean. Both numbers are tiny. A site read 430,113 times by machines was visited roughly three hundred times by people.
That is the shape of the channel, not a failure of the site. The assistant fetches the page, extracts what it needs, and answers in the conversation; the question is resolved without a visit, which is the entire point of asking an assistant instead of opening ten tabs. We did not run a citation test here, so we cannot say how often those 17,270 fetches produced a visible mention. On the Stampede property, where we did test, the gap was total: zero of 72 prompts cited us. Treating fetches as a ceiling rather than a proxy for attribution is the safer reading.
Serving constantly, failing quietly
The other instrument fails the other way. The site was rebuilt every day, its seat data refreshed every fifteen minutes, and it stayed up throughout. Traffic rose. Over the same 49 days the share of requests it answered with a 404 went from 2.9% to 62.4%, and 89.7% of those were requests for a date that had already passed.
Figure 8. Bars are total daily requests; the faint line is the raw daily 404 share and the bold line its seven-day trailing mean. Both rose together.
This is the per-screening URL problem from chapter 7, seen from the operator's side rather than the assistant's. Addresses that expire accumulate: the stock of dead URLs grows every day while the stock of live ones stays flat. Crawlers vary in how fast they notice — GPTBot aimed 4.4% of its dated requests at expired dates, Googlebot 82.8% — but none of that is visible on a dashboard, because a rising 404 count and a rising traffic count look identical from above.
The cost lands where it hurts most. 22.4% of ChatGPT's answer-time fetches returned nothing: a person asked, the assistant came to look, and the page was gone. We have since changed the site to retire expired URLs to the theatre's current page at the CDN edge rather than deleting them.
Neither of those is visible from outside, and both are plainly legible in a server log. That is most of the reason we ran the experiment this way.
What we learned
The experiment's premise held. Take information that is technically public but practically unreadable, publish it as flat structured pages, and AI systems will find it within the hour and consume essentially all of it. That part is no longer in doubt.
Five things the logs settled that we could not have reasoned our way to:
Depth beat breadth, decisively.
Nearly all of the build went into seat-level availability, and that is what got used: 54% of live fetches, against 4.3% for the navigational pages. If you are choosing between covering more entities and going deeper on the ones you have, this dataset says go deeper.
The lag between publishing and being used was five weeks.
Discovery took 50 minutes; meaningful retrieval demand took until 14 July. Those are very different clocks, and conflating them is how people conclude too early that structured publishing does not work.
Live data changes the traffic mix.
Retrieval overtook indexing here and did not on a static catalogue. If your content moves, expect proportionally more answer-time fetches, and those are the requests with a person attached.
Serve every format, and judge each by the right bot.
Markdown twins earned their place on half of GPTBot's and ClaudeBot's traffic and would have looked worthless measured on live fetches alone.
Verify by IP before you believe anything.
Verification moves numbers in both directions here: it clears Googlebot, disqualifies the earliest apparent GPTBot fetch, and cuts two vendors' apparent volume several times over. The same scepticism belongs on the human side, where a forged referrer inflated search traffic twentyfold. If a number about AI traffic is going to inform a decision, it needs to survive a check against something harder than a self-reported string.
The broader read is that the barrier was never AI's willingness to use this data. It was that nobody had written it down where a machine could reach it. Once we did, demand appeared quickly, grew steadily, and went straight for the most specific facts we had. Almost none of it showed up in any analytics dashboard we would normally look at.
Methodology
Source. CloudFront access logs for opentheatreseats.com, 10 June – 28 July 2026: 936,487 request rows, parsed in full with no sampling.
Bot identification. Agents are matched on user-agent substring, then grouped by function (training, indexing, live retrieval, search, SEO tooling, human) rather than by vendor.
IP verification. Requests claiming OpenAI, Google, Perplexity or Anthropic agents are resolved against those vendors' published prefix lists, fetched at analysis time.1234 Vendors publishing no ranges — Microsoft, Apple, Amazon, Meta, Yandex and the SEO crawlers — are reported by user-agent only and flagged wherever they appear. Claude-User is the exception noted in chapter 5: it legitimately fetches from the end user's machine, so its unverified share is expected rather than suspect.
Definitions. "Distinct URLs AI fetched" counts unique URI stems returning 200 to a verified agent, over all unique stems the site ever returned 200 for. A request is "stale" when the date in its path is earlier than the date it was logged; only dated paths count. Referrals come from the referrer field on non-bot user-agents, then segmented by browser fingerprint, IP concentration and device mix, because a referrer is trivially forged.
Exclusions. On launch night we queried ChatGPT to confirm the site was reachable. The five requests that produced are excluded from the first-contact figures, which date each agent from its first organic request; they remain in the traffic totals, where five requests is far below rounding.
Film attribution. Seat-map URLs name a theatre, a date and a session, not a film, and the pages that decode them are deleted once their date passes: only 18% were still readable on the live site. The rest were recovered from the storage bucket's version history, which retains every deleted object. 727 archived theatre-date pages yielded 34,718 session-to-film mappings and resolved 99.7% of seat-map requests, leaving 26 unresolved. A site without object versioning could not reconstruct this after the fact.
Limits. One property, one vertical, 49 days, on a domain new enough that crawler behaviour toward it may not resemble behaviour toward an established one. The human tier in Table 2 is the least trustworthy row here: it is user-agent-based, no published range exists to verify a browser against, and 12.1% of it carries the scraper fingerprint from chapter 10. No citation testing was run. Figures are requests, not unique users.
References
- OpenAI, overview of OpenAI crawlersPublished IP ranges and documented behaviour for GPTBot, OAI-SearchBot and ChatGPT-User.
- Google, verifying Googlebot and other Google crawlersPrefix lists for Googlebot, special-case crawlers and user-triggered fetchers.
- Perplexity, PerplexityBot and Perplexity-UserPublished ranges and the distinction between indexing and user-triggered fetching.
- Anthropic, Claude crawler IP publicationThe prefix list used to verify ClaudeBot and Claude-User.
- Courtyard, an AI knowledge base experiment: Calgary Stampede editionThe first experiment in this series: how fast AI consumes a purpose-built knowledge base, and the gap between being read and being cited.
- Courtyard, how AI reads a knowledge baseThirty days of IP-verified logs across twenty live small-business knowledge bases.
- IndexNowThe submission protocol used to announce the site at launch.