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

# Create batch call

> Uploads a spreadsheet of phone numbers, and your agent calls each one, right away or on a `schedule`. The batch starts by itself once the file is parsed. Follow it with [Get batch call](/api-reference/batch-calls/get-batch-call).

<Note>
You need a number with an outbound gateway, and an outbound [routing rule](/api-reference/routing-rules/create-routing-rule) on it with the `agentId` of the agent that should make the calls.
</Note>




## OpenAPI

````yaml /api-reference/rest/openapi.yaml post /v1/batch-calls
openapi: 3.1.0
info:
  title: Zero Runtime REST API
  version: '1.0'
  description: >-
    Create, configure, version and deploy agents, and wire SIP telephony to
    them.
servers:
  - url: https://api.zeroruntime.ai
security:
  - token: []
tags:
  - name: Agents
  - name: Versions
  - name: Deployment
  - name: Phone numbers
  - name: Routing rules
  - name: Calls
  - name: Batch calls
  - name: Knowledge bases
  - name: Knowledge base folders
paths:
  /v1/batch-calls:
    post:
      tags:
        - Batch calls
      summary: Create batch call
      description: >
        Uploads a spreadsheet of phone numbers, and your agent calls each one,
        right away or on a `schedule`. The batch starts by itself once the file
        is parsed. Follow it with [Get batch
        call](/api-reference/batch-calls/get-batch-call).


        <Note>

        You need a number with an outbound gateway, and an outbound [routing
        rule](/api-reference/routing-rules/create-routing-rule) on it with the
        `agentId` of the agent that should make the calls.

        </Note>
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
                - name
                - phoneNumber
              properties:
                file:
                  type: string
                  format: binary
                  description: >
                    `.csv`, `.xls` or `.xlsx`, at most 5 MB. The first row is
                    the header and needs a `phone_number` column (E.164 with the
                    `+`). Every other column is passed to the agent as metadata
                    for that call.


                    ```csv

                    phone_number,name,plan

                    +919876543210,Asha,gold

                    +14155550100,Tom,silver

                    ```
                name:
                  type: string
                  maxLength: 256
                  description: A name for the batch. Returned as `batchName`.
                  example: October renewals
                description:
                  type: string
                  maxLength: 1000
                  example: Renewal reminders for gold and silver plans
                phoneNumber:
                  type: string
                  description: >-
                    The number to call from, in E.164 with the `+`. It must be
                    on your account.
                  example: '+14155550100'
                phoneNumberId:
                  type: string
                  description: >-
                    The same number by its id. You can send this instead of
                    `phoneNumber`.
                  example: 6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90
                routingRuleId:
                  type: string
                  description: >-
                    The outbound routing rule that picks the agent. Leave it out
                    when the number has exactly one outbound rule.
                  example: rr_2554md
                schedule:
                  type: string
                  description: >
                    JSON string. Leave it out to start calling as soon as the
                    file is parsed.


                    - `date`: required, `YYYY-MM-DD`.

                    - `time`: required, `HH:MM` (24-hour).

                    - `timezone`: IANA name, e.g. `America/New_York`. Default
                    `Asia/Calcutta`.
                  example: >-
                    {"date":"2026-10-14","time":"10:00","timezone":"Asia/Kolkata"}
                retry:
                  type: string
                  description: >
                    JSON string. Sending it turns retries on; leave it out to
                    call each number once.


                    - `retryOn`: required. Any of `failed`, `not-answered`,
                    `rejected`, `missed`, `abandoned`.

                    - `retryDelays`: required. Seconds before each retry, one
                    per attempt, at most 5.
                  example: >-
                    {"retryOn":["not-answered","failed"],"retryDelays":[600,3600]}
                webhook:
                  type: string
                  description: >
                    JSON string. Each event posts `{ batchId, batchName, status,
                    recordsUploaded }`.


                    - `endpoint`: required. The URL that receives the events.

                    - `events`: required, at least one of `batchcall-started`,
                    `batchcall-completed`.
                  example: >-
                    {"endpoint":"https://example.com/hooks/batch","events":["batchcall-started","batchcall-completed"]}
      responses:
        '202':
          description: >-
            Batch created and its file is being parsed. It starts by itself once
            parsing finishes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchCall'
              example:
                batchId: btcl_k3x9q2
                batchName: October renewals
                description: Renewal reminders for gold and silver plans
                phoneNumberId: 6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90
                phoneNumber: '+14155550100'
                routingRuleId: rr_2554md
                status: parsing
                timing: scheduled
                timezone: Asia/Kolkata
                scheduledDate: '2026-10-14'
                scheduledTime: '10:00'
                retry:
                  enabled: true
                  retryOn:
                    - not-answered
                    - failed
                  retryDelays:
                    - 600
                    - 3600
                  maxAttempts: 2
                recordsUploaded: 0
                parseError: null
                file:
                  filename: customers.csv
                  extension: .csv
                  key: batchcall/btcl_k3x9q2/1760261400000-customers.csv
                timestamp: 1760416200
                createdAt: '2026-10-12T09:30:00.000Z'
                updatedAt: '2026-10-12T09:30:00.000Z'
        '400':
          description: >
            The request didn't validate, or the batch couldn't be started.
            Nothing is created.


            **Validation errors** list every problem in `errors`, each prefixed
            with the field's path; `message` is the first one. Every object, and
            the form itself, rejects keys it doesn't know, so a typo like
            `timeZone` is reported instead of ignored.


            Other cases return just `message`:


            - `file is required`

            - `Only CSV and XLS/XLSX files are allowed`

            - `File Size exceeds the 5MB limit`

            - `Phone number has no outbound gateway configured`

            - `Phone number has no outbound routing rule attached`

            - `routingRuleId is required: phone number has multiple outbound
            routing rules (rr_a, rr_b)`

            - `routingRuleId is not attached to this phoneNumberId`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchCallValidationError'
              example:
                message: 'schedule.time: must be HH:MM (24-hour)'
                errors:
                  - 'schedule.time: must be HH:MM (24-hour)'
                  - >-
                    retry.retryOn.0: Invalid enum value. Expected 'failed' |
                    'not-answered' | 'rejected' | 'missed' | 'abandoned',
                    received 'busy'
                  - 'webhook: Unrecognized key(s) in object: ''url'''
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: The number or the routing rule isn't on your account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
              example:
                message: Phone number not found
