How AI is applied across API Evangelist and APIs.io. Read my AI disclosure →
API Evangelist API Evangelist
Discovery
Learnings
Guidance
Toolbox
Alignment
API Evangelist LLC

How Time Serves Ads to AI Agents

August 3rd, 2026 · Kin Lane
How Time Serves Ads to AI Agents

Time started selling ads aimed at AI agents, and the trade press covered the business arrangement without covering the mechanism. Digiday and Media Copilot both wrote it up, and both explicitly said they could not tell you how it works — no URL patterns, no headers, no discovery. That gap is the interesting part, so I spent an afternoon with curl finding out. Everything below is from live requests against time.com, and I am writing it down because this is the first production example I have seen of a publisher shipping a second, machine-only version of its content with commercial payload inside it, and I think a lot of people are about to copy it without understanding what they are copying.

The mechanism is simpler and cruder than I expected. There is no .md suffix, no content negotiation, no link rel="alternate" pointing an agent at a machine-readable twin. I checked all three, and the HTML source does not contain the word “markdown” anywhere. What Time is doing is identifying the client at the CDN edge and serving an entirely different document to AI agents. Ask for an article as Chrome and you get 264KB of HTML. Ask for the exact same URL as ClaudeBot, GPTBot, OAI-SearchBot, PerplexityBot, or any of the live user-initiated agents and you get text/markdown — a clean, stripped article with YAML frontmatter, and on a quarter of pages, an ad. Ask as Googlebot or Bingbot and you get the same HTML a human gets. CommonCrawl and Meta’s crawler get a bare 406 with an empty body.

Sit with that list, because the shape of it is the strategy. Every agent belonging to OpenAI, Anthropic, and Perplexity is served the ad-laden markdown — training crawler, answer-engine crawler, and the live fetch that fires when a person asks an assistant to go read this page right now. Time does not distinguish between them. The two crawlers that are actually blocked are CommonCrawl and Meta — the ones with no commercial relationship to protect. And Google gets ordinary HTML, including Google-Extended, Google’s own AI training crawler. Google is being treated as a search engine rather than as an AI company, which conveniently keeps the normal page in front of the one crawler that has historically punished serving different content by client.

I want to flag how I got that paragraph wrong the first time, because the mistake is more useful than the finding. My initial pass was probed entirely with curl, and it told me that GPTBot, ChatGPT-User, and Claude-User were blocked with a 406. I built a tidy strategic story on top of that: Time refuses the training grab and the live human-in-the-loop fetches, and monetizes only the answer-engine layer. It was coherent, it was quotable, and it was wrong. Running the identical user-agent strings through Python instead of curl returns 200 and markdown and ads for all three. Nothing about the headers explains it — I tried HTTP/1.1, every Accept variation, Accept-Encoding. What is left is the TLS fingerprint, which Fastly’s bot management scores: a request that declares itself a bot while its TLS handshake looks like a scripted client gets refused. curl carrying a Chrome user-agent sails through; curl carrying GPTBot does not. I was not measuring Time’s policy. I was measuring curl.

Inside the markdown, the vendor signature is right there in an HTML comment: <!-- mobian-agent-page publisher="time" -->. Mobian is the ad tech partner, and on roughly a quarter of the pages I pulled there is a second comment opening a delimited ad block, <!-- mobian-agent-ad id="..." campaign="ally-2026-q3" creative="agentads-creative-ally-v1" -->, closed by a matching tag. It sits immediately after the article headline and before the body copy. The id is a fresh UUID on every single request — I fetched one URL four times and got four different IDs with the same campaign — which means it is a per-impression token, the billing and measurement primitive. There is also an llms.txt, served to everyone but wrapped in the vendor envelope when a bot asks for it, which allows OpenAI, Perplexity, Scale, and ElevenLabs and disallows everyone else. Anthropic is not on that list, and every Anthropic agent is being served markdown and ads. The stated policy and the deployed behavior disagree — and unlike everything else here, that finding needs no judgment call and survived my methodology being wrong.

