Start a run
POST /api/runs
Start a new run by specifying the test versions to execute and the connection to use. Returns 201 Created with the full run object, including every simulation in queued state.
The connection type must have a compatible adapter installed on this deployment. If you attempt a phone run on a deployment without a carrier configured, Egma returns phone_setup_required before writing anything.
Request body
string[]
required
The
tstv_… version ids to execute. Each id must be unique in the list and must be a version your credential can read. An empty list starts nothing.string
required
The connection id to run the simulations against. This determines which agent and provider handle the calls.
string
Optional agent id (
agt_…). When supplied, Egma verifies the named connection belongs to this agent and refuses with a clear message if it does not. Useful when a client holds both ids and wants to catch mismatches explicitly.string
An optional human-readable label for this run, e.g. a branch name, deploy SHA, or release tag.
string
Project context. Defaults to the project your API key belongs to.
Response fields
string
Unique run identifier (
run_…).string
Current run status. Starts as
running when simulations are dispatched.string
The agent the run is executing against.
string
The connection used for this run.
string
Provider type, e.g.
retell or livekit.string
Always
voice for current connection types.string | null
The label supplied at creation, or
null.string[]
The pinned version ids this run executes. These never change after creation.
object
The mock-tool world frozen at the moment this run started.
integer
Total number of simulations this run will conduct.
integer | null
Number of simulations that completed successfully.
null until the run finishes (all three counts arrive together).integer | null
Number of simulations that were graded as failed.
null until the run finishes.integer | null
Number of simulations that were canceled.
null until the run finishes.string
A shareable URL to view the results in the Egma web UI. No token or query parameter — open it with any signed-in browser.
string | null
The run-level verdict once grading is complete:
passed, failed, skipped, or errored. null while grading is still in progress.number | null
Aggregate score across all required graders, or
null while ungraded.object | null
Grading counts (
passed, failed, skipped, errored) at the run level, or null while ungraded.object | null
Folded outcome for diagnostic-only (non-required) graders.
null if no diagnostic graders are configured. Contains verdict, score, and counts.object[]
Per-grader verdict breakdown once grading is complete. Each entry includes
grader_id, required, verdict, score, and counts.integer
Number of simulations that have been graded so far. This settles independently of execution — a run can have all simulations
completed but still show graded_count less than expected_simulation_count.object[]
Every simulation in this run.
string
ISO 8601 timestamp of when the run was started.
string | null
ISO 8601 timestamp of when the run finished, or
null while still running.Example
Get a run
GET /api/runs/:runId
Retrieve the full run object with all simulations, current statuses, and grading results. Use this to seed a follower that did not start the run, or to get a complete snapshot at any point.
Path parameters
string
required
The
run_… identifier of the run.Response fields
Same shape as the start-run response.Example
Stream run events
GET /api/runs/:runId/events
Poll for changes to a run since a given sequence number. This endpoint is a numbered cursor, not a WebSocket: call it repeatedly, advancing after with the next value each time. If your connection drops, restart from the last next value you applied — you will miss nothing and replay nothing.
done: true in the response means the run has finished and no further events will be produced.
Path parameters
string
required
The
run_… identifier of the run to follow.Query parameters
integer
The sequence number to start after. Omit (or use
0) to read from the very first event. Must be a plain non-negative integer — hex, scientific notation, and decimals are rejected.Response fields
object[]
Events since the requested sequence number, in order.
integer | null
Pass this as
?after on your next request. null means there are no new events yet (poll again) unless done is also true.boolean
true when the run has finished and no more events will be produced.Example — initial poll
Example — subsequent poll
Cancel a run
POST /api/runs/:runId/cancel
Stop a run. Simulations still in queued state are canceled immediately. Simulations already dispatched to a conductor receive a stop signal and land as canceled when they acknowledge it.
Canceling a run that is already canceled is a no-op and returns the run as-is. Canceling a run that has already finished is refused with 409 Conflict.
The response is the full run object as it stands after the cancel, so you can read the final counts without a second request. The completed_count, failed_count, and canceled_count fields remain null until all three settle together at the finish.
Path parameters
string
required
The
run_… identifier of the run to cancel.Response fields
Same shape as the start-run response: the full run object at its post-cancel state.Example
Get a simulation recording
GET /api/simulations/:simulationId/recording
Retrieve a short-lived signed URL to play back the audio recording of a voice simulation. The URL points directly to the object store; Egma only decides whether you may hear it and then signs. Audio bytes are served directly from storage, so seeking is free.
This endpoint is only meaningful for voice simulations that completed a call. Chat simulations have no recording. A simulation whose call never connected has no recording either.
Path parameters
string
required
The simulation identifier.
Response fields
string
The simulation this recording belongs to.
string
A short-lived signed URL. Pass directly to an audio player or
<audio> element.string
ISO 8601 timestamp of when the URL expires. If the URL has expired, request this endpoint again for a fresh one.
integer | null
The audio bandwidth the recording was measured at (e.g.
8000 for narrow-band telephone audio, 16000 for wideband). null for recordings written before this measurement was introduced. Two simulations with different bands are different units: a narrow-band recording strips what an audio grader reads.