# GET - Retrieve all campaign messages

Retrieves all messages and their delivery statuses for a given campaign ID, along with campaign template information. This includes messages sent via both Single Send and Batch Send.

```
GET /campaigns/<campaignId>/messages
```

***

**Path Parameters**

| Parameter    | Type   | Required | Description                                      |
| ------------ | ------ | -------- | ------------------------------------------------ |
| `campaignId` | string | Yes      | The ID of the campaign to retrieve messages for. |

***

**Query Parameters**

This endpoint supports cursor-based pagination and search.

| Parameter | Type   | Required | Description                                                                                                 |
| --------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------- |
| `limit`   | number | No       | Number of results per page.                                                                                 |
| `search`  | string | No       | Filter by recipient phone number. This is a substring match (e.g. `"11"` would match `"91122233"`).         |
| `after`   | string | No       | Cursor for fetching the next page. Use the `endCursor` value from the previous response's `pageData`.       |
| `before`  | string | No       | Cursor for fetching the previous page. Use the `startCursor` value from the previous response's `pageData`. |

***

**Request Headers**

| Header          | Value                 | Required |
| --------------- | --------------------- | -------- |
| `Authorization` | `Bearer YOUR_API_KEY` | Yes      |

***

**Request Body**

This endpoint does not require a request body.

***

**Response**

**HTTP 200 OK**

Returns a paginated list of message objects with delivery statuses, template information, and batch details (if applicable).

```json
{
  "data": [
    {
      "createdAt": "2024-05-16T17:04:09.071+08:00",
      "updatedAt": "2024-05-16T17:05:39.704+08:00",
      "id": "<YOUR_MESSAGE_ID>",
      "recipient": "6511112222",
      "values": {
        "otp": "123456",
        "name": "tom"
      },
      "fullMessage": "<YOUR_FULL_MESSAGE>",
      "latestStatus": "failure",
      "templateBodyId": "<YOUR_TEMPLATE_BODY_ID>",
      "campaignId": "<YOUR_CAMPAIGN_ID>",
      "templateBody": {
        "createdAt": "2024-05-16T16:55:30.736+08:00",
        "updatedAt": "2024-05-16T16:55:30.736+08:00",
        "id": "<YOUR_TEMPLATE_BODY_ID>",
        "templateId": "<YOUR_TEMPLATE_ID>",
        "language": "english",
        "body": "Dear {{name}}, here is your {{otp}}.",
        "creatorId": "<YOUR_CREATOR_ID>"
      },
      "batches": [
        {
          "createdAt": "2024-05-16T17:02:59.467+08:00",
          "updatedAt": "2024-05-16T17:05:09.690+08:00",
          "id": "<YOUR_BATCH_ID>",
          "originalFileName": "(sample) API Test.csv",
          "status": "messages_enqueued",
          "campaignId": "<YOUR_CAMPAIGN_ID>",
          "creatorId": "<YOUR_CREATOR_ID>",
          "totalMessages": 3,
          "BatchMessage": {
            "createdAt": "2024-05-16T17:04:09.079+08:00",
            "updatedAt": "2024-05-16T17:04:09.079+08:00",
            "id": "30234",
            "batchId": "<YOUR_BATCH_ID>",
            "messageId": "<YOUR_MESSAGE_ID>"
          }
        }
      ],
      "messageAttempts": [
        {
          "sentAt": "2024-05-16T17:05:39.702+08:00",
          "deliveredAt": null,
          "createdAt": "2024-05-16T17:04:09.092+08:00",
          "updatedAt": "2024-05-16T17:05:39.702+08:00",
          "id": "<YOUR_MESSAGE_ATTEMPT_ID>",
          "messageId": "<YOUR_MESSAGE_ID>",
          "externalAttemptId": "",
          "status": "failure",
          "errorType": "delivery_error",
          "errorCode": "recipient_unavailable",
          "metadata": {},
          "creatorId": "<YOUR_CREATOR_ID>",
          "creator": {
            "email": "<YOUR_CREATOR_EMAIL>"
          }
        }
      ],
      "language": "english",
      "batchId": "<YOUR_BATCH_ID>",
      "creatorEmail": "<YOUR_CREATOR_EMAIL>",
      "creatorId": "<USER_ID_OF_MESSAGE_CREATOR>",
      "numAttempts": 1
    },
    {
      "createdAt": "2024-05-16T16:57:53.761+08:00",
      "updatedAt": "2024-05-16T16:58:06.526+08:00",
      "id": "<YOUR_MESSAGE_ID>",
      "recipient": "6599999999",
      "values": {
        "otp": "12345",
        "name": "John Doe"
      },
      "fullMessage": "<YOUR_FULL_MESSAGE>",
      "latestStatus": "success",
      "templateBodyId": "<YOUR_TEMPLATE_BODY_ID>",
      "campaignId": "<YOUR_CAMPAIGN_ID>",
      "templateBody": {
        "createdAt": "2024-05-16T16:55:30.736+08:00",
        "updatedAt": "2024-05-16T16:55:30.736+08:00",
        "id": "<YOUR_TEMPLATE_BODY_ID>",
        "templateId": "<YOUR_TEMPLATE_ID>",
        "language": "english",
        "body": "Dear {{name}}, here is your {{otp}}.",
        "creatorId": "<YOUR_CREATOR_ID>"
      },
      "batches": [],
      "messageAttempts": [
        {
          "sentAt": "2024-05-16T16:57:53.908+08:00",
          "deliveredAt": null,
          "createdAt": "2024-05-16T16:57:53.763+08:00",
          "updatedAt": "2024-05-16T16:58:06.525+08:00",
          "id": "<YOUR_MESSAGE_ATTEMPT_ID>",
          "messageId": "<YOUR_MESSAGE_ID>",
          "externalAttemptId": "<YOUR_EXTERNAL_ATTEMPT_ID>",
          "status": "success",
          "errorType": null,
          "errorCode": null,
          "metadata": {},
          "creatorId": "<YOUR_CREATOR_ID>",
          "creator": {
            "email": "<YOUR_CREATOR_EMAIL>"
          }
        }
      ],
      "language": "english",
      "creatorEmail": "<YOUR_CREATOR_EMAIL>",
      "creatorId": "<USER_ID_OF_MESSAGE_CREATOR>",
      "numAttempts": 1
    }
  ],
  "pageData": {
    "hasNextPage": false,
    "hasPreviousPage": false,
    "startCursor": "WyIyMDI0LTA1LTE2VDE3OjA0OjA5LjA3MSswODowMCIsIm1lc3NhZ2VfZTgxN2NjM2EtMTA0NC01ODYxLWJmZDUtMDMwM2IwYzczYjcxIl0=",
    "endCursor": "WyIyMDI0LTA1LTE2VDE2OjU3OjUzLjc2MSswODowMCIsIm1lc3NhZ2VfZDhiNWY5M2QtZDgyYi00NWRkLWIyZTctMWYxMTlmMjUwMTcyIl0="
  }
}
```

