Vision

For instructions on how to authenticate to use this endpoint, see API overview.

Endpoints

POST
GET
GET
POST
GET
GET
POST
GET
GET
POST
GET
PATCH
DELETE
POST
POST
POST
POST
GET
POST
GET

Create vision observations viewed

Record that the calling user opened this observation. Idempotent.

Required API key scopes

replay_scanner:readsession_recording:read

Path parameters

  • id
    string

Example request

POST /api/projects/:project_id/vision/observations/:id/viewed
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/observations/:id/viewed/

Example response

Status 204 No response body


Retrieve vision observations search suggestions

Example searches drawn from recent observations, for the Search tab's empty state. Reads what the scheduled refresher stored; search_viewed records the view separately so this GET has no side effect.

Required API key scopes

replay_scanner:readsession_recording:read

Query parameters

  • scanner_id
    string

Response


Example request

GET /api/projects/:project_id/vision/observations/search_suggestions
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/observations/search_suggestions/

Example response

Status 200
RESPONSE
{
"queries": [
"string"
]
}

Create vision observations search viewed

Record that the Search tab showed suggestions for this scope. The scheduled refresher serves viewed scanners first, so the stamp lives on a CSRF-protected POST rather than the read.

Required API key scopes

replay_scanner:readsession_recording:read

Request parameters

  • scanner_id
    string

Example request

POST /api/projects/:project_id/vision/observations/search_viewed
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/observations/search_viewed/\
-d scanner_id="string"

Example response

Status 204 No response body

Retrieve environment vision quota

Required API key scopes

replay_scanner:read

Response


Example request

GET /api/projects/:project_id/vision/quota
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/quota/

Example response

Status 200
RESPONSE
{
"credit_limit": 0,
"credits_used": 0,
"credits_settled": 0,
"credits_reserved": 0,
"remaining": 0,
"exhausted": true,
"period_start": "2019-08-24T14:15:22Z",
"period_end": "2019-08-24T14:15:22Z",
"projected_monthly_credits": 0,
"scanners_monthly_credits": 0,
"backfills_committed_credits": 0,
"free_monthly_credits": 0
}

Retrieve environment vision quota spend series

Required API key scopes

replay_scanner:read

Response


Example request

GET /api/projects/:project_id/vision/quota/spend_series
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/quota/spend_series/

Example response

Status 200
RESPONSE
{
"period_start": "2019-08-24T14:15:22Z",
"period_end": "2019-08-24T14:15:22Z",
"days": [
{
"date": "2019-08-24",
"credits": 0
}
]
}

Create vision requests

Scan sessions with a saved scanner or an inline question. Poll the returned request for results.

Required API key scopes

replay_scanner:writesession_recording:read

Request parameters

  • session_ids
    array
  • scanner_id
    string
  • inline
  • idempotency_key
    string
  • reference
    string
    Default:
  • wait_for_session_end
    boolean
    Default: false

Response


Example request

POST /api/projects/:project_id/vision/requests
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/requests/\
-d session_ids="array"

Example response

Status 200 A request with this `idempotency_key` already exists. Nothing new was started.
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"status": "running",
"scanner_id": "43593f58-da3f-45f0-a7bf-8763ef29bdf1",
"reference": "string",
"created_at": "2019-08-24T14:15:22Z",
"sessions": [
{
"session_id": "string",
"scan_outcome": "started",
"state": "pending",
"observation_id": "d5b663f3-1b87-4f94-9f66-dbd8d5553132",
"scanner_result": {
"model_output": null,
"signals_count": 0,
"experiment_variant": "string",
"session_duration_s": 0
}
}
]
}
Status 202
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"status": "running",
"scanner_id": "43593f58-da3f-45f0-a7bf-8763ef29bdf1",
"reference": "string",
"created_at": "2019-08-24T14:15:22Z",
"sessions": [
{
"session_id": "string",
"scan_outcome": "started",
"state": "pending",
"observation_id": "d5b663f3-1b87-4f94-9f66-dbd8d5553132",
"scanner_result": {
"model_output": null,
"signals_count": 0,
"experiment_variant": "string",
"session_duration_s": 0
}
}
]
}
Status 409 This `idempotency_key` already names a request made by another caller.
RESPONSE
{
"detail": "string"
}

Retrieve vision requests

Start scans for named sessions from code, and read their results back through one request id.

Required API key scopes

replay_scanner:writesession_recording:read

Path parameters

  • id
    string

Response


Example request

