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

# Create Campaign

> Creates a campaign with a channel-scoped API key and automatically starts sending after recipient preparation completes. JWT authentication is rejected. The send channel and phone number come from the API key. Do not send `channel_id` or `phone_number_id`. Immediate campaigns are created as `DRAFT` and start after preparation. Scheduled campaigns are created as `SCHEDULED` and send at `scheduled_at`.

Use this endpoint to create a WhatsApp campaign from an external system. The campaign is marked as auto-trigger, so sending starts after recipient preparation finishes. You do not call a separate start endpoint.

<Warning>
  This endpoint accepts an API key only. Send `X-API-Key`. JWT authentication is rejected with `This endpoint is restricted to API key usage only`.
</Warning>

## How it works

1. Authenticate with your workspace API key.
2. The API validates the template, channel, audience, and billing features.
3. The campaign is stored with `preparation_status: PREPARING` and `is_auto_trigger: true`.
4. A background worker builds the recipient list.
5. When preparation is `READY`, the campaign starts automatically.

| `send_type` | Status on create | What happens next                                                                |
| :---------- | :--------------- | :------------------------------------------------------------------------------- |
| `IMMEDIATE` | `DRAFT`          | Starts sending after preparation.                                                |
| `SCHEDULED` | `SCHEDULED`      | Sends at `scheduled_at` after preparation. `scheduled_at` must be in the future. |

`total_contacts` is `0` in the create response. The worker updates the count after it loads the audience.

## Example request

Your API key is channel-scoped. The backend reads the WhatsApp channel and `phone_number_id` from the key. Do not send `channel_id` or `phone_number_id` in the body.

```bash theme={null}
curl --request POST \
  --url https://api.automatechats.com/api/campaigns/auto-trigger \
  --header 'X-API-Key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "September promo",
    "description": "Announce the monthly offer to every contact",
    "template_id": "123e4567-e89b-12d3-a456-426614174000",
    "contact_selection_type": "all_contacts",
    "send_type": "IMMEDIATE",
    "variable_mapping": {
      "body": {
        "1": "firstName"
      }
    }
  }'
```

<Note>
  If the channel wallet cannot cover the send, the campaign is auto-paused. Recharge the channel wallet, then start the campaign from the dashboard.
</Note>

## Channel

The send channel comes from your API key. Create the key against the WhatsApp number you want to send from. The API attaches that channel and phone number to the campaign automatically.

Do not pass `channel_id` or `phone_number_id` in the request body.

The template must belong to the same WhatsApp Business account as the API key's channel. Fetch approved templates first with [Fetch Approved Templates](/automate-chats/api-reference/templates/get-templates).

## Audience

Set `contact_selection_type` and the matching fields.

| Type              | Required fields                                                   | Use when                                            |
| :---------------- | :---------------------------------------------------------------- | :-------------------------------------------------- |
| `all_contacts`    | None                                                              | Send to every contact in the workspace.             |
| `quick_contacts`  | `quick_contacts`                                                  | Send to an explicit phone list.                     |
| `csv_contacts`    | `csv_contacts_string` or a CSV file reference, plus `csv_mapping` | Send to an uploaded list.                           |
| `segmented`       | `segments`                                                        | Send to saved segments. Requires Targeted Segments. |
| `failed_contacts` | Previous failed-audience context                                  | Retarget failed recipients.                         |

`csv_mapping` uses **0-based** column indexes. `phone_column` and `country_code_column` are required for CSV audiences.

## Variable mapping

`variable_mapping` personalizes header, body, button, and carousel fields.

* For `all_contacts` and `segmented`, map template variables to contact fields such as `firstName`, `lastName`, `email`, `phoneNumber`, or `countryCode`.
* For `csv_contacts`, map to CSV keys such as `name_column`, `email_column`, or names from `custom_field_mapping`.
* Use `default_values` when a contact field might be empty.

You can pass a field name (`firstName`) or a `{{firstName}}` placeholder. Both resolve at send time.

