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

# Add contacts to a campaign

> Add up to 10,000 contacts to a `DRAFT` campaign. Phones must be E.164. Duplicates in the request and phones already in the campaign are skipped. For phones that already exist in your workspace, the existing contact's name and metadata are kept. `added` counts new contacts; `total` counts valid unique phones in this request.

**Required scope:** `campaigns.edit`


## OpenAPI

````yaml /api-reference/openapi.json post /campaigns/{id}/contacts
openapi: 3.0.3
info:
  title: Pineyard API
  version: 1.0.0
  description: >-
    Programmatic access to agents, campaigns, calls, phone numbers, WhatsApp and
    results in your Pineyard workspace.
servers:
  - url: https://api.pineyard.ai
    description: Production
security:
  - bearerAuth: []
paths:
  /campaigns/{id}/contacts:
    post:
      summary: Add contacts to a campaign
      description: >-
        Add up to 10,000 contacts to a `DRAFT` campaign. Phones must be E.164.
        Duplicates in the request and phones already in the campaign are
        skipped. For phones that already exist in your workspace, the existing
        contact's name and metadata are kept. `added` counts new contacts;
        `total` counts valid unique phones in this request.
      parameters:
        - schema:
            type: string
          required: true
          name: id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                contacts:
                  type: array
                  items:
                    type: object
                    properties:
                      phone:
                        type: string
                        pattern: ^\+\d{8,15}$
                      name:
                        type: string
                        maxLength: 200
                      metadata:
                        type: object
                        additionalProperties:
                          nullable: true
                    required:
                      - phone
                  minItems: 1
                  maxItems: 10000
              required:
                - contacts
      responses:
        '201':
          description: Added
          content:
            application/json:
              schema:
                type: object
                properties:
                  added:
                    type: number
                  total:
                    type: number
                required:
                  - added
                  - total
        '400':
          description: >-
            - `campaign_not_in_draft`: Adding contacts or CRM import requires a
            DRAFT campaign (or a live CRM_WEBHOOK campaign for imports).

            - `internal_error`: An unexpected error. A `400` with this code
            usually means the body is not valid JSON; a `413` means the body is
            larger than 1 MB.

            - `invalid_body`: The request body (or query) failed validation.
            Details are in `issues` (or `detail`). `422` on `POST
            /v1/campaigns/{campaignId}/leads`.

            - `journey_campaign_contact_cap`: Too many contacts for a journey
            campaign.
        '401':
          description: >-
            - `invalid_api_key`: The API key is unknown, revoked or expired, or
            its workspace was deleted.

            - `unauthorized`: No `Authorization: Bearer` header, or an empty
            token.
        '403':
          description: >-
            - `api_key_not_scoped`: A key issued without scopes was used outside
            `/v1`.

            - `api_key_owner_inactive`: The member the key acts for was removed
            or suspended.

            - `forbidden`: The key lacks the permission named in
            `requiredPermission`, or the resource belongs to another workspace.

            - `workspace_pending_approval`: The workspace has not been approved
            yet.

            - `workspace_suspended`: The workspace is suspended.
        '404':
          description: '- `campaign_not_found`: No campaign with that id in this workspace.'
        '413':
          description: >-
            - `internal_error`: An unexpected error. A `400` with this code
            usually means the body is not valid JSON; a `413` means the body is
            larger than 1 MB.
        '429':
          description: '- `rate_limited`: Too many requests.'
        '500':
          description: >-
            - `internal_error`: An unexpected error. A `400` with this code
            usually means the body is not valid JSON; a `413` means the body is
            larger than 1 MB.
        '502':
          description: >-
            - `provider_error`: The calling service rejected the request
            (`upstreamStatus` 4xx) or was unavailable (5xx).
        '503':
          description: '- `database_unavailable`: The service is temporarily unavailable.'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Your API key, e.g. `pk_live_xxxxxxxxxxxxxxxxxxxxxxxx`.

````

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