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

# Create campaign

> Schedule outbound calls to multiple recipients.

> [!WARNING]
>
> Campaign calls consume credits.

A `202` response means recipients were accepted for scheduling. See [run a campaign](https://docs.getkarta.ai/guides/campaigns.md) and [idempotency](https://docs.getkarta.ai/idempotency.md).


## OpenAPI

````yaml openapi.json POST /voice/campaigns
openapi: 3.1.0
info:
  title: Karta Public API
  version: 1.0.0-draft
  description: >-
    Karta API reference for accounts, agents, calls, campaigns, WebSocket
    sessions, and billing.
servers:
  - url: https://api.getkarta.ai/public/v1
    description: Production
security:
  - BearerApiKey: []
tags:
  - name: Account
  - name: Agents
  - name: Calls
  - name: Phone numbers
  - name: Campaigns
  - name: Realtime
  - name: Billing
  - name: Webhooks
    description: Outgoing call events delivered to your server.
paths:
  /voice/campaigns:
    post:
      tags:
        - Campaigns
      summary: Create campaign
      description: Schedule outbound calls to multiple recipients.
      operationId: createCampaign
      parameters:
        - name: X-Request-ID
          in: header
          required: false
          description: Optional request-tracing identifier.
          schema:
            type: string
          example: example-request-001
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignRequest'
            example:
              campaign_name: Example follow-up
              agent_id: agentexample
              from_number: '+12025550124'
              max_attempts: 1
              call_window:
                time_zone: Asia/Kolkata
                days:
                  - 1
                  - 2
                  - 3
                  - 4
                  - 5
                  - 6
                start: '10:00'
                end: '18:00'
              call_details:
                - to_number: '+12025550123'
                  llm_dynamic_variable:
                    customer_name: Alex
                  transit_data:
                    external_id: example-001
      responses:
        '202':
          description: Accepted for processing.
          headers:
            X-Request-ID:
              description: Request identifier.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignAccepted'
              example:
                campaign_id: campaign_example
                campaign_name: Example follow-up
                accepted_count: 1
                config:
                  agent_id: agentexample
                  from_number: '+12025550124'
                  max_attempts: 1
                  time_gap_between_attempts: 1
                  call_window:
                    time_zone: Asia/Kolkata
                    days:
                      - 1
                      - 2
                      - 3
                      - 4
                      - 5
                      - 6
                    start: '10:00'
                    end: '18:00'
        '400':
          description: Invalid request or account configuration.
          headers:
            X-Request-ID:
              description: Request identifier.
              schema:
                type: string
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AuthProblem'
                    title: Authentication or account configuration error
                  - $ref: '#/components/schemas/RequestProcessingError'
                    title: Request processing error
              examples:
                configuration:
                  summary: Account configuration error
                  value:
                    type: https://httpstatus.es/400
                    title: Missing Data Residency
                    status: 400
                    detail: Client dataResidency not set. Please contact support.
                    instance: example-request-001
                    code: missing_data_residency
                request:
                  summary: Request parsing error (illustrative message)
                  value:
                    message: Unexpected end of JSON input
            application/problem+json:
              schema:
                $ref: '#/components/schemas/VoiceProblem'
                title: Voice service error
              example:
                type: https://api.karta.com/problems/bad-request
                title: Bad Request
                status: 400
                detail: campaign_name required
                instance: /voice/public/v1/campaigns
                trace_id: example-request-001
        '401':
          description: Authentication failed.
          headers:
            X-Request-ID:
              description: Request identifier.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthProblem'
                title: Authentication or account configuration error
              examples:
                authentication:
                  summary: Missing API key
                  value:
                    type: https://httpstatus.es/401
                    title: Invalid API Key
                    status: 401
                    detail: API key is required
                    instance: example-request-001
                    code: invalid_api_key
        '403':
          description: API key not permitted for this operation.
          headers:
            X-Request-ID:
              description: Request identifier.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthProblem'
                title: Authentication or account configuration error
              examples:
                authentication:
                  summary: Wrong key type
                  value:
                    type: https://httpstatus.es/403
                    title: Wrong API Key Type
                    status: 403
                    detail: Widget API keys may only be used on /widget paths
                    instance: example-request-001
                    code: wrong_key_audience
        '409':
          description: Request ID is in progress or was reused with a different payload.
          headers:
            X-Request-ID:
              description: Request identifier.
              schema:
                type: string
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/VoiceProblem'
                title: Voice service error
              example:
                type: https://api.karta.com/problems/conflict
                title: Conflict
                status: 409
                detail: Request with this X-Request-ID is already in progress
                instance: /voice/public/v1/campaigns
                trace_id: example-request-001
        '422':
          description: Request validation failed.
          headers:
            X-Request-ID:
              description: Request identifier.
              schema:
                type: string
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/VoiceProblem'
                title: Voice service error
              example:
                type: https://api.karta.com/problems/validation-error
                title: Unprocessable Entity
                status: 422
                detail: Validation failed
                instance: /voice/public/v1/campaigns
                trace_id: example-request-001
                errors:
                  - path: body
                    message: Field required
                    type: missing
        '500':
          description: Internal server error.
          headers:
            X-Request-ID:
              description: Request identifier.
              schema:
                type: string
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AuthProblem'
                    title: Authentication or account configuration error
                  - $ref: '#/components/schemas/RequestProcessingError'
                    title: Request processing error
                  - $ref: '#/components/schemas/ProxyConnectionError'
                    title: Upstream connection error
              examples:
                authentication:
                  summary: Authentication failure
                  value:
                    type: https://httpstatus.es/500
                    title: Internal Server Error
                    status: 500
                    detail: Authentication failed
                    instance: example-request-001
                    code: internal_error
                request:
                  summary: Request processing failure
                  value:
                    message: Internal Server Error
                ProxyConnectionError:
                  summary: Upstream connection failure
                  value:
                    error: Internal Server Error
                    message: Error connecting to voice agent service
            application/problem+json:
              schema:
                $ref: '#/components/schemas/VoiceProblem'
                title: Voice service error
              example:
                type: https://api.karta.com/problems/internal-server-error
                title: Internal Server Error
                status: 500
                detail: An internal server error occurred
                instance: /voice/public/v1/campaigns
                trace_id: example-request-001
        '503':
          description: Service temporarily unavailable.
          headers:
            X-Request-ID:
              description: Request identifier.
              schema:
                type: string
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/VoiceProblem'
                title: Voice service error
              example:
                type: https://api.karta.com/problems/internal-server-error
                title: Service Unavailable
                status: 503
                detail: Idempotency store unavailable
                instance: /voice/public/v1/campaigns
                trace_id: example-request-001
      x-codeSamples:
        - lang: bash
          label: cURL
          source: >-
            : "${KARTA_API_KEY:?Set your API key}"

            : "${KARTA_REQUEST_ID:?Set a unique ID; preserve it for retries}"


            curl --fail-with-body
            'https://api.getkarta.ai/public/v1/voice/campaigns' \
              -H "Authorization: Bearer $KARTA_API_KEY" \
              -H "X-Request-ID: $KARTA_REQUEST_ID" \
              -H 'Content-Type: application/json' \
              -d '{
              "campaign_name": "Example follow-up",
              "agent_id": "agentexample",
              "from_number": "+12025550124",
              "max_attempts": 1,
              "call_window": {
                "time_zone": "Asia/Kolkata",
                "days": [
                  1,
                  2,
                  3,
                  4,
                  5,
                  6
                ],
                "start": "10:00",
                "end": "18:00"
              },
              "call_details": [
                {
                  "to_number": "+12025550123",
                  "llm_dynamic_variable": {
                    "customer_name": "Alex"
                  },
                  "transit_data": {
                    "external_id": "example-001"
                  }
                }
              ]
            }'
        - lang: python
          label: Python
          source: >-
            import json

            import os

            from urllib.request import Request, urlopen


            # Preserve KARTA_REQUEST_ID and the body when retrying this action.

            body = {'campaign_name': 'Example follow-up', 'agent_id':
            'agentexample', 'from_number': '+12025550124', 'max_attempts': 1,
            'call_window': {'time_zone': 'Asia/Kolkata', 'days': [1, 2, 3, 4, 5,
            6], 'start': '10:00', 'end': '18:00'}, 'call_details':
            [{'to_number': '+12025550123', 'llm_dynamic_variable':
            {'customer_name': 'Alex'}, 'transit_data': {'external_id':
            'example-001'}}]}

            request = Request(
                'https://api.getkarta.ai/public/v1/voice/campaigns',
                data=json.dumps(body).encode(),
                headers={
                    "Authorization": f"Bearer {os.environ['KARTA_API_KEY']}",
                    "X-Request-ID": os.environ["KARTA_REQUEST_ID"],
                    "Content-Type": "application/json",
                },
                method="POST",
            )

            with urlopen(request, timeout=30) as response:
                print(response.status, json.load(response))
        - lang: javascript
          label: JavaScript
          source: >-
            // Run on your server. Preserve this ID and body when retrying.

            const { KARTA_API_KEY, KARTA_REQUEST_ID } = process.env;

            if (!KARTA_API_KEY || !KARTA_REQUEST_ID) throw new Error("Set API
            key and request ID");

            const response = await
            fetch("https://api.getkarta.ai/public/v1/voice/campaigns", {
              method: "POST",
              headers: {
                "Authorization": `Bearer ${KARTA_API_KEY}`,
                "X-Request-ID": KARTA_REQUEST_ID,
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
              "campaign_name": "Example follow-up",
              "agent_id": "agentexample",
              "from_number": "+12025550124",
              "max_attempts": 1,
              "call_window": {
                "time_zone": "Asia/Kolkata",
                "days": [
                  1,
                  2,
                  3,
                  4,
                  5,
                  6
                ],
                "start": "10:00",
                "end": "18:00"
              },
              "call_details": [
                {
                  "to_number": "+12025550123",
                  "llm_dynamic_variable": {
                    "customer_name": "Alex"
                  },
                  "transit_data": {
                    "external_id": "example-001"
                  }
                }
              ]
            }),

            });

            if (!response.ok) throw new Error(`${response.status}: ${await
            response.text()}`);

            console.log(await response.json());
