A practical field guide from Automation Ace.
Short answer: to monitor ChatGPT workspace agents runs, trigger each run with the header OpenAI-Beta: workspace_agent_runs=v1 so the 202 response includes an agent_trigger_run_id, store it, and poll GET https://api.chatgpt.com/v1/workspace_agents/{id}/runs/{run_id} with backoff until the status is completed or failed. Treat queued and in_progress as still running, alert people when a run is suspended (waiting on an action or tool), and alert on failed runs using error.code (dispatch_failed or run_failed). Keep a run log so you can spot stuck runs, failure spikes, and completed runs whose results never arrived.
Run status polling was a beta feature at the time of writing; field names and statuses come from OpenAI's trigger runs documentation and may change.
Short answer
- Always send the
OpenAI-Betaheader when triggering, so you get a run ID. - Save the run ID with the source event and conversation URL.
- Poll the run endpoint with backoff until
completedorfailed. - Notify a person on
suspended; alert onfailedand on runs stuck too long. - Confirm the result actually arrived, because the API does not return the agent's output.
- Review metrics weekly: completion rate, failures by code, queue time, duration.
Why track run status
The trigger call only tells you a run was accepted. Without status tracking you cannot tell a run that finished from one that failed, stalled waiting for approval, or never started. Agent runs can also fail quietly, so status is the first signal, not the only one. See how to test and monitor AI agents for the bigger picture.
Step 1: Get a run ID when you trigger
Add OpenAI-Beta: workspace_agent_runs=v1 to the trigger request. The 202 response then includes agent_trigger_run_id (format apirun_...) alongside conversation_url. Without the header you get no run ID and nothing to poll. Trigger setup: how to trigger a ChatGPT workspace agent via API.
Step 2: Understand the statuses
| Status | Meaning | Terminal? | What to do |
|---|---|---|---|
queued | Accepted and waiting to start | No | Keep polling; alert if it waits too long |
in_progress | The agent is working | No | Keep polling with backoff |
suspended | Waiting on an external action or tool, such as an approval | No (paused) | Notify the owner with the conversation link |
completed | The run finished | Yes | Check that the result arrived where expected |
failed | The run did not finish; see error.code | Yes | Alert; inspect dispatch_failed vs run_failed |
The status endpoint describes the run's latest state, so record each change yourself if you want history.
Step 3: Check a run
# 1. Trigger with the beta header to get a run ID
curl -X POST "https://api.chatgpt.com/v1/workspace_agents/$TRIGGER_ID/trigger" \
-H "Authorization: Bearer $WA_TOKEN" \
-H "Content-Type: application/json" \
-H "OpenAI-Beta: workspace_agent_runs=v1" \
-d '{"input": "Reconcile the Stripe payouts from yesterday with the ledger sheet."}'
# -> 202 { "agent_trigger_run_id": "apirun_...", "conversation_url": ... }
# 2. Check the run
curl "https://api.chatgpt.com/v1/workspace_agents/$TRIGGER_ID/runs/$RUN_ID" \
-H "Authorization: Bearer $WA_TOKEN" \
-H "OpenAI-Beta: workspace_agent_runs=v1"
# -> { ..., "status": "in_progress", ... }
# -> failed runs include an error object with a code such as
# "dispatch_failed" or "run_failed"
Use the same Workspace Agent access token and trigger ID you used to start the run. A 404 means the run is not found or not visible to your workspace; a 403 means the token's user cannot access that agent. Log the full response the first time you build this, so you know exactly which fields your workspace returns.
Step 4: Poll with backoff, not in a tight loop
// Node.js polling with backoff (pseudocode-level; adapt to your stack)
const TERMINAL = new Set(["completed", "failed"]);
const delays = [10, 20, 30, 60, 120, 300]; // seconds, then stay at 300
async function track(triggerId, runId, maxMinutes = 60) {
const started = Date.now();
for (let i = 0; ; i++) {
const res = await fetch(
`https://api.chatgpt.com/v1/workspace_agents/${triggerId}/runs/${runId}`,
{ headers: { Authorization: `Bearer ${process.env.WA_TOKEN}`,
"OpenAI-Beta": "workspace_agent_runs=v1" } });
if (!res.ok) { await logError(runId, res.status, await res.text()); return; }
const run = await res.json();
await saveStatus(runId, run.status, run.error?.code); // keep history
if (TERMINAL.has(run.status)) return run;
if (run.status === "suspended") await notifyOwner(runId); // once
if ((Date.now() - started) / 60000 > maxMinutes) {
await alert(`Run ${runId} still ${run.status} after ${maxMinutes} min`);
return run;
}
await sleep((delays[i] ?? 300) * 1000);
}
}
- Start fast, then slow down: most short runs finish in minutes; long ones do not need checking every few seconds.
- Set a ceiling: decide how long a run may take before someone looks.
- Stop at terminal states:
completedandfailed. - Notify once for
suspended, not on every poll. - Respect rate limits; batch checks for many open runs; see 429 errors.
Step 5: Keep a run log
| Field | Example | Why |
|---|---|---|
| source_event_id | ticket_4821 | Deduplication and traceability |
| trigger_id | agtch_... | Which agent channel was called |
| run_id | apirun_... | Status lookups |
| conversation_key | ticket-4821 | Related runs |
| conversation_url | https://chatgpt.com/... | Human review |
| status | in_progress | Current state |
| error_code | run_failed | Failure analysis |
| triggered_at / finished_at | Timestamps | Duration and stuck-run detection |
| last_checked_at | Timestamp | Know your poller is alive |
| result_confirmed | yes / no | Did the output actually arrive? |
A table in Airtable, Zapier Tables, a Make data store, or a database is enough. The log is also your audit trail; see permissions, approvals, and audit trails.
Polling with Zapier, Make, or n8n
| Tool | How to poll |
|---|---|
| Zapier | A scheduled Zap every 5 to 15 minutes finds rows whose status is not terminal, calls the status URL with Webhooks by Zapier GET, and updates the row; Paths for completed, failed, and suspended |
| Make | A scheduled scenario searches a data store for open runs, iterates, calls HTTP Make a request (GET), updates the record, and routes alerts with filters |
| n8n | A Schedule Trigger reads open runs, an HTTP Request node checks each, a Switch node routes by status; or a Wait node loop for single runs |
| Code | A worker or serverless cron that polls open runs with backoff |
A scheduled poller that checks all open runs scales better than one long-waiting workflow per run. Triggering from these tools: from webhook to workspace agent with Zapier, Make, or n8n. Scheduling help: custom schedule intervals in Zapier and the Make HTTP module.
Step 6: Alert on what matters
- Failed: alert the agent owner with the error code, source event, and conversation link.
- Suspended: tell the person who must act, with the conversation link.
- Stuck:
queuedorin_progresslonger than your ceiling. - Missing result:
completed, but no Slack post, CRM update, or file within a few minutes. - Trigger errors: repeated 401, 403, 404, or 409 on the trigger call, which usually mean an expired token or an unpublished agent.
Keep alerts few and actionable: route them to one channel and send a daily summary of the rest; see daily digests and Slack notification best practices.
Metrics to watch
| Metric | Watch for |
|---|---|
| Completion rate | Completed ÷ triggered, by agent and source |
| Failure rate by error code | dispatch_failed spikes point to setup or availability; run_failed to the agent's work |
| Time in queued | Backlogs or capacity issues |
| Run duration | Changes after an agent edit |
| Suspended count and age | Approvals nobody is answering |
| Result confirmed rate | Completed runs whose output never arrived |
| Trigger errors (401, 403, 404, 409) | Expired tokens, unpublished agents, moved channels |
Compare against a baseline before and after you change the agent; see automation success metrics.
What status tracking cannot tell you
- Whether the work was right:
completedmeans the run ended, not that the answer was good. Review a sample of conversations. - The output itself: the API does not return it at the time of writing; check the destination or the conversation.
- Cost: track usage through your workspace's admin tools; see what it costs to run an AI agent.
For Claude Code agents, the equivalent is each task's run history and notifications; see notifications for Claude Code scheduled tasks.
Frequently asked questions
How do I check the status of a ChatGPT workspace agent run?
Trigger the run with the OpenAI-Beta: workspace_agent_runs=v1 header to get an agent_trigger_run_id, then send GET https://api.chatgpt.com/v1/workspace_agents/{id}/runs/{run_id} with the same Workspace Agent access token. The response describes the run’s latest status.
What are the workspace agent run statuses?
At the time of writing, the documented statuses were queued, in_progress, suspended, completed, and failed. Suspended means the agent is waiting on an external action or tool, and failed runs include an error code such as dispatch_failed or run_failed.
Why don’t I get a run ID from the workspace agent trigger?
The run ID is only returned when you send the beta header OpenAI-Beta: workspace_agent_runs=v1 with the trigger request. Without it, the 202 response includes only the conversation URL.
How often should I poll a workspace agent run?
Start every 10 to 30 seconds, back off to every few minutes, stop at completed or failed, and alert if a run stays queued or in progress longer than you expect. For many runs, use a scheduled poller that checks all open runs from a log table.
Does a completed workspace agent run mean the task succeeded?
No. Completed means the run ended. Check that the agent delivered its result where expected and review a sample of conversations, because the API does not return the agent’s output.
Disclaimer: ChatGPT workspace agents and the Workspace Agents API (including run status polling, which was in beta) change quickly; details reflect public documentation and coverage at the time of writing, so confirm current details with each provider before building. Automation Ace is not affiliated with OpenAI or the other companies named here. This article may include links to apps, products, or services; some links may be affiliate links, which means Automation Ace may earn a commission at no extra cost to you.