Signals

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

Endpoints

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

Create signals reports reingest

Re-ingest a report's signals (same team access as other report actions).

Required API key scopes

task:write

Path parameters

  • id
    string

Response


Example request

POST /api/projects/:project_id/signals/reports/:id/reingest
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/signals/reports/:id/reingest/

Example response

Status 200 A re-ingestion is already running.
RESPONSE
{
"status": "reingestion_started",
"report_id": "5ed7905a-4735-4cf7-b1ab-521e066fb971"
}
Status 202 Re-ingestion started.
RESPONSE
{
"status": "reingestion_started",
"report_id": "5ed7905a-4735-4cf7-b1ab-521e066fb971"
}

Delete signals reports reviewers me

Take the calling user off this report's suggested reviewers, leaving the other reviewers as they are. The report itself is untouched: it stays open for whoever is left, and for the project. Succeeds whether or not the caller was on the list.

Required API key scopes

task:write

Path parameters

  • id
    string

Example request

DELETE /api/projects/:project_id/signals/reports/:id/reviewers/me
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/signals/reports/:id/reviewers/me/

Example response

Status 204 The caller is no longer a suggested reviewer.
Status 400 A reviewer who stays no longer resolves to a member of this team.

Retrieve signals reports signals

Fetch all signals for a report from ClickHouse, including full metadata.

Required API key scopes

task:read

Path parameters

  • id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"report": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"title": "string",
"summary": "string",
"summary_lead": "string",
"status": "potential",
"total_weight": 0.1,
"signal_count": 0,
"signals_at_run": 0,
"collapsed_note_count": 0,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"artefact_count": 0,
"charts": [
{
"chart_id": "string",
"title": "string",
"query": null,
"caption": "string",
"size": "small"
}
],
"metrics": [
{
"metric_id": "string",
"title": "string",
"kind": "affected_users",
"role": "supporting",
"value": 0,
"value_at": "2019-08-24T14:15:22Z",
"series": [
0.1
],
"value_format": "number",
"unit": "string",
"query": null,
"caption": "string",
"goal_value": 0,
"goal_direction": "at_most",
"goal_grain": "whole_window",
"decision_window_days": 1,
"minimum_data_points": 1
}
],
"suggested_prompts": [
"string"
],
"source_suggestion": {
"product": "logs",
"reason": "string"
},
"priority": "string",
"actionability": "string",
"already_addressed": true,
"dismissal_reason": "string",
"dismissal_note": "string",
"repo_slug": "string",
"is_suggested_reviewer": false,
"source_products": [
"string"
],
"scout_name": "string",
"implementation_pr_url": "string",
"pull_requests": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"url": "http://example.com",
"state": "unknown",
"merged": true,
"review_decision": "approved",
"merged_at": "2019-08-24T14:15:22Z",
"attached_by": {
"kind": "user",
"user": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"first_name": "string",
"last_name": "string",
"email": "user@example.com"
},
"agent": "string",
"task_id": "736fde4d-9029-4915-8189-01353d6982cb"
},
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"attached_at": "2019-08-24T14:15:22Z"
}
],
"implementation_pr_state": "unknown",
"implementation_pr_merged": true,
"tracker_issue_url": "string",
"tracker_issue_reference": "string",
"tracker_issue_error": "string",
"work_state": "unclaimed",
"assignee": {
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"kind": "user",
"user": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"first_name": "string",
"last_name": "string",
"email": "user@example.com"
},
"task_id": "736fde4d-9029-4915-8189-01353d6982cb",
"agent": "string",
"claimed_at": "2019-08-24T14:15:22Z"
},
"refund": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"reason": "pr_incorrect",
"note": "string",
"billing_path": "excluded",
"credits": 0,
"pr_url": "string",
"pr_run_created_at": "2019-08-24T14:15:22Z",
"credit_amount_usd": "string",
"billing_synced": true,
"created_at": "2019-08-24T14:15:22Z"
},
"refund_ineligibility_reason": "already_refunded",
"billing_exempt_reason": "posthog_health_check",
"channel_id": "bbe8aa76-a4bb-46f6-a785-df8e831cc459",
"ranking": {
"served_key": "string",
"model_name": "string",
"model_version": "string",
"manifest_version": "string",
"scored_at": "2019-08-24T14:15:22Z",
"scores": {
"property1": 0.1,
"property2": 0.1
},
"lifts": {
"property1": 0.1,
"property2": 0.1
},
"readable_heads": [
"string"
],
"stale": true
}
},
"signals": [
{
"signal_id": "string",
"content": "string",
"source_product": "session_replay",
"source_type": "session_analysis_cluster",
"source_id": "string",
"weight": 0.1,
"timestamp": "2019-08-24T14:15:22Z",
"extra": {
"session_id": "string",
"segment_title": "string",
"start_time": "string",
"end_time": "string",
"problem_type": "confusion",
"distinct_id": "string",
"session_start_time": null,
"session_end_time": null,
"session_duration": null,
"session_active_seconds": null,
"exported_asset_id": null,
"event_history": null
},
"match_metadata": {
"parent_signal_id": "string",
"match_query": "string",
"reason": "string",
"specificity": {
"pr_title": "string",
"specific_enough": true,
"reason": "string"
}
}
}
]
}

