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

# Segmentation and Funnels

> Dynamic criteria-based audiences and step-by-step journeys on Cativa's API.

Segmentation and funnels are Cativa's marketing primitives for describing **who** your audience is and **where in the journey** each person stands. This page explains both concepts and the public routes you use to size, materialize, and automate on top of them.

Think of a segmentation as a **smart playlist**: you define the rule ("90s rock tracks") and the list updates itself as songs that fit come and go. You don't drag each song in by hand; you describe the criterion and the platform resolves who's in at any given moment.

<Note>
  Segmentation and funnels use the same base as every other page: `https://apis.cativalab.digital/tenant/api/v2`. They are admin routes (`/admin/marketing/...`), so they require an API Key with admin scope. Authentication is the same: `Authorization: Bearer cativa_live_...`.
</Note>

## Segmentation: a dynamic audience

A **segmentation** is an audience defined by **criteria** (badges, activity, sign-up, etc.), not a static list of IDs. You describe the rule once and the platform **resolves it in real time** to decide who falls into the segment. When a user earns a badge or becomes active again, they enter or leave the segment without you touching anything.

This is useful to:

* **Targeted communication** — send an email or push to only the people who match.
* **Export to your CRM** — materialize the segment's user list and sync it to HubSpot, RD Station, etc.
* **Size before you act** — know how many people a criterion reaches before saving or sending.

### Segmentation routes

| Method   | Route                                        | Purpose                                    |
| -------- | -------------------------------------------- | ------------------------------------------ |
| `GET`    | `/admin/marketing/segmentations`             | List segmentations                         |
| `POST`   | `/admin/marketing/segmentations`             | Create a segmentation                      |
| `GET`    | `/admin/marketing/segmentations/{id}`        | Get one segmentation                       |
| `PUT`    | `/admin/marketing/segmentations/{id}`        | Update criteria                            |
| `DELETE` | `/admin/marketing/segmentations/{id}`        | Remove a segmentation                      |
| `GET`    | `/admin/marketing/segmentations/{id}/users`  | Materialize the segment's user list        |
| `POST`   | `/admin/marketing/segmentations/users-count` | Count users matching a criterion           |
| `POST`   | `/admin/marketing/segmentations/preview`     | Preview a criterion's result before saving |

The `{id}` is a ULID (e.g. `01HQ7Z3X4Y8N2K5P6R7T8V9W0X`).

### From a criterion to an exportable list

<Steps>
  <Step title="Preview the criterion">
    `POST /admin/marketing/segmentations/preview` (or `users-count`) sends the criterion in the body and returns the audience size and sample, without persisting anything.
  </Step>

  <Step title="Adjust and re-count">
    Refine the criterion (one more badge, a different activity window) and repeat the preview until the audience matches what you expect.
  </Step>

  <Step title="Save the segmentation">
    `POST /admin/marketing/segmentations` persists the rule and returns the `id`.
  </Step>

  <Step title="Materialize and export">
    `GET /admin/marketing/segmentations/{id}/users` resolves the full list in real time, to paginate and sync to your CRM or feed a blast.
  </Step>
</Steps>

### Size before you save

Use `preview` and `users-count` to **test a criterion without creating anything**. Send the criterion in the body and read the audience size and sample before you commit. Once validated, `POST /segmentations` persists the rule and `{id}/users` materializes the full list (for example, to paginate and export it to your CRM or feed a communication blast).

### Create a segmentation

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://apis.cativalab.digital/tenant/api/v2/admin/marketing/segmentations \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Active premium",
      "criteria": {
        "badgeIds": ["01HQBADGE0000000000PREMIUM"],
        "activeInLastDays": 30
      }
    }'
  ```

  ```js Node theme={null}
  const res = await fetch(
    'https://apis.cativalab.digital/tenant/api/v2/admin/marketing/segmentations',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.CATIVA_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: 'Active premium',
        criteria: {
          badgeIds: ['01HQBADGE0000000000PREMIUM'],
          activeInLastDays: 30
        }
      })
    }
  );
  const segmentation = await res.json();
  ```
</CodeGroup>

Illustrative creation response (the authoritative schema is in the API Reference, tag **Segmentation**):

```json theme={null}
{
  "id": "01HQ7Z3X4Y8N2K5P6R7T8V9W0X",
  "createdAt": "2026-07-10T12:00:00Z"
}
```

### Count users for a criterion

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://apis.cativalab.digital/tenant/api/v2/admin/marketing/segmentations/users-count \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "criteria": {
        "badgeIds": ["01HQBADGE0000000000PREMIUM"],
        "activeInLastDays": 30
      }
    }'
  ```

  ```js Node theme={null}
  const res = await fetch(
    'https://apis.cativalab.digital/tenant/api/v2/admin/marketing/segmentations/users-count',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.CATIVA_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        criteria: {
          badgeIds: ['01HQBADGE0000000000PREMIUM'],
          activeInLastDays: 30
        }
      })
    }
  );
  const { count } = await res.json();
  ```