GET /api/projects/:project_id/vision/requests/:id
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/requests/:id/

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"status": "running",
"scanner_id": "43593f58-da3f-45f0-a7bf-8763ef29bdf1",
"reference": "string",
"created_at": "2019-08-24T14:15:22Z",
"sessions": [
{
"session_id": "string",
"scan_outcome": "started",
"state": "pending",
"observation_id": "d5b663f3-1b87-4f94-9f66-dbd8d5553132",
"scanner_result": {
"model_output": null,
"signals_count": 0,
"experiment_variant": "string",
"session_duration_s": 0
}
}
]
}

List all vision scanners

CRUD for Replay Vision scanners.

Required API key scopes

replay_scanner:read

Query parameters

  • created_by
    string
  • emits_signals
    boolean
  • enabled
    string
  • experiment_id
    string
  • limit
    integer
  • offset
    integer
  • order_by
    string
    One of: "-created_at""-created_by""-credits_this_month""-enabled""-name""-sampling_rate""-scanner_type""-updated_at""created_at""created_by""credits_this_month""enabled""name""sampling_rate""scanner_type""updated_at"
  • scanner_type
    string
  • search
    string
  • tags
    string

Response


Example request

GET /api/projects/:project_id/vision/scanners
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/

Example response

Status 200
RESPONSE
{
"count": 123,
"next": "http://api.example.org/accounts/?offset=400&limit=100",
"previous": "http://api.example.org/accounts/?offset=200&limit=100",
"results": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"description": "string",
"tags": [
"string"
],
"scanner_type": "monitor",
"goal": "string",
"creation_method": "ai",
"scanner_config": null,
"prompt_question": "string",
"query": null,
"sampling_rate": 1,
"sampling_mode": "focused",
"credit_limit": 1,
"free_only": true,
"provider": "google",
"model": "gemini-3.5-flash-lite",
"enabled": true,
"emits_signals": true,
"experiment_targeting": {
"experiment_id": 1,
"variant": "string"
},
"scanner_version": 0,
"estimated_monthly_observations": 0,
"estimated_at": "2019-08-24T14:15:22Z",
"credits_per_observation": 0,
"estimated_monthly_credits": 0,
"credits_this_month": 0,
"observations_this_month": 0,
"credits_used_against_limit": 0,
"limit_from_free_credits": true,
"limit_reached": true,
"sweep_throttle_factor": 0,
"dashboard_id": 0,
"dashboard_suggested": true,
"last_swept_at": "2019-08-24T14:15:22Z",
"created_at": "2019-08-24T14:15:22Z",
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"updated_at": "2019-08-24T14:15:22Z",
"user_access_level": "string"
}
]
}

Create vision scanners

CRUD for Replay Vision scanners.

Required API key scopes

replay_scanner:writesession_recording:read

Request parameters

  • name
    string
  • description
    string
  • tags
    array
  • scanner_type
  • goal
    string | null
  • creation_method
  • scanner_config
  • query
  • sampling_rate
    number
  • sampling_mode
  • credit_limit
    integer | null
  • free_only
    boolean
  • provider
  • model
  • enabled
    boolean
  • emits_signals
    boolean
  • experiment_targeting

Response


Example request

POST /api/projects/:project_id/vision/scanners
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/\
-d name="string",\
-d scanner_type=undefined,\
-d scanner_config=undefined,\
-d model=undefined

Example response

Status 201
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"description": "string",
"tags": [
"string"
],
"scanner_type": "monitor",
"goal": "string",
"creation_method": "ai",
"scanner_config": null,
"prompt_question": "string",
"query": null,
"sampling_rate": 1,
"sampling_mode": "focused",
"credit_limit": 1,
"free_only": true,
"provider": "google",
"model": "gemini-3.5-flash-lite",
"enabled": true,
"emits_signals": true,
"experiment_targeting": {
"experiment_id": 1,
"variant": "string"
},
"scanner_version": 0,
"estimated_monthly_observations": 0,
"estimated_at": "2019-08-24T14:15:22Z",
"credits_per_observation": 0,
"estimated_monthly_credits": 0,
"credits_this_month": 0,
"observations_this_month": 0,
"credits_used_against_limit": 0,
"limit_from_free_credits": true,
"limit_reached": true,
"sweep_throttle_factor": 0,
"dashboard_id": 0,
"dashboard_suggested": true,
"last_swept_at": "2019-08-24T14:15:22Z",
"created_at": "2019-08-24T14:15:22Z",
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"updated_at": "2019-08-24T14:15:22Z",
"user_access_level": "string"
}

Retrieve vision scanners

CRUD for Replay Vision scanners.

Required API key scopes

replay_scanner:read

Path parameters

  • id
    string

Response


