Task-runs

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

Endpoints

GET
POST
GET
POST
POST
GET
PATCH
PATCH
POST
GET
GET
POST
GET
POST

Retrieve tasks runs peers

Agent runs this run may send messages to: cloud Pi runs of tasks created by the same user, currently in progress or queued. Discovery and send validation share one visibility policy, so a run can only message what it can list; the per-entry sendable flag is the liveness contract.

Required API key scopes

task:read

Path parameters

  • id
    string
  • task_id
    string

Response


Example request

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

Example response

Status 200 Active agent runs this run may message
RESPONSE
{
"peers": [
{
"run_id": "string",
"task_id": "string",
"task_title": "string",
"created_by_email": "string",
"runtime": "string",
"model": "string",
"repository": "string",
"stage": "string",
"status": "string",
"sendable": true,
"updated_at": "string"
}
]
}
Status 403 Peer messaging is disabled or the task is not on the Pi runtime
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 404 Run not found

Create tasks runs peers message

Relay a message from this run to a peer agent run. The body is delivered below a server-composed provenance envelope as a queued (non-steer) turn; attachments are copied into the target run's own artifact storage. accepted means queued for delivery, never delivered — the sandbox handoff happens later inside the target's workflow.

Required API key scopes

task:write

Path parameters

  • id
    string
  • target_run_id
    string
  • task_id
    string

Request parameters

  • content
    string
  • artifact_ids
    array

Response


Example request

POST /api/projects/:project_id/tasks/:task_id/runs/:id/peers/:target_run_id/message
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/tasks/:task_id/runs/:id/peers/:target_run_id/message/\
-d content="string"

Example response

Status 200 Synchronous send result (accepted / target_finished / rejected)
RESPONSE
{
"result": "accepted",
"detail": "string",
"message_id": "string"
}
Status 400 Invalid message payload
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 403 Peer messaging is disabled or the task is not on the Pi runtime
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 404 Run not found

Retrieve tasks runs preview

Redirects to the PostHog dev stack running inside this run's sandbox. A fresh sandbox access token is minted on every request and carried only in the redirect target, so it is never persisted or returned in a response body. When the run has no preview, or its sandbox has stopped, this renders a short HTML page instead.

Required API key scopes

task:write

Path parameters

  • id
    string
  • task_id
    string

Example request

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

Example response

Status 200 HTML page explaining that the preview is not ready yet or has ended
Status 302 Redirect to the sandbox preview with a freshly minted access token
Status 403 Refused during read-only impersonation
Status 404 Task run not found

Create tasks runs relay message

Queue a Slack relay workflow to post a run message into the mapped Slack thread.

Required API key scopes

task:write

Path parameters

  • id
    string
  • task_id
    string

Request parameters

  • text
    string
  • message_id
    string | null
  • text_parts
    array
  • trace_id
    string | null

Response


Example request

POST /api/projects/:project_id/tasks/:task_id/runs/:id/relay_message
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/tasks/:task_id/runs/:id/relay_message/\
-d text="string"

Example response

Status 200 Relay accepted
RESPONSE
{
"status": "string",
"relay_id": "string"
}
Status 404 Run not found

Create tasks runs resume in cloud

Resume an existing task run in a cloud sandbox. Terminates any existing workflow and starts a new one.

Required API key scopes

task:write

Path parameters

  • id
    string
  • task_id
    string

Response


Example request

POST /api/projects/:project_id/tasks/:task_id/runs/:id/resume_in_cloud
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/tasks/:task_id/runs/:id/resume_in_cloud/

Example response

