# List messages (/docs/api-reference/whatsapp/listWhatsappMessages)

> One conversation's messages, newest first. Poll forward with after (the id of the newest message you already have) to get only new ones. Page backward through history with cursor. Do not pass both.

> **Set up WhatsApp first.** Connect a WhatsApp number in the dashboard or with [Connect numbers](/docs/api-reference/whatsapp/importWhatsappNumbers). Included on every paid plan. [See plans](https://omnidim.io/pricing).

**GET** `/whatsapp/messages`

One conversation's messages, newest first. Poll forward with `after`
(the id of the newest message you already have) to get only new ones.
Page backward through history with `cursor`. Do not pass both.

```yaml
operationId: listWhatsappMessages
parameters:
  - in: query
    name: conversation_id
    required: true
    schema:
      type: string
    description: The conversation to read.
  - in: query
    name: after
    schema:
      type: integer
    description: Return messages newer than this message id. `next_cursor` is null in this mode.
  - in: query
    name: limit
    schema:
      type: integer
      default: 20
      minimum: 1
      maximum: 100
    description: Rows per page.
  - in: query
    name: cursor
    schema:
      type: string
    description: The `next_cursor` from the previous page. Do not combine it with `after`.
responses:
  '200':
    description: One page of messages.
    content:
      application/json:
        schema:
          type: object
          properties:
            data:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: integer
                  conversation_id:
                    type: string
                  wa_message_id:
                    type: string
                    nullable: true
                    description: The message's id at WhatsApp, when there is one.
                  sender:
                    type: string
                    enum:
                      - customer
                      - agent
                      - person
                  type:
                    type: string
                    description: |
                      The message type: `text`, `image`, `video`, `audio`, `document`,
                      `template`, `reaction`, `interactive`, `location`, `contacts`,
                      `call` or `other`.
                  text:
                    type: string
                    nullable: true
                  caption:
                    type: string
                    nullable: true
                  profile_name:
                    type: string
                    nullable: true
                  sent_by_workflow:
                    type: string
                    nullable: true
                    description: The workflow that sent it, when a workflow did.
                  timestamp:
                    type: string
                  status:
                    type: string
                    enum:
                      - pending
                      - sent
                      - delivered
                      - read
                      - received
                      - failed
                    description: |
                      `received` is an inbound customer message. The rest are outbound, in
                      order: `pending`, `sent`, `delivered`, `read`, or `failed`.
                  reply_to:
                    type: object
                    nullable: true
                    description: The message this one quotes, when it quotes one.
                    properties:
                      wa_message_id:
                        type: string
                      preview:
                        type: string
                        nullable: true
                      sender:
                        type: string
                        nullable: true
                        enum:
                          - customer
                          - agent
                          - person
                  reactions:
                    type: array
                    items:
                      type: object
                      properties:
                        emoji:
                          type: string
                        sender:
                          type: string
                          enum:
                            - customer
                            - agent
                            - person
                        timestamp:
                          type: string
                  media:
                    type: object
                    nullable: true
                    description: Media details, when the message carries a file. It holds no download link.
                    properties:
                      mime:
                        type: string
                        nullable: true
                      filename:
                        type: string
                        nullable: true
                      size:
                        type: integer
                        nullable: true
                      fetch_status:
                        type: string
                        enum:
                          - done
                          - pending
                          - failed
                  voice:
                    type: object
                    nullable: true
                    description: Voice note details, when the message is one.
                    properties:
                      duration_seconds:
                        type: number
                        nullable: true
                      transcript:
                        type: string
                        nullable: true
                  location:
                    type: object
                    nullable: true
                    properties:
                      lat:
                        type: number
                        nullable: true
                      lng:
                        type: number
                        nullable: true
                      name:
                        type: string
                        nullable: true
                      address:
                        type: string
                        nullable: true
                      map_url:
                        type: string
                  contacts:
                    type: array
                    nullable: true
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                          nullable: true
                        phones:
                          type: array
                          items:
                            type: string
                  interactive:
                    type: object
                    nullable: true
                    properties:
                      title:
                        type: string
                        nullable: true
                  template:
                    type: object
                    nullable: true
                    description: The template this message sent, when it is a template message.
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                  failure:
                    type: object
                    nullable: true
                    description: Why a send failed, present only when `status` is `failed`.
                    properties:
                      code:
                        type: string
                        nullable: true
                        description: The provider's failure code, when there is one.
                      reason:
                        type: string
                        nullable: true
                      retryable:
                        type: boolean
                        description: |
                          Whether sending the same message again may work. `false` when
                          the message may already have been delivered.
                  charged:
                    type: object
                    nullable: true
                    description: What this send cost, when it has been charged.
                    properties:
                      amount:
                        type: number
                      currency:
                        type: string
            has_more:
              type: boolean
            next_cursor:
              type: string
              nullable: true
  '400':
    description: >-
      A bad parameter or body. `code` says which, such as `invalid_parameter`, `invalid_json`,
      `invalid_limit` or `invalid_cursor`.
    content:
      application/json:
        schema:
          type: object
          description: |
            The error envelope for every WhatsApp route. Some errors add keys:
            `fields` (the template parameters a send still needs), `ref` (a
            500's support reference) and `failed` (on `import_failed`).
          properties:
            error:
              type: string
              description: Machine-readable category, such as `invalid_request`.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: Stable, specific reason, such as `window_closed`.
            request_id:
              type: string
              description: >-
                Correlates this response with the server log. Also sent as the `X-Request-Id`
                header.
            fields:
              type: array
              items:
                type: string
              description: >-
                On a template send missing parameters (`missing_fields`), the field keys you still
                need.
            ref:
              type: string
              description: On a `500`, the reference to quote to support.
            failed:
              type: array
              items:
                type: object
                properties:
                  phone_number_id:
                    type: string
                  message:
                    type: string
                    example: >-
                      This WhatsApp number is already connected to another account. Disconnect it
                      there first, then import it again. Contact support if you cannot access that
                      account.
              description: On `import_failed`, each number and why it could not be connected.
        example:
          error: invalid_request
          error_description: limit must be a whole number from 1 to 100.
          code: invalid_limit
          request_id: req_4a1c7d9e2f60
  '401':
    description: Missing or invalid API key.
    content:
      application/json:
        schema:
          type: object
          description: |
            The error envelope for every WhatsApp route. Some errors add keys:
            `fields` (the template parameters a send still needs), `ref` (a
            500's support reference) and `failed` (on `import_failed`).
          properties:
            error:
              type: string
              description: Machine-readable category, such as `invalid_request`.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: Stable, specific reason, such as `window_closed`.
            request_id:
              type: string
              description: >-
                Correlates this response with the server log. Also sent as the `X-Request-Id`
                header.
            fields:
              type: array
              items:
                type: string
              description: >-
                On a template send missing parameters (`missing_fields`), the field keys you still
                need.
            ref:
              type: string
              description: On a `500`, the reference to quote to support.
            failed:
              type: array
              items:
                type: object
                properties:
                  phone_number_id:
                    type: string
                  message:
                    type: string
                    example: >-
                      This WhatsApp number is already connected to another account. Disconnect it
                      there first, then import it again. Contact support if you cannot access that
                      account.
              description: On `import_failed`, each number and why it could not be connected.
        example:
          error: unauthorized
          error_description: Missing or invalid API key
          code: invalid_api_key
          request_id: req_6e2b9d4f1a38
  '403':
    description: |
      `feature_not_enabled` when your plan or role cannot use WhatsApp,
      `permission_denied` when the key's user cannot make changes, or
      `service_unavailable` when the account is on hold.
    content:
      application/json:
        schema:
          type: object
          description: |
            The error envelope for every WhatsApp route. Some errors add keys:
            `fields` (the template parameters a send still needs), `ref` (a
            500's support reference) and `failed` (on `import_failed`).
          properties:
            error:
              type: string
              description: Machine-readable category, such as `invalid_request`.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: Stable, specific reason, such as `window_closed`.
            request_id:
              type: string
              description: >-
                Correlates this response with the server log. Also sent as the `X-Request-Id`
                header.
            fields:
              type: array
              items:
                type: string
              description: >-
                On a template send missing parameters (`missing_fields`), the field keys you still
                need.
            ref:
              type: string
              description: On a `500`, the reference to quote to support.
            failed:
              type: array
              items:
                type: object
                properties:
                  phone_number_id:
                    type: string
                  message:
                    type: string
                    example: >-
                      This WhatsApp number is already connected to another account. Disconnect it
                      there first, then import it again. Contact support if you cannot access that
                      account.
              description: On `import_failed`, each number and why it could not be connected.
        example:
          error: forbidden
          error_description: You do not have permission to make changes to WhatsApp.
          code: permission_denied
          request_id: req_9f2c1a4b7d3e
  '404':
    description: |
      No number, conversation, message, template, media upload, agent,
      campaign, contact or opt-out with that id in your workspace. `code`
      says which. Another workspace's id gives the same answer.
    content:
      application/json:
        schema:
          type: object
          description: |
            The error envelope for every WhatsApp route. Some errors add keys:
            `fields` (the template parameters a send still needs), `ref` (a
            500's support reference) and `failed` (on `import_failed`).
          properties:
            error:
              type: string
              description: Machine-readable category, such as `invalid_request`.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: Stable, specific reason, such as `window_closed`.
            request_id:
              type: string
              description: >-
                Correlates this response with the server log. Also sent as the `X-Request-Id`
                header.
            fields:
              type: array
              items:
                type: string
              description: >-
                On a template send missing parameters (`missing_fields`), the field keys you still
                need.
            ref:
              type: string
              description: On a `500`, the reference to quote to support.
            failed:
              type: array
              items:
                type: object
                properties:
                  phone_number_id:
                    type: string
                  message:
                    type: string
                    example: >-
                      This WhatsApp number is already connected to another account. Disconnect it
                      there first, then import it again. Contact support if you cannot access that
                      account.
              description: On `import_failed`, each number and why it could not be connected.
        example:
          error: not_found
          error_description: WhatsApp number not found.
          code: number_not_found
          request_id: req_2c8e7a1d9b40
  '500':
    description: Something went wrong on our side. Quote `ref` to support.
    content:
      application/json:
        schema:
          type: object
          description: |
            The error envelope for every WhatsApp route. Some errors add keys:
            `fields` (the template parameters a send still needs), `ref` (a
            500's support reference) and `failed` (on `import_failed`).
          properties:
            error:
              type: string
              description: Machine-readable category, such as `invalid_request`.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: Stable, specific reason, such as `window_closed`.
            request_id:
              type: string
              description: >-
                Correlates this response with the server log. Also sent as the `X-Request-Id`
                header.
            fields:
              type: array
              items:
                type: string
              description: >-
                On a template send missing parameters (`missing_fields`), the field keys you still
                need.
            ref:
              type: string
              description: On a `500`, the reference to quote to support.
            failed:
              type: array
              items:
                type: object
                properties:
                  phone_number_id:
                    type: string
                  message:
                    type: string
                    example: >-
                      This WhatsApp number is already connected to another account. Disconnect it
                      there first, then import it again. Contact support if you cannot access that
                      account.
              description: On `import_failed`, each number and why it could not be connected.
        example:
          error: server_error
          error_description: >-
            Something went wrong on our side. Please try again shortly, or contact support with
            reference 9a1f3e8b02c4.
          ref: 9a1f3e8b02c4
          code: server_error
          request_id: req_9a1f3e8b02c4
```

**curl**

```bash
curl -X GET "https://omnidim.io/api/v1/whatsapp/messages" \
  -H "Authorization: Bearer $OMNIDIM_API_KEY"
```