# Get site access

> Read whether AI crawlers and search engines can fetch a brand's site: each crawler's verdict, the findings and history.

Source: https://ranqo.ai/docs/api/reference/get-site-access

```http
GET https://api.ranqo.ai/v1/brands/{brand_id}/site-access
```

The brand's latest Site Access check and its completed checks, newest first.

## Path parameters

| Name | Type | Description |
| --- | --- | --- |
| `brand_id` | string | The brand id, from `GET /v1/brands`. |

## Response

The response body, as JSON.

| Field | Type | Description |
| --- | --- | --- |
| `brand_id` | string |  |
| `check` | object or null | Whether AI crawlers and search engines can fetch the site: each one fetches the homepage beside a browser. Null when the brand has never run a check. |
| `check.status` | string | The latest check's state. A check that stopped reporting reads `failed`. One of `pending`, `running`, `completed`, `failed`. |
| `check.origin` | string | The site the latest check was pointed at: after redirects once it completes, the brand's own domain while it runs or if it failed. |
| `check.checked_at` | string or null | RFC 3339 timestamp in UTC. When the check the findings below come from completed. While a new check runs, or after one fails, they stay that earlier check's. Null before any check completes. |
| `check.verdict` | string or null | `unknown` comes first: no browser could load the homepage either, or robots.txt disallows RanqoBot, so the crawlers' results cannot be read, whatever else was found. Otherwise `blocked`: a crawler that feeds live AI answers is refused at the edge, or robots.txt turns away a live-answer or search crawler. `warn`: something worth a look, such as a search or training crawler refused at the edge, or no sitemap. `clear`: no blocker and no warning; notices may remain. Null before any check completes. One of `clear`, `warn`, `blocked`, `unknown`. |
| `check.reachable` | boolean or null | Whether a browser could load the homepage, the control every crawler is read against; null when not measured. |
| `check.counts` | object or null | Findings by severity, and `passes`, the crawlers with a `pass` verdict: those that received the page, and robots.txt-only tokens the file allows. Null before any check completes. |
| `check.counts.blockers` | integer |  |
| `check.counts.warnings` | integer |  |
| `check.counts.notices` | integer |  |
| `check.counts.passes` | integer |  |
| `check.findings` | array of objects |  |
| `check.findings[].id` | string |  |
| `check.findings[].severity` | string | One of `blocker`, `warn`, `notice`. |
| `check.findings[].title` | string |  |
| `check.findings[].detail` | string |  |
| `check.crawlers` | array of objects | Each crawler that fetched the homepage, read against the browser control; tokens that exist only in robots.txt, such as Google-Extended, are never requested and carry only their robots.txt verdict. |
| `check.crawlers[].key` | string | The crawler's robots.txt token. |
| `check.crawlers[].label` | string |  |
| `check.crawlers[].vendor` | string |  |
| `check.crawlers[].role` | string | What the crawler feeds. One of `live_answer`, `training`, `search`. |
| `check.crawlers[].verdict` | string | One of `pass`, `blocked`, `rate_limited`, `thin`, `robots_disallowed`, `unknown`. |
| `check.crawlers[].http_status` | integer or null |  |
| `check.crawlers[].fetch_error` | string or null | Set when the request got no HTTP answer. One of `timeout`, `error`. |
| `check.crawlers[].latency_ms` | number or null |  |
| `check.crawlers[].words` | integer or null | Visible words the crawler received. |
| `check.robots_txt` | object or null |  |
| `check.robots_txt.status` | string or null | `ok`, `missing`, `unreadable`, `cdn-blocked` or `ranqo-disallowed`. |
| `check.robots_txt.http_status` | integer or null |  |
| `check.robots_txt.disallowed_ai` | array of strings | AI crawlers the file turns away from the homepage. |
| `check.robots_txt.disallowed_search` | array of strings | Search crawlers the file turns away from the homepage. |
| `check.robots_txt.declares_sitemap` | boolean |  |
| `check.llms_txt` | object or null |  |
| `check.llms_txt.url` | string |  |
| `check.llms_txt.present` | boolean | A real llms.txt: a 200 serving HTML does not count. |
| `check.llms_txt.http_status` | integer or null |  |
| `check.llms_txt.sections` | integer |  |
| `check.llms_txt.links` | integer |  |
| `check.llms_txt.checks` | array of objects |  |
| `check.llms_txt.checks[].id` | string |  |
| `check.llms_txt.checks[].ok` | boolean |  |
| `check.llms_txt.checks[].title` | string |  |
| `check.sitemap` | object or null |  |
| `check.sitemap.url` | string or null |  |
| `check.sitemap.reachable` | boolean |  |
| `check.sitemap.http_status` | integer or null |  |
| `check.sitemap.url_count` | integer |  |
| `check.sitemap.declared_in_robots` | boolean |  |
| `check.sitemap.newest_lastmod` | string or null |  |
| `check.fetch_count` | integer or null | Requests the check sent to the site. |
| `check.error` | string or null | Why the latest check failed; null otherwise. |
| `history` | array of objects | Completed checks, newest first, the latest completed one included, at most 26. |
| `history[].checked_at` | string | RFC 3339 timestamp in UTC. |
| `history[].verdict` | string | `unknown` comes first: no browser could load the homepage either, or robots.txt disallows RanqoBot, so the crawlers' results cannot be read, whatever else was found. Otherwise `blocked`: a crawler that feeds live AI answers is refused at the edge, or robots.txt turns away a live-answer or search crawler. `warn`: something worth a look, such as a search or training crawler refused at the edge, or no sitemap. `clear`: no blocker and no warning; notices may remain. One of `clear`, `warn`, `blocked`, `unknown`. |
| `history[].blockers` | integer |  |
| `history[].warnings` | integer |  |
| `history[].notices` | integer |  |
| `history[].note` | string | What changed since the check before; "First check" on the first. |