Status 200 Run resumed in cloud
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"task": "4879b8a6-fb3e-4a0d-aef8-b0ea469ac85c",
"stage": "string",
"branch": "string",
"status": "string",
"environment": "string",
"runtime_adapter": "claude",
"provider": "anthropic",
"model": "string",
"reasoning_effort": "off",
"log_url": "http://example.com",
"error_message": "string",
"output": {},
"task_summary": "string",
"task_tags": [
"string"
],
"state": {},
"artifacts": [
{
"id": "string",
"name": "string",
"type": "string",
"source": "string",
"size": 0,
"content_type": "string",
"metadata": {
"skill_name": "string",
"skill_source": "user",
"content_sha256": "string",
"bundle_format": "zip",
"schema_version": 1
},
"storage_path": "string",
"uploaded_at": "string",
"uploaded_by": "agent",
"uploaded_by_user_id": 0,
"dismissed_at": "string",
"url": "http://example.com"
}
],
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"completed_at": "2019-08-24T14:15:22Z",
"scheduled_at": "2019-08-24T14:15:22Z",
"preview_available": true
}
Status 400 Run already active or workflow failed
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 403 PostHog Desktop access is required, or Pi cloud runtime is disabled
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 429 Team is over its posthog_code usage limit
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 503 PostHog Desktop access could not be verified
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}

Retrieve tasks runs session logs

Fetch session log entries for a task run with optional filtering by timestamp, event type, and limit.

Required API key scopes

task:read

Path parameters

  • id
    string
  • task_id
    string

Query parameters

  • after
    string
  • event_types
    string
  • exclude_types
    string
  • limit
    integer
    Default: 1000
  • offset
    integer
    Default: 0

Example request

GET /api/projects/:project_id/tasks/:task_id/runs/:id/session_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/tasks/:task_id/runs/:id/session_logs/

Example response

Status 200 Filtered log events as JSON array
Status 404 Task run not found

Update tasks runs set output

Update the output field for a task run (e.g., PR URL, commit SHA, etc.)

Required API key scopes

task:write

Path parameters

  • id
    string
  • task_id
    string

Request parameters

  • output

Response


Example request

PATCH /api/projects/:project_id/tasks/:task_id/runs/:id/set_output
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/tasks/:task_id/runs/:id/set_output/\
-d output=undefined

Example response

Status 200 Run with updated output
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"task": "4879b8a6-fb3e-4a0d-aef8-b0ea469ac85c",
"stage": "string",
"branch": "string",
"status": "string",
"environment": "string",
"runtime_adapter": "claude",
"provider": "anthropic",
"model": "string",
"reasoning_effort": "off",
"log_url": "http://example.com",
"error_message": "string",
"output": {},
"task_summary": "string",
"task_tags": [
"string"
],
"state": {},
"artifacts": [
{
"id": "string",
"name": "string",
"type": "string",
"source": "string",
"size": 0,
"content_type": "string",
"metadata": {
"skill_name": "string",
"skill_source": "user",
"content_sha256": "string",
"bundle_format": "zip",
"schema_version": 1
},
"storage_path": "string",
"uploaded_at": "string",
"uploaded_by": "agent",
"uploaded_by_user_id": 0,
"dismissed_at": "string",
"url": "http://example.com"
}
],
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"completed_at": "2019-08-24T14:15:22Z",
"scheduled_at": "2019-08-24T14:15:22Z",
"preview_available": true
}
Status 404 Run not found

Update tasks runs set summary

Replace the running summary for a task run, and optionally its slug tags.

Required API key scopes

task:write

Path parameters

  • id
    string
  • task_id
    string

Request parameters

  • summary
    string
  • tags
    array

Response


Example request

PATCH /api/projects/:project_id/tasks/:task_id/runs/:id/set_summary
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/tasks/:task_id/runs/:id/set_summary/\
-d summary="string"

Example response

