Engineering

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

Endpoints

GET
GET
GET
GET
GET
GET
GET
GET
GET
GET

Retrieve engineering analytics run failure

The thinned CI failure logs of one workflow run, grouped by failed job: the run-scoped twin of ci_failure_logs for surfaces that aren't PR-scoped (default-branch failures, the run page). logs_available is false when the run didn't fail or its logs aged out of the short Logs retention.

Required API key scopes

engineering_analytics:read

Query parameters

  • ci_engine
    string
    One of: "depot_ci""github_actions"
  • repo
    string
  • run_id
    integer
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"jobs": [
{
"lines": [
{
"original_line": 0,
"text": "string"
}
],
"job_id": 0,
"run_id": 0,
"conclusion": "string",
"branch": "string",
"original_total_lines": 0,
"line_count": 0,
"truncated": true,
"ci_engine": "github_actions"
}
],
"run_id": 0,
"logs_available": true,
"truncated": true,
"ci_engine": "github_actions"
}
Status 400 Missing or non-integer run_id, ambiguous run identity, or invalid ci_engine/source_id.

Retrieve engineering analytics run failure

The thinned CI failure logs of one workflow run, grouped by failed job: the run-scoped twin of ci_failure_logs for surfaces that aren't PR-scoped (default-branch failures, the run page). logs_available is false when the run didn't fail or its logs aged out of the short Logs retention.

Required API key scopes

engineering_analytics:read

Query parameters

  • ci_engine
    string
    One of: "depot_ci""github_actions"
  • repo
    string
  • run_id
    integer
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"jobs": [
{
"lines": [
{
"original_line": 0,
"text": "string"
}
],
"job_id": 0,
"run_id": 0,
"conclusion": "string",
"branch": "string",
"original_total_lines": 0,
"line_count": 0,
"truncated": true,
"ci_engine": "github_actions"
}
],
"run_id": 0,
"logs_available": true,
"truncated": true,
"ci_engine": "github_actions"
}
Status 400 Missing or non-integer run_id, ambiguous run identity, or invalid ci_engine/source_id.

Retrieve engineering analytics

The team's selectable GitHub repositories, oldest source first: one entry per repository a source is configured to sync, so a source syncing several repositories appears once per repo. Populate a repo picker from this and pass a chosen entry's id back as source_id and its repo back as repo to the other endpoints. Includes repositories whose tables aren't fully synced yet.

Required API key scopes

engineering_analytics:read

Example request

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

Example response

Status 200
RESPONSE
{
"id": "string",
"repo": "string",
"prefix": "string",
"synced": true
}

Retrieve engineering analytics

The team's selectable GitHub repositories, oldest source first: one entry per repository a source is configured to sync, so a source syncing several repositories appears once per repo. Populate a repo picker from this and pass a chosen entry's id back as source_id and its repo back as repo to the other endpoints. Includes repositories whose tables aren't fully synced yet.

Required API key scopes

engineering_analytics:read

Example request

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

Example response

Status 200
RESPONSE
{
"id": "string",
"repo": "string",
"prefix": "string",
"synced": true
}

Retrieve engineering analytics team ci

One owning team's CI test activity: per-test current-vs-prior signal pairs (the before/after comparison) over the window and its equal-length prior twin. Signal = runs where an owned test failed, errored, or a retry recovered it. Counts are absolute, never rates: CI emits every failure but omits ordinary passing spans, so there is no execution denominator. 'suspected_regression' means no recovery was recorded in this data, not that the test never flakes.

Required API key scopes

engineering_analytics:read

Query parameters

  • date_from
    string
  • date_to
    string
  • owner_team
    string
  • source_id
    string
  • test_limit
    integer

Response


Example request

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

Example response

Status 200
RESPONSE
{
"tests": [
{
"runner": "pytest",
"nodeid": "string",
"selector": "string",
"signal_count": 0,
"signal_count_prior": 0,
"last_seen_at": "2019-08-24T14:15:22Z"
}
],
"owner_team": "string",
"truncated_tests": true
}
Status 400 Missing owner_team, invalid date, test_limit, or source_id, or a window longer than 30 days.