components:
  schemas:
    CampaignRequest:
      type: object
      properties:
        campaign_name:
          type: string
          minLength: 1
        agent_id:
          type: string
          minLength: 1
        from_number:
          type: string
          description: An eligible account phone number.
          minLength: 1
        start_date:
          type:
            - string
            - 'null'
          description: >-
            Omit or pass null to use the current UTC date; scheduling interprets
            the date in call_window.time_zone.
          format: date
        end_date:
          type:
            - string
            - 'null'
          description: >-
            Last campaign date; must not precede start_date. Omit or pass null
            to leave it unset.
          format: date
        max_attempts:
          type:
            - integer
            - 'null'
          minimum: 1
          maximum: 4
          default: 1
          description: Omit or pass null to use one attempt.
        time_gap_between_attempts:
          type:
            - number
            - 'null'
          description: >-
            Minutes between retries; required and at least 1 when max_attempts >
            1, otherwise ignored.
        max_concurrent_dials:
          type:
            - integer
            - 'null'
          description: >-
            Maximum concurrent calls, subject to account limits. Omit or pass
            null to use account settings.
          minimum: 1
          maximum: 100
        call_window:
          $ref: '#/components/schemas/CallWindow'
        call_details:
          type: array
          items:
            type: object
            properties:
              to_number:
                type: string
                minLength: 1
              llm_dynamic_variable:
                type:
                  - object
                  - 'null'
                properties: {}
                description: Prompt variables for this recipient.
                additionalProperties: true
              transit_data:
                type:
                  - object
                  - 'null'
                properties: {}
                description: Application metadata associated with this call.
                additionalProperties: true
            required:
              - to_number
          minItems: 1
      required:
        - campaign_name
        - agent_id
        - from_number
        - call_window
        - call_details
      allOf:
        - if:
            properties:
              max_attempts:
                minimum: 2
                type: integer
            required:
              - max_attempts
          then:
            required:
              - time_gap_between_attempts
            properties:
              time_gap_between_attempts:
                minimum: 1
                type: number
    CampaignAccepted:
      type: object
      properties:
        campaign_id:
          type: string
        campaign_name:
          type: string
        accepted_count:
          type: integer
          description: >-
            Recipients accepted for scheduling; can be lower than submitted
            count.
        config:
          $ref: '#/components/schemas/CampaignConfig'
    AuthProblem:
      type: object
      properties:
        type:
          type: string
          description: Identifier for this error category.
        title:
          type: string
          description: Short summary of the error.
        status:
          type: integer
          description: HTTP status code for this response.
        detail:
          type: string
          description: Explanation of the failure.
        instance:
          type: string
          description: Request identifier.
        code:
          type: string
          description: Machine-readable error code.
      title: Authentication or account configuration error
    RequestProcessingError:
      title: Request processing error
      type: object
      properties:
        message:
          type: string
          description: Description of the request-processing failure.
        errors:
          type: array
          items:
            additionalProperties: true
            type: object
          description: Additional error details, when supplied.
    VoiceProblem:
      type: object
      properties:
        type:
          type: string
          description: Identifier for this error category.
        title:
          type: string
          description: Short summary of the error.
        status:
          type: integer
          description: HTTP status code for this response.
        detail:
          type: string
          description: Explanation of the failure.
        instance:
          type: string
          description: Request path.
        trace_id:
          type: string
          description: Request identifier for support and troubleshooting.
        errors:
          type: array
          items:
            type: object
            properties:
              path:
                type: string
              message:
                type: string
              type:
                type: string
      title: Voice service error
    ProxyConnectionError:
      title: Upstream connection error
      type: object
      properties:
        error:
          type: string
          enum:
            - Internal Server Error
          description: Machine-readable error code.
        message:
          type: string
          description: Explanation of the failure.
    CallWindow:
      type: object
      properties:
        time_zone:
          type: string
          description: IANA time-zone name.
          examples:
            - Asia/Kolkata
        days:
          type:
            - array
            - 'null'
          items:
            type: integer
            enum:
              - 1
              - 2
              - 3
              - 4
              - 5
              - 6
              - 7
          minItems: 1
          default:
            - 1
            - 2
            - 3
            - 4
            - 5
            - 6
          description: >-
            Weekdays: Monday=1 to Sunday=7. Sundays are skipped; include at
            least one other day. Omit or pass null for Monday–Saturday.
          contains:
            type: integer
            enum:
              - 1
              - 2
              - 3
              - 4
              - 5
              - 6
          minContains: 1
        start:
          type:
            - string
            - 'null'
          description: Local start time, HH:MM. Omit or pass null to use 10:00.
          default: '10:00'
        end:
          type:
            - string
            - 'null'
          description: >-
            Local end time, HH:MM. Must be later than start. Omit or pass null
            to use 21:00.
          default: '21:00'
      required:
        - time_zone
    CampaignConfig:
      type: object
      properties:
        campaign_name:
          type: string
        agent_id:
          type: string
        from_number:
          type: string
        start_date:
          type: string
        end_date:
          type: string
        max_attempts:
          type: integer
        time_gap_between_attempts:
          type: number
        max_concurrent_dials:
          type: integer
        call_window:
          type: object
          properties:
            time_zone:
              type:
                - string
                - 'null'
            days:
              type:
                - array
                - 'null'
              items:
                type: integer
            start:
              type:
                - string
                - 'null'
            end:
              type:
                - string
                - 'null'
  securitySchemes:
    BearerApiKey:
      type: http
      scheme: bearer
      description: 'API key in the format: Bearer YOUR_KARTA_API_KEY.'

````

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