Create signals reports state

Transition a report to a new state. The model validates allowed transitions, except that a verdict the report already holds (dismissing a suppressed report, resolving a resolved one) is a 200 that records the dismissal feedback without touching the status.

The request body is validated by SignalReportStateRequestSerializer — only the fields it declares (state, dismissal_reason, dismissal_note, corrected_repository, snooze_for) are read, and only snooze_for is ever forwarded to transition_to. Any other key is ignored, so internal transition_to kwargs (reset_weight, error, ...) can't be injected.

Body: { "state": "suppressed" | "potential" | "resolved", # Optional dismissal feedback (honored when state == "suppressed", "potential", or "resolved"): "dismissal_reason": "<canonical reason code, see SIGNAL_REPORT_DISMISSAL_REASON_CHOICES>", "dismissal_note": "free-form text", # Optional, only allowed with dismissal_reason == "wrong_repo": "corrected_repository": "owner/repo the report should have targeted", # Optional, only honored for state == "potential": "snooze_for": <number of additional signals before re-promotion>, }

Required API key scopes

task:write

Path parameters

  • id
    string

Request parameters

  • state
  • dismissal_reason
  • dismissal_note
    string
  • corrected_repository
    string
  • snooze_for
    integer

Response


Example request

POST /api/projects/:project_id/signals/reports/:id/state
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/signals/reports/:id/state/\
-d state=undefined

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"title": "string",
"summary": "string",
"summary_lead": "string",
"status": "potential",
"total_weight": 0.1,
"signal_count": 0,
"signals_at_run": 0,
"collapsed_note_count": 0,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"artefact_count": 0,
"charts": [
{
"chart_id": "string",
"title": "string",
"query": null,
"caption": "string",
"size": "small"
}
],
"metrics": [
{
"metric_id": "string",
"title": "string",
"kind": "affected_users",
"role": "supporting",
"value": 0,
"value_at": "2019-08-24T14:15:22Z",
"series": [
0.1
],
"value_format": "number",
"unit": "string",
"query": null,
"caption": "string",
"goal_value": 0,
"goal_direction": "at_most",
"goal_grain": "whole_window",
"decision_window_days": 1,
"minimum_data_points": 1
}
],
"suggested_prompts": [
"string"
],
"source_suggestion": {
"product": "logs",
"reason": "string"
},
"priority": "string",
"actionability": "string",
"already_addressed": true,
"dismissal_reason": "string",
"dismissal_note": "string",
"repo_slug": "string",
"is_suggested_reviewer": false,
"source_products": [
"string"
],
"scout_name": "string",
"implementation_pr_url": "string",
"pull_requests": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"url": "http://example.com",
"state": "unknown",
"merged": true,
"review_decision": "approved",
"merged_at": "2019-08-24T14:15:22Z",
"attached_by": {
"kind": "user",
"user": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"first_name": "string",
"last_name": "string",
"email": "user@example.com"
},
"agent": "string",
"task_id": "736fde4d-9029-4915-8189-01353d6982cb"
},
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"attached_at": "2019-08-24T14:15:22Z"
}
],
"implementation_pr_state": "unknown",
"implementation_pr_merged": true,
"tracker_issue_url": "string",
"tracker_issue_reference": "string",
"tracker_issue_error": "string",
"work_state": "unclaimed",
"assignee": {
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"kind": "user",
"user": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"first_name": "string",
"last_name": "string",
"email": "user@example.com"
},
"task_id": "736fde4d-9029-4915-8189-01353d6982cb",
"agent": "string",
"claimed_at": "2019-08-24T14:15:22Z"
},
"refund": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"reason": "pr_incorrect",
"note": "string",
"billing_path": "excluded",
"credits": 0,
"pr_url": "string",
"pr_run_created_at": "2019-08-24T14:15:22Z",
"credit_amount_usd": "string",
"billing_synced": true,
"created_at": "2019-08-24T14:15:22Z"
},
"refund_ineligibility_reason": "already_refunded",
"billing_exempt_reason": "posthog_health_check",
"channel_id": "bbe8aa76-a4bb-46f6-a785-df8e831cc459",
"ranking": {
"served_key": "string",
"model_name": "string",
"model_version": "string",
"manifest_version": "string",
"scored_at": "2019-08-24T14:15:22Z",
"scores": {
"property1": 0.1,
"property2": 0.1
},
"lifts": {
"property1": 0.1,
"property2": 0.1
},
"readable_heads": [
"string"
],
"stale": true
}
}

