---
title: React Native - MomentPerks API Integration Guide
slug: react-native-momentperks-api-integration-guide
icon: {"faIcon":"fa-brands fa-react"}
docTags: 
createdAt: 2025-08-12T13:43:13.674Z
---

# Overview

The [MomentPerks API](https://docs.momentscience.com/momentperks-api) enables you to integrate dynamic, personalized offer experiences directly into your React Native application. This guide walks you through how to fetch offers, build the UI to display them, and track user interactions using event beacons.

**By the end of this guide, you’ll be able to:**

- Configure your project for Moments API access
- Fetch offers using the provided API
- Render offers using custom React Native components
- Track and report user engagement events such as impressions, dismissals, and clicks

:::hint{type="success"}
To explore a working example, see the [MomentScience React Native demo on GitHub.](https://github.com/AdsPostX/examples/tree/main/react-native/MomentsAPIDemoApp)

:::

Prerequisites


Before diving into the integration process, there are a few preliminary steps you need to take

1. **Obtain an API key:&#x20;**&#x42;efore you start the integration, you must acquire a unique API key. Follow the [instructions provided here](https://docs.momentscience.com/getting-your-api-key) to obtain your key.
2. **Verify Supported Versions:&#x20;**&#x45;nsure your project dependencies meet these requirements.
   - **React Native:** `0.73` or higher
   - **React:&#x20;**`18.0.0` or higher
3. **Install Required Packages:&#x20;**&#x52;un the following command in your project directory to install the necessary dependencies:

:::CodeblockTabs{indent="2"}
```bash
npm install axios react-native-config react-native-device-info
```
:::

:::Paragraph{listStyleType="disc" indent="2"}
[Axios:](https://www.npmjs.com/package/axios) for making HTTP requests.
:::

:::Paragraph{listStyleType="disc" listStart="2" indent="2"}
[react-native-device-info:](https://www.npmjs.com/package/react-native-device-info) for accessing device details.
:::

:::Paragraph{listStyleType="disc" listStart="3" indent="2"}
[react-native-config:](https://www.npmjs.com/package/react-native-config) for accessing environment variables via a .env file.(optional)
:::

4. **Add Android Internet Permission:&#x20;**&#x49;n your `android/app/src/main/AndroidManifest.xml`, add the following line to allow network requests:

:::CodeblockTabs{indent="2"}
```xml
<uses-permission android:name="android.permission.INTERNET" />
```
:::

5. **Add Android Manifest Queries Block:&#x20;**&#x46;or Android `11`and above, add the following `<queries>` block outside the `<application>` tag in your `AndroidManifest.xml` to allow opening offer URLs in an external browser:

:::CodeblockTabs{indent="2"}
```xml
<queries>
  <intent>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https" />
  </intent>
</queries>
```
:::

# Integration Steps

The [MomentPerks API](https://docs.momentscience.com/momentperks-api) delivers personalized offer data based on a set of query parameters and request payload values. In this section, you’ll implement a utility function to retrieve and normalize offers for use in your UI.

:::hint{type="success"}
For complete details on MomentPerks API, refer to the [MomentPerks API documentation](https://docs.momentscience.com/momentperks-api).
:::

## &#x20;Step 1:  Fetch Offers

To retrieve personalized offers from the Moments API, make a POST request to the [`https://api.adspostx.com/native/v4/offers.json `](https://api.adspostx.com/native/v4/offers.json)endpoint.&#x20;

:::CodeblockTabs
fetchMomentOffers Function

```javascript
// API_BASE_URL=https://api.adspostx.com/native/v4

const fetchMomentOffers = async (
  apiKey,
  queryParameters = {},
  payload = {},
) => {
  try {
    const userAgent = payload.ua ?? (await getUserAgent());

    const headers = {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      'User-Agent': userAgent,
    };

    const allQueryParameters = {
      api_key: apiKey,
      ...queryParameters,
    };

    const filteredQueryParameters = Object.fromEntries(
      Object.entries(allQueryParameters).filter(([, v]) => v != null)
    );

    const filteredPayload = Object.fromEntries(
      Object.entries(payload).filter(([, v]) => v != null)
    );

    const queryString = new URLSearchParams(filteredQueryParameters).toString();
    const apiUrl = `${Config.API_BASE_URL}/offers.json${queryString ? `?${queryString}` : ''}`;

    const response = await axios.post(apiUrl, filteredPayload, { headers });
    return response;
  } catch (error) {
    Logger.log('[fetchMomentOffers] Error:', error);
    Logger.log('[fetchMomentOffers] Details:', error.response || error.request || error.message);
    throw error;
  }
};

```

Payload Example

```javascript
const payload = {
  adpx_fp:'<unique_value>',
  pub_user_id: '<unique_value>',
  placement: 'checkout',
  ua: '<user_agent_value>',
};
```
:::

**&#x20;Parameters**

| **Name**          | **Type** | **Description**                                                                                                                      |
| ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `apiKey`          | String   | Your MomentScience API key. Required for authentication.                                                                             |
| `queryParameters` | Object   | Optional URL query parameters such as `loyaltyboost`, `creative` , `campaignId` or any custom key supported by your API integration. |
| `payload`         | Object   | Request body containing user-specific data (e.g. ua, adpx\_fp).                                                                      |

**Common Payload Fields**

| **Field**     | **Type** | **Description**                                                                                          |
| ------------- | -------- | -------------------------------------------------------------------------------------------------------- |
| `adpx_fp`     | String   | A unique identifier for the end user                                                                     |
| `pub_user_id` | String   | A unique, non-PII identifier for the end user.                                                           |
| `placement`   | String   | An attribute that represents the specific page, section, or location where the Offer Unit was triggered  |
| `dev`         | String   | Set to "1" to enable test mode.                                                                          |
| `ua`          | String   | The user-agent string.                                                                                   |

**Returns:&#x20;**&#x41; successful response returns a JSON object containing:

- An array of offers
- Metadata such as tracking beacons, creative assets, and eligibility flags
- Optional styling rules

:::hint{type="info"}
See [OffersService.js](https://github.com/AdsPostX/examples/blob/main/react-native/MomentsAPIDemoApp/src/services/OffersService.js)[ ](https://github.com/AdsPostX/AdsPostXReactNativeAPIDemoApp/blob/feature/code-refactor/src/services/OffersService.js), [useOffers.js](https://github.com/AdsPostX/examples/blob/main/react-native/MomentsAPIDemoApp/src/hooks/useOffers.js) , and [OfferModel.js](https://github.com/AdsPostX/examples/blob/main/react-native/MomentsAPIDemoApp/src/models/OfferModel.js) in the demo app for examples of how to request, consume, and structure offer data.
:::

***

## &#x20;Step 2: Build the Offer UI

After retrieving offer data, the next step is to design a user interface that presents the offers and captures user actions such as claiming or dismissing them.

:::::VerticalSplit{layout="middle"}
::::VerticalSplitItem
:::hint{type="warning"}
The UI components shown below are taken from our demo app and **serve as reference implementations** only. You are free to build your own components based on your app’s design system and platform conventions.&#x20;
:::


::::

:::VerticalSplitItem


![](https://api.archbee.com/api/optimize/ELjiwjWcrv0a1IejQFFAF/48DKTXrCyttBlF7S4hUYn_image.png "Example App UI")
:::
:::::

:::hint{type="success"}
For a detailed explanation of how each field in the offer object is used refer to the [Offer Anatomy documentation](https://docs.momentscience.com/offer-anatomy). This guide will help you understand how to map API fields to UI components and apply dynamic styling correctly.&#x20;
:::

### Offer Container UI

Use the `OfferContainerView` to manage and display a sequence of offers. This component handles navigation, dynamic styling, and user interactions.

```javascript
<OfferContainerView
  offers={offers}
  OnCloseOfferCTA={handleOfferClose}
  apiStyles={apiStyles}
/>
```

**Props:**

| **Property**      | **Type&#x20;** | **Description&#x20;**                                                                                                      |
| ----------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `offers`          | Array          | List of offer objects retrieved from the API.                                                                              |
| `OnCloseOfferCTA` | Function       | Callback triggered when the offer container is closed. Receives two parameters: `currentIndex`and `shouldFirePixel`.<br /> |
| `apiStyles`       | Object         | UI styles returned from the API for dynamic theming.                                                                       |

:::hint{type="info"}
See [OfferContainerView.js  ](https://github.com/AdsPostX/examples/blob/main/react-native/MomentsAPIDemoApp/src/components/OfferContainerView.js)in the demo app for a working implementation.
:::

### Individual Offer UI

Use the `OfferView` component to render a single offer and handles user interactions, including:

- Tapping the offer image
- Clicking CTA buttons
- Triggering pixel events

```javascript
<OfferView
  title={currentOffer.title} // Offer headline
  description={currentOffer.description} // Offer description
  imageURL={currentOffer.image} // URL of the offer creative (image)
  clickURL={currentOffer.click_url} // URL to open on image or positive CTA tap
  onImageCTA={handleImageCTA} //Called when the offer image is tapped
  positiveCTA={currentOffer.cta_yes} // Label for the primary CTA button
  onPositiveCTA={handlePositiveCTA} // Called when the primary CTA is tapped
  negativeCTA={currentOffer.cta_no} // Label for the secondary CTA button
  onNegativeCTA={handleNegativeCTA} // Called when the secondary CTA is tapped
  apiStyles={apiStyles?.offerText} // Optional styling applied to text or CTA components
/>
```

:::hint{type="info"}
See [OfferView.js ](https://github.com/AdsPostX/examples/blob/main/react-native/MomentsAPIDemoApp/src/components/OfferView.js) and [ useOffers.js](https://github.com/AdsPostX/examples/blob/main/react-native/MomentsAPIDemoApp/src/hooks/useOffers.js)  in the demo app for a working implementation.&#x20;
:::

## Step 3: Track User Interactions

To measure user engagement and support advertiser attribution, fire tracking beacons (pixel URLs) at key moments in the user journey. The `fireOfferPixel`utility sends HTTP `GET`requests to tracking URLs provided in the offer metadata.

:::CodeblockTabs
fireOfferPixel&#x20;

```javascript
const fireOfferPixel = async (url) => {
  if (!url) return;

  try {
    Logger.log('Inside fire pixel:', url);
    const response = await axios.get(url);
    Logger.log('Fire pixel Success:', response.data);
  } catch (error) {
    Logger.log('Fire pixel Error:', error);
  }
};
```
:::

**When to Fire Beacons&#x20;**

Use `fireOfferPixel`at the following points in the offer flow:

1. **When the Offer is Displayed:&#x20;**&#x46;ire both `pixel`and `adv_pixel_url`if they exist.

:::CodeblockTabs{indent="2"}
```javascript
fireOfferPixel(offers[currentOfferIndex]?.pixel);

fireOfferPixel(offers[currentOfferIndex]?.adv_pixel_url);
```
:::

2. **When the User Taps negative CTA:&#x20;**&#x46;ire the `no_thanks_click`beacon if available.

:::CodeblockTabs{indent="2"}
```javascript
fireOfferPixel(offers[currentIndex].beacons?.no_thanks_click);
```
:::

3. **When the Offer Container is Closed: &#x20;**&#x46;ire the `close` beacon to indicate the user exited the offer sequence.

:::CodeblockTabs{indent="2"}
```javascript
fireOfferPixel(offers[currentIndex].beacons?.close
```
:::

:::hint{type="info"}
See [useOfferContainer.js](https://github.com/AdsPostX/examples/blob/main/react-native/MomentsAPIDemoApp/src/hooks/useOfferContainer.js) and [useOffers.js](https://github.com/AdsPostX/examples/blob/main/react-native/MomentsAPIDemoApp/src/hooks/useOffers.js)  in the demo app for a working implementation.  &#x20;
:::

# Next Steps

We recommend that you go through [the MomentPerks API Implementation Checklist ](https://docs.momentscience.com/momentperks-integration-checklist)to verify your integration. Completing this checklist ensures that all best practices and requirements are met for a successful Moments API deployment.

***

📢 If you're running into any issues while going through the integration process, feel free to contact us at [help@momentscience.com](mailto\:help@momentscience.com).