</CodeGroup>

Illustrative response (the authoritative schema is in the API Reference, tag **Segmentation**). `count` is the size of the audience matching the criterion **right now**:

```json theme={null}
{
  "count": 342
}
```

<Note>
  The exact field names and types of each response (count, user sample, criteria shape) live in the API Reference, under the **Segmentation** tag. Don't assume the body shape from the examples above: check the per-endpoint published contract.
</Note>

## Funnel: the step-by-step journey

A **funnel** models the user journey across ordered **steps** (for example: visited, signed up, purchased, engaged). Unlike a segmentation, which answers "who matches this criterion right now", a funnel answers "how many people are at each step" and where the journey loses people.

Use `step-count` to get the **per-step user count** and see conversion from one step to the next.

### Funnel routes

| Method   | Route                                 | Purpose             |
| -------- | ------------------------------------- | ------------------- |
| `GET`    | `/admin/marketing/funnels`            | List funnels        |
| `POST`   | `/admin/marketing/funnels`            | Create a funnel     |
| `GET`    | `/admin/marketing/funnels/{id}`       | Get one funnel      |
| `PUT`    | `/admin/marketing/funnels/{id}`       | Update steps        |
| `DELETE` | `/admin/marketing/funnels/{id}`       | Remove a funnel     |
| `GET`    | `/admin/marketing/funnels/step-count` | Per-step user count |

<Note>
  The contract for each funnel response (step definition, per-step count) lives in the API Reference, under the **Funnel** tag. Check the published endpoint instead of inferring the fields.
</Note>

## Segmentation vs funnel

|                    | Segmentation                          | Funnel                                         |
| ------------------ | ------------------------------------- | ---------------------------------------------- |
| **Question**       | Who matches this criterion right now? | Which journey step is each person at?          |
| **Shape**          | A set resolved in real time           | Ordered steps with a per-step count            |
| **Typical output** | User list (`{id}/users`)              | Per-step count (`step-count`)                  |
| **Use**            | Targeted communication, CRM export    | Measure conversion and where the journey leaks |

The two complement each other: you can size an audience with `users-count`, materialize it with `{id}/users`, and track how that audience advances through the funnel's steps over time.

## Common errors and questions

<AccordionGroup>
  <Accordion title="I hit a /tenant/api/v2 route and got 404">
    Segmentation and funnels use the same base as every other page: `https://apis.cativalab.digital/tenant/api/v2`.
  </Accordion>

  <Accordion title="The count changed between preview and materialize">
    That's expected. A segmentation is **resolved in real time**: between one step and the next, someone may have earned a badge or become active again and entered (or left) the segment. `count` is a snapshot at call time, not a frozen number.
  </Accordion>

  <Accordion title="Do preview and users-count create a segmentation?">
    No. Both only **size** a criterion sent in the body, without persisting anything. `POST /segmentations` is what creates the rule. Use preview freely to calibrate before saving.
  </Accordion>

  <Accordion title="When do I use a segmentation and when a funnel?">
    A segmentation answers "who matches this criterion right now" (output: a user list). A funnel answers "which journey step is each person at" (output: a per-step count via `step-count`). One measures audience, the other measures conversion.
  </Accordion>

  <Accordion title="I got 403 on the marketing routes">
    The `/admin/marketing/...` routes require an API Key with admin scope. Check the `Authorization: Bearer cativa_live_...` header and the key's scope. Never expose the key in the frontend.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Identity and Users" icon="user" href="/en/concepts/identity-and-users">
    The `User` model that segmentations resolve against and the canonical endpoint to validate credentials.
  </Card>

  <Card title="Sync members from your CRM" icon="arrows-rotate" href="/en/guides/sync-members-from-crm">
    Materialize a segment's list and keep your CRM in sync with the community.
  </Card>
</CardGroup>
