BlogFindings

Content signals robots.txt: one of ten Cloudflare endpoints reads it

Cloudflare's changelog of 31 August 2026 records that the Browser Run crawl endpoint now respects the Content Signals use directive and rejects a job with HTTP 400 when the caller declares a more permissive level than the site does. We opened all ten Browser Run quick action documentation pages on 3 September 2026: nine of them name neither Content Signals nor robots.txt.

16 min read Lantad

On 31 August 2026 one piece of software started acting on it. Cloudflare's changelog records that the crawl endpoint of Browser Run, its hosted browser product, now reads the Content Signals use directive out of a target site's robots.txt and refuses to start a job when the caller has declared an intent the site did not permit. This post reports what Cloudflare published about that change, reads the endpoint documentation it applies to, and then does the one piece of first-hand work available: opening every sibling endpoint in the same product and writing down which of them mentions any of this. Lantad has sent no request to the crawl endpoint, holds no log of a rejection, and has not observed any site being refused. What follows is a reading of published documentation and of this repository, with the dates on it.

In short

  • Cloudflare's changelog of 31 August 2026 records that the Browser Run crawl endpoint now respects the Content Signals use directive, adding a contentUse parameter whose allowed values are reference and full and whose default is full.
  • A content signals robots.txt line now has one documented consumer: Cloudflare's crawl endpoint documentation, carrying a last updated date of 31 August 2026, states that a crawl is rejected when the declared contentUse level is more permissive than the site's declared use level.
  • Cloudflare's crawl endpoint documentation states in that same section that Content Signals are trust-based, and that by setting crawlPurposes and contentUse an operator is declaring to the site owner how it intends to use the crawled content.
  • Lantad opened all ten Browser Run quick action documentation pages on 3 September 2026: only the crawl page names Content Signals or robots.txt, and the other nine carry last updated dates between 28 May 2026 and 17 July 2026.
  • Read out of this repository on 3 September 2026, Lantad's production renderer calls the content and screenshot endpoints of the same Cloudflare API and never the crawl endpoint, so none of this enforcement applies to any scan this scanner runs.
Browser Run endpointDocs last updatedNames Content SignalsNames robots.txt
/crawl31 August 2026YesYes
/content28 May 2026NoNo
/screenshot28 May 2026NoNo
/pdf28 May 2026NoNo
/markdown28 May 2026NoNo
/links7 July 2026NoNo
/json7 July 2026NoNo
/snapshot7 July 2026NoNo
/accessibilityTree7 July 2026NoNo
/scrape17 July 2026NoNo
The ten Browser Run quick action endpoints, each documentation page opened and read on 3 September 2026, with the last updated date the page itself carries. A reading of Cloudflare's published documentation, not a test of any endpoint.

What Cloudflare changed on 31 August 2026

The crawl endpoint is not new. Cloudflare's Browser Run changelog records it arriving in beta on 10 March 2026, described there as scraping content from a starting URL and following links across the site. The product it belongs to was called Browser Rendering until 15 April 2026, when Cloudflare's changelog announced the rename to Browser Run; the REST path still carries the old name, which is worth knowing if you go looking for it in your own code.

What changed on 31 August 2026 is a rule about who may start a job. Cloudflare's changelog entry for that date states that the crawl endpoint now respects the use directive of the Content Signals standard, that a caller declares its intended level through a new contentUse parameter whose allowed values are reference and full from least to most permissive, that the default is full, and that a crawl request is rejected with a 400 error if the target site's robots.txt sets a more restrictive level. The crawl endpoint documentation, which carries a last updated date of 31 August 2026, puts the rule in one sentence: a crawl is rejected when your declared contentUse level is more permissive than the site's declared use level.

There is a second rule alongside it, covering the three purpose signals rather than the use level. That documentation states that if a target site sets any of those content signals to no, the crawl request will be rejected at initiation with a 400 Bad Request error unless you explicitly narrow your declared purposes. Rejected at initiation is the part to notice. This is not a per-URL skip buried in a results file. The job does not start.

The same page records that the endpoint respects the directives of robots.txt files, including crawl-delay, and that URLs blocked by robots.txt come back in the results with a status of disallowed. Those two behaviours are ordinary and have been available since the endpoint shipped. The Content Signals rules are the new part, and they are different in kind: a Disallow line stops a fetch, while a Content-signal line now stops a job on the basis of what the caller said it was going to do afterwards.

Sample Illustrative, not a measurement of any real site.

POST /browser-rendering/crawl, parameters left at their defaults

  • crawlPurposes omitted, so the declaration is search, ai-input and ai-train all three
  • contentUse omitted, so the declaration is full most permissive
  • GET /robots.txt at the target host 200
  • Content-signal line found, ai-train=no purpose refused
  • Job initiation 400 Bad Request
