> ## Documentation Index
> Fetch the complete documentation index at: https://docs.masivo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate in-app messages

> Learn how to fetch, display, and track in-app messages using Masivo's REST API

<Note>
  See the full parameter and response reference for [`GET in-app
      messages`](/api-reference/customers/\[id]/inapp-messages/get), [`POST log
      event`](/api-reference/customers/\[id]/inapp-messages/\[messageId]/events/post),
  and [`GET capabilities`](/api-reference/inapp/capabilities/get).
</Note>

### Prerequisites

Authenticate with the Storefront API using a Bearer access token. See [Integrate with Masivo](/api-reference/guides/integrate-with-masivo).

<Note>
  These endpoints work with **CLIENT** and **SERVER** API keys. Use a SERVER key
  when fetching messages from your backend; CLIENT keys are suitable for
  embedded apps that call Masivo directly.
</Note>

### 1. Check capabilities

```typescript theme={null}
const response = await fetch(
  "https://app.masivo.ai/api/storefront/v1/inapp/capabilities",
  {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "x-account-id": accountId
    }
  }
);
const { data } = await response.json();
// { inappEnabled: true, eventTypes: ["PURCHASE", "APP_OPEN"] }
```

### 2. Fetch eligible messages

```typescript theme={null}
const customerId = "user_abc123";
const params = new URLSearchParams({ limit: "5", trigger: "APP_OPEN" });
const response = await fetch(
  `https://app.masivo.ai/api/storefront/v1/customers/${customerId}/inapp-messages?${params}`,
  {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "x-account-id": accountId
    }
  }
);
const { data } = await response.json();
const messages = data.messages;
```

Only `pending` messages that are scheduled, not expired, and under their impression cap are returned.

### 3. Log impression events

```typescript theme={null}
const messageId = messages[0].id;
const payload = { action: "shown" as const };

await fetch(
  `https://app.masivo.ai/api/storefront/v1/customers/${customerId}/inapp-messages/${messageId}/events`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "x-account-id": accountId,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(payload)
  }
);
```

For button clicks:

```typescript theme={null}
const clickPayload = {
  action: "clicked",
  metadata: { button_id: "primary" }
};
```

### Message content fields

| Field                                | Description                                                          |
| ------------------------------------ | -------------------------------------------------------------------- |
| `type`                               | Surface type: `modal`, `fullscreen`, `slideup`, `banner`             |
| `content.title`                      | Headline                                                             |
| `content.body`                       | Main copy                                                            |
| `content.image_url`                  | Optional hero image                                                  |
| `content.buttons`                    | Action buttons with `action`: `dismiss`, `deeplink`, `url`, `custom` |
| `display_rules.max_impressions`      | Server-enforced show limit                                           |
| `display_rules.min_interval_seconds` | Minimum gap between `shown` events                                   |
| `trigger.event`                      | When set, pass the same value as the `trigger` query param           |

### Common errors

| Status | Cause                          | Example `details`           |
| ------ | ------------------------------ | --------------------------- |
| `404`  | Message not found for customer | `In-app message not found`  |
| `422`  | Invalid action or query params | Validation message from Zod |

### Related documentation

* [In-app messages concept](/concepts/in-app-messages)
* [In-app messages](/guides/create-in-app-templates)
* [Integrate in-app messages](/guides/in-app-messages)
