Skip to main content
POST
Create run
Creates an empty draft run for a custom agent.

Overview

A run is one agent working through a list of contacts. Building one is three steps, and none of them can call anybody twice:
A draft dials nothing. Nothing is queued and nobody is called until you launch it.

Contacts are not accepted here, on purpose

You cannot pass contacts to this endpoint, and that is a deliberate safety property rather than an omission. If create took a contact list, a request that timed out after the server had committed would leave you unable to tell whether it worked. Retrying would produce a second draft holding the same list — dialling nothing, but sitting there, launchable. An orphan holding 500 real contacts is exactly the thing someone finds later and launches “to be safe”, and then every one of those people is called twice. A retried create here leaves an empty draft instead. It holds nothing, so there is nothing to launch by mistake. Attach is idempotent by construction, so the second request is safe to repeat too.
This is why there is no Idempotency-Key header on this API. The one endpoint that would have needed it does not need it once create is empty.

The agent must be a custom agent

A run is the batch form of a custom agent’s conversation, so the hiring focuses (SCREENING, OUTREACH, LANGUAGE_TEST, GENERIC) cannot back one. A non-custom agent is a 422. The agent must also be in your own company. One that is not returns 404 rather than 403 — the API does not confirm that a resource you cannot reach exists.

Basic Usage

The company comes from your API key, never from the body. An ATS key names the child company with the companyId query parameter; a companyId in the body is rejected outright rather than quietly ignored, so a caller who thought they were targeting another company finds out.

Response

The new run, in the same shape Get Run returns — with an all-zero aggregate, because it has produced nothing yet:

Error Scenarios

  • 404 Not Found: the agent does not exist, or belongs to another company
  • 422 Unprocessable Entity: the agent is not a custom agent
  • 400 Bad Request: the body carries a field this endpoint does not accept, companyId included
  • 403 Forbidden: the API key does not hold write:runs

Attach Contacts

Add the people this run will call

Launch Run

Fan the draft out into conversations

Runs Resource Guide

How a run batches conversations

Create Agent

Build the custom agent a run needs

Authorizations

Authorization
string
header
required

API key for authentication using Bearer scheme

Query Parameters

companyId
string

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

Body

application/json
name
string
required

Human-readable name for the run

Required string length: 2 - 120
Example:

"Q3 product follow-ups"

agentId
string<uuid>
required

The custom agent this run dials with. Must be a custom (Agent Designer) agent in the same company.

Example:

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

Response

Run created

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."