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

# Design your watchlists

> How to lay out watchlists before you create them: one signal per watchlist, prompt mode first, reading with labels=default, people and company member limits, and the mistakes that produce an unusable feed.

[How OutX works](/docs/api-reference/concepts/how-outx-works) covers the mechanics. This page covers the layout: how many watchlists to create, what goes in each one, and how to read them back. Getting this wrong is the most common way an agent builds an account that technically works and returns nothing useful.

## One watchlist covers one signal for one audience

Competitor mentions, buying intent, and mentions of your own brand are three different questions. They are three keyword watchlists, not one prompt that lists all three.

Three things on a watchlist are shared by everything in it, which is why merging signals breaks them:

* **The relevance objective is one sentence.** Every collected post is scored against it. A sentence covering three signals scores everything as half relevant.
* **Intent labels are chosen per watchlist.** A merged watchlist spends its label budget describing which signal a post is, instead of what the person wants.
* **The product marks up to two labels as default**, and the defaults are what it opens the watchlist on. Three signals cannot each get their own default view.

```bash theme={null}
# Three signals, three creates. Reuse nothing between them but the API key.
curl -X POST "https://api.outx.ai/api-keyword-watchlist" \
  -H "Content-Type: application/json" -H "x-api-key: YOUR_API_KEY" \
  -d '{ "prompt": "Teams comparing Salesforce and HubSpot and saying which they picked",
        "name": "Competitor mentions", "idempotency_key": "3f9a2c10-6b74-4d51-8e02-1c5b7a9d4e31" }'

curl -X POST "https://api.outx.ai/api-keyword-watchlist" \
  -H "Content-Type: application/json" -H "x-api-key: YOUR_API_KEY" \
  -d '{ "prompt": "Ops leads asking for CRM recommendations after outgrowing spreadsheets",
        "name": "Buying intent", "idempotency_key": "5c2e8b44-90a1-4f7c-b3d6-2e81f0a76c95" }'

curl -X POST "https://api.outx.ai/api-keyword-watchlist" \
  -H "Content-Type: application/json" -H "x-api-key: YOUR_API_KEY" \
  -d '{ "prompt": "Mentions of Acme CRM, including complaints and comparisons",
        "name": "Brand mentions", "idempotency_key": "a71d0f36-2c58-49b0-8d14-6f3e9b25c087" }'
```

This recipe needs three watchlist slots, and the free plan has two. Call [`GET /api-team`](/docs/api-reference/team/get) first and read `limits.watchlists` before you start, or the third create comes back `402`. For people and company watchlists, the allowance that runs out first is usually the profile count: `GET /api-team` reports it as `limits.tracked_profiles_and_companies`.

A Reddit twin is a fourth create, to [`POST /api-reddit-watchlist`](/docs/api-reference/watchlist/reddit/create) with the same prompt. One watchlist covers one platform, so "on LinkedIn and Reddit" is always two calls. See [Choose a watchlist type](/docs/api-reference/watchlist/overview).

## Prompt mode first

Send `prompt` unless you already know the exact strings to match. OutX reads the sentence into topic, audience and signal, then writes the keywords, the intent labels and the relevance objective. It is the path the product itself uses.

```bash theme={null}
# Prompt mode (recommended)
curl -X POST "https://api.outx.ai/api-keyword-watchlist" \
  -H "Content-Type: application/json" -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "prompt": "Ops managers at 3PL companies complaining about their warehouse software",
    "name": "3PL software pain",
    "idempotency_key": "b2f0e1a4-9c33-4a71-9e0d-2f7c5a11d908"
  }'
```

Keywords mode is for callers that already have their terms. It used to be the way lists got built with no relevance target at all, which produced an unfilterable firehose. That is now handled: when `objective` or `labels` are missing the server generates them in the background, and the create response carries `generated`, telling you which of the two it had to write.

```bash theme={null}
# Keywords mode, with the objective supplied. Still the better version.
curl -X POST "https://api.outx.ai/api-keyword-watchlist" \
  -H "Content-Type: application/json" -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "name": "3PL software pain",
    "keywords": ["warehouse management system", "WMS migration"],
    "objective": "Find ops managers at 3PL companies frustrated with their current WMS so we can pitch a replacement",
    "idempotency_key": "b2f0e1a4-9c33-4a71-9e0d-2f7c5a11d909"
  }'
```

```json theme={null}
{
  "created": true,
  "generated": { "objective": false, "labels": true },
  "message": "Watchlist created. An objective and intent labels are being generated in the background and will be available shortly."
}
```

Supplying `objective` yourself is still better than letting the server infer one from your keyword strings. `generated.objective: true` means OutX guessed at what you were looking for.

## Read with `labels=default`

A keyword or Reddit watchlist can carry **default labels**. The product marks up to two when it generates a taxonomy, and opens the watchlist filtered to them, so a user sees the highest-intent bucket rather than everything collected. The API does not do this on its own: omit `labels` and you get every post, which is the firehose the defaults exist to avoid.

Pass `labels=default` and the server resolves it to that watchlist's default keys.

```bash theme={null}
curl "https://api.outx.ai/api-posts?watchlist_id=WATCHLIST_ID&labels=default" \
  -H "x-api-key: YOUR_API_KEY"
```

