Proactive notifications overview
Understand how system-initiated messages are delivered to Conversations API integrations: architecture, routing behavior, and current limitations.
The Conversations API is in Controlled Availability. Endpoints, behaviors, and configuration surfaces may change during CA. Contact your Moveworks account team to participate.
The Conversations API supports two interaction modes:
- Client-initiated — a user sends a message and your backend polls or streams the response. See Set up authentication with Okta or Set up authentication with Azure AD (Entra ID).
- System-initiated (proactive notifications) — Moveworks routes a message to your integration triggered by an async action callback (for example, “your PTO request was approved”) or a proactive notification (for example, an approval request or employee comms message).
This section covers the system-initiated flow. Start here for architecture and routing rules, then read the page for the delivery mechanism you plan to use:
- Receive via outbound webhook — receive push notifications from Moveworks when a new system-initiated message is available. Recommended path: lower latency to your users and lower load on Moveworks. Requires an HTTPS endpoint on your backend to accept deliveries.
- Receive via polling — poll the events endpoint on your own schedule. Use when an inbound receiver isn’t viable in your environment, or as the source of truth for reconciling events after a webhook outage.
System-initiated messages route to the channel your user most recently interacted with, not to a specific channel of your choosing. If a user has both a CAPI integration and a native chat channel (Slack, Teams, movewebchat) registered on their profile, and their most recent interaction was on the native channel, the message goes there — not to your CAPI integration. See Routing behavior below for details and testing implications.
When to use this
Use this pattern when your integration needs to receive:
- Async action outcomes. A user asks Moveworks to complete an action that resolves later in a source system (filing PTO, provisioning software, opening a support ticket), and you want the outcome delivered to your integration when it happens.
- Proactive notifications. Moveworks needs to reach a user through your integration with no user input to initiate the interaction (approval alerts, employee comms, policy reminders, ticket follow-ups).
If your integration only handles user-initiated messages (user types, Moveworks responds), you do not need proactive notifications. Use the standard client-initiated flow.
Architecture
Your integration provides two components:
Proactive notifications reaching your CAPI integration can originate from any Moveworks feature that produces a system-initiated message: Concierge Notifications, native approvals, employee comms, async action callbacks, and custom Agent Studio Listener triggers you configure yourself. The Conversations API delivery layer is the same regardless of the originating source.
End-to-end sequence:
- A Moveworks-side event produces a system-initiated message for a user (for example, an async action callback resolves, a Concierge Notification fires, an approval alert is raised, or a custom Agent Studio Listener trigger ends in a
notifystep). - Moveworks routes the notification to the recipient’s most recently interacted channel. If that is your CAPI integration, a new conversation with title “System Initiated Conversation” is created (or an existing conversation is used). Otherwise the message goes to the user’s native chat channel and does not reach your CAPI integration.
- Your backend receives the event via outbound webhook push or by polling the events endpoint.
- Your backend delivers the content to the client and advances its per-user checkpoint.
If you configure a custom Agent Studio Listener trigger to fire proactive messages from your own source system, two distinct URLs are involved and are sometimes both called “webhooks”:
- Agent Studio Listener URL (
https://api.moveworks.ai/webhooks/v1/listeners/{listener_id}/notify) — your source system POSTs to this URL to trigger a proactive message. Configured in Agent Studio. - Outbound webhook URL (yours, HTTPS) — Moveworks POSTs to this URL when a new system-initiated message is available for one of your users. Configured in Moveworks Setup. See Receive via outbound webhook.
Routing behavior
System-initiated messages route to the channel the recipient user most recently interacted with. This is a platform-wide behavior that governs how proactive notifications are delivered across all channels, not a CAPI-specific rule. It is the single most important behavior to understand when building on CAPI.
What counts as an interaction. An interaction with the underlying bot — one where the assistant actually processes a message and generates a response. Examples:
- Sending a user message that triggers assistant response generation (
POST /conversations/{id}/responseson CAPI). - Sending a message to the assistant on a native chat channel (Slack DM, Teams DM, movewebchat) that produces a response.
What does not count. Operations that only touch the service layer and do not reach the underlying bot:
- Polling
GET /conversations/-/events. - Listing conversations (
GET /conversations). - Fetching a specific message or response.
- Creating a conversation via
POST /conversationswithout subsequently sending a message.
Fallback after inactivity. If the recipient has not interacted on any channel for approximately 24 hours, routing falls back to the user’s notification preferences configuration rather than the last-known most-recent-interaction channel.
Implications for testing and rollout:
- When your development user is more active on Slack than on CAPI, proactive messages will land on Slack, not on your CAPI integration. This is the most common cause of “the trigger fires but nothing appears in
/events” during development. - Before firing a trigger to test end-to-end, send at least one user message through your CAPI integration first so the bot processes a response. See the testing walkthrough on the polling page.
- For production rollout, users whose primary interaction pattern is on native chat will not receive proactive notifications on your CAPI integration. If your integration is intended as the primary surface, plan for user onboarding that establishes CAPI as the recently-active channel.
There is no channel selector on the notify step of a source-system compound action. Routing is governed entirely by the most-recent-interaction rule with the 24-hour fallback described above.
Prerequisites
Confirm the following before starting:
- Your Moveworks tenant is provisioned for the Conversations API and your account team has provided the Bot Name (used in the
Assistant-Nameheader on Conversations API calls). - Admin access to your Moveworks Admin Portal (
https://{org}.moveworks.com). - The users who will receive proactive notifications are resolvable against your Moveworks user roster and have a
conversations_rest_apichannel entry on their profile. See Set up authentication with Okta or Set up authentication with Azure AD (Entra ID). - An HTTPS endpoint on your backend to receive outbound webhook deliveries (recommended path). Not required if you use polling only.
If you plan to fire your own proactive notifications from a source system in addition to consuming existing Moveworks-initiated notifications (Concierge, native approvals, employee comms), you will also need a custom trigger configured in Agent Studio — a Listener plus a plugin with a compound action ending in a notify step. See the Agent Studio Webhook Triggers Quickstart.
Listener rate limits
Rate limits on the Agent Studio Listener endpoint depend on the security configuration of the listener:
- Unsecured listeners: 1 request per 10 seconds per org. Requests over this rate receive
429 {"error":"Rate limit exceeded"}. - Secured listeners (HMAC signature verification, credential verification, or one-time verification challenge configured): higher rate limits. Configure security on the listener to lift the aggressive default cap. See the Agent Studio Webhook Triggers Quickstart for security configuration.
Every request to the listener endpoint, whether accepted or rate-limited, returns an x-moveworks-root-uuid response header. Capture this value in your source-system integration; it is the trace ID your Moveworks account team can use to look up delivery outcomes in logs.
Current limitations
The following are known limitations of the current API surface. Note them when scoping integration work.
No channel-specific routing control. Notification delivery routing is a platform-wide behavior. The notify step in a source-system compound action does not expose a channel-selection input, and there is no way today to force a proactive message to a specific channel independent of the recipient’s interaction history. Routing follows the recipient’s most-recent-interaction channel with a fallback to notification preferences after approximately 24 hours (see Routing behavior).
Originating source information is not exposed on the payload by design. The webhook envelope and the events endpoint response are intentionally thin. Neither surfaces the originating source system or event definition identifier that produced a system-initiated message.
Do not attempt to derive source information by querying the events endpoint on a per-conversation basis. This pattern is brittle and unsupported.
If your integration needs to route messages differently based on source system (for example, to render notifications from different systems in different UI locations), include a distinguishing marker in the message content itself when configuring the source-system trigger, and match on it in your backend.
Rich UI elements are not surfaced. Message content on the Conversations API comes back as text (MARKDOWN_TEXT, COMMONMARK_TEXT, or PLAIN_TEXT). Interactive rendering that appears on some native surfaces (form widgets, plugin selection menus, catalog cards) is not represented in the output schema. Buttons are supported as flat actions[] entries in two forms:
CALLBACK_ACTION— a button that submits an opaquecallback_idback to the API viainput.callback_idon a follow-up response.URL_ACTION— a button that opens a URL.
Multi-field forms and grouped menu selectors must be rendered by your client based on the message content and any accompanying actions.
Per-user, per-source subscription preferences are not built in. Moveworks does not track per-user opt-in or opt-out settings scoped to a specific source system or notification type. If your integration needs users to be able to unsubscribe from specific classes of proactive notifications, implement the preference layer in your backend and filter incoming events before pushing them to your client.