**Top-level response fields**

| Field      | Type   | Description                      |
| ---------- | ------ | -------------------------------- |
| `data`     | array  | Array of message objects.        |
| `pageData` | object | Pagination metadata (see below). |

**Message object fields**

| Field             | Type   | Description                                                                                          |
| ----------------- | ------ | ---------------------------------------------------------------------------------------------------- |
| `createdAt`       | string | ISO 8601 timestamp of when the message was created.                                                  |
| `updatedAt`       | string | ISO 8601 timestamp of the last update to the message.                                                |
| `id`              | string | The unique message ID.                                                                               |
| `recipient`       | string | The recipient's phone number.                                                                        |
| `values`          | object | The template parameter values used in the message.                                                   |
| `fullMessage`     | string | The full rendered message text, including Postman's header and footer.                               |
| `latestStatus`    | string | The current delivery status. See Message Statuses for all possible values.                           |
| `templateBodyId`  | string | The ID of the template body used.                                                                    |
| `campaignId`      | string | The campaign ID the message belongs to.                                                              |
| `templateBody`    | object | The template body object containing `id`, `templateId`, `language`, `body`, and `creatorId`.         |
| `batches`         | array  | Array of batch objects if the message was sent via batch send. Empty array for single send messages. |
| `messageAttempts` | array  | Array of delivery attempt objects (see below).                                                       |
| `language`        | string | The language used for the message.                                                                   |
| `batchId`         | string | The batch ID if the message was sent via batch send. Absent for single send messages.                |
| `creatorEmail`    | string | The email address of the message creator.                                                            |
| `creatorId`       | string | The user ID of the message creator.                                                                  |
| `numAttempts`     | number | Total number of delivery attempts for this message.                                                  |

**`batches` array (for batch send messages)**

Each batch object describes the batch the message belongs to.