Create signals reports viewed

Record that the caller opened this report's detail view. One row per person per report is kept (repeat views bump a counter), and the record counts as consumption evidence for the scout that authored the report — scouts whose reports nobody consumes are eventually paused. Intended as fire-and-forget from the inbox UI when a person opens a report. Only browser-session requests leave a record; a call with any other credential (personal API key, OAuth token) returns 204 but records nothing.

Required API key scopes

task:read

Path parameters

  • id
    string

Example request

POST /api/projects/:project_id/signals/reports/: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/signals/reports/:id/viewed/

Example response

Status 204 No response body

List all signals report artefacts

List every artefact on a report — the full work log: signal findings (the evidence behind the report), status judgments (safety / actionability / priority, repo selection, suggested reviewers — the newest row of each status type is canonical), and log entries (code references, commits, task runs, notes). suggested_reviewers content is enriched with PostHog user info at read time.

Required API key scopes

task:read

Path parameters

  • report_id
    string

Query parameters

  • limit
    integer
  • offset
    integer

Response


Example request

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

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": [
{
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"pull_request_id": "5c951947-9b15-4693-a43b-42f8e37fd0d1",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"type": "video_segment",
"content": {},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"actor_kind": "user",
"actor_agent": "string",
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"first_name": "string",
"last_name": "string",
"email": "user@example.com"
},
"task_id": "736fde4d-9029-4915-8189-01353d6982cb"
}
]
}

Create signals report artefacts

Append an artefact to a report (see artefact_type for the writable types). Everything is append-only: log entries (code reference, commit, task run, note) accumulate, while status types (safety / actionability / priority judgments, repo selection, suggested reviewers, channel assignments) are latest-wins — appending a new version supersedes the previous one as the report's canonical status. Content is validated against the type's schema.

Required API key scopes

task:write

Path parameters

  • report_id
    string

Request parameters

  • claim_id
    string
  • artefact_type
    string
  • content

Response


Example request

POST /api/projects/:project_id/signals/reports/:report_id/artefacts
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/signals/reports/:report_id/artefacts/\
-d artefact_type="string",\
-d content=undefined

Example response

Status 201 Artefact created.
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"report_id": "5ed7905a-4735-4cf7-b1ab-521e066fb971",
"type": "string",
"content": null,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"task_id": "736fde4d-9029-4915-8189-01353d6982cb"
}
Status 400 Unknown artefact type, content not matching the type's schema, or an invalid X-PostHog-Task-Id header.
Status 404 Report not found for this project.

Retrieve signals report artefacts

Get one artefact by id, content parsed (and reviewers enriched) the same way as the list.

Required API key scopes

task:read

Path parameters

  • id
    string
  • report_id
    string

Response


Example request

GET /api/projects/:project_id/signals/reports/:report_id/artefacts/: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/signals/reports/:report_id/artefacts/:id/

Example response

Status 200
RESPONSE
{
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"pull_request_id": "5c951947-9b15-4693-a43b-42f8e37fd0d1",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"type": "video_segment",
"content": {},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"actor_kind": "user",
"actor_agent": "string",
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"first_name": "string",
"last_name": "string",
"email": "user@example.com"
},
"task_id": "736fde4d-9029-4915-8189-01353d6982cb"
}

Update signals report artefacts

Replace the content of an existing artefact, addressed by id. The new content is validated against the artefact's type schema. Editing the latest row of a status type changes the report's canonical status (latest-wins); to re-assess while keeping history, append a new artefact instead. Attribution is creation-time only — edits don't reassign it.

Required API key scopes

task:write

