Skip to main content
POST
Create conversation
POST /interviews is a permanent alias of this endpoint and keeps working unchanged, with the same scopes and the same response. See Resource names.
Creates a conversation — one AI-run call to one contact, by phone or on the web. You can point at contacts and agents you already have, or define them inline in the same request.

Overview

A conversation is created either to run immediately or at a scheduleTime you name. Everything it needs can come from ids you already hold (contactId, agentId) or from inline objects the request creates as it goes, so an integration that has just learned about a person does not need two round trips before it can call them.

Use Cases

  • Scheduled calls: Run the conversation at a specific date and time
  • Immediate calls: Start as soon as the agent’s calling hours allow
  • Inline resources: Create a conversation without pre-creating the contact or the agent
  • Bulk outreach: Automate one conversation per contact across a list

Inline Contact, Agent, and Job Support

Contacts, agents and jobs that do not exist yet can be defined inline as objects on the request. Nothing has to be created first.
The inline contact body is contact. candidate is its permanent legacy alias and takes the same fields; send one or the other, not both. The same holds for contactId and candidateId.

Inline Contact with Job Association

Inline Contact with Inline Job

Create both the contact and the job inline for a completely self-contained request:
Complete inline workflow: when you send contact together with job: - a new Job is created for your company - a new Contact is created and automatically associated with that job - the Conversation is linked to both - all three become permanent resources you can fetch and manage afterwards

Inline Contact without Job Association

Job specification options: you can name the job in several ways: - Create inline: use job at the top level to create a new job - Reference existing: use jobId at the top level to link an existing job - Within the inline contact: use jobId inside contact for a more compact request when creating the contact and the association together - No job: omit every job field. A job is optional on a conversation, and most callers outside hiring never send one; the contact can still be assigned to jobs later via the update contact endpoint. Priority: when several job sources are provided, job wins over top-level jobId, which wins over contact.jobId. XOR validation: contact.jobId cannot be combined with a top-level jobId or job, since that would be ambiguous. Pick one per request.

Inline Custom Agent

The inline agent accepts the same custom-agent fields as Create Agent: send a flow (optionally with guardrails, contextConfig and analyticsConfig) and the agent is created as a custom agent, running the conversation you designed instead of a template. As there, focus must be omitted when a flow is present, ids and schemaVersion are assigned by InstaView, and an invalid flow is rejected with a 422 carrying the same errors array — every problem found, each with the path of the block it is on. No conversation is created when that happens. Sending analyticsConfig here is how a one-off call returns structured data rather than just a transcript — the results come back as analytics on this conversation and on its analysis.completed webhook.
Inline creation mints a permanent agent per conversation. That is fine for a one-off, but calling a list of 50 people this way leaves 50 near-identical custom agents behind. When the same flow will call more than one person, create the agent once via POST /agents and pass agentId.

Job-Optional Focuses

Two kinds of agent are job-optional — they can call someone without associating the conversation with a job: GENERIC, and any custom agent (one created with a flow). Every other focus requires a job. The two are not identical, and the difference is worth knowing:
A job-optional focus ignores the contact’s assignments entirely. You do not need to pick one with jobId, and a contact assigned to five jobs is called exactly like one assigned to none. The “specify a jobId” error described under Contact with Multiple Jobs applies only to job-requiring focuses.
Custom agents are always jobless. An agent created with a flow is job-agnostic by design: its prompt comes entirely from the flow, so a job would never be read. This is stricter than GENERIC, which merely makes a job optional — sending job, jobId or contact.jobId for a custom agent is a 400 rather than a silently ignored field.
GENERIC agents exist for conversations that are not about a job at all. That covers most non-hiring work, and in hiring it covers:
  • Talent pool building: calling people about future openings rather than a specific role
  • General outreach: reaching contacts in your database who hold no job assignment
  • Pre-screening: an initial conversation before anyone is matched to a position

Creating a Jobless Conversation with GENERIC Focus

Validation: The API will return a 400 Bad Request error if:
  • You try to create a jobless conversation (no job specified) with an agent whose focus requires a job — that is, anything other than GENERIC or a custom agent
  • You attach a job to a custom agent’s conversation
Note that a GENERIC conversation is not rejected for a contact who has job assignments: the assignments are simply not used.For more detail on how a GENERIC conversation is analysed, see the Conversations Resource Guide.

Existing Contact with Inline Job

You can also define the job inline using job when you already have the contact but don’t want to create a separate job resource first.
Inline job behaviour: when you provide job together with an existing contactId, the API: - creates a full Job for your company from the inline fields - associates the contact with that job if they were not already linked - links the conversation to the new job. jobId and job are mutually exclusive (XOR): use either jobId (an existing job) or job (an inline definition), never both.