Retrieve engineering analytics team ci

One owning team's CI test activity: per-test current-vs-prior signal pairs (the before/after comparison) over the window and its equal-length prior twin. Signal = runs where an owned test failed, errored, or a retry recovered it. Counts are absolute, never rates: CI emits every failure but omits ordinary passing spans, so there is no execution denominator. 'suspected_regression' means no recovery was recorded in this data, not that the test never flakes.

Required API key scopes

engineering_analytics:read

Query parameters

  • date_from
    string
  • date_to
    string
  • owner_team
    string
  • source_id
    string
  • test_limit
    integer

Response


Example request

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

Example response

Status 200
RESPONSE
{
"tests": [
{
"runner": "pytest",
"nodeid": "string",
"selector": "string",
"signal_count": 0,
"signal_count_prior": 0,
"last_seen_at": "2019-08-24T14:15:22Z"
}
],
"owner_team": "string",
"truncated_tests": true
}
Status 400 Missing owner_team, invalid date, test_limit, or source_id, or a window longer than 30 days.

Retrieve engineering analytics team ci

Per-owning-team rollup of the CI test surfaces each team owns, over the same run evidence as flaky_tests and with the same meaning of flaky: flaky_test_count is owned tests one commit was seen both failing and passing in the window, regression_test_count is owned tests that failed with no such proof and still hit the blast-radius bar, plus failed/recovery/quarantined run counts. Each has an equal-length previous-window twin for honest deltas. Ownership is stamped on the spans at CI emission time from the repo's ownership map (the distributed owners.yaml files); unstamped spans aggregate under the literal team 'unowned', and a re-stamped test lands under its latest owner only. Each row also carries test_file_count (the daily owners.yaml census denominator, with a window-start twin) and merged_pr_count (merged PRs by the team's members, bots excluded); teams with census counts but no CI signal appear with zero signal counts and a null last_seen_at. Teams are organizational owners of code surfaces, never authors. Counts are absolute, never rates: CI emits every failure but omits ordinary passing spans, so there is no execution denominator. 'suspected_regression' means no recovery was recorded in this data, not that the test never flakes.

Required API key scopes

engineering_analytics:read

Query parameters

  • date_from
    string
  • date_to
    string
  • limit
    integer
  • min_failed_prs
    integer
  • owner_team
    string
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"items": [
{
"owner_team": "string",
"flaky_test_count": 0,
"flaky_test_count_prior": 0,
"regression_test_count": 0,
"regression_test_count_prior": 0,
"failed_run_count": 0,
"failed_run_count_prior": 0,
"same_commit_recovery_run_count": 0,
"same_commit_recovery_run_count_prior": 0,
"quarantined_failed_run_count": 0,
"quarantined_failed_run_count_prior": 0,
"last_seen_at": "2019-08-24T14:15:22Z",
"test_file_count": 0,
"test_file_count_prior": 0,
"merged_pr_count": 0,
"merged_pr_count_prior": 0
}
],
"truncated": true,
"limit": 0
}
Status 400 Invalid date, threshold, limit, or source_id, or a window longer than 30 days.

Retrieve engineering analytics team ci

Per-owning-team rollup of the CI test surfaces each team owns, over the same run evidence as flaky_tests and with the same meaning of flaky: flaky_test_count is owned tests one commit was seen both failing and passing in the window, regression_test_count is owned tests that failed with no such proof and still hit the blast-radius bar, plus failed/recovery/quarantined run counts. Each has an equal-length previous-window twin for honest deltas. Ownership is stamped on the spans at CI emission time from the repo's ownership map (the distributed owners.yaml files); unstamped spans aggregate under the literal team 'unowned', and a re-stamped test lands under its latest owner only. Each row also carries test_file_count (the daily owners.yaml census denominator, with a window-start twin) and merged_pr_count (merged PRs by the team's members, bots excluded); teams with census counts but no CI signal appear with zero signal counts and a null last_seen_at. Teams are organizational owners of code surfaces, never authors. Counts are absolute, never rates: CI emits every failure but omits ordinary passing spans, so there is no execution denominator. 'suspected_regression' means no recovery was recorded in this data, not that the test never flakes.

