Polling for Results¶
After executing a workflow, use the status endpoint to check progress and retrieve results.
Endpoint¶
Request¶
Headers¶
No request body is needed.
Response¶
Running¶
{
"run_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "running",
"progress": {
"current_step": 2,
"total_steps": 5,
"current_step_name": "Generate content",
"percentage": 40
},
"started_at": "2026-03-10T15:30:00Z",
"completed_at": null,
"result": null,
"cost_cents": null,
"error": null
}
Completed¶
{
"run_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"progress": {
"current_step": 5,
"total_steps": 5,
"current_step_name": "Post to Slack",
"percentage": 100
},
"started_at": "2026-03-10T15:30:00Z",
"completed_at": "2026-03-10T15:31:45Z",
"result": {
"generated_content": "Daily digest: 3 emails from team...",
"summary": "Posted summary to #daily-digest"
},
"cost_cents": 15,
"error": null
}
Failed¶
{
"run_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"progress": {
"current_step": 3,
"total_steps": 5,
"current_step_name": "Send email",
"percentage": 60
},
"started_at": "2026-03-10T15:30:00Z",
"completed_at": "2026-03-10T15:30:58Z",
"result": null,
"cost_cents": 8,
"error": "Gmail connection expired. Please reconnect."
}
Status Values¶
| Status | Meaning |
|---|---|
queued | Workflow is queued and will start shortly |
running | Workflow is actively executing |
completed | Workflow finished successfully |
failed | Workflow encountered an error |
Polling Strategy¶
Workflows typically complete within seconds to a few minutes, depending on the number of steps and external API latency.
Recommended polling approach:
import time
import requests
def wait_for_completion(run_id, api_key, max_wait=300, request_timeout=10):
"""Poll until workflow completes or times out."""
url = f"https://app.gloriamundo.com/api/v1/runs/{run_id}/status"
headers = {"Authorization": f"Bearer {api_key}"}
start = time.monotonic()
while time.monotonic() - start < max_wait:
try:
response = requests.get(url, headers=headers, timeout=request_timeout)
except requests.exceptions.Timeout:
# Transient timeout — continue polling until max_wait expires
time.sleep(2)
continue
except requests.exceptions.RequestException as exc:
raise RuntimeError(f"Request failed for run {run_id}: {exc}") from exc
if response.status_code == 401:
raise PermissionError("Invalid or expired API key (401 Unauthorized)")
if response.status_code == 404:
raise LookupError(f"Run {run_id} not found (404)")
response.raise_for_status()
data = response.json()
if data["status"] in ("completed", "failed"):
return data
# Back off between polls
time.sleep(2)
raise TimeoutError(f"Workflow {run_id} did not complete within {max_wait}s")
Tip
Start with a 2-second polling interval. For longer-running workflows, you can increase the interval after the first few checks.
Error Responses¶
| Status | Meaning |
|---|---|
401 Unauthorized | Missing or invalid API key |
404 Not Found | Run not found or you don't own the workflow |