Status 200 Run with updated task summary
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"task": "4879b8a6-fb3e-4a0d-aef8-b0ea469ac85c",
"stage": "string",
"branch": "string",
"status": "string",
"environment": "string",
"runtime_adapter": "claude",
"provider": "anthropic",
"model": "string",
"reasoning_effort": "off",
"log_url": "http://example.com",
"error_message": "string",
"output": {},
"task_summary": "string",
"task_tags": [
"string"
],
"state": {},
"artifacts": [
{
"id": "string",
"name": "string",
"type": "string",
"source": "string",
"size": 0,
"content_type": "string",
"metadata": {
"skill_name": "string",
"skill_source": "user",
"content_sha256": "string",
"bundle_format": "zip",
"schema_version": 1
},
"storage_path": "string",
"uploaded_at": "string",
"uploaded_by": "agent",
"uploaded_by_user_id": 0,
"dismissed_at": "string",
"url": "http://example.com"
}
],
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"completed_at": "2019-08-24T14:15:22Z",
"scheduled_at": "2019-08-24T14:15:22Z",
"preview_available": true
}
Status 404 Run not found

Create tasks runs start

Start an existing cloud run after any initial run-scoped attachments have been uploaded.

Required API key scopes

task:write

Path parameters

  • id
    string
  • task_id
    string

Request parameters

  • pending_user_message
    string
  • pending_user_artifact_ids
    array

Response


Example request

POST /api/projects/:project_id/tasks/:task_id/runs/:id/start
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/tasks/:task_id/runs/:id/start/\
-d pending_user_message="string"

Example response

Status 200 Task with updated latest run
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"task_number": 0,
"slug": "string",
"title": "string",
"title_manually_set": true,
"description": "string",
"origin_product": "string",
"runtime": "acp",
"repository": "string",
"repositories": [
"string"
],
"github_integration": 0,
"github_user_integration": "d46b8f4e-2e12-4354-88a4-723bb64114d3",
"signal_report": "f46cde2b-d4ed-4f8c-8d95-dad529d245b3",
"json_schema": {},
"internal": true,
"archived": true,
"archived_at": "2019-08-24T14:15:22Z",
"latest_run": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"task": "4879b8a6-fb3e-4a0d-aef8-b0ea469ac85c",
"stage": "string",
"branch": "string",
"status": "string",
"environment": "string",
"runtime_adapter": "claude",
"provider": "anthropic",
"model": "string",
"reasoning_effort": "off",
"log_url": "http://example.com",
"error_message": "string",
"output": {},
"task_summary": "string",
"task_tags": [
"string"
],
"state": {},
"artifacts": [
{
"id": "string",
"name": "string",
"type": "string",
"source": "string",
"size": 0,
"content_type": "string",
"metadata": {
"skill_name": "string",
"skill_source": "user",
"content_sha256": "string",
"bundle_format": "zip",
"schema_version": 1
},
"storage_path": "string",
"uploaded_at": "string",
"uploaded_by": "agent",
"uploaded_by_user_id": 0,
"dismissed_at": "string",
"url": "http://example.com"
}
],
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"completed_at": "2019-08-24T14:15:22Z",
"scheduled_at": "2019-08-24T14:15:22Z",
"preview_available": true
},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"last_activity_at": "2019-08-24T14:15:22Z",
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "string",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "string"
},
"ci_prompt": "string",
"channel": "e03ac425-e659-44cf-b8d7-f4176416fcf2",
"slack_thread_references": [
{
"url": "string",
"channel": "string",
"created_at": "string"
}
],
"origin_key": "string"
}
Status 400 Invalid start payload
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 403 PostHog Desktop access is required, or Pi cloud runtime is disabled
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 404 Task run not found
Status 429 Team is over its posthog_code usage limit
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 503 PostHog Desktop access could not be verified
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}

Retrieve tasks runs stream

Server-Sent Events stream of task run events. Events carry an id: line (a Redis stream id, or a synthetic log-<n> id during backlog replay) usable as a resume cursor.

The server caps each connection at 900 seconds: it emits event: end with data: {"type": "rotated"} and closes. This does NOT mean the run finished — reconnect with the Last-Event-ID header set to the last received event id to resume. Only treat the stream as complete when the run itself reaches a terminal status.

Resume guarantees cover mirrored events only: on runs where live mirroring is presence-gated, events produced while no viewer was connected are not in the live stream. Reload the run's session logs to recover the agent's output; run-state and progress frames are not in those logs, so refetch the run itself for its current state.