## Feature and billing checks

* `send_type: SCHEDULED` requires the Schedule Campaigns feature.
* `contact_selection_type: segmented` requires Targeted Segments.
* Starting a campaign counts against Broadcasts Per Month.
* The template must be approved and available on the resolved channel's WhatsApp Business account.


## OpenAPI

````yaml POST /api/campaigns/auto-trigger
openapi: 3.1.0
info:
  title: Automate Chats API
  description: >-
    API for managing WhatsApp template messages, contacts, custom fields, tags,
    campaigns, and external integrations.
  version: 1.0.0
servers:
  - url: https://api.automatechats.com
security:
  - apiKeyAuth: []
paths:
  /api/campaigns/auto-trigger:
    post:
      tags:
        - Campaigns
      summary: Create Campaign
      description: >-
        Creates a campaign with a channel-scoped API key and automatically
        starts sending after recipient preparation completes. JWT authentication
        is rejected. The send channel and phone number come from the API key. Do
        not send `channel_id` or `phone_number_id`. Immediate campaigns are
        created as `DRAFT` and start after preparation. Scheduled campaigns are
        created as `SCHEDULED` and send at `scheduled_at`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCampaignInput'
            examples:
              allContactsImmediate:
                summary: All workspace contacts, send now
                value:
                  name: September promo
                  description: Announce the monthly offer to every contact
                  template_id: 123e4567-e89b-12d3-a456-426614174000
                  contact_selection_type: all_contacts
                  send_type: IMMEDIATE
                  variable_mapping:
                    body:
                      '1': firstName
              quickContacts:
                summary: Explicit phone list
                value:
                  name: Order reminders
                  template_id: 123e4567-e89b-12d3-a456-426614174000
                  contact_selection_type: quick_contacts
                  quick_contacts:
                    - '919876543210'
                    - '918765432109'
                  send_type: IMMEDIATE
                  variable_mapping:
                    body:
                      '1': firstName
              csvContacts:
                summary: CSV audience with column mapping
                value:
                  name: CSV restock alert
                  template_id: 123e4567-e89b-12d3-a456-426614174000
                  contact_selection_type: csv_contacts
                  csv_contacts_string: |-
                    phone,country_code,name
                    9876543210,+91,John
                    8765432109,+91,Priya
                  csv_mapping:
                    phone_column: 0
                    country_code_column: 1
                    name_column: 2
                  send_type: IMMEDIATE
                  variable_mapping:
                    body:
                      '1': name_column
              segmentedScheduled:
                summary: Segment audience, send later
                value:
                  name: VIP restock
                  template_id: 123e4567-e89b-12d3-a456-426614174000
                  contact_selection_type: segmented
                  segments:
                    - 65e0bc51c12e4d70834b070e
                  send_type: SCHEDULED
                  scheduled_at: '2026-10-01T10:00:00.000Z'
                  variable_mapping:
                    header:
                      link: https://example.com/offer.jpg
                    body:
                      '1': firstName
                    default_values:
                      body:
                        '1': there
      responses:
        '201':
          description: >-
            Campaign created. Recipient preparation is queued and sending starts
            automatically when the audience is ready.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateCampaignResponse'
              example:
                status: success
                code: 201
                message: Campaign created successfully
                data:
                  campaign:
                    id: 65f12ab3c9e4f1a2b3c4d5f1
                    name: September promo
                    description: Announce the monthly offer to every contact
                    template_id: 123e4567-e89b-12d3-a456-426614174000
                    contact_selection_type: all_contacts
                    total_contacts: 0
                    total_contacts_skipped: 0
                    preparation_status: PREPARING
                    preparation_version: 1
                    audience_version: 1
                    status: DRAFT
                    send_type: IMMEDIATE
                    scheduled_at: null
                    workspace_id: 123
                    is_auto_trigger: true
                    created_at: '2026-09-22T12:00:00.000Z'
                    updated_at: '2026-09-22T12:00:00.000Z'
                  summary:
                    total_contacts: 0
                    can_send_test: true
                timestamp: '2026-09-22T12:00:00.000Z'
        '400':
          description: >-
            Bad Request (validation error, missing audience, invalid channel, or
            feature not available)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                missingName:
                  summary: Missing campaign name
                  value:
                    status: error
                    code: 400
                    message: Campaign name is required
                    timestamp: '2026-09-22T12:00:00.000Z'
                missingChannel:
                  summary: Channel could not be resolved
                  value:
                    status: error
                    code: 400
                    message: Either channel_id or phone_number_id is required
                    timestamp: '2026-09-22T12:00:00.000Z'
                scheduledInPast:
                  summary: Scheduled time is not in the future
                  value:
                    status: error
                    code: 400
                    message: Scheduled time must be in the future
                    timestamp: '2026-09-22T12:00:00.000Z'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          description: Template not found for this workspace and WhatsApp Business account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                status: error
                code: 404
                message: Template not found
                timestamp: '2026-09-22T12:00:00.000Z'