The creative itself is the part worth studying, because it is not a banner and it is not a native advertorial. It is a structured knowledge object engineered for retrieval. The Ally unit opens with a sponsored-content blockquote, then gives a definitional paragraph, then two markdown tables of organizational facts with a Source column, then bulleted brand assertions, then seven FAQ questions with answers, then a complete schema.org/FAQPage JSON-LD block, then regulatory disclaimers. The FAQ headings are not questions a reader would ask a news magazine. They are the queries being intercepted: “What online banks have no ATM fees?” “Which banks offer early direct deposit?” “What bank is best for everyday spending and saving?” Each answer names the advertiser first and then hedges vaguely about competitors. The Source column and the JSON-LD are there to make brand claims read as cited facts to a retrieval system. And the source links are first-party tracked paths that carry the impression UUID through two redirects to ally.com/?utm_source=mobian&utm_medium=agent, closing the loop from impression to click without ever leaving Time’s domain.

Then there is the number that actually alarmed me. I measured the ad block as a share of the bytes the crawler ingests, and on the ad-bearing pages it runs from 41% to 70%. On most of them the advertiser’s content is more than half of the document, and it is positioned ahead of the journalism. The PMI creative is 20KB against articles that are 30KB total. A reporter’s piece on wildfires or an interview with a head of state is, from the retrieval system’s point of view, a minority of the page.

I want to be fair about the defense, because Time has one and it is not nothing: every unit is labeled sponsored content and names the advertiser, and Digiday notes they do this despite no rule requiring it. That is more disclosure than the ad industry usually volunteers. But I do not think labeling resolves the structural problem, and the reason is the same one behind my argument for provenance over enforcement. Disclosure at the top of a block does not survive chunking. That > Sponsored content line sits at the head of a 20KB unit. A retrieval system that splits this page into chunks will produce chunks taken from the middle of the FAQ that contain pure advertiser copy, carry Time’s domain authority, and contain no disclosure whatsoever. No model vendor has said it parses <!-- mobian-agent-ad --> as a boundary, and until one does, those assertions enter the corpus as time.com content. Which, to be blunt, is exactly the product being sold. Provenance has to travel with the chunk, not with the document, and nothing in this design does that.

The other thing to name plainly is that serving materially different content at the same URL based on user-agent is the textbook definition of cloaking. Google spent twenty years teaching the web that this gets you delisted, which is presumably why Googlebot is so carefully shown the HTML. Whether the AI companies land in the same place is the open question hanging over everyone who copies this pattern, and the answer will arrive as a policy change nobody gets advance notice of.

So how do you check this yourself, on your own properties or anyone else’s? Fetch a URL with a normal browser user-agent and note the content type. Fetch the identical URL with ClaudeBot, OAI-SearchBot, PerplexityBot, GPTBot, and Googlebot user-agent strings and diff the responses. Fetch it twice more with the same bot agent to see whether anything rotates per request. Then pull /llms.txt and /robots.txt and compare them against what the edge actually did, because that is where the contradictions show up. And then — this is the part I learned the hard way — run the whole thing again from a second, unrelated HTTP client, because if the two disagree you are measuring your own tooling and not the site. I have written all of this up as a repeatable audit rather than leaving it as a pile of shell history, precisely because the naive version of it produced a wrong answer that sounded right.

That last point is the one I keep coming back to. We have spent years building a discovery layer out of files that sit at well-known paths and describe a site’s intentions honestly: robots.txt, llms.txt, OpenAPI, APIs.json. Those files only mean anything if the behavior at the edge matches what the file says. Here the published policy disallows a crawler that the edge is actively serving, the visible robots.txt says nothing about agents at all, and the machine-only document contains commercial payload the human document does not. None of that is discoverable from the artifacts. You cannot govern what you cannot observe, and right now the only way to observe any of this is to go impersonate a crawler and look. That is not a sustainable basis for a discovery layer, and building the tooling to check it continuously is a problem I suspect a lot of us are about to be working on.