# Checking audience membership

## Overview

In this tutorial, you’ll check whether a user belongs to an [**audience**](https://kbase.whitelabel-loyalty.com/product/loyalty-engine/audiences) in the White Label Loyalty (WLL) platform. You’ll learn two ways of doing this with the API:

1. **Eventually consistent (async)** checks.
2. **Strongly consistent (sync)** checks.

By the end, you’ll be able to:

* Create an audience in the console for users with at least one reported event.
* Verify audience membership using both async and sync APIs.
* Understand when each approach is appropriate.

***

## Prerequisites

Before starting, make sure you have:

* Access to the Loyalty Console with your tenant and tenant API key
* Completed the tutorial [Reporting your first event](/developer/tutorials/reporting-your-first-event.md)
* A **user ID** from the previous tutorial
* An admin API token (for impersonation) or the user’s own token
* A tool to make API requests (<kbd>curl</kbd>, Postman, or your preferred language)

***

## Instructions

{% stepper %}
{% step %}

### Create an audience

Follow this tutorial in our product docs: [Create an audience of users who have or haven't reported one or more events](https://kbase.whitelabel-loyalty.com/product/loyalty-engine/audiences/audience-tutorials/create-audiences-based-on-user-activity/create-an-audience-of-users-who-have-or-havent-reported-one-or-more-events).

Use the `VISITED_VENUE` event type you created in the tutorial [Reporting your first event](/developer/tutorials/reporting-your-first-event.md).

When the audience is created, an **initial calculation** runs across the entire user base. At some point, the user from Tutorial 2 should appear in the audience. You can wait for this user to appear under the audience members in the console or move on to step 2.&#x20;

Keep the audience ID created here handy for the next steps.&#x20;
{% endstep %}

{% step %}

### Eventually consistent (async) check

{% hint style="info" %}
Use this approach when slight delays in audience calculation are acceptable (e.g., segmentation for marketing campaigns).
{% endhint %}

Audience membership is calculated asynchronously in the background (via daily cron, triggered by new events, or manual recalculation).

To check membership after the async calculation, call the [`GET /audiences/:id/results`](https://docs.whitelabel-loyalty.com/rewards#audiences-audience-results-get) endpoint.

#### Request

{% tabs %}
{% tab title="Admin token + impersonation" %}

```bash
curl -X GET "https://api.staging.rewards.wlloyalty.net/v1/audiences/<audience_id>/results" \
  -H "Authorization: Bearer <admin_token>" \
  -H "x-api-key: <your_tenant_api_key>" \
  -H "x-impersonate: <user_id>"
```

{% endtab %}

{% tab title="User's own token" %}

```bash
curl -X GET "https://api.staging.rewards.wlloyalty.net/v1/audiences/<audience_id>/results" \
  -H "x-api-key: <your_tenant_api_key>" \
  -H "Authorization: Bearer <user_token>"
```

{% endtab %}
{% endtabs %}

#### **Responses**

**❌ User not in audience.** For the above user, this could indicate that the background async calculation hasn't completed yet:

```json
{
  "status": "success",
  "data": []
}
```

**✅ User in audience.** This indicates the calculation is done and the user we checked this audience for does in fact belong to this audience:

{% code expandable="true" %}

```json
{
  "status": "success",
  "data": [
    {
      "accountNumber": 1000123,
      "isRestricted": false,
      "authIdentifier": "<user_auth_id>",
      "id": "<user_id>",
      "createdAt": "2023-11-29T06:40:25.259Z",
      "updatedAt": "2023-11-29T06:40:25.259Z",
      "externalIdentifier": null,
      "flags": {
        "genderProvided": true
      }
    }
  ]
}
```

{% endcode %}
{% endstep %}

{% step %}

### Strongly consistent (sync) check

{% hint style="info" %}
Use this approach when **immediate correctness matters**, e.g., showing or hiding features in an app (lock screen, gating functionality).
{% endhint %}

For real-time membership checks, call [`POST /audiences/syncly-search-results`](https://docs.whitelabel-loyalty.com/rewards#audiences-synchronous-audience-results-post). This calculates audience membership on demand, which can be slower than async results.

#### **Request**

{% tabs %}
{% tab title="curl" %}

```bash
curl -X POST "https://api.staging.rewards.wlloyalty.net/v1/audiences/syncly-search-results" \
  -H "Authorization: Bearer <user_token>" \
  -H "Content-Type: application/json" \
  -H "x-api-key: <your_tenant_api_key>" \
  -d '{
    "audienceIds": ["<audience_id>"]
  }'
```

{% endtab %}

{% tab title="Node.js" %}
{% code expandable="true" %}

```javascript
import axios from "axios";

const USER_TOKEN = "<user_token>";
const AUDIENCE_ID = "<audience_id>";

async function checkAudienceMembership() {
  const response = await axios.post(
    "https://api.staging.rewards.wlloyalty.net/v1/audiences/syncly-search-results",
    {
      audienceIds: [AUDIENCE_ID],
    },
    {
      headers: {
        Authorization: `Bearer ${USER_TOKEN}`,
        "Content-Type": "application/json",
      },
    }
  );

  console.log("Sync membership result:", response.data);
}

checkAudienceMembership().catch(console.error);
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### **Response**

This returns a key value pair of audience IDs to a boolean suggesting whether the user is in the audience. For the user in question, we expect this to be the response.

```json
{
  "status": "success",
  "data": {
    "<audience_id>": true
  }
}
```

{% endstep %}
{% endstepper %}

### Recap

* You created an audience in the console based on reported events.
* You checked membership using the **async API** (eventually consistent).
* You checked membership using the **sync API** (strongly consistent).
* You learned when to use each approach.

***

## Assessment

Try the following:

1. Fire the `VISITED_VENUE` event for another user. Wait for the reactive audience recalculation, then check membership for this new user using the async API.
2. Fire the `VISITED_VENUE` event for a third user, but immediately call the syncly search results API to confirm membership without waiting for the background calculation.
3. Add another audience and check membership for multiple audiences in one sync request.
4. Compare the results between async and sync checks for the same user.

***

## Next steps

* See [Audiences](https://kbase.whitelabel-loyalty.com/product/loyalty-engine/audiences) for deeper explanation
* See the [Audience API reference](https://docs.whitelabel-loyalty.com/rewards#audiences)
* See the [Audience syncly search results API reference](https://docs.whitelabel-loyalty.com/rewards#audiences-synchronous-audience-results-post)


---

# 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://kbase.whitelabel-loyalty.com/developer/tutorials/checking-audience-membership.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.