## Response headers

| Header | Description |
| --- | --- |
| `X-Request-Id` | The request id; quote it to support. |
| `RateLimit` | Requests left in this window and seconds until it resets. |
| `RateLimit-Policy` | The key's limit per window. |

## Example request

```bash title="curl"
curl "https://api.ranqo.ai/v1/brands/BRAND_ID/site-access" \
  -H "Authorization: Bearer $RANQO_API_KEY"
```

## Errors

Errors are problem details (`application/problem+json`) with a stable `code`. See [Errors](https://ranqo.ai/docs/api/errors) for each one.

| Status | Codes |
| --- | --- |
| 400 | [`unknown_parameter`](https://ranqo.ai/docs/api/errors#unknown_parameter), [`api_key_in_url`](https://ranqo.ai/docs/api/errors#api_key_in_url) |
| 401 | [`missing_api_key`](https://ranqo.ai/docs/api/errors#missing_api_key), [`invalid_api_key`](https://ranqo.ai/docs/api/errors#invalid_api_key), [`api_key_revoked`](https://ranqo.ai/docs/api/errors#api_key_revoked), [`api_key_expired`](https://ranqo.ai/docs/api/errors#api_key_expired), [`api_key_orphaned`](https://ranqo.ai/docs/api/errors#api_key_orphaned) |
| 403 | [`plan_upgrade_required`](https://ranqo.ai/docs/api/errors#plan_upgrade_required), [`subscription_inactive`](https://ranqo.ai/docs/api/errors#subscription_inactive) |
| 404 | [`not_found`](https://ranqo.ai/docs/api/errors#not_found) |
| 429 | [`rate_limited`](https://ranqo.ai/docs/api/errors#rate_limited) |
| 500 | [`internal_error`](https://ranqo.ai/docs/api/errors#internal_error) |
| 503 | [`service_unavailable`](https://ranqo.ai/docs/api/errors#service_unavailable) |