The documented rejection path for a crawl job, constructed from the rules stated on Cloudflare's crawl endpoint documentation page read on 3 September 2026. Illustrative of the published rule, not a request Lantad sent.

What can a content signals robots.txt line make a crawler do?

Six values, on two axes. Cloudflare's crawl documentation sets them out and gives each a definition, which is worth quoting because the definitions are narrower than the labels suggest.

The three purpose signals are search, ai-input and ai-train. Cloudflare defines search as building a search index and providing search results with links and excerpts, ai-input as inputting content into AI models at query time, giving retrieval-augmented generation and grounding as the examples, and ai-train as training or fine-tuning AI models. That split is the same distinction this blog has kept returning to, because it is the one that decides whether blocking a bot costs you the citations an answer engine hands out or only the training corpus. The ai-input row is the one most site owners set wrongly, since it covers the retrieval that puts a page inside an answer today rather than a model weight next year.

The use directive is the second axis and carries three levels, given least to most permissive. Cloudflare defines immediate as ephemeral, single-response use where content is not retained, reference as content may be retained, indexed, or cited, and full as unrestricted use, including AI training. A site expresses a ceiling on that scale, and the caller declares where it intends to sit.

None of these are new fields in robots.txt. They are values carried on a Content-signal record, and RFC 9309, published in September 2022, is explicit about the status of such a record. The robots exclusion protocol says at section 2.2.4 that crawlers MAY interpret other records that are not part of the protocol, and that parsing them MUST NOT interfere with the parsing of the records section 2 defines. Google's own robots.txt reference lists four supported fields and states that anything else is ignored by its parser. So a Content-signal line remains, at the level of the standard, a comment that happens to be machine-shaped. What changed is that one commercial crawling service has chosen to read it, which is exactly the permission the RFC grants and nothing more.

That distinction matters for anyone about to edit a file. Adding a use directive does not make your robots.txt stricter in any way a general crawler is obliged to notice. It adds a line that a specific set of clients have volunteered to honour, which is a real thing and a much smaller thing. If you want the part that binds, that is still the Disallow line, and it is still worth checking what your file actually says per crawler rather than assuming.

SignalCloudflare's published definitionCaller parameterDeclarable by a caller
searchBuilding a search index and providing search results with links and excerpts.crawlPurposesYes
ai-inputInputting content into AI models at query time, for example retrieval-augmented generation or grounding.crawlPurposesYes
ai-trainTraining or fine-tuning AI models.crawlPurposesYes
use=immediateEphemeral, single-response use, where content is not retained.contentUseNo, not an allowed value
use=referenceContent may be retained, indexed, or cited.contentUseYes
use=fullUnrestricted use, including AI training.contentUseYes, and it is the default
The six Content Signals values and their definitions, transcribed from Cloudflare's crawl endpoint documentation on 3 September 2026, against the parameter a caller uses to declare each one. Cloudflare's published wording, not a measurement.

The defaults declare the maximum on both axes

Read the two parameter definitions next to each other and one property falls out. Cloudflare documents crawlPurposes as defaulting to all three purposes, and contentUse as defaulting to full, which its own scale calls the most permissive level. A developer who calls the endpoint with nothing but a URL has therefore declared the widest possible intent on both axes, without typing a word to that effect.

That inverts the usual shape of a default. The untouched call is the one most likely to be refused, because it collides with any restriction a site has expressed. A caller who wants jobs to succeed has an incentive to narrow, and the documentation says so directly: the purpose rejection applies unless you explicitly narrow your declared purposes. Narrowing is free, takes one array, and is checked against nothing.

There is a second asymmetry, and it is arithmetic on the two published lists rather than anything Cloudflare states. The use directive defines three levels and contentUse accepts two of them, reference and full. immediate is not among the values a caller can send. Since the rejection rule fires whenever the declared level is more permissive than the site's, and both declarable values sit above immediate on Cloudflare's own ordering, a site publishing use=immediate cannot be crawled by this endpoint under any parameter the endpoint accepts. Whether that is intended or simply a gap between a specification with three levels and a parameter with two, the published lists do not say, and we are not going to guess at it.