Example request

GET /api/projects/:project_id/vision/scanners/:id
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"description": "string",
"tags": [
"string"
],
"scanner_type": "monitor",
"goal": "string",
"creation_method": "ai",
"scanner_config": null,
"prompt_question": "string",
"query": null,
"sampling_rate": 1,
"sampling_mode": "focused",
"credit_limit": 1,
"free_only": true,
"provider": "google",
"model": "gemini-3.5-flash-lite",
"enabled": true,
"emits_signals": true,
"experiment_targeting": {
"experiment_id": 1,
"variant": "string"
},
"scanner_version": 0,
"estimated_monthly_observations": 0,
"estimated_at": "2019-08-24T14:15:22Z",
"credits_per_observation": 0,
"estimated_monthly_credits": 0,
"credits_this_month": 0,
"observations_this_month": 0,
"credits_used_against_limit": 0,
"limit_from_free_credits": true,
"limit_reached": true,
"sweep_throttle_factor": 0,
"dashboard_id": 0,
"dashboard_suggested": true,
"last_swept_at": "2019-08-24T14:15:22Z",
"created_at": "2019-08-24T14:15:22Z",
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"updated_at": "2019-08-24T14:15:22Z",
"user_access_level": "string"
}

Update vision scanners

CRUD for Replay Vision scanners.

Required API key scopes

replay_scanner:writesession_recording:read

Path parameters

  • id
    string

Request parameters

  • name
    string
  • description
    string
  • tags
    array
  • scanner_type
  • goal
    string | null
  • creation_method
  • scanner_config
  • query
  • sampling_rate
    number
  • sampling_mode
  • credit_limit
    integer | null
  • free_only
    boolean
  • provider
  • model
  • enabled
    boolean
  • emits_signals
    boolean
  • experiment_targeting

Response


Example request

PATCH /api/projects/:project_id/vision/scanners/:id
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl -X PATCH \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/\
-d name="string"

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"description": "string",
"tags": [
"string"
],
"scanner_type": "monitor",
"goal": "string",
"creation_method": "ai",
"scanner_config": null,
"prompt_question": "string",
"query": null,
"sampling_rate": 1,
"sampling_mode": "focused",
"credit_limit": 1,
"free_only": true,
"provider": "google",
"model": "gemini-3.5-flash-lite",
"enabled": true,
"emits_signals": true,
"experiment_targeting": {
"experiment_id": 1,
"variant": "string"
},
"scanner_version": 0,
"estimated_monthly_observations": 0,
"estimated_at": "2019-08-24T14:15:22Z",
"credits_per_observation": 0,
"estimated_monthly_credits": 0,
"credits_this_month": 0,
"observations_this_month": 0,
"credits_used_against_limit": 0,
"limit_from_free_credits": true,
"limit_reached": true,
"sweep_throttle_factor": 0,
"dashboard_id": 0,
"dashboard_suggested": true,
"last_swept_at": "2019-08-24T14:15:22Z",
"created_at": "2019-08-24T14:15:22Z",
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"updated_at": "2019-08-24T14:15:22Z",
"user_access_level": "string"
}

Delete vision scanners

CRUD for Replay Vision scanners.

Required API key scopes

replay_scanner:write

Path parameters

  • id
    string

Example request

DELETE /api/projects/:project_id/vision/scanners/:id
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl -X DELETE \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/

Example response

Status 204 No response body

Create vision scanners affected cohort

Save the users this scanner matched as a static cohort, for surveys, funnels, and retention analysis.

Required API key scopes

replay_scanner:readsession_recording:readcohort:write

Path parameters

  • id
    string

Request parameters

  • window_days
    integer
    Default: 30
  • verdict
  • tag
    string | null
  • min_score
    number | null
  • max_score
    number | null

Response


Example request

POST /api/projects/:project_id/vision/scanners/:id/affected_cohort
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/affected_cohort/\
-d window_days="integer"

Example response

Status 201
RESPONSE
{
"cohort_id": 0,
"name": "string",
"users_in_cohort": 0,
"window_days": 0
}

Create vision scanners bulk observe

Apply this scanner to many sessions on demand. Starts as many as fit under the in-flight caps and monthly credit quota, reporting the rest as skipped rather than failing the batch.

Required API key scopes

replay_scanner:writesession_recording:read

Path parameters

  • id
    string

Request parameters

  • session_ids
    array

Response


Example request

POST /api/projects/:project_id/vision/scanners/:id/bulk_observe
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/bulk_observe/\
-d session_ids="array"

Example response