| Field              | Type   | Description                                                                           |
| ------------------ | ------ | ------------------------------------------------------------------------------------- |
| `createdAt`        | string | ISO 8601 timestamp of when the batch was created.                                     |
| `updatedAt`        | string | ISO 8601 timestamp of the last update to the batch.                                   |
| `id`               | string | The unique batch ID.                                                                  |
| `originalFileName` | string | The original CSV file name that was uploaded.                                         |
| `status`           | string | The batch status (e.g. `messages_enqueued`, `messages_enqueuing_failed`).             |
| `campaignId`       | string | The campaign ID the batch belongs to.                                                 |
| `creatorId`        | string | The user ID of the batch creator.                                                     |
| `totalMessages`    | number | Total number of messages in the batch.                                                |
| `BatchMessage`     | object | Object linking the batch to the message, containing `id`, `batchId`, and `messageId`. |

**`messageAttempts` array**

Each attempt object contains the delivery attempt details.

| Field               | Type           | Description                                                                                                                                                                                      |
| ------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sentAt`            | string         | ISO 8601 timestamp of when the message was sent to the provider.                                                                                                                                 |
| `deliveredAt`       | string or null | ISO 8601 timestamp of when the message was delivered. `null` if not delivered.                                                                                                                   |
| `createdAt`         | string         | ISO 8601 timestamp of when the attempt was created.                                                                                                                                              |
| `updatedAt`         | string         | ISO 8601 timestamp of the last update to the attempt.                                                                                                                                            |
| `id`                | string         | The unique attempt ID.                                                                                                                                                                           |
| `messageId`         | string         | The message ID this attempt belongs to.                                                                                                                                                          |
| `externalAttemptId` | string         | The external attempt ID from the messaging service provider. May be empty.                                                                                                                       |
| `status`            | string         | The status of this attempt (e.g. `success`, `failure`, `sent`).                                                                                                                                  |
| `errorType`         | string or null | The error type if the attempt failed: `delivery_error` or `server_error`. `null` if no error.                                                                                                    |
| `errorCode`         | string or null | The error code if the attempt failed. See [Message Delivery Errors](https://postman-v2.guides.gov.sg/general-notes-for-api-users/message-delivery-errors) for the full list. `null` if no error. |
| `metadata`          | object         | Additional metadata for the attempt.                                                                                                                                                             |
| `creatorId`         | string         | The user ID of the message creator.                                                                                                                                                              |
| `creator`           | object         | Object containing the `email` of the message creator.                                                                                                                                            |

**`pageData` object**

| Field             | Type    | Description                                                                             |
| ----------------- | ------- | --------------------------------------------------------------------------------------- |
| `hasNextPage`     | boolean | Whether there is a next page of results.                                                |
| `hasPreviousPage` | boolean | Whether there is a previous page of results.                                            |
| `startCursor`     | string  | Cursor for the first record on the current page. Use with the `before` query parameter. |
| `endCursor`       | string  | Cursor for the last record on the current page. Use with the `after` query parameter.   |

***

**Error Responses**

**HTTP 401 Unauthorized**

| Error Code                 | Message                                          | Cause                                           |
| -------------------------- | ------------------------------------------------ | ----------------------------------------------- |
| `invalid_api_key_provided` | The API key provided is invalid.                 | API key is incorrect, expired, or deleted.      |
| `invalid_ip_address_error` | The IP address used for this request is invalid. | Request sent from a non-whitelisted IP address. |

**HTTP 404 Not Found**

The campaign ID does not exist or you do not have access to it.

**HTTP 429 Too Many Requests**

| Error Code          | Message           | Cause                                                                                                                      |
| ------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `too_many_requests` | Too many requests | Rate limit exceeded. Default is 10 TPS per campaign, shared across all endpoints. Implement exponential backoff and retry. |

***

**Example: cURL**

```bash
curl -X GET \
  "https://postman.gov.sg/api/v2/campaigns/<YOUR_CAMPAIGN_ID>/messages" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**With pagination and search:**

```bash
curl -X GET \
  "https://postman.gov.sg/api/v2/campaigns/<YOUR_CAMPAIGN_ID>/messages?limit=10&search=9999&after=<END_CURSOR>" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

***

**Notes**

* This endpoint returns **all** messages for a campaign, including both single send and batch send messages. You can distinguish them by checking the `batches` array: it is empty for single send messages and populated for batch send messages.
* Results are sorted by `createdAt` followed by `id`.
* The `search` parameter performs a substring match on the recipient phone number. For example, searching for `"11"` will match `"91122233"`.
* Webhooks for delivery status updates are not currently supported. You must poll this endpoint to check for status changes.
* Telcos do not provide read statuses. The terminal statuses are `success` (delivered) and `failure` (failed).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://postman-v2.guides.gov.sg/technical-users-api/api-reference/get-retrieve-all-campaign-messages.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
