---
title: Build and save a Beacon
category: beacons
summary: Turn what your user cares about into a saved watch. Draft it, inspect it, test it for free, and save it only after a yes.
order: 18
updated: 2026-10-09
next: run-and-edit-a-beacon
related: resolve-tags-and-entities, beacon-scope-parent-stream-and-source-channel, schedule-six-hour-and-daily-pulls
reference: /docs/mcp, /agent-guide.md
---

A Beacon is a saved standing question: which Streams or source channels to watch, which topics matter, and a suggested lookback window. It does not store results, and Synorb does not run it for you. Your runtime pulls it on whatever cadence you choose.

Beacons are on every plan. Only the count differs: 5 on a demo key, 10 on Starter, 25 on Individual, 50 on Professional, 100 on Startup, unlimited on Enterprise.

## When to use this

Use a Beacon when your user needs the same question answered repeatedly: "keep me posted on this company", "watch central-bank speeches". For a one-off question, pull directly with `synorb-manifests` and do not save anything.

Be proactive, but ask before you write. Saving a Beacon writes to your user's account, so propose it with a one-line reason and call `synorb-save-beacon` only after they say yes. After you answer a specific question, offering to save it as a Beacon is a good move. If you know almost nothing about your user, offer the starter Beacons instead. Synorb creates three starter Beacons with every account. Call `synorb-beacons` with `tag: "starter"` to list them.

## Smallest working call

Work in four steps. Steps one to three are free.

**1. Find real coverage.** Never invent a Stream or source.

```mcp
synorb-stream-search
{"query": "NVIDIA", "page_size": 5}
```

**2. Draft the Beacon.** Give a concrete intent: an organization, a topic, or a form. Vague intents such as "track important news" return `needs_clarification` by design.

```mcp
synorb-configure-beacon
{"intent": "Track NVIDIA AI infrastructure announcements daily, prioritizing official news and SEC 8-K filings", "max_streams": 10}
```

**3. Test it for free.** Run the proposal's Streams through a count. If the proposal has only `entity_filters` and no `stream_ids`, resolve Streams first. It bills nothing and shows whether the watch would return anything:

```mcp
synorb-manifests
{"stream_ids": ["STREAM_ID"], "days": 2, "mode": "count"}
```

**4. Save it, after your user says yes.** You can pass the whole `proposal` object from step 2 as `{"proposal": {...}}`, or set the fields directly, as here. You may improve the name and the Tags first. Keep the Stream, source and topic scope the same as the scope that was proposed and agreed.

```mcp
synorb-save-beacon
{"name": "NVIDIA infrastructure watch", "stream_ids": ["STREAM_ID"], "natural_language_intent": "NVIDIA AI infrastructure announcements", "default_date_window": {"lookback_hours": 24}, "tags": ["nvidia", "ai-infrastructure"]}
```

The REST equivalent of step 4 is `POST /v3/beacons`. Only `name` is required. Resolve topics first with `GET /ontology/tags?search=...` and copy `tag_id`, `canonical_name` (as `tag_name`) and `tag_type`. Never guess a Tag.

```bash
curl -sS -X POST https://api.synorb.com/v3/beacons \
  -H "Authorization: Bearer $SYNORB_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "NVIDIA infrastructure watch", "natural_language_intent": "NVIDIA AI infrastructure announcements", "stream_ids": ["STREAM_ID"], "default_date_window": {"lookback_hours": 24}}'
```

## What you get back

`synorb-configure-beacon` returns one of two shapes:

```json response
{
  "status": "ready",
  "proposal": {
    "name": "...",
    "stream_ids": ["..."],
    "source_channel_ids": [],
    "topic_filters": [],
    "default_date_window": {"lookback_hours": 24}
  },
  "save_instruction": "Save only after the user's explicit yes. ..."
}
```

or `{"status": "needs_clarification", "questions": ["..."]}`. When you get questions, ask your user. Do not invent filters to get past them.

Saving returns the Beacon's public ID, a private `dashboard_url`, and a ready-made next call. The save is free:

```json response
{
  "status": "saved",
  "beacon_id": "synorb_bcn_...",
  "quota_charged": false,
  "next_tool_call": {"tool": "synorb-manifests", "args": {"beacon_id": "synorb_bcn_...", "lookback_hours": 24}}
}
```