Required API key scopes

engineering_analytics:read

Query parameters

  • date_from
    string
  • date_to
    string
  • limit
    integer
  • min_failed_prs
    integer
  • owner_team
    string
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"items": [
{
"owner_team": "string",
"flaky_test_count": 0,
"flaky_test_count_prior": 0,
"regression_test_count": 0,
"regression_test_count_prior": 0,
"failed_run_count": 0,
"failed_run_count_prior": 0,
"same_commit_recovery_run_count": 0,
"same_commit_recovery_run_count_prior": 0,
"quarantined_failed_run_count": 0,
"quarantined_failed_run_count_prior": 0,
"last_seen_at": "2019-08-24T14:15:22Z",
"test_file_count": 0,
"test_file_count_prior": 0,
"merged_pr_count": 0,
"merged_pr_count_prior": 0
}
],
"truncated": true,
"limit": 0
}
Status 400 Invalid date, threshold, limit, or source_id, or a window longer than 30 days.

Retrieve engineering analytics team merge

One team's daily time-to-merge trend: the median and average open→merge seconds over the PRs the team's members merged each day (PR author login → GitHub org team membership). Team-level aggregates only, never per-member figures or cross-team rankings. Timing is the coarse open→merge (draft + review time combined); bots are excluded. Requires the GitHub source's team_members snapshot; has_membership_data is false without it.

Required API key scopes

engineering_analytics:read

Query parameters

  • date_from
    string
  • date_to
    string
  • owner_team
    string
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"points": [
{
"day": "2019-08-24T14:15:22Z",
"median_seconds": 0,
"average_seconds": 0,
"merged_count": 0
}
],
"owner_team": "string",
"has_membership_data": true
}
Status 400 Missing owner_team, invalid date or source_id, or a window longer than 30 days.

Retrieve engineering analytics team merge

One team's daily time-to-merge trend: the median and average open→merge seconds over the PRs the team's members merged each day (PR author login → GitHub org team membership). Team-level aggregates only, never per-member figures or cross-team rankings. Timing is the coarse open→merge (draft + review time combined); bots are excluded. Requires the GitHub source's team_members snapshot; has_membership_data is false without it.

Required API key scopes

engineering_analytics:read

Query parameters

  • date_from
    string
  • date_to
    string
  • owner_team
    string
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"points": [
{
"day": "2019-08-24T14:15:22Z",
"median_seconds": 0,
"average_seconds": 0,
"merged_count": 0
}
],
"owner_team": "string",
"has_membership_data": true
}
Status 400 Missing owner_team, invalid date or source_id, or a window longer than 30 days.

Retrieve engineering analytics trunk

The standing Trunk quarantine debt: every test Trunk currently quarantines (failures suppressed in CI), attributed to the team that owns its file in the repository, aged against a TTL, and rolled up per team with the most indebted first. A quarantine only masks a test; it never fixes it, so this is the work queue of tests someone still has to repair or delete. available is false when no TrunkIo source has the QuarantinedTests endpoint synced: that is not an error.

Required API key scopes

engineering_analytics:read

Query parameters

  • repo
    string
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"teams": [
{
"owner_team": "string",
"test_count": 0,
"overdue_count": 0,
"oldest_age_days": 0
}
],
"tests": [
{
"runner": "string",
"nodeid": "string",
"file": "string",
"owner_team": "string",
"status": "string",
"quarantine_setting": "string",
"quarantined_at": "2019-08-24T14:15:22Z",
"age_days": 0,
"overdue": true,
"trunk_url": "string"
}
],
"available": true,
"owners_resolved": true,
"ttl_days": 0,
"repository": "string",
"trunk_url": "string",
"truncated": true,
"limit": 0
}
Status 400 Invalid repo or source_id.

Retrieve engineering analytics trunk

The standing Trunk quarantine debt: every test Trunk currently quarantines (failures suppressed in CI), attributed to the team that owns its file in the repository, aged against a TTL, and rolled up per team with the most indebted first. A quarantine only masks a test; it never fixes it, so this is the work queue of tests someone still has to repair or delete. available is false when no TrunkIo source has the QuarantinedTests endpoint synced: that is not an error.

