> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://help.moveworks.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://help.moveworks.com/_mcp/server.

# Receive proactive notifications via polling

The Conversations API is in **Controlled Availability**. Endpoints, behaviors, and configuration surfaces may change during CA. Contact your Moveworks account team to participate.

Poll the events endpoint on your own schedule to retrieve system-initiated messages that have been routed to CAPI users. Polling is the recommended path when an inbound HTTPS receiver isn't viable on your backend, and the source of truth for reconciling events after a webhook outage. If you can run an inbound receiver, prefer [outbound webhook push](/api-reference/conversations-api/proactive-notifications/webhook-push) for lower latency to your users and lower load on Moveworks.

Before reading this page, review [Proactive notifications overview](/api-reference/conversations-api/proactive-notifications/overview) for architecture, routing behavior, and prerequisites.

The examples below use `https://api.moveworks.ai`, which is only correct for orgs on the US Production data center. Replace it with the base URL for your data center from the [Base URLs table](/api-reference/overview#base-urls) (for example, `https://api.am-eu-central.moveworks.ai` for EU). Requests to the wrong host return 404 or `invalid_audience`.

## The events endpoint

Retrieve system-initiated messages for a user:

```bash
curl "https://api.moveworks.ai/assistant/v1/conversations/-/events?starting_after=<YOUR_CHECKPOINT>" \
  -H "Authorization: Bearer <MW_ACCESS_TOKEN>" \
  -H "Assistant-Name: <YOUR_BOT_NAME>"
```

Substitute:

* `<YOUR_CHECKPOINT>` — the `event_id` you last successfully processed for this user. Passed as `starting_after` (exclusive lower bound). Omit on the first-ever call for a user.
* `<MW_ACCESS_TOKEN>` — a valid Moveworks bearer token for the recipient user. See the [auth guides](/api-reference/conversations-api/set-up-authentication-with-okta) for token issuance.
* `<YOUR_BOT_NAME>` — the Bot Name provided by your account team.

The `-` in the URL is a wildcard that returns events across all of the user's conversations, including new conversations Moveworks created for proactive messages with no prior user input.

### Query parameters

| Parameter        | Type    | Required | Description                                                                                                                                     |
| ---------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `starting_after` | string  | No       | Event ID (base-62, `evt_` prefix). Exclusive lower bound. Pass your stored `last_event_id` to retrieve events after your last known checkpoint. |
| `ending_at`      | string  | No       | Event ID (base-62, `evt_` prefix). Inclusive upper bound. Used to bound recovery queries.                                                       |
| `cursor`         | string  | No       | Pagination cursor from a prior response.                                                                                                        |
| `limit`          | integer | No       | Results per page. Range: 1-100. Default: 20.                                                                                                    |

When both `starting_after` and `ending_at` are supplied, `ending_at` must refer to an event created after the one identified by `starting_after`.

### Response

```json
{
  "events": [
    {
      "event_id": "evt_340xdCuTfBHbSriGYQz6J",
      "conversation_id": "conv_340xdCMeTfceLCg8Gt6LP",
      "created_at": "2026-08-03T22:03:22.965068Z",
      "event_payload": {
        "type": "MESSAGE_EVENT",
        "message": {
          "message_id": "msg_340xdCrqXA6LvcoIgVbfs",
          "conversation_id": "conv_340xdCMeTfceLCg8Gt6LP",
          "response_id": "resp_340xdCMeTfceLCg0s1LRL",
          "actor": "ASSISTANT",
          "content": {
            "type": "MARKDOWN_TEXT",
            "markdown_text": { "text": "Reminder: Your password expires in 3 days." }
          },
          "created_at": "2026-08-03T22:03:22.965068Z"
        }
      }
    }
  ],
  "metadata": {}
}
```

### Response fields

| Field                                                       | Type              | Description                                                                                                                                                        |
| ----------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `events[].event_id`                                         | string            | Unique event identifier. Base-62 identifier prefixed with `evt_` (for example, `evt_32bt9WkPqRnEtYsLmXc4v`), consistent with other Conversations API resource IDs. |
| `events[].conversation_id`                                  | string            | The conversation this event belongs to.                                                                                                                            |
| `events[].created_at`                                       | string (ISO 8601) | When the event was created.                                                                                                                                        |
| `events[].event_payload.type`                               | string            | Event payload type discriminator. Currently `MESSAGE_EVENT`.                                                                                                       |
| `events[].event_payload.message.message_id`                 | string            | Message identifier.                                                                                                                                                |
| `events[].event_payload.message.conversation_id`            | string            | The conversation this message belongs to (matches the outer `conversation_id`).                                                                                    |
| `events[].event_payload.message.response_id`                | string            | The response this message belongs to.                                                                                                                              |
| `events[].event_payload.message.actor`                      | string            | `"ASSISTANT"` for system-generated messages.                                                                                                                       |
| `events[].event_payload.message.content.type`               | string            | Content type. Common values: `MARKDOWN_TEXT`, `COMMONMARK_TEXT`, `PLAIN_TEXT`.                                                                                     |
| `events[].event_payload.message.content.markdown_text.text` | string            | Message content (for `MARKDOWN_TEXT`). Field name matches the content type.                                                                                        |
| `events[].event_payload.message.created_at`                 | string (ISO 8601) | When the message was created.                                                                                                                                      |
| `metadata.next_cursor`                                      | string / null     | Cursor for the next page when the result set exceeds `limit`; `null` if no more results.                                                                           |

The events endpoint returns only final messages; intermediate reasoning or in-progress states are not included.

**Scope.** The events endpoint is scoped to a single user, consistent with all other Conversations API endpoints. Polling and recovery must be performed per user using each user's stored `last_event_id`.

**Response headers.** Every response includes an `x-trace-id` header identifying the request. Capture it if you need to correlate to Moveworks-side logs when opening a support case. The legacy `x-moveworks-root-uuid` header is also returned for backward compatibility but is deprecated; prefer `x-trace-id`.

## Recommended pattern: per-user checkpoint

Advancing through the event stream requires tracking your position per user. Maintain a `{user_id, last_event_id}` record per user in your backend and pass `last_event_id` as `starting_after` on each poll.

| Rule                      | Detail                                                                                                   |
| ------------------------- | -------------------------------------------------------------------------------------------------------- |
| One checkpoint per user   | The events endpoint is user-scoped; polling and recovery are per user.                                   |
| Advance after processing  | Only update `last_event_id` after successfully delivering the content to your client.                    |
| Never regress             | Only advance the checkpoint forward.                                                                     |
| Initialize on first event | If no checkpoint exists, the first `event_id` returned by the events endpoint becomes the initial value. |

Event IDs are base-62 identifiers with an `evt_` prefix, consistent with other Conversations API resource IDs. Use each processed event's ID as your next cursor value for exact iteration through the stream.

The same checkpoint pattern underlies webhook-based delivery — see [Per-user checkpoint](/api-reference/conversations-api/proactive-notifications/webhook-push#per-user-checkpoint) on the outbound webhook page.

## Recovery after an outage

If your backend was unavailable when new events were created, call the events endpoint per affected user using that user's stored checkpoint:

```bash
curl "https://api.moveworks.ai/assistant/v1/conversations/-/events?starting_after=<USER_CHECKPOINT>" \
  -H "Authorization: Bearer <MW_ACCESS_TOKEN>" \
  -H "Assistant-Name: <YOUR_BOT_NAME>"
```

Omit `ending_at` to fetch all events since the checkpoint up to the present. Paginate using `next_cursor` if the result set exceeds one page.

## Testing end-to-end

Because of the [routing behavior](/api-reference/conversations-api/proactive-notifications/overview#routing-behavior), testing requires establishing the CAPI integration as the recipient's most-recent-interaction channel before triggering the source-system webhook.

#### Send a user message through your CAPI integration

Create a conversation, send at least one user message, and poll the response until it completes so the recipient's most-recent-interaction channel is CAPI. Creating a conversation alone does not count as an interaction with the bot — the bot must actually process a message and generate a response.

```bash
# 1. Create a conversation
curl -X POST "https://api.moveworks.ai/assistant/v1/conversations" \
  -H "Authorization: Bearer <MW_ACCESS_TOKEN>" \
  -H "Assistant-Name: <YOUR_BOT_NAME>" \
  -H "Content-Type: application/json" \
  -d '{"title":"pre-interaction for proactive test"}'

# 2. Send a user message. This returns 202 with status IN_PROGRESS.
curl -X POST "https://api.moveworks.ai/assistant/v1/conversations/<CONV_ID>/responses" \
  -H "Authorization: Bearer <MW_ACCESS_TOKEN>" \
  -H "Assistant-Name: <YOUR_BOT_NAME>" \
  -H "Content-Type: application/json" \
  -d '{"input":{"text":"hello"}}'

# 3. Poll the response until status becomes COMPLETED before proceeding.
curl "https://api.moveworks.ai/assistant/v1/conversations/<CONV_ID>/responses/<RESP_ID>" \
  -H "Authorization: Bearer <MW_ACCESS_TOKEN>" \
  -H "Assistant-Name: <YOUR_BOT_NAME>"
```

#### Fire the source-system trigger

POST your test payload to the Agent Studio Listener URL configured for your trigger. See the [Agent Studio Webhook Triggers Quickstart](https://docs.moveworks.com/agent-studio/quickstart-guide/webhook-triggers-quickstart-guide) if you need to set one up.

```bash
curl -i -X POST "<YOUR_LISTENER_URL>" \
  -H "Content-Type: application/json" \
  -d '<YOUR_TEST_PAYLOAD>'
```

The response body is `{"message":"Event received successfully","status":"RECEIVED"}` on HTTP `200`. Capture the `x-moveworks-root-uuid` response header for tracing.

#### Poll the events endpoint

Within a few seconds of the trigger, the proactive message should appear:

```bash
curl "https://api.moveworks.ai/assistant/v1/conversations/-/events" \
  -H "Authorization: Bearer <MW_ACCESS_TOKEN>" \
  -H "Assistant-Name: <YOUR_BOT_NAME>"
```

Expect one event with a new `conversation_id` (title auto-populated as "System Initiated Conversation") and an `actor: ASSISTANT` message.

#### Store the checkpoint

Persist the returned `event_id` as your `last_event_id` checkpoint for that user. Subsequent runs should use `starting_after=<checkpoint>` to receive only new events.

### Common test failures and diagnostic paths

| Symptom                                                               | Likely cause                                                                                  | How to confirm                                                                                                                                      |
| --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Listener returns `200 RECEIVED` but the events endpoint stays empty   | Recipient's most-recent-interaction channel is not CAPI (message went to Slack/Teams instead) | Check the user's Slack DMs — if the message is there, that's the routing behavior. Follow the pre-interaction pattern above.                        |
| Listener returns `200 RECEIVED` but no message appears on any channel | The plugin in Agent Studio is in a draft state, or its compound action has a schema mismatch  | Check the listener log for `skipped: [...]`. Publish the plugin and compound action, verify Event Filter is blank (not `TRUE`).                     |
| Listener returns `429`                                                | Unsecured listener rate limit (1 request per 10 seconds per org)                              | Wait for the interval to clear, or configure signature/credential verification on the listener to raise the limit.                                  |
| Listener returns `200 RECEIVED` but a downstream service errors       | Compound action input type mismatch, or a step references an undefined variable               | Inspect the trace via the `x-moveworks-root-uuid` response header; downstream failures produce error spans your Moveworks account team can look up. |

## Related

* [Proactive notifications overview](/api-reference/conversations-api/proactive-notifications/overview)
* [Receive via outbound webhook](/api-reference/conversations-api/proactive-notifications/webhook-push)
* [Agent Studio Webhook Triggers Quickstart](https://docs.moveworks.com/agent-studio/quickstart-guide/webhook-triggers-quickstart-guide)