Signals

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

Endpoints

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

Create signals reports feedback

Record the thumbs rating at the end of a report, with an optional note. For browser-session requests the rating is persisted as a per-person report action, which counts as consumption evidence for the scout that authored the report (scouts whose output nobody consumes are eventually paused); requests authenticated any other way record no action. When a note is present and the report was authored by a scout, the note is also forwarded to that scout as a steering note it reads on its next run; for any other report there is nothing to steer. The report's state is never changed.

Required API key scopes

task:read

Path parameters

  • id
    string

Request parameters

  • sentiment
  • note
    string
    Default:

Response


Example request

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

Example response

Status 200
RESPONSE
{
"forwarded": true
}

Retrieve signals reports feedback state

Required API key scopes

task:read

Path parameters

  • id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"sentiment": "positive",
"note": "string"
}

Create signals reports merge

Fold one or more duplicate reports into this report, which survives. The sources' signals, work-log artefacts, pull requests, task runs and checks move onto the survivor, the survivor's signal counters take on theirs, and each source is archived with a 'duplicate of' link back to the survivor. A source's open pull request stays open, because the survivor holds it after the move. Pick the survivor deliberately: prefer the older report, and prefer the one with an open implementation PR or an active claim. Any active claim on a source is released, so re-claim the survivor if you were working on one. Titles and summaries are not combined, so edit it afterwards if it needs a rewrite. A merged report keeps its URL but cannot be restored, because its signals now belong to the survivor.

Required API key scopes

task:write

Path parameters

  • id
    string

Request parameters

  • source_report_ids
    array
  • reason
    string

Response


Example request

POST /api/projects/:project_id/signals/reports/:id/merge
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/merge/\
-d source_report_ids="array"

Example response

Status 200 The surviving report after the merge, plus one result per merged source.
RESPONSE
{
"report": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"title": "string",
"summary": "string",
"summary_lead": "string",
"reviewer_assignment": {
"state": {
"reviewers_id": "2e0d6f9a-f7b9-4851-80c4-2938b51252f8",
"corrections_id": "d6237cc9-ee4f-4270-9a15-7e959436f098"
},
"pinned_user_uuids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
],
"excluded_user_uuids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
],
"confirmed": true,
"needs_review": true,
"enabled": true
},
"status": "potential",
"monitoring_started_at": "2019-08-24T14:15:22Z",
"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",
"suppression_source": "dismissed",
"suppression_explanation": "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
}
},
"sources": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"artefacts_moved": 0,
"signals_moved": 0,
"released_claim": true
}
]
}
Status 404 The surviving report was not found in this project.
Status 409 Both ends of a merge must be a live report of this project. Returned when the survivor is resolved, or when a source is the survivor itself, is resolved or archived, is still being researched, carries more signals than one merge can move, or belongs to another project. Nothing is applied.

Retrieve signals report pr

Fetch the CI status (GitHub Actions check runs and legacy commit statuses) of the pull request attached to the report, via the team's GitHub integration.

Required API key scopes

task:read

Path parameters

  • id
    string

Query parameters

  • pull_request_id
    string

Response


Example request

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

Example response

Status 200 The CI checks on the report's implementation pull request.
RESPONSE
{
"checks": [
{
"name": "string",
"status": "string",
"conclusion": "string",
"url": "string"
}
]
}
Status 403 GitHub is connected without permission to read pull request checks.
RESPONSE
{
"code": "string",
"error": "string",
"remediation_url": "string"
}
Status 404 Report has no implementation PR, or no GitHub integration can access it.
Status 502 GitHub could not return the checks.
Status 503 The GitHub egress budget is temporarily unavailable.

Retrieve signals report pr

Fetch the pull request's conversation comments and inline review comments, merged chronologically, via the team's GitHub integration.

Required API key scopes

task:read

Path parameters

  • id
    string

Query parameters

  • pull_request_id
    string

Response


Example request

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

Example response

Status 200 Conversation and review comments on the report's implementation pull request.
RESPONSE
{
"comments": [
{
"id": "string",
"author": "string",
"author_avatar_url": "string",
"body": "string",
"created_at": "string",
"url": "string",
"comment_type": "conversation",
"path": "string",
"line": 0,
"start_line": 0,
"side": "LEFT",
"diff_hunk": "string",
"in_reply_to_id": "string",
"commit_id": "string",
"reactions": [
{
"id": "string",
"content": "string",
"user_login": "string"
}
]
}
]
}
Status 404 Report has no implementation PR, or no GitHub integration can access it.
Status 502 GitHub could not return the comments.
Status 503 The GitHub egress budget is temporarily unavailable.

Create signals report pr review comments

Post an inline review comment on the report's implementation pull request, attributed to the requesting user's own GitHub identity via their personal GitHub connection. Either replies to an existing thread (in_reply_to) or starts a new thread on a diff line (path + line).

Required API key scopes

task:write

Path parameters

  • id
    string

Query parameters

  • pull_request_id
    string

Request parameters

  • body
    string
  • in_reply_to
    string | null
  • path
    string | null
  • line
    integer | null
  • side

Response


Example request

POST /api/projects/:project_id/signals/reports/:id/pr_review_comments
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/pr_review_comments/\
-d body="string"

Example response

Status 201 The created review comment, in the normalized PR-comment shape.
RESPONSE
{
"comment": {
"id": "string",
"author": "string",
"author_avatar_url": "string",
"body": "string",
"created_at": "string",
"url": "string",
"comment_type": "conversation",
"path": "string",
"line": 0,
"start_line": 0,
"side": "LEFT",
"diff_hunk": "string",
"in_reply_to_id": "string",
"commit_id": "string",
"reactions": [
{
"id": "string",
"content": "string",
"user_login": "string"
}
]
}
}
Status 400 Invalid comment payload.
Status 403 Not a signed-in user, or the requesting user has no usable personal GitHub connection (reconnect GitHub).
Status 404 Report has no implementation PR, or no GitHub integration can access it.
Status 502 GitHub rejected the comment.
Status 503 The GitHub egress budget is temporarily unavailable.

