# Get a message (/docs/api-reference/whatsapp/getWhatsappMessage)

> One message with its timeline: the delivery and read steps, oldest first. Poll it after a send to learn whether the message was delivered and read. Also shows what the send cost once it is charged.

> **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/{message_id}`

One message with its `timeline`: the delivery and read steps, oldest
first. Poll it after a send to learn whether the message was delivered
and read. Also shows what the send cost once it is charged.

```yaml
operationId: getWhatsappMessage
parameters:
  - in: path
    name: message_id
    required: true
    schema:
      type: integer
    description: Id of a message, from `listWhatsappMessages` or a send response.
responses:
  '200':
    description: The message.
    content:
      application/json:
        schema:
          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
            timeline:
              type: array
              description: The delivery steps of this message, oldest first.
              items:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - received
                      - accepted
                      - sent
                      - delivered
                      - read
                      - failed
                  at:
                    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://backend.omnidim.io/api/v1/whatsapp/messages/{message_id}" \
  -H "Authorization: Bearer $OMNIDIM_API_KEY"
```