components:
  schemas:
    BatchCall:
      type: object
      properties:
        batchId:
          type: string
          example: btcl_k3x9q2
        batchName:
          type: string
          description: The `name` you sent.
          example: October renewals
        description:
          type: string
        phoneNumberId:
          type: string
          description: The number calls are made from.
        phoneNumber:
          type: string
          description: That number in E.164.
          example: '+14155550100'
        routingRuleId:
          type: string
          description: The outbound routing rule in use.
          example: rr_2554md
        status:
          type: string
          enum:
            - parsing
            - parse_failed
            - scheduled
            - running
            - cancelling
            - cancelled
            - completed
          description: >
            Without a `schedule`, a batch goes straight from `parsing` to
            `running`.


            - `parsing`: the file is being read. No calls yet.

            - `parse_failed`: the file couldn't be used, and `parseError` says
            why. Fix the file and create a new batch.

            - `scheduled`: parsed, waiting for its start time.

            - `running`: calls are being placed.

            - `cancelling`: a cancel is in progress.

            - `cancelled`: stopped before every number was called.

            - `completed`: every number has been called, retries included.
        timing:
          type: string
          enum:
            - immediate
            - scheduled
          description: '`scheduled` when you sent a `schedule`, otherwise `immediate`.'
        timezone:
          type: string
          example: Asia/Kolkata
        scheduledDate:
          type: string
          description: '`schedule.date`.'
          example: '2026-10-14'
        scheduledTime:
          type: string
          description: '`schedule.time`.'
          example: '10:00'
        retry:
          type: object
          properties:
            enabled:
              type: boolean
              description: '`true` when you sent `retry`.'
            retryOn:
              type: array
              items:
                type: string
                enum:
                  - failed
                  - not-answered
                  - rejected
                  - missed
                  - abandoned
            retryDelays:
              type: array
              items:
                type: integer
                minimum: 0
              description: Seconds before each retry.
            maxAttempts:
              type: integer
              description: Number of retries
              the length of `retryDelays`.: null
        recordsUploaded:
          type: integer
          description: Phone numbers read from the file. `0` until parsing finishes.
        parseError:
          type:
            - string
            - 'null'
          description: Why parsing failed. Set when `status` is `parse_failed`.
        file:
          type: object
          description: The uploaded file.
          properties:
            filename:
              type: string
              example: customers.csv
            extension:
              type: string
              example: .csv
            key:
              type: string
        timestamp:
          type: integer
          description: Start time as a Unix timestamp in seconds. For an immediate batch
          its creation time.: null
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    BatchCallValidationError:
      type: object
      properties:
        message:
          type: string
          description: The first problem.
          example: 'schedule.time: must be HH:MM (24-hour)'
        errors:
          type: array
          description: >-
            Every problem found, each prefixed with the field's path. Only on
            field validation errors.
          items:
            type: string
          example:
            - 'schedule.time: must be HH:MM (24-hour)'
    Message:
      type: object
      properties:
        message:
          type: string
    Error:
      type: object
      properties:
        error:
          type: string
  responses:
    Unauthorized:
      description: Missing or invalid `Authorization` header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    token:
      type: apiKey
      in: header
      name: Authorization
      description: Your API token, sent raw (no `Bearer` prefix).
      x-default: <auth-token>

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.