Path parameters

  • id
    string
  • report_id
    string

Request parameters

  • content

Response


Example request

PATCH /api/projects/:project_id/signals/reports/:report_id/artefacts/: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/signals/reports/:report_id/artefacts/:id/\
-d content=undefined

Example response

Status 200 Artefact updated.
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"report_id": "5ed7905a-4735-4cf7-b1ab-521e066fb971",
"type": "string",
"content": null,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"task_id": "736fde4d-9029-4915-8189-01353d6982cb"
}
Status 400 Content does not match the artefact type's schema.
Status 404 Artefact not found for this report / project.

Delete signals report artefacts

Delete an artefact, addressed by id. Deleting the latest row of a status type reverts the report's canonical status to the previous version (latest-wins over what remains). task_run artefacts are an append-only work log and cannot be deleted. Neither can the types this API cannot write, which the pipeline owns: autostart_skip, check_cancelled, check_expired, check_result, check_scheduled, code_review, impact_measurement_plan, implementation_decision, implementation_dispatch, implementation_handover, implementation_replacement, pull_request, ranking_score, report_link, summary_change, task_run, title_change, video_segment, work_claim, work_release.

Required API key scopes

task:write

Path parameters

  • id
    string
  • report_id
    string

Example request

DELETE /api/projects/:project_id/signals/reports/:report_id/artefacts/: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/signals/reports/:report_id/artefacts/:id/

Example response

Status 204 Artefact deleted.
Status 400 Artefact type cannot be deleted through the API.
Status 404 Artefact not found for this report / project.

Retrieve signals report artefacts

Fetch the unified diff for a commit artefact via the team's GitHub integration. A commit linked to a report pull request uses GitHub's durable pull request diff. A commit without that link compares the branch's current tip with the default branch.

Required API key scopes

task:read

Path parameters

  • id
    string
  • report_id
    string

Response


Example request

GET /api/projects/:project_id/signals/reports/:report_id/artefacts/:id/diff
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/signals/reports/:report_id/artefacts/:id/diff/

Example response

Status 200 The pull request diff, or the branch diff when no pull request is linked.
RESPONSE
{
"diff": "string",
"truncated": true
}
Status 400 Artefact is not a commit, or is missing repository/branch.
Status 404 Artefact not found, or no GitHub integration can access the repository.
Status 502 GitHub could not produce the diff (branch not found, fetch failed).

List all signals report checks

List the forward-looking checks on a report. A check says what must stay true after the report was acted on, and the coordinator records each verdict as a check_result artefact on the report.

Required API key scopes

task:read

Path parameters

  • report_id
    string

Query parameters

  • limit
    integer
  • offset
    integer

Response


Example request

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

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",
"title": "string",
"rationale": "string",
"kind": "metric_threshold",
"status": "pending",
"config": {
"metric_id": null,
"query": null,
"comparison": {
"operator": "lte",
"value": null,
"bounds": null
},
"baseline_value": null,
"metric_kind": null,
"value_format": null,
"unit": null
},
"approved_at": "2019-08-24T14:15:22Z",
"next_run_at": "2019-08-24T14:15:22Z",
"soak_minutes": 0,
"run_interval_minutes": 0,
"runs_remaining": 0,
"expires_at": "2019-08-24T14:15:22Z",
"last_run_at": "2019-08-24T14:15:22Z",
"last_outcome": "passed",
"dispatched_at": "2019-08-24T14:15:22Z",
"consecutive_errors": 0,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z"
}
]
}

Retrieve signals report checks

Checks attached to a signal report: read, approve, replace metrics, and cancel.

There is no create here. A check is authored by a scout run or by the research pipeline, both through report_check_authoring.create_check. An agent check puts its author's prose in front of a privileged scout run, and task:write does not authorize that, so no caller-facing endpoint accepts one. Anyone who can read the report can read its checks, and a person can still stop one.

There is no in-place update: a check is a claim about the future, and editing its threshold after a result would make the recorded verdict unreadable. Replacing an open metric check cancels the old row and creates a new one in one transaction.

Required API key scopes

task:read

Path parameters

  • id
    string
  • report_id
    string

Response


Example request

