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

# Tags, attributes, activity, and segments

> Build audiences from contact facts and behavior.

Segments are saved audience rules. They combine contact data, tags, custom attributes, membership, checkout, and activity.

## Tags

Tags are team-scoped labels you can attach to team contacts.

```text theme={null}
GET  /api/v1/teams/{team_id}/tags
POST /api/v1/teams/{team_id}/tags
POST /api/v1/teams/{team_id}/contacts/{team_contact_id}/tags
```

Use tags for simple lifecycle markers such as `vip`, `trial`, `webinar-attendee`, or `needs-follow-up`.

## Contact attributes

Attributes are custom fields for a team's contacts. They can be visible in profiles or onboarding.

```text theme={null}
GET  /api/v1/teams/{team_id}/contact-attributes
POST /api/v1/teams/{team_id}/contact-attributes
GET  /api/v1/hub/{team_id}/hubs/{hub_id}/onboarding-attributes
POST /api/v1/hub/{team_id}/hubs/{hub_id}/onboarding-attributes
```

## Activity

Activity tracks behavior such as login, search, lesson started, and lesson completed.

```text theme={null}
POST /api/v1/hub/{hub_id}/activity                                      record an activity event (contact-auth)
GET  /api/v1/teams/{team_id}/hubs/{hub_id}/activity/contacts/{contact_id}  get stats for one contact (admin)
GET  /api/v1/teams/{team_id}/hubs/{hub_id}/activity/top-engaged         list top-engaged contacts (admin)
```

## Segments

Segments combine conditions and return matching contacts.

```text theme={null}
POST /api/v1/teams/{team_id}/segments
POST /api/v1/teams/{team_id}/segments/search
GET  /api/v1/teams/{team_id}/segments/{segment_id}/members
GET  /api/v1/teams/{team_id}/segments/{segment_id}/members/count
```

Use segments to answer practical questions:

* Who bought Product A but has not completed onboarding?
* Who watched fewer than three lessons this month?
* Who is tagged `vip` and has not logged in recently?
* Who should get a reactivation email?

### Tag and hub condition shapes

Most condition types (`email`, `first_name`, `has_product`, …) take a primitive `value`, but the tag and hub-membership types have a specific **write** shape that differs from what they return:

| Type             | `value`                                                           | `operator`               |
| ---------------- | ----------------------------------------------------------------- | ------------------------ |
| `has_tag`        | `{ "tag_slug": "vip" }` or `{ "tag_slugs": ["vip", "founding"] }` | `has`, `has_not`         |
| `belongs_to_hub` | `{ "hub_id": "<a hub id owned by this team>" }`                   | `belongs`, `not_belongs` |

```json theme={null}
{ "type": "has_tag", "operator": "has", "value": { "tag_slug": "vip" } }
{ "type": "belongs_to_hub", "operator": "belongs", "value": { "hub_id": "hub_abc123" } }
```

<Warning>
  For `has_tag`, use the tag **slug**, not its id — `{ "tag_id": … }` / `{ "tag_ids": … }` is the *compiled/read-back* shape and is **rejected on input** (*"Extra inputs are not permitted"*), which is why every id-based attempt fails. A `422 "One or more condition references failed to compile."` means a referenced tag slug or hub was not found for your team, or the operator is unsupported for that type; the CLI names the exact offender (the unresolved slug / cross-team ref) in the error line (`mio` ≥ the MIO-2590 build).
</Warning>
