I shipped llms.txt, JSON-LD and AI crawler allowances. Here's what each one actually does. A developer building an answer engine optimization site for SearchD implemented llms.txt, JSON-LD, and AI crawler allowances, then tested whether each actually delivers the promised citation benefits. Testing 12 AI crawler user agents against the site returned HTTP 200 across the board, but the developer found that robots.txt allowances prove nothing about edge-level bot blocking, that Google states it ignores llms.txt, and that an Ahrefs study of 1,885 pages found no citation lift from schema markup. I am building a site whose entire job is to be quoted by AI assistants. It is the marketing site for SearchD https://searchd.ai , an answer engine optimization practice, which makes the site both the product and the test case. Three things get recommended everywhere for this: let the AI crawlers in, publish an llms.txt , ship JSON-LD. I implemented all three. Then I went looking for evidence that each one does what the advice says it does. Only one of the three can fail silently. The other two turned out to do a different job from the one the advice promises. A robots.txt that allows GPTBot proves nothing. The file is a request to a well-behaved crawler; it has no effect on the layer in front of it. If your CDN has a bot-management rule, the crawler can be challenged or blocked at the edge and never get as far as reading your robots file. The only way to know is to ask as each crawler and look at the status code: for ua in GPTBot OAI-SearchBot ChatGPT-User ClaudeBot Claude-User PerplexityBot \ Google-Extended Applebot-Extended CCBot Amazonbot Bingbot Googlebot; do printf "%-20s %s\n" "$ua" "$ curl -s -o /dev/null -w '%{http code}' -A "$ua" https://example.com/ " done Run against my own site on 11 September 2026: GPTBot 200 OAI-SearchBot 200 ChatGPT-User 200 ClaudeBot 200 Claude-User 200 PerplexityBot 200 Google-Extended 200 Applebot-Extended 200 CCBot 200 Amazonbot 200 Bingbot 200 Googlebot 200 A 403 or a 503 here outranks any amount of markup work, because it means nothing downstream of it can matter. Passing the check does not get you cited. It removes a way of being invisible that you would otherwise never see. The status code leaves two things open. It says nothing about whether the response body is a JavaScript shell, so fetch one and read it: a 200 carrying an empty