None of this makes the feature pointless. It makes it a declaration mechanism rather than an access control, which is a distinction this blog has had to draw before: a licence directive in robots.txt changes no access by its own admission, and a pay per crawl price is carried on a status code the specification leaves undefined. The pattern repeats because the layer where these controls live was designed for one question, whether to fetch, and is being asked a different one, what you may do with what you fetched.

  • use=full Declarable, and the default Cloudflare defines it as unrestricted use, including AI training. A caller that sets nothing has declared this.
  • use=reference Declarable Content may be retained, indexed, or cited. A caller must set contentUse explicitly to declare it.
  • use=immediate Not a contentUse value Ephemeral, single-response use. Both declarable values sit above it on Cloudflare's own ordering.
  • No use directive No ceiling expressed The rejection rule compares a declaration against a site's declared level, so a file without one triggers neither test.
The three use levels Cloudflare's crawl documentation defines, against the contentUse values the same page says a caller may send, read on 3 September 2026. The consequence in the third row is our reading of the two published lists, not a Cloudflare statement.

Nine of the ten Browser Run endpoints name none of it

The rule applies to one endpoint. That is not a criticism, it is scope, and scope is the thing a reader most needs to know before deciding whether any of this touches them. So we checked it rather than assuming.

Cloudflare documents ten quick actions in Browser Run: content, screenshot, pdf, markdown, snapshot, accessibilityTree, scrape, json, links and crawl. On 3 September 2026 we opened all ten documentation pages and searched each for the phrases Content Signals, contentUse, crawlPurposes and robots.txt. The crawl page carries all four. The other nine carry none of them, and none of the nine mentions robots.txt at all. Their last updated dates run from 28 May 2026 for content, screenshot, pdf and markdown, through 7 July 2026 for links, json, snapshot and accessibilityTree, to 17 July 2026 for scrape. The crawl page is dated 31 August 2026, the day of the change.

The nine are single-page actions rather than site crawlers, which explains part of it: a robots.txt file governs automated traversal, and fetching one page a human named is a different act. But several of them do the thing the Content Signals vocabulary is written about. The markdown endpoint extracts prose in the format AI crawlers were observed fetching by URL rather than by content negotiation. The json endpoint runs a model over the page. Those are ai-input shaped operations by Cloudflare's own definition, performed by a documented product, with no declaration asked for and no signal read.

This is also the point at which we have to say what it means for this scanner, because the honest answer is nothing. Read out of this repository on 3 September 2026, Lantad's production renderer calls the content and screenshot endpoints of exactly this API and never the crawl endpoint, which is what you would expect of a tool that fetches the single URL a person pasted. So the 31 August change alters no scan we run, and our own crawler conduct policy is unaffected by it. Saying so is cheaper than letting a reader assume the product they are reading about was in scope.

/crawl, updated 31 August 2026

  • Names Content Signals and defines all six values
  • Documents crawlPurposes and contentUse
  • States the 400 Bad Request rejection at initiation
  • Says it respects robots.txt, including crawl-delay

The other nine, updated 28 May to 17 July 2026

  • No occurrence of Content Signals on any of the nine
  • No crawlPurposes and no contentUse parameter
  • No mention of robots.txt on any of the nine
  • Includes markdown extraction and model-driven json capture
The crawl endpoint documentation against the other nine Browser Run quick action pages, all ten opened and read on 3 September 2026. Counts of what each page contains, not a test of what any endpoint does.

Cloudflare calls it trust-based, and that is the whole mechanism

The documentation does not oversell this, and the sentence it uses is the most important one on the page. Content Signals are trust-based, it says, and by setting crawlPurposes and contentUse you are declaring to the site owner how you intend to use the crawled content.

Nothing verifies the declaration. A caller that intends to train a model may send a crawlPurposes array containing only search, pass every check, and receive the pages. The check is on the string, not on the use. That is not a flaw Cloudflare has hidden; it is the property the word trust-based names, and it is the same property that runs through every control in this area. A bot declares three things about itself and can prove one, which is identity. Intent has never been provable from the outside and is not provable here.

What the mechanism does achieve is worth stating plainly rather than dismissing. It moves the moment of refusal from the site to the crawler's own vendor. Before 31 August 2026 a site's Content-signal line reached a general purpose crawling API and was ignored, in the way our 30 July 2026 parse found. Now one such API reads it and refuses its own paying customer at job initiation. The site did nothing differently. The change happened entirely on the other side, and that is the only place a change of this kind can happen, because a request that arrives is a request that arrived.

It also means the population this binds is not the population most site owners worry about. It binds developers who chose a documented, hosted, invoiced product. It does not touch anyone running their own headless browser, and it does not touch the crawlers whose behaviour we keep having to measure rather than read: the ones where a Disallow line was published and a 200 was served anyway, or where a robots.txt block did not stop 12 of 18 chatbots. Compliance improving among the compliant is a real improvement with a narrow base.

The documented decision path for a crawl job, drawn from the rules on Cloudflare's crawl endpoint documentation read on 3 September 2026. A diagram of published rules, not of any observed request.