Status 202
RESPONSE
{
"started": 0,
"results": [
{
"session_id": "string",
"scan_outcome": "started"
}
]
}

Create vision scanners create dashboard

Create a dashboard that charts this scanner's observations, and link it to the scanner.

The tiles depend on the scanner type: who the scanner matched, which accounts they belong to, type-specific breakdowns, and the latest matching recordings. Calling it again returns the existing dashboard rather than a second one.

Required API key scopes

replay_scanner:readsession_recording:readdashboard:writeinsight:write

Path parameters

  • id
    string

Response


Example request

POST /api/projects/:project_id/vision/scanners/:id/create_dashboard
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/create_dashboard/

Example response

Status 200 The scanner already had a dashboard.
RESPONSE
{
"dashboard_id": 0,
"name": "string",
"created": true
}
Status 201
RESPONSE
{
"dashboard_id": 0,
"name": "string",
"created": true
}

Create vision scanners duplicate

Copy a scanner into a new disabled scanner named "<name> (copy)".

Copies the stored model row rather than the serializer's read representation, so a query that no longer validates survives the copy; duplicating through the create endpoint would silently drop it. Experiment targeting is the exception and follows the read path instead. Unlike create, no digest is provisioned: the copy starts disabled and unreviewed.

Required API key scopes

replay_scanner:writesession_recording:read

Path parameters

  • id
    string

Response


Example request

POST /api/projects/:project_id/vision/scanners/:id/duplicate
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/duplicate/

Example response

Status 201
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"description": "string",
"tags": [
"string"
],
"scanner_type": "monitor",
"goal": "string",
"creation_method": "ai",
"scanner_config": null,
"prompt_question": "string",
"query": null,
"sampling_rate": 1,
"sampling_mode": "focused",
"credit_limit": 1,
"free_only": true,
"provider": "google",
"model": "gemini-3.5-flash-lite",
"enabled": true,
"emits_signals": true,
"experiment_targeting": {
"experiment_id": 1,
"variant": "string"
},
"scanner_version": 0,
"estimated_monthly_observations": 0,
"estimated_at": "2019-08-24T14:15:22Z",
"credits_per_observation": 0,
"estimated_monthly_credits": 0,
"credits_this_month": 0,
"observations_this_month": 0,
"credits_used_against_limit": 0,
"limit_from_free_credits": true,
"limit_reached": true,
"sweep_throttle_factor": 0,
"dashboard_id": 0,
"dashboard_suggested": true,
"last_swept_at": "2019-08-24T14:15:22Z",
"created_at": "2019-08-24T14:15:22Z",
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"updated_at": "2019-08-24T14:15:22Z",
"user_access_level": "string"
}

Retrieve vision scanners impact

Affected sessions and users for this scanner over the trailing window.

Required API key scopes

replay_scanner:readsession_recording:read

Path parameters

  • id
    string

Query parameters

  • max_score
    number | null
  • min_score
    number | null
  • tag
    string | null
  • verdict
    string | null
    One of: "yes""no""inconclusive"
  • window_days
    integer
    Default: 30

Response


Example request

GET /api/projects/:project_id/vision/scanners/:id/impact
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/impact/

Example response

Status 200
RESPONSE
{
"affected_sessions": 0,
"affected_users": 0,
"sessions_without_user": 0,
"window_days": 0
}

Create vision scanners observe

Apply this scanner to one specific session, on demand. Returns 202 with the workflow handle.

Required API key scopes

replay_scanner:writesession_recording:read

Path parameters

  • id
    string

Request parameters

  • session_id
    string

Response


Example request

POST /api/projects/:project_id/vision/scanners/:id/observe
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/observe/\
-d session_id="string"

Example response

Status 200
RESPONSE
{
"observation_id": "d5b663f3-1b87-4f94-9f66-dbd8d5553132"
}
Status 202
RESPONSE
{
"workflow_id": "string"
}
Status 503 The observation workflow couldn't be started.
RESPONSE
{
"detail": "string"
}

Retrieve vision scanners self driving stats

What self-driving did with this scanner's signals: reports contributed to and PRs opened.

Required API key scopes

replay_scanner:readtask:read

Path parameters

  • id
    string

Response


Example request

GET /api/projects/:project_id/vision/scanners/:id/self_driving_stats
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/vision/scanners/:id/self_driving_stats/

Example response

Status 200
RESPONSE
{
"signals_emitted": 0,
"reports_contributed": 0,
"prs_opened": 0,
"prs_merged": 0,
"reports": [
{
"id": "string",
"title": "string",
"status": "string"
}
],
"pull_requests": [
{
"url": "string",
"merged": true
}
]
}