> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeroclick.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Report a page view over REST

> Send one page-content request to POST /v1/page-views from any stack: the key scope, the request body, the fire-and-forget 204, and the errors.

`POST /v1/page-views` records one page view. Use it from any language or framework that has no [SDK middleware](/page-views/sdk-middleware): call it once per page-content `GET` your site serves, from the request that serves it. It answers `204` without waiting for anything downstream, so a report never sits on your response.

## Mint a key

Reporting authenticates with a `zc_` key carrying the [`page-views:write` scope](/page-views/overview#the-page-views-key-scope). In the [dashboard](https://dashboard.zeroclick.io) under **Settings → API keys**, create a key with the **Page views** group's **Write** toggle enabled, and keep it on your marketing site's server.

## Report a view

```sh theme={null}
curl -sS -X POST https://api.zeroclick.io/v1/page-views \
  -H "Authorization: Bearer $ZEROCLICK_PAGE_VIEWS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "seller": "sel_your_seller_id",
    "path": "/pricing",
    "status": 200,
    "capturedAt": "2026-08-26T17:00:00.000Z",
    "userAgent": "Mozilla/5.0 (compatible; GPTBot/1.1; +https://openai.com/gptbot)",
    "accept": "text/markdown, text/html",
    "clientIp": "203.0.113.7",
    "country": "US",
    "referrerHost": "www.google.com"
  }'
```

A success is an empty `204`.

## Request body

Report only page-content `GET` requests — the same thing a reader loads to view a page — so there is no method field; the method is always `GET`.

| Field          | Type   | Required | Notes                                                                                                                                                                            |
| -------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `seller`       | string | yes      | The seller whose site served the page (its public `sel_…` id).                                                                                                                   |
| `path`         | string | yes      | The request path, starting with `/`. Send the path only; any query string or fragment is dropped on our side.                                                                    |
| `status`       | number | no       | The response status you served (100–599).                                                                                                                                        |
| `durationMs`   | number | no       | How long the request took, in milliseconds.                                                                                                                                      |
| `capturedAt`   | string | no       | When your edge observed the request (ISO 8601). Omit it rather than guessing; it is never invented on our side.                                                                  |
| `journeyId`    | string | no       | A [zcj](/concepts/how-zeroclick-works) reading-chain id, when the request carried one.                                                                                           |
| `userAgent`    | string | no       | The visitor's `User-Agent`. Read to derive the viewer id and classify the viewer, then discarded — never stored raw.                                                             |
| `accept`       | string | no       | The visitor's `Accept` header, which sharpens agent detection.                                                                                                                   |
| `clientIp`     | string | no       | The visitor's IP. Combined with the user-agent into the anonymous viewer id and never stored raw.                                                                                |
| `country`      | string | no       | The edge's Cloudflare `cf-ipcountry` value. Clamped to a 2-letter ISO code on our side; sentinels like `XX` are dropped.                                                         |
| `referrerHost` | string | no       | The referrer's host, e.g. `www.google.com`. Send the host only; if you send a full URL we reduce it to the host, but the referrer's path and query should never leave your site. |

Forward the visitor's `userAgent`, `accept`, and `clientIp` from the original request, not your server's — the request reaches ZeroClick from your backend, so its own headers describe your server, not the reader. Report only what a reader loads to view a page; skip assets and redirects, exactly as the [middleware does](/page-views/sdk-middleware).

## Response and errors

| Status | Meaning                                                                          |
| ------ | -------------------------------------------------------------------------------- |
| `204`  | Recorded. The body is empty.                                                     |
| `400`  | The body failed validation (for example a `path` that does not start with `/`).  |
| `403`  | The key is missing the `page-views:write` scope, or resolves to no organization. |
| `404`  | `seller` does not name a seller in the key's organization.                       |
| `429`  | Per-organization rate limit exceeded.                                            |

Reporting is fire-and-forget by design: send the beacon without blocking your response, and treat any failure as a no-op so a reporting problem never affects the page. The [SDK middleware](/page-views/sdk-middleware) does exactly this for you.

## Next steps

<Columns cols={2}>
  <Card title="SDK middleware" icon="package" href="/page-views/sdk-middleware">
    Report automatically from a TypeScript site, fail-open.
  </Card>

  <Card title="Overview" icon="book-open" href="/page-views/overview">
    What is captured, how viewers are classified, and the privacy model.
  </Card>
</Columns>
