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

# Get Campaign Details

> Retrieve campaign details and monitor recipient delivery status



## OpenAPI

````yaml GET /whatsapp/campaigns/{_id}
openapi: 3.1.1
info:
  title: OTPIQ SMS API
  description: >-
    Enterprise-grade SMS and messaging API for sending verification codes,
    custom messages, and managing sender IDs. Supports multiple providers
    including SMS, WhatsApp, and Telegram with intelligent fallback routing.


    ## Features


    * **Multi-Provider Support**: Send messages via SMS, WhatsApp, or Telegram

    * **Smart Fallback Routes**: Automatic provider switching for maximum
    delivery success

    * **Verification Codes**: Automated OTP delivery with customizable codes

    * **Custom Messages**: Send personalized messages with custom sender IDs

    * **Rate Limiting**: Built-in protection against abuse

    * **Spending Controls**: Configurable spending thresholds and credit
    management

    * **Real-time Tracking**: Monitor message delivery status

    * **Sender ID Management**: Register and manage custom sender IDs

    * **Webhook Notifications**: Real-time delivery status updates via webhooks


    ## Provider Options


    OTPIQ now offers 6 provider options including smart fallback routes:


    - **`whatsapp-sms`**: Try WhatsApp first, fallback to SMS

    - **`telegram-sms`**: Try Telegram first, fallback to SMS

    - **`whatsapp-telegram-sms`**: Try WhatsApp → Telegram → SMS (maximum
    delivery success)

    - **`sms`**: SMS only

    - **`whatsapp`**: WhatsApp only

    - **`telegram`**: Telegram only


    ## Authentication


    All API requests require authentication using your project API key. Include
    it in the Authorization header:


    ```

    Authorization: Bearer sk_live_your_api_key_here

    ```


    ## Webhooks


    OTPIQ provides real-time delivery status notifications via webhooks. See the
    Webhooks section for detailed documentation and examples.


    ## Support


    * **Documentation**: [https://docs.otpiq.com](https://docs.otpiq.com)

    * **Support Email**: info@otpiq.com
  version: 1.0.0
  contact:
    name: OTPIQ Support
    url: https://otpiq.com
    email: info@otpiq.com
  license:
    name: Commercial
    url: https://otpiq.com/terms
servers:
  - url: https://api.otpiq.com/api
    description: Production API
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: API key authentication and project information
  - name: SMS
    description: >-
      Send SMS messages, verification codes, and track delivery with multiple
      provider options and fallback routing
  - name: Sender IDs
    description: Manage custom sender IDs for your messages
  - name: Webhooks
    description: Real-time delivery status notifications via webhooks
  - name: Delivery Reports
    description: Generate and list CSV delivery reports for SMS/messages in a date range
  - name: Pricing
    description: Retrieve international SMS pricing information
  - name: WhatsApp
    description: >-
      List WhatsApp businesses, accounts, phone numbers, and message templates
      connected to a project
externalDocs:
  description: OTPIQ Documentation
  url: https://docs.otpiq.com
paths:
  /whatsapp/campaigns/{_id}:
    get:
      tags:
        - WhatsApp Campaigns
      summary: Get campaign details and recipients
      operationId: getWhatsAppCampaign
      parameters:
        - $ref: '#/components/parameters/CampaignIdPath'
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 20
        - name: status
          in: query
          required: false
          schema:
            type: string
            enum:
              - queued
              - sent
              - delivered
              - read
              - failed
          description: Filter paginated recipients by delivery status
        - name: phoneNumber
          in: query
          required: false
          schema:
            type: string
          description: Partial phone number search on recipients
      responses:
        '200':
          description: Campaign with paginated recipients
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignDetailResponse'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          $ref: '#/components/responses/ForbiddenError'
        '404':
          $ref: '#/components/responses/NotFoundError'
components:
  parameters:
    CampaignIdPath:
      name: _id
      in: path
      required: true
      schema:
        type: string
        pattern: ^[a-fA-F0-9]{24}$
      example: 664abc123def456789012346
      description: Campaign MongoDB id returned on create
  schemas:
    CampaignDetailResponse:
      allOf:
        - $ref: '#/components/schemas/SuccessResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/CampaignDetailData'
    SuccessResponse:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          enum:
            - true
        data:
          type: object
          additionalProperties: true
    CampaignDetailData:
      allOf:
        - $ref: '#/components/schemas/WhatsAppCampaign'
        - type: object
          properties:
            recipients:
              type: array
              items:
                $ref: '#/components/schemas/CampaignRecipient'
            linkedSampleCampaigns:
              type: array
              items:
                $ref: '#/components/schemas/LinkedSampleCampaign'
              description: >-
                Sample sends linked to this campaign (empty for sample
                campaigns)
            pagination:
              $ref: '#/components/schemas/Pagination'
    ApiErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          enum:
            - false
        error:
          type: string
        unsupportedPhoneNumbers:
          type: array
          items:
            type: string
          description: Present when one or more recipient countries are unsupported
      additionalProperties: true
    MessageOnly:
      type: object
      properties:
        message:
          type: string
      additionalProperties: true
    WhatsAppCampaign:
      type: object
      properties:
        _id:
          type: string
          pattern: ^[a-fA-F0-9]{24}$
        campaignId:
          type: string
          pattern: ^wac_[a-z0-9]+$
          description: Human-readable campaign reference (e.g. wac_abc123)
        name:
          type: string
        status:
          type: string
          enum:
            - draft
            - scheduled
            - running
            - completed
            - failed
        category:
          type: string
          enum:
            - MARKETING
            - UTILITY
        template:
          oneOf:
            - type: string
            - type: object
              additionalProperties: true
          description: MongoDB id or populated object with name, language, category
        phoneNumber:
          oneOf:
            - type: string
            - type: object
              additionalProperties: true
          description: >-
            MongoDB id or populated object with displayPhoneNumber, phoneNumber,
            verifiedName
        scheduleType:
          $ref: '#/components/schemas/ScheduleType'
        scheduledFor:
          type: string
          format: date-time
          nullable: true
        startedAt:
          type: string
          format: date-time
          nullable: true
        completedAt:
          type: string
          format: date-time
          nullable: true
        totalRecipients:
          type: integer
        sentCount:
          type: integer
        deliveredCount:
          type: integer
        failedCount:
          type: integer
        estimatedTotalCost:
          type: number
          description: Total estimated cost in IQD (set when recipients are attached)
        reservedAmount:
          type: number
          description: Credits reserved at start in IQD
        reconciledAmount:
          type: number
          description: Final billed amount after delivery reconciliation
        billingStatus:
          type: string
          enum:
            - none
            - reserved
            - reconciled
        isSampleCampaign:
          type: boolean
        sampleOfCampaign:
          oneOf:
            - type: string
            - type: object
              additionalProperties: true
          nullable: true
          description: Parent campaign when this is a sample send
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      additionalProperties: true
    CampaignRecipient:
      type: object
      properties:
        _id:
          type: string
        phoneNumber:
          type: string
        status:
          type: string
          enum:
            - queued
            - sent
            - delivered
            - read
            - failed
        templateParameters:
          $ref: '#/components/schemas/TemplateParameters'
        estimatedCost:
          type: number
          description: Per-recipient estimated cost in IQD
        finalCost:
          type: number
          description: Final billed cost in IQD after delivery
        billingState:
          type: string
          enum:
            - reserved
            - finalized
            - refunded
        errorMessage:
          type: string
          nullable: true
        sentAt:
          type: string
          format: date-time
          nullable: true
        deliveredAt:
          type: string
          format: date-time
          nullable: true
        readAt:
          type: string
          format: date-time
          nullable: true
        failedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: true
    LinkedSampleCampaign:
      type: object
      properties:
        _id:
          type: string
        name:
          type: string
        campaignId:
          type: string
        status:
          type: string
          enum:
            - draft
            - scheduled
            - running
            - completed
            - failed
        totalRecipients:
          type: integer
        createdAt:
          type: string
          format: date-time
      additionalProperties: true
    Pagination:
      type: object
      properties:
        total:
          type: integer
        pages:
          type: integer
        page:
          type: integer
        limit:
          type: integer
    ScheduleType:
      type: string
      enum:
        - now
        - schedule
      description: >
        Exactly two allowed values:

        - `now` — save as draft; start manually via POST `.../start`
        (`scheduledFor` not used)

        - `schedule` — **requires** `scheduledFor` (future datetime); saves as
        `scheduled`; auto-starts at that time
    TemplateParameters:
      type: object
      properties:
        body:
          type: object
          additionalProperties:
            type: string
          description: Body variable values keyed by placeholder index (e.g. `"1"`, `"2"`)
        header:
          type: object
          additionalProperties:
            type: string
          description: >
            Header variable values keyed by placeholder index, or media URLs:

            `imageUrl`, `videoUrl`, `documentUrl` depending on template header
            format
        buttons:
          type: object
          additionalProperties:
            type: object
            additionalProperties:
              type: string
          description: Button URL variables keyed by button index, then variable index
      additionalProperties: false
  responses:
    BadRequestError:
      description: Validation or business rule error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            success: false
            error: Recipients cannot exceed 1000 per request
    UnauthorizedError:
      description: Missing, invalid, or unknown API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/MessageOnly'
          example:
            message: Unauthorized, please use your project api key
    ForbiddenError:
      description: Forbidden (IP allowlist, dev key restrictions, etc.)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
    NotFoundError:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            success: false
            error: Campaign not found
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Project API key (`sk_live…` or `sk_dev…`). Send it as `Authorization:
        Bearer <api_key>`.

````