Billing and Limits

Creating a conversation consumes call minutes from your company’s billing plan. Make sure enough are available before scheduling in bulk — the API returns 402 Payment Required once billing limits are exceeded, with a billing object naming what the request needed and what was left. See Billing errors.Exception: test conversations (created with isTest: true) consume no minutes and bypass all billing checks.

Scheduling Options

Immediate Conversation

Omit scheduleTime to start the conversation as soon as possible:
With no scheduleTime, the time is ours to pick, so the agent’s calling window applies: a conversation created outside those hours goes out when they next open, in the contact’s own timezone.

Scheduled Conversation

Provide a future scheduleTime timestamp (max 30 days in the future):
A scheduleTime you send is used exactly as given, including when it falls outside the agent’s calling window. You know things the window does not, such as an appointment the contact agreed to, so naming a time overrides the hours rather than being moved into them. The window still governs everything we schedule ourselves: conversations created without a scheduleTime, and every retry after a call that did not connect.The future and 30-day limits above still apply, and are the only bounds on the value. Within them the offset only pins the moment: 14:00:00Z and 16:00:00+02:00 are the same instant and are treated identically.
Note: a contactId must already exist. For an inline contact, every required field (firstName, lastName, email or phoneNumber, gdprExpiryDate) must be present.

Job Selection for Existing Contacts

When using an existing contactId, you can optionally name a jobId to record which job the conversation is for. This matters when the contact is associated with several jobs.

Contact with Single Job

If the contact has one job or none, jobId is optional — the contact’s first job is used if there is one:

Contact with Multiple Jobs

When the contact is associated with several jobs, you must name the jobId:
Multiple job assignments: if the contact holds several and you send no jobId, the API returns 400 Bad Request with the message “This candidate is assigned to multiple jobs. Please specify a ‘jobId’ to associate with this interview.” — quoted as it is actually sent. Error strings are matched on by integrations, so they keep their original wording; only the resource names in this documentation changed.This applies only to job-requiring focuses. GENERIC and custom (flow-based) agents are job-optional, so they call a multi-job contact without a jobId — and a custom agent rejects one outright.
Job association: the jobId you provide must belong to the same company as your API key. If the contact is not already assigned to that job, they are assigned to it when the conversation is created.
Job selection rules: jobId and job are XOR (mutually exclusive) — provide jobId and omit job, or provide job and omit jobId. When job is used: a new job is created for your company, that job becomes the conversation’s jobId, and the contact is associated with it before the conversation is created.

Company Isolation

Every resource involved (contact, agent, job) must belong to the same company as your API key. The API validates ownership and returns 403 Forbidden when they do not.

Complete Workflow Examples

Scenario 1: Conversation with Job Association

Scenario 2: Conversation without Job Association

Scenario 3: Conversation for a Contact with Multiple Jobs

Scenario 4: Existing Contact with Inline Job

The inline job is saved as a regular Job. You can fetch and manage it afterwards through the Jobs API using the jobId returned on the conversation.

Test Mode

Test mode creates a conversation that completes immediately and consumes no billing minutes. It exists so you can exercise webhook handlers and integration flows without placing a call.

When to Use Test Mode

  • Testing webhook handlers: check that your endpoint handles conversation.completed and analysis.completed correctly
  • Integration testing: exercise your processing logic without waiting for a real call
  • Development: build against completed conversations on demand
  • Demos: create sample conversations to show

How Test Mode Works

When you set isTest: true:
  1. Billing bypass: all billing checks are skipped — no minutes are consumed
  2. Immediate completion: the conversation is created with COMPLETED status straight away
  3. Mock analysis: realistic analysis data is generated and stored
  4. Webhook events: both conversation.completed and analysis.completed fire
  5. Default duration: 5 minutes
The event names above are the default NEUTRAL vocabulary. A webhook registered before that option existed is on LEGACY and receives interview.completed instead — same payload, same trigger. See Event name vocabulary.

Example: Creating a Test Conversation

Test Conversation Characteristics

  • Status: always COMPLETED immediately
  • Duration: 5 minutes (300 seconds)
  • Analysis: mock analysis, including:
    • conversation check results (candidateInterest: true, conversationCompleted: true)
    • analysis scores and recommendations
    • mock transcript segments
  • Webhooks: fires conversation.completed and analysis.completed
  • Billing: no minutes consumed, no billing checks performed
Test conversations carry isTest: true. They appear in listings and can be queried like any other, but they do not affect billing or production metrics.

Conversations Resource Guide

Learn how conversations are run and analysed

Agents Resource Guide

