---
title: "Get job-detail visitors by first-touch channel"
method: GET
path: "/analytics/job-visitors"
tags: ["Analytics"]
---

# Get job-detail visitors by first-touch channel

`GET /analytics/job-visitors`

## Request

- Base URL: `https://api.cavuno.com/v1`
- URL: `https://api.cavuno.com/v1/analytics/job-visitors`
- Auth: HTTP bearer

Paginated unique visitors (sessions) that viewed a job-detail page, grouped by company slug, job slug, and first-touch channel (ADR-0029). First-touch UTM campaign/source/medium are included when the landing href was tagged (empty otherwise). `visitors` counts unique sessions and will always be lower than `views` in the jobs export; the two are not expected to match. Join `companySlug` + `jobSlug` to jobs export `company_slug` + `slug` — unlike `GET /v1/analytics/apply-clicks`, which joins on `jobId` / export `id`. Inclusive UTC `start`/`end` (YYYY-MM-DD) so scheduled pulls can be incremental; defaults to the last 30 completed UTC days ending yesterday. Max range 366 days. Page with `limit` (1–1000, default 100) and `cursor`. Requires `analytics.read`.

## Query parameters

- `start` string: Inclusive range start (UTC date-only YYYY-MM-DD).
- `end` string: Inclusive range end (UTC date-only YYYY-MM-DD).
- `limit` integer: Page size (1–1000). Defaults to 100. Not a board-wide top-N cap.
- `cursor` string: Opaque page cursor from the previous `nextCursor`.

## Response `200`

Job-detail visitors by first-touch channel and campaign.

- object
  - `object` 'list', required
  - `url` string, required
  - `hasMore` boolean, required
  - `nextCursor` string, nullable, required
  - `data` AnalyticsJobVisitor[], required
    - `object` 'analytics_job_visitor', required
    - `companySlug` string, required: Company slug from the job-detail path.
    - `jobSlug` string, required: Frozen job slug from `/companies/{companySlug}/jobs/{jobSlug}`. Join with jobs export `company_slug` + `slug` (not `id`). A deliberate slug rename splits history.
    - `channel` string, required: First-touch channel for the session (same keys as Home Channel).
    - `campaign` string, required: utm_campaign from the first-touch href. Empty when the landing URL was untagged.
    - `utmSource` string, required: utm_source from the first-touch href. Empty when untagged.
    - `utmMedium` string, required: utm_medium from the first-touch href. Empty when untagged.
    - `visitors` integer, required: Unique sessions that viewed this job-detail page, attributed to that first-touch. Always lower than jobs-export `views` (page hits); the two are not expected to match.
  - `count` integer: Total number of results matching the query.
  - `limit` integer: The page size used for this response.
  - `offset` integer: The number of results skipped before this page.
  - `gatedCount` integer: Jobs hidden behind the candidate paywall for the current viewer; absent or 0 for an entitled viewer.

## Other responses

- `default`: An error. Every non-2xx response uses the same envelope; see the Errors section of the introduction.

## Changes

- **2026-10-19** `c34152c38176`: 1 info
  - added the optional property `error/upgrade` to the response with the `default` status

[Operation history](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api/changes/analytics/job-visitors/get.md)

---

[API](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api.md) · [All operations](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api/revisions/d5974dabff14?raw)
