A search an agent can use is a search whose results have an address. If typing rendering into your search box produces a page at /search?q=rendering, an agent never needs the box: it can build that URL from the term it already has, fetch it once, and read the results out of the HTML. If the same search POSTs a form body, or lives in a JavaScript combobox that calls an API as you type, there is no address to build and no page to fetch. Check C6, on-site search, is three points for the difference.
C6 is worth 3 of the 25 actionability points and carries a Medium effort rating. The rubric's definition is one sentence: a search form exists, and it uses GET with a query parameter so an agent can construct search URLs directly rather than having to drive a form. This post goes through how the scanner finds the form, how the three points are assembled, what the three shapes of search look like from a program's side, and how our own header search is built, since it is the example we can vouch for.
How C6 finds the form
The check reads the raw HTML of the homepage only, before any script runs. It collects every form element and keeps the ones that look like search, which means any of the following: the form contains an input with type="search"; its action attribute contains the word search; its role attribute contains search; or any input inside it has a name matching search, query or exactly q. Matching is case-insensitive. The first form that qualifies is the one examined; the rest are ignored.
For that form the scanner reads the method attribute, treating a missing one as get because that is the HTML default, and records the name of the first input whose name matches the same pattern as the query parameter.
Separately, it searches the homepage HTML for the literal text "@type": "SearchAction", with any whitespace around the colon, which is how a WebSite block advertises a search endpoint.
The three points come in two parts. One point if a search form was found. Two points if either the form uses GET or a SearchAction is present. Written out, the possible outcomes are these.
| Homepage has | Points |
|---|---|
| A search form using GET | 3 |
| A search form using POST, plus a SearchAction | 3 |
| A SearchAction but no recognisable form | 2 |
| A search form using POST, no SearchAction | 1 |
| Neither | 0 |
The evidence block on the report shows searchForm, usesGet, param and searchAction, so you can see which part was missing. A form that scores 3 with param: q is the ordinary good case.
One honest limit. The scanner reads the form as declared and cannot see a script that intercepts the submit event. A form that declares method="get" and action="/search" but is hijacked by a handler that opens an overlay will pass C6. It still helps nobody unless /search?q= is a real route that returns results in its HTML, so the declared form has to be true, not merely present.
GET, POST and the combobox
The three shapes differ in what an agent has to do to get a results page.
With a GET form, the query goes into the URL. The results page is addressable, cacheable, linkable and repeatable, and an agent can reach it in one request without ever having seen the form, provided it knows the path and the parameter name. That is what a SearchAction provides: a URL template with a placeholder for the term.
With a POST form, the query goes into the request body. An agent has to fetch the page that carries the form, parse it, assemble a body with the right field names, and submit it. The results it gets back have no URL of their own, so they cannot be cited, bookmarked or fetched again without repeating the whole exercise. Nothing about search needs POST; the method exists for requests that change something, and a search changes nothing.
With a JavaScript combobox, there is usually no form element at all. There is an input, a keyup handler, and a call to a search API whose results are drawn into a dropdown. In the raw HTML there is nothing for the check to find and nothing for an agent doing a plain fetch to use. The results exist only inside a running browser, after script, and the same is true of the API the widget calls if it is undocumented and needs a session token. This is a common shape for hosted site-search widgets, and it is the shape that scores zero.
Our header search
The search field in our header is a plain GET form. Stripped of styling classes, this is what the raw HTML contains on every page.
<form action="/search" method="get" role="search">
<label for="nav-search" class="sr-only">Search this site</label>
<button type="submit">
<span class="sr-only">Search</span>
<!-- icon -->
</button>
<input id="nav-search" name="q" type="search" placeholder="Search">
</form>
Four things in that markup are deliberate. method="get" puts the query in the URL. role="search" and type="search" are two of the ways C6 recognises the form, and name="q" is a third, so the check does not depend on any one of them. The label is visually hidden but present, and the submit control is a real button, because relying on Enter to submit leaves a form with nothing an agent can activate; that is the C1 point Forms an agent can fill covers, and it cost us a point until it was caught.
The route at /search reads q from the query string and renders the results on the server, so /search?q=rendering returns a results list in the HTML of the response. Nothing on that page waits for a client bundle.
The WebSite block in our sitewide JSON-LD then advertises the endpoint, so an agent can find the template without parsing the form at all.
{
"@type": "WebSite",
"url": "https://agentfriendlyrank.com",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://agentfriendlyrank.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
potentialAction and SearchAction are defined at schema.org/WebSite. The urlTemplate carries the placeholder, and query-input names it. Substitute a term for {search_term_string} and you have the results URL.
Switching from POST or from a widget
If you have a form that POSTs, the change is one attribute and one route. Set method="get", make sure the server handles a GET to the same path by rendering results into the response, and keep the parameter name short and conventional; q is the one most software expects. Then add the SearchAction to your WebSite block with the same path and parameter, so the two agree.
If your search is a hosted widget with no form, add a real one. A form with method="get" posting to a results page you render yourself can sit alongside the widget, or the widget can be mounted on top of it so the form is what the raw HTML contains and the script is an enhancement. Some search providers expose a results URL of their own; pointing a GET form at it counts for the check only if the form lives on your homepage, and it helps an agent only if that URL returns results in its HTML rather than a shell.
Whatever the route, test it the way the check does: fetch your homepage with curl, find the form, and then fetch the URL you would build from it. If the second response contains results, you are done.
Check your own site
The free scan reports whether it found a search form on your homepage, what method it uses, which parameter it found and whether a SearchAction is present. The definition of C6 is on the methodology page under actionability, and the search on this site is at /search if you want to see the shape working.