Configure the agents that run them

Contacts Resource Guide

Manage the people you call

Billing Guide

Understand call costs and limits

Webhooks Guide

Learn about webhook events and testing

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
contactId
string<uuid>
required

Existing contact ID (XOR with contact). Must exist and belong to the same company as the API key; both are validated server-side.

Example:

"123e4567-e89b-12d3-a456-426614174000"

jobId
string<uuid>
required

Job ID to associate the conversation with (XOR with job). Required when the contact has multiple job assignments and no job is provided, unless the agent's focus is job-optional (GENERIC, CUSTOM). Must belong to the API key's company. If the contact is not already assigned to this job, they will be automatically assigned. Rejected with 400 for custom agents (agents defined by a conversation flow), which are always jobless.

Example:

"123e4567-e89b-12d3-a456-426614174000"

agentId
string<uuid>
required

Existing agent ID (XOR with agent). Must exist and belong to the same company as the API key. Existence/company relationship is validated server-side.

Example:

"987e6543-e21b-12d3-a456-426614174000"

candidateId
string<uuid>
deprecated

Deprecated alias of contactId, kept for the life of v1. Sending both is allowed only when they hold the same value.

Example:

"123e4567-e89b-12d3-a456-426614174000"

job
object

Job for inline creation (XOR with jobId). When provided, a new job will be created and used for the conversation. Cannot be combined with jobId. Rejected with 400 for custom agents (agents defined by a conversation flow), which are always jobless.

contact
object

Contact for inline creation (XOR with contactId)

candidate
object
deprecated

Deprecated alias of contact, kept for the life of v1. Send one inline body, not both.

agent
object

Agent for inline creation (XOR with agentId)

scheduleTime
string<date-time>

Scheduled time in ISO 8601 format (max 30 days in future). Used exactly as sent, including when it falls outside the agent's calling window: naming a time overrides those hours. Omit it and the call is placed inside the window instead. The offset only pins the instant, so 14:00:00Z and 16:00:00+02:00 behave identically.

Example:

"2025-11-20T10:00:00Z"

metadata
object

Custom metadata for the conversation (max 10KB, 5 levels deep, 50 keys)

Example:
isTest
boolean
default:false

If true, creates a test conversation that completes immediately without consuming billing minutes. Triggers webhook events (conversation.completed, analysis.completed — interview.completed on a LEGACY-vocabulary webhook) for testing webhook handlers.

Example:

false

Response

OK (legacy; prefer 201)

id
string<uuid>
required

Conversation ID

Example:

"123e4567-e89b-12d3-a456-426614174000"

contactId
string<uuid>
required

Contact ID

Example:

"987e6543-e21b-12d3-a456-426614174000"

candidateId
string<uuid>
required
deprecated

Deprecated alias of contactId, always identical to it. Kept for the life of v1 so existing integrations keep working; new callers should read contactId.

Example:

"987e6543-e21b-12d3-a456-426614174000"

agentId
string<uuid>
required

Agent ID

Example:

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

status
enum<string>
required

Conversation status

Available options:
UNDEFINED,
SCHEDULED,
CANCELLED,
FAILED,
COMPLETED,
IN_PROGRESS,
UNREACHABLE
Example:

"SCHEDULED"

scheduledAt
string<date-time>
required

Scheduled time

Example:

"2025-11-20T10:00:00Z"

createdAt
string
required

Created timestamp

Example:

"2024-11-16T10:30:00Z"

updatedAt
string
required

Updated timestamp

Example:

"2024-11-16T10:30:00Z"

jobId
string<uuid> | null

Job ID associated with this conversation, if any

Example:

"123e4567-e89b-12d3-a456-426614174000"

runId
string<uuid> | null

The run that produced this conversation, or null for one created on its own. A run mints one conversation per contact, so this is how a conversation is traced back to the batch it came from without listing the run.

Example:

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

durationMinutes
number

Conversation duration in minutes

Example:

15

finishedDate
string<date-time>

Finished date

Example:

"2025-11-20T10:15:00Z"

metadata
object

Custom metadata

Example:
callAttempts
object[]

Call attempt logs for this conversation. Present for PHONE conversations, typically empty or undefined for ONLINE ones.

analysis
object

Conversation analysis data. Present only if analysis has been generated.

analytics
object

What the agent's own analytics configuration produced on this call: extracted fields, match score, outcomes and tags. Present only for a custom agent whose after-call analysis has run.

isTest
boolean

Whether this is a test conversation. A test conversation is created with isTest=true, completes immediately without consuming billing minutes, and is excluded from billing and usage summaries. Use them to exercise webhook handlers and integration flows.

Example:

false