# Intake API

> Reference for the public Site Tracking endpoint every install calls, with its parameters, response, rate limit and monthly allowances.

Source: https://ranqo.ai/docs/integrations/site-tracking/intake-api

Every Site Tracking install, whatever the stack, makes the same call: one `GET` request per page view to the intake endpoint. This page describes that endpoint for anyone writing an install by hand.

## Endpoint

```text title="Request"
GET /api/v1/intake/pageview?url=…&userAgent=…&ref=…&ip=…&websiteKey=…
```

The endpoint is on Ranqo's app host: https://app.ranqo.ai/api/v1/intake/pageview. It takes no request body and no authentication header; the site key in the query string identifies the brand. Only `GET` is accepted.

## Parameters

All values go in the query string, URL-encoded.

| Parameter | Required | Value | Longest accepted |
| --- | --- | --- | --- |
| `url` | Yes | The full URL of the page requested, including scheme and host. Ranqo reads the host and path from it. | 4,096 characters |
| `websiteKey` | Yes | Your site key: `rk_live_` followed by 40 lowercase hexadecimal characters. | Fixed length |
| `userAgent` | No | The request's `User-Agent` header. Empty or missing is treated as no user agent. | 2,048 characters |
| `ref` | No | The request's `Referer` header. | 2,048 characters |
| `ip` | No | The visitor's IP address, IPv4 or IPv6. | 64 characters |

A value longer than its limit makes the whole report fail. Without `ip`, bot visits cannot be checked against their operators' published ranges. Without `userAgent`, every visit is counted as a person.

## Response

The endpoint answers every report it accepts or refuses with HTTP `200`, a JSON body and `Cache-Control: no-store`:

```json title="Accepted"
{ "ok": true }
```

```json title="Refused"
{ "ok": false }
```

A refusal carries no detail, by design: your install code has nothing to handle or retry, and a caller trying keys learns nothing about which exist. A failure on Ranqo's side, such as while it looks the key up, can return an error status instead of the `200`. Ignore that too, and do not retry it.

`{"ok":false}` means one of these:

- `url` or `websiteKey` is missing, or a value is longer than its limit.
- The key is malformed, does not exist, or has been revoked.
- The key has gone over its rate limit (below).

A key whose brand has been deleted is not refused: its reports are still recorded under that brand. See [Site keys](https://ranqo.ai/docs/integrations/site-tracking/keys#deleting-a-brand).

`{"ok":true}` means the key was valid and the report was accepted. The answer does not wait for the report to be queued or stored: if queuing fails, the report is lost. Processing happens afterwards, and it discards some accepted reports:

- Requests for paths that only vulnerability scanners ask for, such as `/.env`, `/.git/`, `/wp-admin`, `/wp-login` and `xmlrpc.php`.
- Requests whose user agent is itself a web address, a pattern only probes use.

Every other accepted report is recorded as a new visit. Nothing is deduplicated: sending the same report twice records two visits.

## Rate limit

Each key accepts up to 100 reports per second. Reports over that are refused with `{"ok":false}` and not recorded. A normal site does not come near it.

## Monthly allowance

Recorded visits are counted per brand per calendar month (UTC), bots and people together, against your plan's allowance:

| Plan | Visits per brand per month |
| --- | --- |
| Starter | 100K |
| Pro | 500K |
| Agency Growth | 5M |
| Agency Scale | 10M |

The allowance is not enforced: the endpoint does not refuse visits for being over it, and nothing is dropped. The Site Tracking view on the Traffic page shows the month's usage. Business is a custom plan, with limits set together with you.

## CORS

The endpoint answers cross-origin requests (`Access-Control-Allow-Origin: *`) and `OPTIONS` preflights, so a call from a Worker or an edge function on another origin is not blocked.

Call it from your server or edge, not from a script in your pages. A browser script would put your site key in your page source, and it would never see the crawlers Site Tracking exists to catch, because they do not run scripts.

## Related

- [Any backend](https://ranqo.ai/docs/integrations/site-tracking/any-backend): The install contract, with curl and Python examples.
- [Privacy](https://ranqo.ai/docs/integrations/site-tracking/privacy): What Ranqo stores from each report.
- [Site keys](https://ranqo.ai/docs/integrations/site-tracking/keys): Finding, protecting and revoking a key.
