Runs
A run is the complete unit of agent work. Budgets, policies, and audit trails apply to the run, not the individual API call.
A run is the central concept in Rungate. It represents the complete unit of agent work — first model call, every tool invocation, every retry, every approval gate, the final output. Governance applies to the run as a whole.
This page covers how to group calls into runs, what happens when a run auto-closes, how to handle long-horizon workflows that span hours or days, and how runs interact with the rest of the system.
Grouping calls into a run
You tell Rungate what run a call belongs to via the
x-rungate-run-id header (or the equivalent body field
under a rungate key for SDKs that strip unknown
headers).
x-rungate-run-id: run_customer_refund_2026_04_26 Pick a stable, meaningful ID. The format is up to you — Rungate just uses it as a string key. Common patterns:
run_{feature}_{date}— readable for humans scanning the dashboard.run_{uuid}— easiest if your agent already generates UUIDs.run_{customer_id}_{timestamp}— if you want runs scoped to a customer.
What Rungate does with the ID
On every call:
- If a run with that ID does not exist, Rungate creates a new run.
- If a run with that ID exists and is open, Rungate appends the call to it.
- If a run with that ID exists and is closed, Rungate returns
409 Conflict. Start a new run with a different ID.
If you don't pass an ID, Rungate auto-groups calls by the agent's idle window — calls within the idle timeout (default 15 minutes) get grouped into one auto-run. This is fine for one-shot evaluations but explicit IDs are recommended for production workflows.
Closing a run
Three ways a run closes:
- Idle timeout — no calls for 15 minutes (default;
configurable per policy). Run is marked
completed. - Explicit completion — call
POST /v1/runs/{id}/complete. Idempotent; calling it on an already-closed run returns 200 with the same run object. - Hard stop — a budget or policy violation closes
the run with status
blocked. The agent receives the relevant 4xx response on the next call.
Long-horizon workflows
The 15-minute idle timeout is a fallback, not a hard cap. As long
as the agent keeps sending calls with the same
x-rungate-run-id, the run stays open indefinitely.
Budgets and policies span the entire life of the run.
The auto-close exists for one reason: to recover from agents that crashed or forgot to send a completion. It is not a deadline you need to design around.
/v1/runs/{id}/complete when done.
Inspecting a run
Your agent (or operator tooling) can read run data through
/v1 endpoints scoped to the agent's token:
GET /v1/runs/mine?limit=20 Your recent runs
GET /v1/runs/current The run in progress, if any
GET /v1/runs/{id} Full run object
GET /v1/runs/{id}/steps Step-by-step reconstruction
POST /v1/runs/{id}/complete Close the run (idempotent)
POST /v1/runs/current/complete Close whatever run is current
POST /v1/runs/complete-all Bulk-close (recovery utility) Special headers
Beyond x-rungate-run-id, a few related headers tune
run behavior:
| Header | Purpose |
|---|---|
x-rungate-new-run | Boolean. Force a new run on this call even if a run is in-flight. |
x-rungate-policy | Override the agent's default policy for this run (policy id or name). |
x-rungate-user | End-user identifier — surfaces in analytics filters and webhook payloads. |
x-rungate-tags | Comma-separated tags — surface in analytics + webhooks. |
Example: a multi-step workflow
# Same x-rungate-run-id across all calls — one run, cumulative budget
RUN_ID="run_research_$(uuidgen)"
# Step 1: planning
curl -X POST https://api.rungate.dev/v1/chat/completions \
-H "Authorization: Bearer rg_agt_..." \
-H "x-rungate-run-id: $RUN_ID" \
-d '{ "model": "gpt-4", "messages": [...] }'
# Step 2: research
curl -X POST https://api.rungate.dev/v1/chat/completions \
-H "Authorization: Bearer rg_agt_..." \
-H "x-rungate-run-id: $RUN_ID" \
-d '{ "model": "claude-sonnet-4", "messages": [...] }'
# Step 3: synthesis (might trigger budget alert)
curl -X POST https://api.rungate.dev/v1/chat/completions \
-H "Authorization: Bearer rg_agt_..." \
-H "x-rungate-run-id: $RUN_ID" \
-d '{ "model": "claude-opus-4", "messages": [...] }'
# Done
curl -X POST https://api.rungate.dev/v1/runs/$RUN_ID/complete \
-H "Authorization: Bearer rg_agt_..."