> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instaview.sk/llms.txt
> Use this file to discover all available pages before exploring further.

# 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'.

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:

```
POST /runs                    →  an empty draft
POST /runs/{id}/contacts      →  add contacts (idempotent)
POST /runs/{id}/launch        →  one conversation per contact
```

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](/api-reference/runs/attach-run-contacts) is idempotent by construction, so the second request is safe to repeat too.

<Info>
  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.
</Info>

## The agent must be a custom agent

A run is the batch form of a [custom agent's](/api-reference/agents/create-agent#custom-agents) 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

```javascript theme={null}
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}`);
}
```

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](/api-reference/runs/get-run) returns — with an all-zero aggregate, because it has produced nothing yet:

```json theme={null}
{
  "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, `companyId` included
* **403 Forbidden**: the API key does not hold `write:runs`

## Related Resources

<CardGroup cols={2}>
  <Card title="Attach Contacts" icon="user-plus" href="/api-reference/runs/attach-run-contacts">
    Add the people this run will call
  </Card>

  <Card title="Launch Run" icon="play" href="/api-reference/runs/launch-run">
    Fan the draft out into conversations
  </Card>

  <Card title="Runs Resource Guide" icon="layer-group" href="/guides/resources/runs">
    How a run batches conversations
  </Card>

  <Card title="Create Agent" icon="robot" href="/api-reference/agents/create-agent">
    Build the custom agent a run needs
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /runs
openapi: 3.0.0
info:
  title: InstaView API
  description: |-
    InstaView API Documentation

    ## Authentication

    All endpoints require API key authentication using Bearer token:
    ```
    Authorization: Bearer sk_your_api_key_here
    ```

    ## API Key Management

    The API Key module provides comprehensive key management for:
    - **Direct Client Keys**: Company-scoped keys for your applications
    - **ATS Partner Keys**: Resource-scoped keys for ATS integrations

    ### Key Features
    - HMAC-SHA256 hashing for API key storage
    - Configurable rate limiting
    - Comprehensive audit logging
    - Company-level isolation
    - Resource scoping for ATS partners
  version: 1.0.0
  contact: {}
servers:
  - url: https://api.instaview.sk
    description: Production API Gateway
security: []
tags: []
paths:
  /runs:
    post:
      tags:
        - Runs
      summary: Create run
      description: >-
        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'.
      operationId: PublicRunsController_createRun_v1
      parameters:
        - name: companyId
          required: false
          in: query
          description: >-
            Required for ATS API keys to specify which company to access.
            Ignored for standard company API keys.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicCreateRunDto'
      responses:
        '201':
          description: Run created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicRunDto'
        '422':
          description: >-
            Unprocessable Entity - the agent is not a custom agent, or does not
            belong to this company.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearer: []
components:
  schemas:
    PublicCreateRunDto:
      type: object
      properties:
        name:
          type: string
          description: Human-readable name for the run
          example: Q3 product follow-ups
          minLength: 2
          maxLength: 120
        agentId:
          type: string
          format: uuid
          description: >-
            The custom agent this run dials with. Must be a custom (Agent
            Designer) agent in the same company.
          example: 456e7890-e12b-34d5-a678-901234567890
      required:
        - name
        - agentId
    PublicRunDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Run ID
          example: 789e0123-e45b-67d8-a901-234567890123
        name:
          type: string
          description: Name of the run
          example: Q3 product follow-ups
        agentId:
          type: string
          format: uuid
          description: The agent this run dials with
          example: 456e7890-e12b-34d5-a678-901234567890
        status:
          type: string
          description: >-
            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`.
          enum:
            - DRAFT
            - SCHEDULED
            - RUNNING
            - PAUSED
            - COMPLETED
            - CANCELLED
          example: RUNNING
        scheduledAt:
          type: string
          format: date-time
          nullable: true
          description: >-
            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:
          type: string
          nullable: true
          description: >-
            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.
        progress:
          description: >-
            Aggregate progress across the run's conversations. Every
            conversation lands in exactly one bucket, so the six counts sum to
            `total`.
          allOf:
            - $ref: '#/components/schemas/PublicRunProgressDto'
        createdAt:
          type: string
          description: Created timestamp
          example: '2026-08-20T09:00:00Z'
        updatedAt:
          type: string
          description: Updated timestamp
          example: '2026-08-20T11:42:00Z'
      required:
        - id
        - name
        - agentId
        - status
        - progress
        - createdAt
        - updatedAt
    ErrorResponse:
      type: object
      properties:
        statusCode:
          type: integer
          example: 400
        message:
          type: string
          example: Validation failed
        error:
          type: string
          example: Bad Request
      required:
        - statusCode
        - message
    PublicRunProgressDto:
      type: object
      properties:
        total:
          type: number
          description: Conversations this run has produced
          example: 42
        queued:
          type: number
          description: Queued, not yet dialled
          example: 30
        inProgress:
          type: number
          description: Ringing or connected right now
          example: 3
        completed:
          type: number
          description: Finished conversations
          example: 8
        failed:
          type: number
          description: Conversations that failed
          example: 1
        cancelled:
          type: number
          description: Conversations that were cancelled
          example: 0
        unreachable:
          type: number
          description: >-
            Contacts whose retry budget was spent without the call ever
            connecting
          example: 0
        completion:
          type: number
          description: >-
            Fraction of conversations in a terminal state (completed + failed +
            cancelled + unreachable), 0 to 1. `0` on a run that has produced
            nothing yet.
          example: 0.21
      required:
        - total
        - queued
        - inProgress
        - completed
        - failed
        - cancelled
        - unreachable
        - completion
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      description: API key for authentication using Bearer scheme

````