GET /api/projects/:project_id/signals/reports/:report_id/checks/: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/signals/reports/:report_id/checks/:id/

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"title": "string",
"rationale": "string",
"kind": "metric_threshold",
"status": "pending",
"config": {
"metric_id": null,
"query": null,
"comparison": {
"operator": "lte",
"value": null,
"bounds": null
},
"baseline_value": null,
"metric_kind": null,
"value_format": null,
"unit": null
},
"approved_at": "2019-08-24T14:15:22Z",
"next_run_at": "2019-08-24T14:15:22Z",
"soak_minutes": 0,
"run_interval_minutes": 0,
"runs_remaining": 0,
"expires_at": "2019-08-24T14:15:22Z",
"last_run_at": "2019-08-24T14:15:22Z",
"last_outcome": "passed",
"dispatched_at": "2019-08-24T14:15:22Z",
"consecutive_errors": 0,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z"
}

Delete signals report checks

Stop a check that is still open — active, or pending its report resolving. Its recorded results stay on the report.

Required API key scopes

task:write

Path parameters

  • id
    string
  • report_id
    string

Response


Example request

DELETE /api/projects/:project_id/signals/reports/:report_id/checks/: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/signals/reports/:report_id/checks/:id/

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"title": "string",
"rationale": "string",
"kind": "metric_threshold",
"status": "pending",
"config": {
"metric_id": null,
"query": null,
"comparison": {
"operator": "lte",
"value": null,
"bounds": null
},
"baseline_value": null,
"metric_kind": null,
"value_format": null,
"unit": null
},
"approved_at": "2019-08-24T14:15:22Z",
"next_run_at": "2019-08-24T14:15:22Z",
"soak_minutes": 0,
"run_interval_minutes": 0,
"runs_remaining": 0,
"expires_at": "2019-08-24T14:15:22Z",
"last_run_at": "2019-08-24T14:15:22Z",
"last_outcome": "passed",
"dispatched_at": "2019-08-24T14:15:22Z",
"consecutive_errors": 0,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z"
}

Create signals report checks approve

Record a person's quality signal. Approval does not affect scheduling or execution.

Required API key scopes

task:write

Path parameters

  • id
    string
  • report_id
    string

Response


Example request

POST /api/projects/:project_id/signals/reports/:report_id/checks/:id/approve
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/signals/reports/:report_id/checks/:id/approve/

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"title": "string",
"rationale": "string",
"kind": "metric_threshold",
"status": "pending",
"config": {
"metric_id": null,
"query": null,
"comparison": {
"operator": "lte",
"value": null,
"bounds": null
},
"baseline_value": null,
"metric_kind": null,
"value_format": null,
"unit": null
},
"approved_at": "2019-08-24T14:15:22Z",
"next_run_at": "2019-08-24T14:15:22Z",
"soak_minutes": 0,
"run_interval_minutes": 0,
"runs_remaining": 0,
"expires_at": "2019-08-24T14:15:22Z",
"last_run_at": "2019-08-24T14:15:22Z",
"last_outcome": "passed",
"dispatched_at": "2019-08-24T14:15:22Z",
"consecutive_errors": 0,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z"
}

Create signals report checks replace

Atomically replace an open metric check. The old check stays live if the new one is invalid.

Required API key scopes

task:writequery:read

Path parameters

  • id
    string
  • report_id
    string

Request parameters

  • title
    string
  • rationale
    string
  • config

Response


Example request

POST /api/projects/:project_id/signals/reports/:report_id/checks/:id/replace
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/signals/reports/:report_id/checks/:id/replace/\
-d title="string",\
-d config=undefined

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"title": "string",
"rationale": "string",
"kind": "metric_threshold",
"status": "pending",
"config": {
"metric_id": null,
"query": null,
"comparison": {
"operator": "lte",
"value": null,
"bounds": null
},
"baseline_value": null,
"metric_kind": null,
"value_format": null,
"unit": null
},
"approved_at": "2019-08-24T14:15:22Z",
"next_run_at": "2019-08-24T14:15:22Z",
"soak_minutes": 0,
"run_interval_minutes": 0,
"runs_remaining": 0,
"expires_at": "2019-08-24T14:15:22Z",
"last_run_at": "2019-08-24T14:15:22Z",
"last_outcome": "passed",
"dispatched_at": "2019-08-24T14:15:22Z",
"consecutive_errors": 0,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z"
}

Retrieve signals reports available reviewers

Required API key scopes

task:read

Query parameters

  • query
    string

Example request

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

Example response

Status 200 Candidate reviewers keyed by user UUID.

Create signals reports bulk state

Transition many reports to a new state in one call.

