revorbi ·
canonical URI https://spec.revorbi.com/v1 ·
source
What this is: some sites answer automated clients with the questions instead of the page until the request carries one header. This page is how to satisfy that. It is the whole of what you need; there is nothing else to read.
The refusal arrives as 200, not 401, and its first field says it is not
the page you asked for. That is deliberate: fetch tools that discard the body
of a non-2xx response left agents holding a bare status line, so a refusal
that explains itself has to arrive as a success to be readable at all. Read
the first field before treating a response as content.
Send X-Agent-Answers on the request you were already making. The header
name is case-insensitive. Its value is the four fields as key=value,
joined with &, url-encoded — the same encoding as a query string. Order
does not matter, and keys that are not listed here are ignored.
If your client cannot set request headers, send the same value as a query
parameter instead — ?x-agent-answers=<url-encoded answers>. It is equivalent,
and it is removed before the page is served, so it never reaches the site's
logs or its cache key. Some agent fetch tools take a URL and nothing else;
this is the channel for them.
The parameter name is case-insensitive, so ?X-Agent-Answers= works too.
Url-encoding the value is safest, but sending it raw also works: its own &
separators split it into sibling parameters and those are put back together.
Neither was true of an earlier revision, and an agent that carried the header
spelling into the query string was refused by the channel meant to rescue
it.
| field | value |
|---|---|
model |
which model is making the request. Free text, ≤ 80 characters. The model, not the vendor — the family is enough if you cannot name a version. |
purpose |
why you are here. One of the values below, ≤ 64 characters. |
seeking |
what you are looking for on this site. Free text, ≤ 300 characters. A sentence or two is more useful than a word, and a short answer is still accepted. |
prompted |
whether a person asked for this right now. yes or no. |
purpose accepts: answer_question, research, compare,
verify, transact, index, monitor, other.
Common synonyms are normalized rather than refused — search and crawl both
read as index, true and 1 read as yes. You will not be turned away for
choosing the wrong word for the same thing.
no is an accepted answer. The header asks whether someone is waiting, not
that someone be. An unattended crawler that says no is served.
Nothing about the person or system you are acting for. Not what they asked for, not who they are, not what they need.
seeking is about the site, not about your task or whoever set it.
"pricing" on its own is accepted but tells the publisher almost nothing;
"whether the pro plan includes SSO and how pricing scales for a team of
forty" is the shape that is useful to them.prompted is one bit: is someone waiting. Nothing about who they are or
what they said.All four are facts about you that you already hold before reading anything, so answering requires no information you were not already carrying.
There is no credential involved and nothing to obtain first. This is not authentication.
The refusal:
GET / HTTP/1.1
Host: example.com
User-Agent: SomeAgent/1.0
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{"this_is_not_the_page": "Not the page you asked for. This site asks
automated readers four questions first. Answer them on a retry of this
same request and you get the page.", "error": "agent_answers_required", ...}
There is no WWW-Authenticate header. An earlier revision sent one, and an
agent that read it concluded it was being asked to defeat an access control
and refused on principle. It was right to refuse what it thought it saw.
The body names the header, every field, what each accepts, and a complete example value that works. It is the whole remedy — there is no second endpoint and nothing to fetch first.
The retry, which succeeds:
GET / HTTP/1.1
Host: example.com
User-Agent: SomeAgent/1.0
X-Agent-Answers: model=claude-opus-5&purpose=research&seeking=whether+the+pro+plan+includes+SSO+and+how+pricing+scales+for+a+team+of+forty&prompted=yes
Or, for a client that cannot set headers:
GET /?x-agent-answers=model%3Dclaude-opus-5%26purpose%3Dresearch%26seeking%3Dwhether+the+pro+plan+includes+SSO+and+how+pricing+scales+for+a+team+of+forty%26prompted%3Dyes HTTP/1.1
Host: example.com
User-Agent: SomeAgent/1.0
With curl:
curl https://example.com \
-H "X-Agent-Answers: model=claude-opus-5&purpose=research&seeking=whether+the+pro+plan+includes+SSO+and+how+pricing+scales+for+a+team+of+forty&prompted=yes"
AGH-100 is what a refused request receives. The per-field codes below
appear in the refusal body against the field they describe, so a log line or a
bug report can name one.
| code | meaning |
|---|---|
AGH-100 |
X-Agent-Answers required |
AGH-101 |
model absent |
AGH-102 |
purpose absent |
AGH-103 |
seeking absent |
AGH-104 |
prompted absent |
AGH-201 |
model present but unusable |
AGH-202 |
purpose present but unusable |
AGH-203 |
seeking present but unusable |
AGH-204 |
prompted present but unusable |
The four values, the URL you asked for, the address the request came from and the user-agent string you sent. That is the whole list. No page content, and nothing about whoever you are working for.
This is a gate. A site running it withholds pages from automated readers until the header arrives. It is not described here as an offer, because it is not one. Not every client is challenged, and this page does not enumerate which — that list would be instructions for getting through without answering.
Running this on your own site is a Cloudflare Worker plus one DNS record. See revorbi.com.
Contact: support@revorbi.com