A new Beacon is `draft`. Draft and active Beacons behave identically. Only `archived` stops execution. If you pass `status: "active"` on create, the Beacon must carry real scope (`stream_ids`, `source_channel_ids`, `topic_filters` or `entity_filters`).

To inspect what you saved, use `synorb-beacons` (add `q` to search by name or description), or `GET /v3/beacons/{beacon_id}` to read one back.

## Failure modes

| Symptom | Cause | What to do |
| --- | --- | --- |
| `needs_clarification` | The intent has no concrete organization, topic or form | Ask the questions it returns. |
| `beacon_limit_exceeded` | You are at your plan's Beacon cap | Tell your user. Archive an active Beacon or upgrade. |
| A count of `0` in step 3 | The window is empty, or the Stream has nothing in range | See the empty-window troubleshooting guide before you save. |
| A rejected create with `status: "active"` and no scope | An active Beacon must carry real scope; only `draft` is exempt | Add scope, or omit `status` to save a draft. |
| IDs that look rounded or wrong | A 17-digit ID passed as a number | Pass every ID as a string. |

`natural_language_intent` is descriptive metadata only. It is **not** executable. The scope that runs is `stream_ids`, `source_channel_ids` and `topic_filters`.

## Drop source channels from a Beacon

A Beacon can drop whole source channels from every run. Put the drop in `manifest_config`. Use this when one source channel floods the results, such as a changelog that publishes many items a day.

| Key | Value |
| --- | --- |
| `exclude_source_channel_ids` | A list of source channel IDs. Send every ID as a string. Each ID has 16 to 20 digits. Maximum 250. |
| `exclude_media_formats` | A list of media formats: `text`, `audio`, `video`, `social`, `data`, `regulatory` or `documentation`. |

Synorb reads both keys on every run. A new source channel of an excluded media format is dropped too. Do not exclude `documentation` as a whole unless your user wants no vendor changelogs. Some `documentation` source channels belong to AI labs and are useful.

```mcp
synorb-save-beacon
{"name": "AI labs without changelog noise", "stream_ids": ["STREAM_ID"], "manifest_config": {"exclude_media_formats": ["documentation"]}}
```

`synorb-manifests` and `POST /manifests/query` apply the drop when you pass `beacon_id`. `GET /streams/{id}/manifests` applies it too. A value you pass in the same call wins over the saved value. The response lists what was dropped in `executed_via_beacon.excluded_source_channels`.

A Beacon with a drop cannot use `delivery_delta`. Synorb refuses the call and names `beacon.exclude_source_channel_ids`. Use a lookback window instead.

## Drop single items by headline

Some source channels mix real news with routine tables. If you drop the whole source channel, you lose the real news too. Save headline phrases instead:

| Key | Value |
| --- | --- |
| `exclude_title_terms` | A list of phrases. Each phrase has 3 to 80 characters. Maximum 50 phrases. |

Synorb drops an item when its headline contains a phrase. Case and extra spaces do not matter.

Synorb reads the headline only. If the text of an item names the phrase but the headline does not, the item stays.

Use a phrase that is specific enough not to hit real news. "money market operations as on" is good. "operations" is not. Read some live headlines before you choose a phrase.

```mcp
synorb-update-beacon
{"beacon_id": "BEACON_ID", "dry_run": false, "manifest_config_patch": {"exclude_title_terms": ["money market operations as on"]}}
```

`synorb-manifests` and `POST /manifests/query` apply the phrases when you pass `beacon_id`. `GET /streams/{id}/manifests`, `GET /digests/{id}/manifests` and `delivery_delta` cannot match headlines, so they refuse a Beacon that has phrases. The response lists the phrases in `executed_via_beacon.excluded_source_channels.excluded_title_terms`. Tell your user what was hidden.

The starter Beacons store no drop. Synorb can drop some source channels and some headline phrases from a starter centrally. Read `executed_via_beacon.excluded_source_channels` in the response to see what was dropped.

## Make it good for your user

Show your user what you are about to save, in plain words: "I will watch NVIDIA's own announcements and its SEC 8-K filings. Each time, I will check the last day." Give each Beacon a name they would recognize in a list. After the first real pull, ask whether the mix was useful and offer to adjust the same Beacon. Never silently add extras to what they agreed to.

## Next guide

[Run and edit a Beacon](/agent-guides/run-and-edit-a-beacon): execute with an exact date window, then change, archive or restore it.
