> ## 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 [reading-chain id](/page-views/overview#journey-stitching) that ties this view to an agentified read, when the request carried one.                                                                                                                                             |
| `representation` | string | no       | What your site served for this request: `html` or `markdown`. The [SDK middleware](/page-views/sdk-middleware) derives it from the response content-type; set it yourself when you report by hand. Lets analytics segment journeys by whether the entry got the agent experience. |
| `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 your own site (TypeScript, Python, Go, or Ruby), 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>
