Skip to main content
GET
Get run by ID
Retrieves a single run by ID, with its lifecycle status and aggregate progress.

Overview

A run is one agent dialling a list of contacts. It does not replace the conversation, it batches it: launching a run mints one conversation per contact, and the call attempts hang off that conversation exactly as they do for a conversation you created on its own. This endpoint returns the roll-up. For the per-contact detail behind it, use List Run Conversations.
Runs are writable over the API: create one, attach contacts and launch it now or up to 30 days out. This endpoint and its conversations list are how you monitor it afterwards.

Use Cases

  • Monitor a batch: poll one endpoint for the state of hundreds of calls
  • Correlate: match a conversation.* webhook back to the batch it came from, through the runId in its payload
  • Report: show your users how far a campaign has got without holding call state yourself

Response Data

Reading the buckets:
  • Every conversation lands in exactly one bucket, so the six counts sum to total, and total is the run’s real conversation count. A DRAFT run has produced none yet, so every count is 0.
  • inProgress counts calls that are ringing or connected right now. That is not the same as the conversation’s stored status, which stays SCHEDULED while a call is being placed — such a call is moved out of queued rather than added on top, which is why the buckets still sum.
  • unreachable is its own bucket rather than part of failed. Nothing malfunctioned: the retry budget was spent without the contact ever picking up.
  • completion is the fraction of conversations in a terminal state — completed + failed + cancelled + unreachable over total — between 0 and 1. It is 0 on a run that has produced nothing.

Scheduled runs

scheduledAt is when a SCHEDULED run will start dialling, and null on every run that launched immediately. scheduleError is why a scheduled run did not start at its time. A scheduled launch is re-admitted against billing when it fires, and a refusal then has no request to answer — so it is reported here instead. The run stays SCHEDULED and is retried, which means resolving the cause is enough to make it go; there is nothing to re-book.
This field is the only place a failed start is visible. A run whose scheduledAt has passed while its status is still SCHEDULED has been refused, and if you are not reading scheduleError it will sit there indefinitely with nobody watching.

Status

COMPLETED is not terminal. Attaching a contact to a finished run reopens it to RUNNING, which is what makes a run usable as a rolling sequence rather than a one-shot batch. Do not treat COMPLETED as a signal to stop polling unless you also know nothing more will be attached.

Polling

Polling is the fallback, not the recommendation. Each conversation the run produces fires the ordinary conversation.* webhooks, and every one of those payloads carries runId — so a handler attributes the call to this run without polling, and without reading the conversation back.

Company Isolation

You can only read runs belonging to your own API key’s company. A run in another company returns 404 Not Found, the same as one that does not exist — the API does not confirm that a resource you cannot read exists.

Error Scenarios

  • 404 Not Found: the run does not exist, has been deleted, or belongs to a different company
  • 403 Forbidden: the API key does not hold read:runs

Runs Resource Guide

How a run batches conversations

List Run Conversations

The per-contact detail behind the aggregate

Conversations Resource Guide

What each conversation in a run carries

Webhooks

Be told about each call instead of polling

Authorizations

Authorization
string
header
required

API key for authentication using Bearer scheme

Path Parameters

id
string<uuid>
required

Query Parameters

companyId
string

Required for ATS API keys to specify which company to access. Ignored for standard company API keys.

Response

200 - application/json
id
string<uuid>
required

Run ID

Example:

"789e0123-e45b-67d8-a901-234567890123"

name
string
required

Name of the run

Example:

"Q3 product follow-ups"

agentId
string<uuid>
required

The agent this run dials with

Example:

"456e7890-e12b-34d5-a678-901234567890"

status
enum<string>
required

Lifecycle status. A DRAFT run has dialled nothing yet; COMPLETED is not terminal, because attaching a contact to a finished run reopens it to RUNNING.

Available options:
DRAFT,
SCHEDULED,
RUNNING,
PAUSED,
COMPLETED,
CANCELLED
Example:

"RUNNING"

progress
object
required

Aggregate progress across the run's conversations. Every conversation lands in exactly one bucket, so the six counts sum to total.

createdAt
string
required

Created timestamp

Example:

"2026-08-20T09:00:00Z"

updatedAt
string
required

Updated timestamp

Example:

"2026-08-20T11:42:00Z"

scheduledAt
string<date-time> | null

When a scheduled run will start dialling, or null for one that launches immediately. Set together with the SCHEDULED status.

Example:

"2026-09-15T09:00:00Z"

scheduleError
string | null

Why a scheduled run did not start at its time, or null. A scheduled launch is re-admitted against billing when it fires, and a refusal then has no request to answer - it is reported here instead. The run stays SCHEDULED and is retried, so resolving the cause is enough to make it go.

Example:

"Insufficient minutes available to schedule 10 interviews (50 minutes total). Please purchase additional minutes."