curl --request POST \
--url https://api.instaview.sk/runs \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Q3 product follow-ups",
"agentId": "456e7890-e12b-34d5-a678-901234567890"
}
'import requests
url = "https://api.instaview.sk/runs"
payload = {
"name": "Q3 product follow-ups",
"agentId": "456e7890-e12b-34d5-a678-901234567890"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Q3 product follow-ups', agentId: '456e7890-e12b-34d5-a678-901234567890'})
};
fetch('https://api.instaview.sk/runs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.instaview.sk/runs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Q3 product follow-ups',
'agentId' => '456e7890-e12b-34d5-a678-901234567890'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.instaview.sk/runs"
payload := strings.NewReader("{\n \"name\": \"Q3 product follow-ups\",\n \"agentId\": \"456e7890-e12b-34d5-a678-901234567890\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.instaview.sk/runs")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Q3 product follow-ups\",\n \"agentId\": \"456e7890-e12b-34d5-a678-901234567890\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.instaview.sk/runs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Q3 product follow-ups\",\n \"agentId\": \"456e7890-e12b-34d5-a678-901234567890\"\n}"
response = http.request(request)
puts response.read_body{
"id": "789e0123-e45b-67d8-a901-234567890123",
"name": "Q3 product follow-ups",
"agentId": "456e7890-e12b-34d5-a678-901234567890",
"status": "RUNNING",
"progress": {
"total": 42,
"queued": 30,
"inProgress": 3,
"completed": 8,
"failed": 1,
"cancelled": 0,
"unreachable": 0,
"completion": 0.21
},
"createdAt": "2026-08-20T09:00:00Z",
"updatedAt": "2026-08-20T11:42:00Z",
"scheduledAt": "2026-09-15T09:00:00Z",
"scheduleError": "Insufficient minutes available to schedule 10 interviews (50 minutes total). Please purchase additional minutes."
}{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}Create Run
Creates an empty draft run for a custom agent. A draft dials nothing: attach contacts, then launch. Contacts are deliberately not accepted here - a retried create would otherwise leave a second draft holding the same list, and that draft is exactly the thing someone launches later ‘to be safe’.
curl --request POST \
--url https://api.instaview.sk/runs \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Q3 product follow-ups",
"agentId": "456e7890-e12b-34d5-a678-901234567890"
}
'import requests
url = "https://api.instaview.sk/runs"
payload = {
"name": "Q3 product follow-ups",
"agentId": "456e7890-e12b-34d5-a678-901234567890"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Q3 product follow-ups', agentId: '456e7890-e12b-34d5-a678-901234567890'})
};
fetch('https://api.instaview.sk/runs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.instaview.sk/runs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Q3 product follow-ups',
'agentId' => '456e7890-e12b-34d5-a678-901234567890'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.instaview.sk/runs"
payload := strings.NewReader("{\n \"name\": \"Q3 product follow-ups\",\n \"agentId\": \"456e7890-e12b-34d5-a678-901234567890\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.instaview.sk/runs")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Q3 product follow-ups\",\n \"agentId\": \"456e7890-e12b-34d5-a678-901234567890\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.instaview.sk/runs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Q3 product follow-ups\",\n \"agentId\": \"456e7890-e12b-34d5-a678-901234567890\"\n}"
response = http.request(request)
puts response.read_body{
"id": "789e0123-e45b-67d8-a901-234567890123",
"name": "Q3 product follow-ups",
"agentId": "456e7890-e12b-34d5-a678-901234567890",
"status": "RUNNING",
"progress": {
"total": 42,
"queued": 30,
"inProgress": 3,
"completed": 8,
"failed": 1,
"cancelled": 0,
"unreachable": 0,
"completion": 0.21
},
"createdAt": "2026-08-20T09:00:00Z",
"updatedAt": "2026-08-20T11:42:00Z",
"scheduledAt": "2026-09-15T09:00:00Z",
"scheduleError": "Insufficient minutes available to schedule 10 interviews (50 minutes total). Please purchase additional minutes."
}{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}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:POST /runs → an empty draft
POST /runs/{id}/contacts → add contacts (idempotent)
POST /runs/{id}/launch → one conversation per contact
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.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
const run = await fetch("https://api.instaview.sk/runs", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INSTAVIEW_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "Q3 product follow-ups", agentId: "agent-uuid" }),
signal: AbortSignal.timeout(10_000),
});
if (!run.ok) {
throw new Error(`Creating the run failed: ${run.status} ${run.statusText}`);
}
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:{
"id": "789e0123-e45b-67d8-a901-234567890123",
"name": "Q3 product follow-ups",
"agentId": "456e7890-e12b-34d5-a678-901234567890",
"status": "DRAFT",
"progress": {
"total": 0,
"queued": 0,
"inProgress": 0,
"completed": 0,
"failed": 0,
"cancelled": 0,
"unreachable": 0,
"completion": 0
},
"createdAt": "2026-08-29T09:00:00Z",
"updatedAt": "2026-08-29T09:00:00Z"
}
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,
companyIdincluded - 403 Forbidden: the API key does not hold
write:runs
Related Resources
Attach Contacts
Launch Run
Runs Resource Guide
Create Agent
Authorizations
API key for authentication using Bearer scheme
Query Parameters
Required for ATS API keys to specify which company to access. Ignored for standard company API keys.
Body
Response
Run created
Run ID
"789e0123-e45b-67d8-a901-234567890123"
Name of the run
"Q3 product follow-ups"
The agent this run dials with
"456e7890-e12b-34d5-a678-901234567890"
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.
DRAFT, SCHEDULED, RUNNING, PAUSED, COMPLETED, CANCELLED "RUNNING"
Aggregate progress across the run's conversations. Every conversation lands in exactly one bucket, so the six counts sum to total.
Show child attributes
Show child attributes
Created timestamp
"2026-08-20T09:00:00Z"
Updated timestamp
"2026-08-20T11:42:00Z"
When a scheduled run will start dialling, or null for one that launches immediately. Set together with the SCHEDULED status.
"2026-09-15T09:00:00Z"
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.
"Insufficient minutes available to schedule 10 interviews (50 minutes total). Please purchase additional minutes."