Update signals report pr review comment

Required API key scopes

task:write

Path parameters

  • comment_id
    string
  • id
    string

Query parameters

  • pull_request_id
    string

Request parameters

  • body
    string

Response


Example request

PATCH /api/projects/:project_id/signals/reports/:id/pr_review_comments/:comment_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/:id/pr_review_comments/:comment_id/\
-d body="string"

Example response

Status 200 The edited review comment, in the normalized PR-comment shape.
RESPONSE
{
"comment": {
"id": "string",
"author": "string",
"author_avatar_url": "string",
"body": "string",
"created_at": "string",
"url": "string",
"comment_type": "conversation",
"path": "string",
"line": 0,
"start_line": 0,
"side": "LEFT",
"diff_hunk": "string",
"in_reply_to_id": "string",
"commit_id": "string",
"reactions": [
{
"id": "string",
"content": "string",
"user_login": "string"
}
]
}
}
Status 403 Not a signed-in user, no usable personal GitHub connection, or not the comment's author.
Status 404 Report has no implementation PR, or the comment isn't on it.
Status 502 GitHub rejected the edit.
Status 503 The GitHub egress budget is temporarily unavailable.

Delete signals report pr review comment

Required API key scopes

task:write

Path parameters

  • comment_id
    string
  • id
    string

Query parameters

  • pull_request_id
    string

Example request

DELETE /api/projects/:project_id/signals/reports/:id/pr_review_comments/:comment_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/:id/pr_review_comments/:comment_id/

Example response

Status 204 Comment deleted.
Status 403 Not a signed-in user, no usable personal GitHub connection, or not the comment's author.
Status 404 Report has no implementation PR, or the comment isn't on it.
Status 502 GitHub rejected the delete.
Status 503 The GitHub egress budget is temporarily unavailable.

Create signals report pr review comment reactions

Required API key scopes

task:write

Path parameters

  • comment_id
    string
  • id
    string

Query parameters

  • pull_request_id
    string

Request parameters

  • content

Response


Example request

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

Example response

Status 201 The created reaction.
RESPONSE
{
"reaction": {
"id": "string",
"content": "string",
"user_login": "string"
}
}
Status 403 Not a signed-in user, or no usable personal GitHub connection.
Status 404 Report has no implementation PR, or the comment isn't on it.
Status 502 GitHub rejected the reaction.
Status 503 The GitHub egress budget is temporarily unavailable.

Delete signals report pr review comment reaction

Required API key scopes

task:write

Path parameters

  • comment_id
    string
  • id
    string
  • reaction_id
    string

Query parameters

  • pull_request_id
    string

Example request

DELETE /api/projects/:project_id/signals/reports/:id/pr_review_comments/:comment_id/reactions/:reaction_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/:id/pr_review_comments/:comment_id/reactions/:reaction_id/

Example response

Status 204 Reaction removed.
Status 403 Not a signed-in user, or no usable personal GitHub connection.
Status 404 Report has no implementation PR, or the comment isn't on it.
Status 502 GitHub rejected the removal.
Status 503 The GitHub egress budget is temporarily unavailable.

Create signals reports refund

Refund the flat charge for this report's implementation PR and archive the report. Refunds auto-approve: the charge is either excluded from usage before it is ever reported to billing (refund on the same UTC day as the PR run) or returned as a Stripe customer-balance credit on the next invoice. A refunded PR does not count toward the free monthly PR allowance. One refund per report, ever — repeat calls return the existing refund with already_refunded=true. The report is archived as part of the refund (a resolved report stays resolved) and can't be restored afterwards.

Required API key scopes

task:write

Path parameters

  • id
    string

Request parameters

  • reason
  • note
    string

Response


Example request

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

Example response

Status 200 The refund (created, or the existing one with already_refunded=true when the report was refunded before).
RESPONSE
{
"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",
"already_refunded": false
}
Status 400 Report is not refundable: no billable implementation PR, the PR run is outside the current billing period, or the report is system-marked never-billable.
Status 404 Report not found, or refunds are not enabled for this organization.

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",
"reviewer_assignment": {
"state": {
"reviewers_id": "2e0d6f9a-f7b9-4851-80c4-2938b51252f8",
"corrections_id": "d6237cc9-ee4f-4270-9a15-7e959436f098"
},
"pinned_user_uuids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
],
"excluded_user_uuids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
],
"confirmed": true,
"needs_review": true,
"enabled": true
},
"status": "potential",
"monitoring_started_at": "2019-08-24T14:15:22Z",
"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",
"suppression_source": "dismissed",
"suppression_explanation": "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": [
{
"total_spend": 0,
"spend_accounting_failed_stages": [
"string"
],
"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",
"reviewer_assignment": {
"state": {
"reviewers_id": "2e0d6f9a-f7b9-4851-80c4-2938b51252f8",
"corrections_id": "d6237cc9-ee4f-4270-9a15-7e959436f098"
},
"pinned_user_uuids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
],
"excluded_user_uuids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
],
"confirmed": true,
"needs_review": true,
"enabled": true
},
"status": "potential",
"monitoring_started_at": "2019-08-24T14:15:22Z",
"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",
"suppression_source": "dismissed",
"suppression_explanation": "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. ranking_score content keeps only the head fields of each model's metadata; get the artefact by id for the full metadata.

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

  • expected_reviewers
  • reviewer_outcome
    Default: selected
  • reviewer_retry_reason
    string
  • 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.