```json theme={null}
{
  "data": [ /* ... */ ],
  "count": 42,
  "default_labels": ["buying-intent", "competitor-mention"],
  "applied_labels": ["buying-intent", "competitor-mention"]
}
```

`default_labels` is what the watchlist considers primary. `applied_labels` is what actually filtered this response. Both are on every `/api-posts` response, so you can tell a narrowed feed from a full one without a second call.

Read with `labels=default` first. Omit `labels` only when you deliberately want everything, for example when counting collection volume or exporting.

**Handle the no-defaults case.** Plenty of watchlists have no default labels. There, `labels=default` applies no filter and `default_labels` comes back empty. That empty array is your cue to choose labels explicitly: read the watchlist's label set, pick the ones matching what you are after, and pass those keys instead of working through the unfiltered feed. Full behaviour: [Intent labels and defaults](/docs/api-reference/concepts/intent-labels).

## People and company watchlists

These track a named set rather than a topic. They differ from keyword watchlists in ways that catch agents out:

* **No prompt mode.** You send `profiles` (or `companies`). There is nothing to generate.
* **No intent labels.** Every post comes back tagged `"na"`. Do not poll waiting for tags, and `labels=default` resolves to no filter.
* **`fetchFreqInHours` works the same as everywhere else.** Optional on create and update, allowed values `1, 3, 6, 12, 24, 48, 72`, default 12.
* **200 members per watchlist**, and a team-wide entitlement across every watchlist you own.

Add and remove members with `PUT`. Removals are applied before the caps are checked, so swapping members in one call works.

```bash theme={null}
curl -X PUT "https://api.outx.ai/api-people-watchlist" \
  -H "Content-Type: application/json" -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "id": "770e8400-e29b-41d4-a716-446655440000",
    "add_profiles": ["https://linkedin.com/in/satyanadella", "elon-musk"],
    "remove_profiles": ["former-prospect-slug"]
  }'
```

```json theme={null}
{
  "id": "770e8400-e29b-41d4-a716-446655440000",
  "updated": true,
  "added": 2,
  "removed": 1,
  "profiles_count": 181,
  "skipped": []
}
```

`skipped` lists the raw inputs that did nothing: unparseable, repeated in the same request, already on the list when adding, or absent when removing. Company watchlists are the same shape with `add_companies`, `remove_companies` and `companies_count`.

### Job changes

When a tracked person changes job, that arrives as a row in the same people watchlist feed with `post_type` set to `job_update`. There is no separate endpoint and no intent label on those rows.

```bash theme={null}
curl "https://api.outx.ai/api-posts?watchlist_id=PEOPLE_WATCHLIST_ID&post_type=job_update" \
  -H "x-api-key: YOUR_API_KEY"
```

## When each type starts filling

* **Keyword watchlists backfill within minutes**, on create and whenever you change `keywords` or send a new `prompt`. You do not wait for a fetch cycle.
* **Reddit, people and company watchlists never backfill.** They fill from their first fetch cycle onward, so an empty feed shortly after create is expected.

## Take inventory before you create

Watchlists count against your plan, and creating a near-duplicate wastes a slot. One call lists every watchlist the team has, all four types:

```bash theme={null}
curl "https://api.outx.ai/api-watchlists" -H "x-api-key: YOUR_API_KEY"
```

Reuse or update what is already there rather than creating alongside it, and send an `idempotency_key` on every create so a retry cannot produce a second copy. See [List all watchlists](/docs/api-reference/watchlist/list-all).

## Never do these

| Do not                                                                              | Why                                                                                                                                                                                                               |
| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Split a large people list across watchlists to get past the 200 cap                 | The team-wide entitlement counts every tracked profile and company you own, so extra watchlists do not raise the total. Ask for the right plan instead.                                                           |
| Put several signals in one prompt                                                   | One objective and one set of default labels are shared by everything in the watchlist.                                                                                                                            |
| Create in keywords mode with no `objective`                                         | The server will write one from your keyword strings, which is a guess at what you meant.                                                                                                                          |
| Assume the feed is pre-filtered                                                     | `/api-posts` returns everything unless you pass `labels`.                                                                                                                                                         |
| Delete a watchlist to reset it                                                      | `PUT` with a new `prompt` regenerates keywords and labels and keeps the id, the slug and the posts already collected.                                                                                             |
| Burst LinkedIn actions from the LinkedIn Data API or `/api-like` and `/api-comment` | Every one runs on a real LinkedIn account through a real browser session. A burst gets that account restricted, not your API key. Pace them, see [Recommended pace](/docs/api-reference/rate-limits#recommended-pace). |

## Next steps

<CardGroup cols={2}>
  <Card title="List all watchlists" icon="list" href="/docs/api-reference/watchlist/list-all">
    Every watchlist of every type in one call
  </Card>

  <Card title="Choose a watchlist type" icon="list-check" href="/docs/api-reference/watchlist/overview">
    The four types side by side
  </Card>

  <Card title="Intent labels and defaults" icon="tags" href="/docs/api-reference/concepts/intent-labels">
    How posts get classified and what `default` does
  </Card>

  <Card title="Get posts" icon="newspaper" href="/docs/api-reference/engagement/posts/get">
    Read and filter any watchlist's feed
  </Card>
</CardGroup>