Each id is processed independently: a report whose transition isn't allowed from its current status is reported as skipped (a 409 on the single-report endpoint) and the rest still go through. Returns one result per requested id (in request order, after de-duplication) plus per-outcome counts. The whole call is 200 even on partial failure — inspect results / the counts to see what happened.

Required API key scopes

task:write

Request parameters

  • state
  • dismissal_reason
  • dismissal_note
    string
  • corrected_repository
    string
  • snooze_for
    integer
  • ids
    array

Response


Example request

POST /api/projects/:project_id/signals/reports/bulk-state
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/signals/reports/bulk-state/\
-d state=undefined,\
-d ids="array"

Example response

Status 200
RESPONSE
{
"results": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"outcome": "string",
"status": "string",
"detail": "string"
}
],
"transitioned_count": 0,
"skipped_count": 0,
"failed_count": 0,
"not_found_count": 0
}

Retrieve signals reports for you

The open, actionable reports for the current user, best first, and how many there are in total. Uses the same ranking and count as the Today briefing, so this is the short list to show someone who asks what needs them. Pass include_unowned=false to leave out the P0 reports nobody owns, which belong to the project rather than to this person.

Required API key scopes

task:read

Query parameters

  • include_unowned
    boolean
    Default: true
  • limit
    integer
    Default: 5

Response


Example request

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

Example response

Status 200
RESPONSE
{
"results": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"title": "string",
"summary": "string",
"summary_lead": "string",
"status": "potential",
"total_weight": 0.1,
"signal_count": 0,
"signals_at_run": 0,
"collapsed_note_count": 0,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"artefact_count": 0,
"charts": [
{
"chart_id": "string",
"title": "string",
"query": null,
"caption": "string",
"size": "small"
}
],
"metrics": [
{
"metric_id": "string",
"title": "string",
"kind": "affected_users",
"role": "supporting",
"value": 0,
"value_at": "2019-08-24T14:15:22Z",
"series": [
0.1
],
"value_format": "number",
"unit": "string",
"caption": "string",
"goal_value": 0,
"goal_direction": "at_most",
"goal_grain": "whole_window",
"decision_window_days": 1,
"minimum_data_points": 1
}
],
"suggested_prompts": [
"string"
],
"source_suggestion": {
"product": "logs",
"reason": "string"
},
"priority": "string",
"actionability": "string",
"already_addressed": true,
"dismissal_reason": "string",
"dismissal_note": "string",
"repo_slug": "string",
"is_suggested_reviewer": false,
"source_products": [
"string"
],
"scout_name": "string",
"implementation_pr_url": "string",
"pull_requests": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"url": "http://example.com",
"state": "unknown",
"merged": true,
"review_decision": "approved",
"merged_at": "2019-08-24T14:15:22Z",
"attached_by": {
"kind": "user",
"user": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"first_name": "string",
"last_name": "string",
"email": "user@example.com"
},
"agent": "string",
"task_id": "736fde4d-9029-4915-8189-01353d6982cb"
},
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"attached_at": "2019-08-24T14:15:22Z"
}
],
"implementation_pr_state": "unknown",
"implementation_pr_merged": true,
"tracker_issue_url": "string",
"tracker_issue_reference": "string",
"tracker_issue_error": "string",
"work_state": "unclaimed",
"assignee": {
"claim_id": "6ed32748-64af-4d95-94ea-a78b6397033c",
"kind": "user",
"user": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"first_name": "string",
"last_name": "string",
"email": "user@example.com"
},
"task_id": "736fde4d-9029-4915-8189-01353d6982cb",
"agent": "string",
"claimed_at": "2019-08-24T14:15:22Z"
},
"refund": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"reason": "pr_incorrect",
"note": "string",
"billing_path": "excluded",
"credits": 0,
"pr_url": "string",
"pr_run_created_at": "2019-08-24T14:15:22Z",
"credit_amount_usd": "string",
"billing_synced": true,
"created_at": "2019-08-24T14:15:22Z"
},
"refund_ineligibility_reason": "already_refunded",
"billing_exempt_reason": "posthog_health_check",
"channel_id": "bbe8aa76-a4bb-46f6-a785-df8e831cc459",
"ranking": {
"served_key": "string",
"model_name": "string",
"model_version": "string",
"manifest_version": "string",
"scored_at": "2019-08-24T14:15:22Z",
"scores": {
"property1": 0.1,
"property2": 0.1
},
"lifts": {
"property1": 0.1,
"property2": 0.1
},
"readable_heads": [
"string"
],
"stale": true
}
}
],
"count": 0
}