components:
  schemas:
    CreateCampaignInput:
      type: object
      required:
        - name
        - template_id
        - contact_selection_type
        - send_type
      properties:
        name:
          type: string
          maxLength: 255
          description: Campaign name.
          example: September promo
        description:
          type: string
          maxLength: 1000
          description: Optional campaign description.
          example: Announce the monthly offer to every contact
        template_id:
          type: string
          description: >-
            Approved WhatsApp template UUID that belongs to the same WhatsApp
            Business account as the sending channel.
          example: 123e4567-e89b-12d3-a456-426614174000
        channel_id:
          type: string
          format: uuid
          description: >-
            Not required for this endpoint. The channel-scoped API key supplies
            the send channel.
          example: b340b1b3-bf45-4a61-be71-853a31830dc5
        phone_number_id:
          type: string
          description: >-
            Not required for this endpoint. The channel-scoped API key supplies
            the WhatsApp phone number ID.
          example: '106294715428491'
        contact_selection_type:
          type: string
          enum:
            - all_contacts
            - segmented
            - csv_contacts
            - quick_contacts
            - failed_contacts
          description: >-
            How recipients are selected. `segmented` requires the Targeted
            Segments feature.
        contact_filters:
          type: object
          description: Optional extra filters for `segmented` campaigns.
          properties:
            match:
              type: string
              enum:
                - all
                - any
              example: any
            conditions:
              type: array
              items:
                type: object
                required:
                  - field
                  - operator
                  - value
                properties:
                  field:
                    type: string
                    example: firstName
                  operator:
                    type: string
                    example: equals
                  value:
                    description: Value to compare against the selected field.
        segments:
          type: array
          description: >-
            Segment IDs for `segmented` campaigns. Contacts in any listed
            segment are included.
          items:
            type: string
          example:
            - 65e0bc51c12e4d70834b070e
        quick_contacts:
          type: array
          description: >-
            Phone numbers for `quick_contacts`. Each value must be a valid phone
            number. You can append inline variables after the number using a
            comma, pipe, or semicolon.
          items:
            type: string
          example:
            - '919876543210'
            - '918765432109'
        csv_contacts_string:
          type: string
          description: >-
            Raw CSV text for `csv_contacts`. Must include a header row and at
            least one data row. Provide this or a CSV file reference.
          example: |-
            phone,country_code,name
            9876543210,+91,John
        csv_file_key:
          type: string
          description: S3 key of a previously uploaded campaign CSV.
          example: workspaces/1/campaign-csvs/1730000000-abc123.csv
        csv_file_url:
          type: string
          description: Public URL of a previously uploaded campaign CSV.
        csv_mapping:
          type: object
          description: 0-based column indexes for `csv_contacts`.
          properties:
            phone_column:
              type: integer
              example: 0
            country_code_column:
              type: integer
              example: 1
            name_column:
              type: integer
              example: 2
            email_column:
              type: integer
            custom_field_mapping:
              type: object
              additionalProperties:
                type: integer
              description: Map custom field names to CSV column indexes.
        variable_mapping:
          type: object
          description: >-
            Template personalization. Use contact field names such as
            `firstName`, CSV column keys such as `name_column`, or static
            values. Missing contact values fall back to `default_values`.
          properties:
            header:
              type: object
              additionalProperties: true
              example:
                link: https://example.com/offer.jpg
            body:
              type: object
              additionalProperties: true
              example:
                '1': firstName
            buttons:
              description: Button variable mapping. Accepts an object or an array.
            limited_time_offer:
              type: object
              additionalProperties: true
            footer:
              type: object
              additionalProperties: true
            carousel:
              type: array
              items:
                type: object
                properties:
                  header:
                    type: object
                    properties:
                      link:
                        type: string
                      product:
                        type: object
                        properties:
                          product_retailer_id:
                            type: string
                          catalog_id:
                            type: string
                  body:
                    type: object
                    additionalProperties: true
                  buttons:
                    type: array
                    items:
                      type: object
                      properties:
                        type:
                          type: string
                          example: url
                        url_suffix:
                          type: string
            default_values:
              type: object
              description: Fallback values used when a mapped contact field is empty.
              properties:
                header:
                  type: object
                  additionalProperties:
                    type: string
                body:
                  type: object
                  additionalProperties:
                    type: string
                buttons:
                  type: object
                  additionalProperties:
                    type: string
                footer:
                  type: object
                  additionalProperties:
                    type: string
                carousel:
                  type: array
                  items:
                    type: object
        send_type:
          type: string
          enum:
            - IMMEDIATE
            - SCHEDULED
          description: >-
            `SCHEDULED` requires `scheduled_at` in the future and the Schedule
            Campaigns feature.
        scheduled_at:
          type: string
          format: date-time
          description: >-
            ISO 8601 send time. Required when `send_type` is `SCHEDULED`. Must
            be in the future.
          example: '2026-10-01T10:00:00.000Z'
    CreateCampaignResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        code:
          type: integer
          example: 201
        message:
          type: string
          example: Campaign created successfully
        data:
          type: object
          properties:
            campaign:
              $ref: '#/components/schemas/Campaign'
            summary:
              type: object
              properties:
                total_contacts:
                  type: integer
                  example: 0
                can_send_test:
                  type: boolean
                  example: true
        timestamp:
          type: string
          format: date-time
    ErrorResponse:
      type: object
      properties:
        status:
          type: string
          example: error
        code:
          type: integer
          example: 400
        message:
          type: string
          example: 'Invalid input: field first_name is required.'
        error:
          description: Optional validation error details or raw stack traces.
        timestamp:
          type: string
          format: date-time
          example: '2026-05-18T15:00:00.000Z'
    Campaign:
      type: object
      properties:
        id:
          type: string
          example: 65f12ab3c9e4f1a2b3c4d5f1
        name:
          type: string
          example: September promo
        description:
          type: string
        template_id:
          type: string
          format: uuid
        contact_selection_type:
          type: string
        total_contacts:
          type: integer
          description: >-
            Recipient count is `0` on create. The preparation worker fills this
            in.
        total_contacts_skipped:
          type: integer
        preparation_status:
          type: string
          enum:
            - PREPARING
            - READY
            - FAILED
          example: PREPARING
        status:
          type: string
          description: >-
            `DRAFT` for immediate campaigns until they start. `SCHEDULED` for
            future sends.
          example: DRAFT
        send_type:
          type: string
          example: IMMEDIATE
        scheduled_at:
          type: string
          format: date-time
          nullable: true
        workspace_id:
          type: integer
        is_auto_trigger:
          type: boolean
          example: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
  responses:
    UnauthorizedError:
      description: Unauthorized (missing or invalid API key / JWT token)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            status: error
            code: 401
            message: >-
              Unauthorized access: Invalid or missing authentication
              credentials.
            timestamp: '2026-05-18T15:00:00.000Z'
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

````