Required API key scopes

engineering_analytics:read

Query parameters

  • repo
    string
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"teams": [
{
"owner_team": "string",
"test_count": 0,
"overdue_count": 0,
"oldest_age_days": 0
}
],
"tests": [
{
"runner": "string",
"nodeid": "string",
"file": "string",
"owner_team": "string",
"status": "string",
"quarantine_setting": "string",
"quarantined_at": "2019-08-24T14:15:22Z",
"age_days": 0,
"overdue": true,
"trunk_url": "string"
}
],
"available": true,
"owners_resolved": true,
"ttl_days": 0,
"repository": "string",
"trunk_url": "string",
"truncated": true,
"limit": 0
}
Status 400 Invalid repo or source_id.

Retrieve engineering analytics workflow

Per-workflow CI health over a window (default last 24 hours, maximum 366 days): run count, success rate, p50/p95 duration, last failure time, latest-run status, and a zero-filled run history bucketed by hour/day/week to fit the window. Success rate covers runs that succeeded or ended in a decisive failure. Skipped, cancelled, neutral, and action-required runs are excluded. p50/p95 are over successful runs only, so cancelled (superseded) and failed runs never bias the duration trend. Runs under 10 seconds that did no work are excluded when longer successful runs exist. An all-fast workflow uses every successful run. Optionally scope to a single git branch via branch, to one workflow via workflow_name, or to one run group via run_scope (default_branch, pull_request, merge_queue). Use this for 'is CI getting slower' and 'which workflow is the long pole'; compare two windows to get a trend.

Required API key scopes

engineering_analytics:read

Query parameters

  • branch
    string
  • date_from
    string
  • date_to
    string
  • repo
    string
  • run_scope
    string
    One of: "all""default_branch""merge_queue""pull_request"
  • source_id
    string
  • workflow_name
    string

Example request

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

Example response

Status 200
RESPONSE
{
"repo": {
"provider": "string",
"owner": "string",
"name": "string"
},
"buckets": [
{
"bucket_start": "2019-08-24T14:15:22Z",
"run_count": 0,
"completed": 0,
"successes": 0,
"failures": 0
}
],
"workflow_name": "string",
"run_count": 0,
"successful_run_count": 0,
"conclusive_run_count": 0,
"success_rate": 0,
"p50_seconds": 0,
"p95_seconds": 0,
"last_failure_at": "2019-08-24T14:15:22Z",
"latest_run_failed": true,
"latest_run_conclusion": "string",
"latest_run_id": 0,
"latest_run_attempt": 0,
"granularity": "string",
"billable_minutes": 0,
"estimated_cost_usd": 0,
"rerun_cycles": 0,
"success_rate_prev": 0,
"percentile_run_count": 0,
"merge_queue_run_count": 0,
"latest_ci_engine": "github_actions"
}
Status 400 Invalid date_from, date_to, run_scope, or source_id, or a window longer than 366 days.

Retrieve engineering analytics workflow

Per-workflow CI health over a window (default last 24 hours, maximum 366 days): run count, success rate, p50/p95 duration, last failure time, latest-run status, and a zero-filled run history bucketed by hour/day/week to fit the window. Success rate covers runs that succeeded or ended in a decisive failure. Skipped, cancelled, neutral, and action-required runs are excluded. p50/p95 are over successful runs only, so cancelled (superseded) and failed runs never bias the duration trend. Runs under 10 seconds that did no work are excluded when longer successful runs exist. An all-fast workflow uses every successful run. Optionally scope to a single git branch via branch, to one workflow via workflow_name, or to one run group via run_scope (default_branch, pull_request, merge_queue). Use this for 'is CI getting slower' and 'which workflow is the long pole'; compare two windows to get a trend.

Required API key scopes

engineering_analytics:read

Query parameters

  • branch
    string
  • date_from
    string
  • date_to
    string
  • repo
    string
  • run_scope
    string
    One of: "all""default_branch""merge_queue""pull_request"
  • source_id
    string
  • workflow_name
    string

Example request

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

Example response