What a site owner can check today

The practical consequence is small, cheap and worth doing, so here it is without inflation.

Your Content-signal line, if you have one, now has one documented consumer where it previously had none. That is a reason to check the line says what you meant, not a reason to expect traffic to change. If Cloudflare generates the file for you, remember that the token list inside it is refreshed by Cloudflare rather than by you, so the file you approved is not necessarily the file being served this week.

Check the file is served at all, and served consistently. When we fetched robots.txt across the 14 hostnames belonging to six real sites on 2 September 2026, three of the six served a different file on a second hostname and one returned nothing. A signal on the wrong hostname is not a signal. So is the status code: a 404 on robots.txt allows every crawler and a 503 blocks them all, and neither outcome is visible from a browser tab that renders your homepage fine.

Do not spend the effort on the Content-signal line that belongs on the Disallow lines under it. Those are the records the standard defines and every compliant AI crawler evaluates, and their behaviour is less obvious than it looks: we found that appending a trailing asterisk changed the verdict on none of 168 path comparisons while a trailing dollar sign changed 36 of 112. If you want to see which named agents your current file admits, the crawler reference lists the tokens and a single page fetch shows what one of them receives.

Finally, keep the layers separate in your head. Cloudflare is also changing defaults at the edge, where a new domain's AI bot policy will depend on whether the page carries ads from 15 September 2026. That is enforcement against arriving requests. The crawl endpoint change is enforcement against departing ones, applied to Cloudflare's own customers. They are different mechanisms with different populations, and a site owner who conflates them will over-estimate what either has done. What we grade, and how we grade it, stays where it has always been: whether a crawler that does arrive can fetch, parse and read the page.

  • The Content-signal line says what you meant Six values across two axes, defined on Cloudflare's crawl endpoint documentation read on 3 September 2026.
  • robots.txt is served on every hostname that serves pages Three of six sites served a different file on a second hostname when we fetched all 14 on 2 September 2026.
  • The status code is 200, not 404 or 503 A 404 allows every crawler and a 503 blocks them all under RFC 9309, and neither is visible from a rendered homepage.
  • The Disallow lines match the crawlers you meant to name The records the standard defines. A Content-signal line changes no verdict for a parser that follows RFC 9309.
  • You know which of your vendors calls a crawling API The rejection lands on the caller of Cloudflare's crawl endpoint, not on the site, so it is your suppliers who meet it.
What a site owner can verify about their own file after the 31 August 2026 change, with the source of each check. Steps a reader can run, not results Lantad measured on any reader's site.

Written by

Lantad

Published .

A content signals robots.txt line has spent most of a year being a sentence addressed to nobody in particular. Cloudflare published the Content Signals Policy on 24 September 2025, as recorded here on 30 July 2026, and the line it writes into a file sits outside the four fields the robots exclusion protocol defines. When we ran Cloudflare's own published example through this scanner's parser on that date, the Content-signal line came back as an unknown field and changed no verdict for any of the 15 crawler tokens in our registry. That was not a defect in the parser. It was the correct handling of a record the standard does not define.

Common questions

What is a content signals robots.txt line?

A record beginning Content-signal, carrying values on two axes. Cloudflare's crawl endpoint documentation, read on 3 September 2026, names three purposes, being search, ai-input and ai-train, and three use levels, being immediate, reference and full. RFC 9309 classes such a record as an other record: crawlers MAY interpret it, and parsing it MUST NOT interfere with the allow, disallow and user-agent records the protocol defines.

Does adding a use directive block AI crawlers?

No. It expresses a ceiling that a client may choose to honour. As of 3 September 2026 the one documented consumer we can point at is Cloudflare's Browser Run crawl endpoint, which rejects a job at initiation with a 400 Bad Request when the caller's declared contentUse is more permissive than the site's declared use level. Every other client is free to ignore the line, and the records that actually stop a fetch are still the Disallow lines.

Can a crawler lie about its declared purpose?

Cloudflare's own documentation answers this. It states that Content Signals are trust-based, and that by setting crawlPurposes and contentUse you are declaring to the site owner how you intend to use the crawled content. Nothing in the published rules verifies the declaration against the eventual use, and narrowing a declaration to pass the check costs one array element.

Does this change what Lantad does?

No. Read out of this repository on 3 September 2026, Lantad's production renderer calls the content and screenshot endpoints of Cloudflare's browser API and never the crawl endpoint, because it fetches the single URL a person pasted rather than traversing a site. Our conduct policy and user agent are published at /bot and are unchanged by the 31 August 2026 update.

See what AI can read on your site

Run a free scan and get a graded report of exactly what AI crawlers can and cannot read, with ranked fixes.