On runs with durable backlog serving, a connection without Last-Event-ID first replays history from the run log under synthetic log-<n> event ids, then attaches the live stream, skipping live entries the backlog already covered. Reconnecting with a log-<n> id resumes the backlog replay from that point; reconnecting with a Redis id resumes the live stream, may re-deliver a few events already served as backlog frames, and falls back to a full backlog replay when the resume point was trimmed or the stream expired. Runs whose log exceeds the backlog byte cap skip the replay and serve only the recent live window. When the backlog is temporarily unavailable (a storage read failure, or a worker at its concurrent replay budget), the stream emits an event: error frame and closes; reconnect with the same cursor to retry. Treat delivery as at-least-once across reconnects.

?start=latest consumers must also carry Last-Event-ID across reconnects: reconnecting without it re-resolves to the then-current latest event, silently skipping anything published while disconnected.

SDK consumers: do not call the generated fetch wrapper for this path — it will buffer the entire stream. Use the URL builder (getTasksRunsStreamRetrieveUrl) with a streaming fetch/EventSource-style consumer and the Last-Event-ID header instead.

Required API key scopes

task:read

Path parameters

  • id
    string
  • task_id
    string

Query parameters

  • start
    string

Example request

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

Example response

Status 200

Retrieve tasks runs stream token

Generate a run-scoped JWT that authorizes reading this task run's live event stream via the agent-proxy. A run that keeps only a short live tail in Redis is routed to the proxy only when the client sets resync=true, meaning it rebuilds from the durable run log when the proxy reports a trimmed cursor.

Required API key scopes

task:read

Path parameters

  • id
    string
  • task_id
    string

Query parameters

  • resync
    boolean
    Default: false

Response


Example request

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

Example response

Status 200 Run-scoped token for reading the live event stream via the agent-proxy
RESPONSE
{
"token": "string",
"stream_base_url": "string"
}
Status 404 Task run not found

Create tasks runs subscription token

Give the run's agent-server a short-lived ChatGPT access token from the run owner's connected account. Only the run's sandbox may call this, and it must present the run token it received at launch. Send the digest of a token Codex rejected so the server refreshes it early, once.

Required API key scopes

task:write

Path parameters

  • id
    string
  • task_id
    string

Request parameters

  • rejected_access_token_sha256
    string | null

Response


Example request

POST /api/projects/:project_id/tasks/:task_id/runs/:id/subscription_token
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/tasks/:task_id/runs/:id/subscription_token/\
-d rejected_access_token_sha256="string"

Example response

Status 200 Short-lived ChatGPT access token for this run
RESPONSE
{
"access_token": "string",
"account_id": "string",
"plan_type": "string",
"expires_at": "2019-08-24T14:15:22Z"
}
Status 400 Missing required header
Status 403 Caller is not this run's sandbox, or the run token is invalid
Status 404 Task run not found
Status 409 reauth_required: the run owner must reconnect their ChatGPT account
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}
Status 502 openai_unavailable: OpenAI did not answer the token refresh
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}

Retrieve tasks runs task session

API for managing task runs. Each run represents an execution of a task.

Required API key scopes

task:read

Path parameters

  • id
    string
  • task_id
    string

Response


Example request

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

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"download_url": "http://example.com",
"content_sha256": "string"
}
Status 404 Task session not found

Create tasks runs task session sync

API for managing task runs. Each run represents an execution of a task.

Required API key scopes

task:write

Path parameters

  • id
    string
  • task_id
    string


Response


Example request

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"content_sha256": "string"
}
Status 400 Missing required header
Status 403 Invalid task run token
Status 404 Task session not found
Status 409
RESPONSE
{
"detail": "string",
"error": "string",
"type": "string",
"code": "string",
"retry_token": "string",
"reason": "startup_plan",
"attr": "string",
"missing_artifact_ids": [
"string"
],
"limit_type": "burst",
"reset_at": "string",
"is_pro": true
}