Status 200
RESPONSE
{
"repo": {
"provider": "string",
"owner": "string",
"name": "string"
},
"buckets": [
{
"bucket_start": "2019-08-24T14:15:22Z",
"run_count": 0,
"completed": 0,
"successes": 0,
"failures": 0
}
],
"workflow_name": "string",
"run_count": 0,
"successful_run_count": 0,
"conclusive_run_count": 0,
"success_rate": 0,
"p50_seconds": 0,
"p95_seconds": 0,
"last_failure_at": "2019-08-24T14:15:22Z",
"latest_run_failed": true,
"latest_run_conclusion": "string",
"latest_run_id": 0,
"latest_run_attempt": 0,
"granularity": "string",
"billable_minutes": 0,
"estimated_cost_usd": 0,
"rerun_cycles": 0,
"success_rate_prev": 0,
"percentile_run_count": 0,
"merge_queue_run_count": 0,
"latest_ci_engine": "github_actions"
}
Status 400 Invalid date_from, date_to, run_scope, or source_id, or a window longer than 366 days.

Retrieve engineering analytics workflow

Jobs of a single workflow run attempt, with per-job duration, runner tier, and estimated cost. Scoped to one run_attempt (the latest unless specified) so a re-run's attempts don't merge. Returns an empty list when the job-level source isn't synced yet.

Required API key scopes

engineering_analytics:read

Query parameters

  • ci_engine
    string
    One of: "depot_ci""github_actions"
  • repo
    string
  • run_attempt
    integer
  • run_id
    integer
  • source_id
    string

Example request

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

Example response

Status 200
RESPONSE
{
"steps": [
{
"number": 0,
"name": "string",
"status": "string",
"conclusion": "string",
"started_at": "2019-08-24T14:15:22Z",
"completed_at": "2019-08-24T14:15:22Z",
"duration_seconds": 0
}
],
"id": 0,
"run_id": 0,
"name": "string",
"status": "string",
"conclusion": "string",
"started_at": "2019-08-24T14:15:22Z",
"completed_at": "2019-08-24T14:15:22Z",
"duration_seconds": 0,
"runner_provider": "string",
"runner_label": "string",
"estimated_cost_usd": 0,
"ci_engine": "github_actions",
"native_run_id": "string",
"native_workflow_run_id": "string",
"native_job_id": "string",
"native_attempt_id": "string"
}
Status 400 Missing or non-integer run_id/run_attempt, ambiguous run identity, or invalid ci_engine/source_id.

Retrieve engineering analytics workflow

Jobs of a single workflow run attempt, with per-job duration, runner tier, and estimated cost. Scoped to one run_attempt (the latest unless specified) so a re-run's attempts don't merge. Returns an empty list when the job-level source isn't synced yet.

Required API key scopes

engineering_analytics:read

Query parameters

  • ci_engine
    string
    One of: "depot_ci""github_actions"
  • repo
    string
  • run_attempt
    integer
  • run_id
    integer
  • source_id
    string

Example request

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

Example response

Status 200
RESPONSE
{
"steps": [
{
"number": 0,
"name": "string",
"status": "string",
"conclusion": "string",
"started_at": "2019-08-24T14:15:22Z",
"completed_at": "2019-08-24T14:15:22Z",
"duration_seconds": 0
}
],
"id": 0,
"run_id": 0,
"name": "string",
"status": "string",
"conclusion": "string",
"started_at": "2019-08-24T14:15:22Z",
"completed_at": "2019-08-24T14:15:22Z",
"duration_seconds": 0,
"runner_provider": "string",
"runner_label": "string",
"estimated_cost_usd": 0,
"ci_engine": "github_actions",
"native_run_id": "string",
"native_workflow_run_id": "string",
"native_job_id": "string",
"native_attempt_id": "string"
}
Status 400 Missing or non-integer run_id/run_attempt, ambiguous run identity, or invalid ci_engine/source_id.

Retrieve engineering analytics workflow

A single workflow run: status, conclusion, duration, branch, attempt, and the attributed pull request. Run-level only: per-job and per-step detail are not tracked yet.

Required API key scopes

engineering_analytics:read

Query parameters

  • ci_engine
    string
    One of: "depot_ci""github_actions"
  • repo
    string
  • run_id
    integer
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"repo": {
"provider": "string",
"owner": "string",
"name": "string"
},
"id": 0,
"workflow_name": "string",
"head_sha": "string",
"head_branch": "string",
"status": "string",
"conclusion": "string",
"run_started_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"duration_seconds": 0,
"run_attempt": 0,
"pr_number": 0,
"commit_pr_number": 0,
"is_merge_queue": true,
"ci_engine": "github_actions",
"native_run_id": "string",
"native_workflow_run_id": "string",
"workflow_id": 0,
"event": "string"
}
Status 400 Missing or non-integer run_id, ambiguous run identity, or invalid ci_engine/source_id.
Status 404 No workflow run with that id in the warehouse.

Retrieve engineering analytics workflow

A single workflow run: status, conclusion, duration, branch, attempt, and the attributed pull request. Run-level only: per-job and per-step detail are not tracked yet.

Required API key scopes

engineering_analytics:read

Query parameters

  • ci_engine
    string
    One of: "depot_ci""github_actions"
  • repo
    string
  • run_id
    integer
  • source_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"repo": {
"provider": "string",
"owner": "string",
"name": "string"
},
"id": 0,
"workflow_name": "string",
"head_sha": "string",
"head_branch": "string",
"status": "string",
"conclusion": "string",
"run_started_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"duration_seconds": 0,
"run_attempt": 0,
"pr_number": 0,
"commit_pr_number": 0,
"is_merge_queue": true,
"ci_engine": "github_actions",
"native_run_id": "string",
"native_workflow_run_id": "string",
"workflow_id": 0,
"event": "string"
}
Status 400 Missing or non-integer run_id, ambiguous run identity, or invalid ci_engine/source_id.
Status 404 No workflow run with that id in the warehouse.

Retrieve engineering analytics workflow run

Compact per-run points for a single workflow over a window (date_from default -30d), newest first, for the run-activity chart: each run's start time, duration, conclusion, branch, and attributed PR. Optionally scope to a single git branch via branch or one run group via run_scope, matching workflow_runs. Leaner and higher-capped than workflow_runs so the chart spans the full window even on busy workflows; truncated is true when the cap is hit, so the chart covers only the most recent runs.

Required API key scopes

engineering_analytics:read

Query parameters

  • branch
    string
  • date_from
    string
  • date_to
    string
  • repo
    string
  • run_scope
    string
    One of: "all""default_branch""merge_queue""pull_request"
  • source_id
    string
  • workflow_name
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"points": [
{
"run_id": 0,
"conclusion": "string",
"run_started_at": "2019-08-24T14:15:22Z",
"duration_seconds": 0,
"head_branch": "string",
"pr_number": 0,
"head_sha": "string",
"ci_engine": "github_actions"
}
],
"truncated": true,
"limit": 0
}
Status 400 Missing workflow_name/repo, or invalid date, run_scope, or source_id.

Retrieve engineering analytics workflow run

Compact per-run points for a single workflow over a window (date_from default -30d), newest first, for the run-activity chart: each run's start time, duration, conclusion, branch, and attributed PR. Optionally scope to a single git branch via branch or one run group via run_scope, matching workflow_runs. Leaner and higher-capped than workflow_runs so the chart spans the full window even on busy workflows; truncated is true when the cap is hit, so the chart covers only the most recent runs.

Required API key scopes

engineering_analytics:read

Query parameters

  • branch
    string
  • date_from
    string
  • date_to
    string
  • repo
    string
  • run_scope
    string
    One of: "all""default_branch""merge_queue""pull_request"
  • source_id
    string
  • workflow_name
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"points": [
{
"run_id": 0,
"conclusion": "string",
"run_started_at": "2019-08-24T14:15:22Z",
"duration_seconds": 0,
"head_branch": "string",
"pr_number": 0,
"head_sha": "string",
"ci_engine": "github_actions"
}
],
"truncated": true,
"limit": 0
}
Status 400 Missing workflow_name/repo, or invalid date, run_scope, or source_id.