Skill instructions
alerts10.8 KB
View saved version →
---
name: alerts
description: Turn any alertable Ultralayer endpoint into a realtime monitor that emails, telegrams, or webhooks new results. Operations are create_alert, get_alerts, execute_alert, activate_alert, deactivate_alert, and delete_alert.
---
# Alerts
Alerts wrap an existing Ultralayer endpoint, poll it on a schedule, skip what was already delivered, and push new matches to email, Telegram, and/or a webhook. Same filters and queries as the underlying endpoint — plus schedule and delivery. Alerts are billed as the underlying endpoint calls — there is no alert surcharge.
| Operation | Role |
|-----------|------|
| `create_alert` | Validate + persist, return the created alert |
| `get_alerts` | List alerts with recent attempts and deliveries |
| `activate_alert` / `deactivate_alert` | `active` ↔ `paused` |
| `execute_alert` | Run now (same path as scheduled execution) |
| `delete_alert` | Permanent delete |
---
## When to use
**Use alerts when you need:**
- Continuous monitoring of Wire, developments, filings, events, or any other alertable path
- Delivery to inbox, Telegram, or a webhook without running your own cron
- The same conditions you already validated interactively, left running
**Do not use alerts when you need:**
- A one-shot answer → call the underlying endpoint directly
- To alert on endpoints that are not in the alertable set below
---
## Use cases
**Company wire monitor** — Get emailed when a company prints material news with strong positive or negative tone, skipping copycat syndication.
```json
{
"name": "Apple important news",
"path": "/v0/search/list_wire",
"arguments": {
"entities": ["Apple Inc."],
"novelty": ["new", "update", "correction"],
"entity_relevance": ["primary", "significant"],
"min_entity_sentiment": 0.3,
"max_entity_sentiment": -0.3,
"detail": "full"
},
"interval_minutes": 15,
"threshold": 1,
"receivers": [{ "type": "email" }]
}
```
Sentiment min/max together = strong positive **or** strong negative. Novelty drops syndication duplicates.
**Semantic Monitoring** — Watch a theme by meaning (not just a ticker) and push new matching passages to email and a webhook.
```json
{
"name": "Hormuz Oil Passages",
"path": "/v0/search/semantic_search",
"arguments": {
"queries": ["Strait of Hormuz tanker disruption Brent crude"],
"max_tokens": 1000,
"min_utility_score": 0.5,
"min_cosine_similarity": 0.75,
"detail": "standard"
},
"interval_minutes": 30,
"receivers": [
{ "type": "email" },
{ "type": "webhook", "url": "https://hooks.example.com/ultralayer" }
]
}
```
**Ticker development feed** — Get pinged when important new developments land for a ticker, with who is affected already scored.
```json
{
"name": "Tesla Developments",
"path": "/v0/search/search_developments",
"arguments": {
"symbols": ["TSLA"],
"min_importance_score": 0.7,
"limit": 20,
"detail": "full"
},
"interval_minutes": 30,
"receivers": [{ "type": "telegram", "chat_id": "123456789" }]
}
```
**Tracked event lifecycle** — Follow one known story (earnings cycle, M&A, etc.) and get notified as new developments attach to it.
```json
{
"name": "Tesla 2026 Financial Event",
"path": "/v0/search/retrieve_event_developments",
"arguments": {
"event_id": 125,
"limit": 20,
"include_future_developments": true,
"detail": "standard"
},
"interval_minutes": 60,
"lookback_minutes": 180,
"receivers": [{ "type": "email" }]
}
```
Discover `event_id` via `search_events` or a development hit first.
**Events scan (M&A)** — Stay on top of new deal activity without polling for mergers yourself.
```json
{
"name": "M&A Events",
"path": "/v0/search/search_events",
"arguments": {
"event_type": "merger_acquisition",
"developments_per_event": 1,
"limit": 10,
"detail": "essential"
},
"interval_minutes": 60,
"receivers": [{ "type": "email" }]
}
```
**Guidance raised or cut** — Across the market, get emailed when a company revises an official outlook up or down.
```json
{
"name": "Guidance raised or cut",
"path": "/v0/filings/list_guidance",
"arguments": {
"revision_direction": ["raised", "lowered"],
"detail": "standard",
"limit": 10
},
"interval_minutes": 60,
"receivers": [{ "type": "email" }]
}
```
**KPI definition and disclosure** — Across the market, get pinged when a release changes how a metric is calculated, or starts or stops highlighting a named KPI.
```json
{
"name": "KPI definition and disclosure",
"path": "/v0/filings/list_changes",
"arguments": {
"change_categories": ["metric_definition", "disclosed_metric"],
"detail": "standard",
"limit": 10
},
"interval_minutes": 60,
"receivers": [{ "type": "email" }]
}
```
**Guide versus actual** — Get emailed when a prior guide significantly exceeds or significantly misses the reported result.
```json
{
"name": "Guidance versus actual",
"path": "/v0/filings/list_guidance_outcomes",
"arguments": {
"outcomes": ["significantly_exceeded", "significantly_missed"],
"detail": "standard",
"limit": 10
},
"interval_minutes": 60,
"receivers": [{ "type": "email" }]
}
```
---
## Alertable endpoints
| `path` | What you’re monitoring |
|--------|------------------------|
| `/v0/search/list_wire` | Filtered headlines |
| `/v0/search/semantic_search` | PIT / utility-filtered corpus passages |
| `/v0/search/search_developments` | Structured developments |
| `/v0/search/search_events` | Events with recent activity |
| `/v0/search/retrieve_event_developments` | Developments on a known `event_id` |
| `/v0/filings/list_guidance` | Official outlook series that moved in the window |
| `/v0/filings/list_changes` | Wording changes in the window |
| `/v0/filings/list_guidance_outcomes` | Company guidance versus the reported actual |
Wire for headlines. Developments/events for structured lifecycle. Thematic / corpus passage monitors use path `/v0/search/semantic_search`. `list_guidance` for the official outlook and revision. `list_changes` for wording changes between releases. `list_guidance_outcomes` for guide versus actual.
---
## Create params
| Field | Notes |
|-------|-------|
| `name` | Optional; unique per user. Duplicate → 400. |
| `path` | One of the alertable paths above |
| `arguments` | Upstream body **minus timestamps**. Never include `start_timestamp` / `end_timestamp` (422). |
| `interval_minutes` | ≥ 5 and a multiple of 5 |
| `lookback_minutes` | Rolling window; defaults to `interval_minutes` |
| `threshold` | Min matching items before delivery (default 1) |
| `receivers` | 1–2 targets; duplicate targets rejected |
### Receivers
| Type | Config |
|------|--------|
| `email` | `{ "type": "email" }` — delivers to the verified account email |
| `telegram` | `{ "type": "telegram", "chat_id": "…" }` — start the Ultralayer alerts bot first |
| `webhook` | `{ "type": "webhook", "url": "…", "headers"?, "body_wrap_key"?, "body_wrap_as_string"?, "body_extra"? }` — public http(s) only |
Canonical envelope: `{ "name": "<alert name>", "response": <exact upstream JSON> }`. Email/telegram always get that envelope. Subject: `ULTRALAYER ALERT: {name}`.
`create_alert` immediately calls the endpoint and delivers a **sample** to every receiver before persisting.
#### Webhook body shaping
Use these when the receiving API rejects an arbitrary JSON body and requires a fixed envelope. Structured merge only — no templating.
| Field | Role |
|-------|------|
| `body_wrap_key` | Place the envelope under this key. One level of dot-separated nesting (`variables.PAYLOAD` → `{"variables": {"PAYLOAD": …}}`). |
| `body_wrap_as_string` | JSON-encode the envelope to a string before placing it. Requires `body_wrap_key`. |
| `body_extra` | Static keys merged into the top level of the body. Values must be string / number / boolean / null. |
Examples:
```json
{
"type": "webhook",
"url": "https://api.example.com/hooks/ingest",
"headers": { "Authorization": "Bearer …" },
"body_wrap_key": "client_payload",
"body_extra": { "event_type": "ultralayer_alert" }
}
```
→ `{ "event_type": "ultralayer_alert", "client_payload": { "name": "…", "response": … } }`
```json
{
"type": "webhook",
"url": "https://ci.example.com/api/v4/projects/1/trigger/pipeline",
"body_wrap_key": "variables.PAYLOAD",
"body_wrap_as_string": true,
"body_extra": { "token": "…", "ref": "main" }
}
```
→ `{ "token": "…", "ref": "main", "variables": { "PAYLOAD": "{\"name\":…}" } }`
Arbitrary-JSON receivers (Zapier, Make, n8n, custom endpoints) need none of these fields.
---
## Delivery behavior
Each run checks a rolling lookback window and never re-sends data already delivered. The alert fires only when at least `threshold` new items match. Attempt outcomes (`delivered`, `no_data`, `below_threshold`, `endpoint_error`, `delivery_partial`, `delivery_failed`) and recent deliveries are visible via `get_alerts`. If all receivers fail, the same data is retried next run.
There is no update-alert endpoint. Changing filters = delete + recreate.
---
## Workflow
1. Prototype filters with the underlying endpoint until results look right.
2. `create_alert` with those arguments (no timestamps) + receivers + interval. Expect a sample delivery.
3. `get_alerts` to confirm status and early attempts.
4. `execute_alert` to force a test run. `deactivate_alert` / `activate_alert` to pause/resume.
5. `delete_alert` when done. Prefer pause over delete if the config may be reused.
---
## Limitations
- Poll-based (minimum 5-minute cadence), not push-on-insert.
- Only the alertable paths listed above.
- Max 2 receivers; email is account-bound.
- Webhooks must be public.
- Webhook `headers` are count- and size-capped, and framing, routing and provenance headers (`Host`, `Content-Type`, `Content-Length`, `User-Agent`, `X-Forwarded-*`, …) are rejected. `Authorization`, `Cookie` and custom `X-` headers are fine.
- Webhook `body_extra` and `body_wrap_key` are count-, size- and character-capped — see the OpenAPI schema for exact limits. Values are scalars only, and a field name containing a literal `.` cannot be targeted by `body_wrap_key`.
- Create always sends a sample — warn before creating noisy webhooks.
- No patch API for existing alerts.
---
## FAQ
**Q: Is this more expensive than calling the API myself on a cron?**
A: Same underlying pricing; you gain dedupe, thresholding, multi-channel delivery, history, and managed scheduling.
**Q: Why can’t I set `start_timestamp` in arguments?**
A: The alert owns the rolling window. Including timestamps → 422.
**Q: Why did create email me immediately?**
A: Receiver verification delivers a real sample by design.
**Q: `no_data` every 15 minutes — broken?**
A: Healthy. The window had zero matches. Check `deliveries` for real fires.
**Q: How do I change an alert’s filters?**
A: There is no patch. Pause or delete + recreate.
changes11.5 KB
View saved version →
---
name: changes
description: Wording changes between one earnings press release and the last — what the company started saying, stopped saying, or now says differently. Operation is list_changes.
---
# Changes
`list_changes` compares a company’s latest earnings press release to the previous one. Each result is one thing they added, removed, or rewrote.
| Operation | Role |
|-----------|------|
| `list_changes` | Return matching wording changes |
Every filter works **without a ticker list**, so this is a market-wide screen as much as a single-filing read: who redefined a metric this quarter, who rewrote what the outlook assumes, who quietly dropped a risk. The material change is usually the one nobody headlined.
---
## When to use
**Use it for** the language, not the numbers: what this release says that last quarter’s did not, what they stopped mentioning, how a metric is now defined, how segments are cut, what the outlook assumes.
**Not this tool:** the outlook figure or who raised / lowered → `list_guidance`. Guide vs actual → `list_guidance_outcomes`. Headlines, rumor, or what the market is reacting to → Wire. Anything outside an earnings press release → your own web search.
---
## Use cases
**Realtime change tape** — What companies just started or stopped saying, market-wide, minutes after each release. No tickers.
```json
{
"sort": "timestamp",
"min_materiality_score": 0.5,
"detail": "standard",
"limit": 40
}
```
**Comparability breaks** — A redefined non-GAAP metric or a re-cut segment silently invalidates every model and screen built on the old basis, and it is stated once in the release. Highest-value screen here. INTU dropping share-based comp from non-GAAP scores 0.97; moving Mailchimp into its own segment scores 0.88.
```json
{
"change_categories": ["metric_definition", "reporting_structure"],
"sort": "materiality",
"min_materiality_score": 0.7,
"detail": "standard",
"limit": 30
}
```
**What the outlook now assumes** — Not the figure, the basis: a deal folded in, a tariff line added, a multi-year target dropped. A guide that looks cut is sometimes just re-based. Then `list_guidance` for the number.
```json
{
"change_categories": ["guidance_basis"],
"sort": "materiality",
"min_materiality_score": 0.5,
"detail": "standard",
"limit": 30
}
```
**Quiet de-risking** — What they stopped saying: a lawsuit no longer named, a KPI no longer highlighted, an assumption dropped. The proof is `prior_quote`.
```json
{
"change_kinds": ["removed"],
"sort": "materiality",
"min_materiality_score": 0.5,
"detail": "standard",
"limit": 30
}
```
**Theme sweep** — No text search. One theme (tariffs, refunds, AI capex) lands across several categories; pass a few and read the summaries.
```json
{
"change_categories": ["policy", "guidance_basis", "discrete_item", "results_attribution"],
"sort": "materiality",
"min_materiality_score": 0.5,
"detail": "standard",
"limit": 40
}
```
**Legal and one-off items** — Do not require `impact: ["negative"]`. Dropping a named lawsuit is often `legal` and `positive`. Big charges sometimes land in `discrete_item`, not `legal`.
```json
{
"change_categories": ["legal", "discrete_item"],
"sort": "materiality",
"min_materiality_score": 0.7,
"detail": "standard",
"limit": 20
}
```
**One release, deep read** — Ticker + the fiscal year and quarter of that release. The prior period is the previous quarter (INTU FY26 Q4 vs Q3). Floor `0` when you want everything in one filing.
```json
{
"symbols": ["INTU"],
"fiscal_year": 2026,
"fiscal_quarter": 4,
"min_materiality_score": 0,
"detail": "standard",
"limit": 40
}
```
**Watchlist** — Up to 8 tickers. `materiality` puts the biggest changes first (including older ones); `timestamp` puts the newest first.
```json
{
"symbols": ["NVDA", "INTU", "WMT", "DE"],
"start_timestamp": "2026-06-01T00:00:00Z",
"sort": "materiality",
"min_materiality_score": 0.5,
"detail": "standard",
"limit": 30
}
```
---
## Response detail
Default is `full`. `detail` only drops fields. Price does not change.
| Level | What you get |
|-------|----------------|
| `essential` | Ticker, when it published, fiscal period, kind, category, summary. No quotes. |
| `standard` | That plus company name, both quotes, scores, impact, prior period, and the SEC URLs |
| `full` | That plus `cik` and extra source fields (`document_type`, fiscal period on the source) |
Use **`standard`** with an LLM — the quotes are already there. Use `essential` when you only need the one-line summary. Use `full` when a machine needs `cik` or the extra source fields.
At `standard`, `source_metadata` is null. The URL is still on the source.
---
## What you get back
Each item is one change. Default `limit` is 10 (max 100). Default `min_materiality_score` is **0.4**.
| Field | Notes |
|-------|-------|
| `symbol` / `company_name` / `cik` | `cik` only at `full` |
| `timestamp` | When we recorded the change. **Time filters use this.** |
| `source_timestamp` | When the company published the current release. Returned, not filtered. |
| `fiscal_year` / `fiscal_quarter` | Period the **current** release is about. Quarter is null on a full-year report. |
| `prior_fiscal_year` / `prior_fiscal_quarter` | The previous release. `fiscal_quarter=4` is Q4 vs Q3, not the full year. |
| `change_kind` | `added` / `removed` / `modified` |
| `change_category` | What kind of disclosure changed |
| `summary` | One sentence. Trust the quote if they disagree. |
| `current_quote` / `prior_quote` | The sentence in that release. Null on a removal / addition. |
| `materiality_score` | `0-.2` reword; `.2-.4` weak; `.4-.6` mod; `.6-.8` high; `.8-1` must-read |
| `impact` | Whether the wording change itself reads better or worse for the company — not a price call |
| `current_source` / `prior_source` | Always both, with a URL to each release |
`added` has `current_quote` only. `removed` has `prior_quote` only — read it. `modified` has both.
---
## Filters and sort
Filters combine with AND. Values inside a list are OR. Tickers are case-insensitive, max 8. Categories max 8. A category that is not in the list is rejected.
| Param | Notes |
|-------|-------|
| `start_timestamp` / `end_timestamp` | On `timestamp`. `end_timestamp: null` means now. A future end is treated as now. A future start is rejected. |
| `symbols` + `fiscal_year` + `fiscal_quarter` | One release. Year alone returns every pair in that year. |
| `change_kinds` | `added` / `removed` / `modified` |
| `change_categories` | See **Categories** |
| `impact` | `positive` / `negative` / `neutral`. Do not filter on this alone — the same kind of change can be positive at one company and negative at another. |
| `min_materiality_score` | Inclusive. Default **0.4** skips rewording and weak rows. Pass `0` to turn the floor off. |
| `sort` | Order |
|-------|--------|
| `timestamp` (default) | Newest first |
| `materiality` | Highest score first, then newest |
---
## Categories
Category is *what changed*, not whether it is good news. Taking a named lawsuit out of the risk list is often `legal` or `risk`, `removed`, and `positive`.
| Category | Use for |
|----------|---------|
| `metric_definition` | How a non-GAAP or adjusted metric is calculated |
| `disclosed_metric` | A named highlight they started, stopped, or renamed |
| `reporting_structure` | Segments or what is in the report |
| `guidance_basis` | Assumptions behind the outlook — not a raise or a cut |
| `policy` | Tariffs, tax rules, regulation |
| `discrete_item` | Impairments, charges, restructuring, one-offs |
| `legal` | Lawsuits and other legal actions |
| `capital_action` | Buybacks, financing, deals, spins |
| `risk` / `catalyst` | A threat vs an upcoming event. Good or bad does not pick the label. |
`accounting_policy`, `control_and_audit`, `concentration`, and `compensation` rarely return rows here. Empty on those is not “the company is clean.”
`product` and `catalyst` can flood a list that includes drug or chip names. Skip `business_description` and low-scoring `results_attribution` unless you asked for them.
---
## Workflow
Chains worth more than a single call.
**Earnings-night read on one name**
1. `list_changes` — ticker + that release’s fiscal year and quarter, floor `0`. Everything that moved in the language.
2. `list_guidance` — same ticker, for the figures the wording sits around.
3. `list_guidance_outcomes` — how the period that just closed scored against the guide they set a quarter ago.
4. Wire for how the tape read it; your own web search for the sell-side take.
**Comparability break → fix the model**
1. `list_changes` — `metric_definition` and `reporting_structure`, market-wide, floor 0.7.
2. Read `prior_quote` against `current_quote` for the old and new basis, and note the fiscal period the change takes effect.
3. `list_guidance` — whether the outlook is now stated on the new basis. A guide that looks cut can just be re-based.
4. Restate history before comparing anything across that boundary, and re-check any screen that ranks on the affected metric.
**Theme exposure across the market**
1. `list_changes` — theme categories, `sort: "materiality"`, no tickers. Who is talking about it and how it hit them.
2. Group the tickers that come back; the same theme appears under several categories.
3. `identify_stakeholders` — the full winner/loser map, beyond the filers who happened to word it into a release.
4. `list_guidance` — whether any of them put the theme into the outlook basis, which is where it becomes a number.
**Quiet de-risking sweep**
1. `list_changes` — `change_kinds: ["removed"]`, floor 0.5, no tickers.
2. Read `prior_quote` on each. Removal means they stopped saying it, not that the underlying item resolved.
3. Wire or your own web search — confirm whether the case settled, the KPI moved into a table, or the risk simply went unmentioned.
**Leave it running**
`create_alert` with `path: "/v0/filings/list_changes"`, same filters minus timestamps. `metric_definition` + `reporting_structure` at a high floor is a low-noise, high-value inbox; pin `detail` and `min_materiality_score`.
---
## Combine with
- **`list_guidance`** — The outlook and how it was revised. Same ticker; match fiscal year / quarter to the report period on the guidance source (`source_metadata`, which needs `list_guidance` at `full`).
- **Wire** — The headline.
- **Alerts** — Alertable. Threshold counts changes; the alert owns the window. See **Workflow**. Wire remains the headline monitor.
---
## Limitations
- Not every listed company is in the data.
- An empty list can mean nothing matched, the floor is too high, or that release is not in yet. Do not treat it as “nothing changed.”
- Rows show up a few minutes after the release. Then nothing until the next earnings press release.
- No keyword search. Use categories and read the summaries.
- `removed` often means they stopped highlighting something, not that they stopped reporting it.
- One theme can appear under more than one category.
---
## FAQ
**Why did a 0.6 floor miss HD’s IEEPA guidance-basis change?**
It is 0.56. Default 0.4 is safer if you care about outlook assumptions.
**I filtered to the press-release time and got nothing.**
Time filters use `timestamp` (when we recorded it), not `source_timestamp` (when they published). INTU’s release is `20:02:29Z`; the rows show up at `20:04:20Z`.
**Does `removed` mean they stopped reporting the number?**
No. They may have stopped highlighting it. The figure can still be in a table. Deere no longer *names* the FTC suit — that is not the same as the case ending.
developments-and-events14 KB
View saved version →
---
name: developments-and-events
description: Structured market narratives — impact-scored, source-cited developments clustered into longer-lived events. Operations are search_developments, retrieve_development, search_events, and retrieve_event_developments.
---
# Developments and events
**Developments** are structured narrative units (name, description, scores, stakeholders with signed impact, sources with quotes) versioned over time. **Events** are longer-lived story containers that group related developments into a lifecycle (earnings cycle, M&A process, regulatory campaign, geopolitical conflict).
| Operation | Role |
|-----------|------|
| `search_developments` | Semantic or filter search over developments — returns packages |
| `retrieve_development` | Package for one known `development_id` (optional as-of) |
| `search_events` | Semantic or filter search over events; embeds recent development summaries |
| `retrieve_event_developments` | Event metadata + developments timeline |
---
## When to use
**Use this surface when you need to:**
- Explain a market move with who wins/loses (signed `impact_score` per ticker) and cited sources
- Track a storyline lifecycle via an `event_id`
- Scan for surprising / important developments
- Filter by public-company ticker involvement
- Backtest “what was known as of T” with `end_timestamp`
**Do not use when you need:**
- Realtime novelty-clustered headlines → Wire
- Open-web research (article body, quotes, filings, prices) → your native web search tool
- A single-entity dossier → `retrieve_entity`
- Entity-filtered headline monitoring → Wire
---
## Use cases
**Ticker blast radius** — Find developments that hit a ticker hard in either direction, with signed impacts and quotes.
```json
{
"symbols": ["TSLA"],
"min_impact_score": 0.5,
"max_impact_score": -0.5,
"limit": 8
}
```
**Negative for one ticker** — Isolate clearly negative impact on a single name.
```json
{
"symbols": ["GOOGL"],
"max_impact_score": -0.5,
"limit": 8
}
```
**Portfolio watchlist** — One query for up to eight tickers instead of one call per name.
```json
{
"symbols": ["AAPL", "MSFT", "NVDA", "AMZN", "GOOGL", "META", "TSLA", "AVGO"],
"min_importance_score": 0.7,
"limit": 10
}
```
**Surprising geopolitics** — Scan for high-surprise security developments, not every geopolitics mention.
```json
{
"development_type": "geopolitical_security",
"min_surprise_score": 0.6,
"start_timestamp": "2026-07-20T00:00:00Z",
"limit": 10
}
```
**Theme → development evidence** — Ask in natural language and get structured impact packages back.
```json
{
"query": "Strait of Hormuz shipping disruption oil",
"start_timestamp": "2026-07-01T00:00:00Z",
"limit": 5
}
```
**Theme → event clusters** — See how a theme groups into longer-lived stories, not just one-off updates.
```json
{
"query": "Middle East oil",
"limit": 5,
"developments_per_event": 2
}
```
**M&A scan** — List active deal storylines without inventing your own type labels.
```json
{
"event_type": "merger_acquisition",
"limit": 5,
"developments_per_event": 1
}
```
**Important prints** — Desk scan for high-importance developments without a theme query.
```json
{
"min_importance_score": 0.8,
"limit": 10
}
```
**Lifecycle expand** — Once you have an event id, pull the full timeline (scheduled → print → follow-ons).
```json
{
"event_id": 125,
"limit": 20,
"include_future_developments": true
}
```
**As-of / backtest search** — Ask what developments were known as of a past timestamp.
```json
{
"query": "Tesla Q2 earnings margins",
"end_timestamp": "2026-07-22T21:00:00Z",
"limit": 10
}
```
**As-of single development** — Reconstruct one development’s package as it stood at a prior time.
```json
{
"development_id": 1793,
"end_timestamp": "2026-07-22T21:00:00Z"
}
```
---
## Mental model
```text
Event (long-lived story)
└── Development (versioned fact/update in that story)
├── scores: importance / surprise / confidence
├── occurrence_*: real-world time + status
├── stakeholders[]: PUBLIC_COMPANY + symbol + impact ∈ [-1,1]
└── sources[]: citations with quotes
```
A development can belong to **multiple events**. Always read `events` / `event_ids`.
Three clocks (do not conflate):
| Field | Meaning |
|-------|---------|
| `timestamp` | System/version time — used for backtest `start`/`end_timestamp` and “latest version” collapse |
| `source_timestamp` | Latest source used for the development |
| `occurrence_timestamp` | Estimated real-world when it happened (or will) — lifecycle ordering and `include_future_developments` |
---
## Response detail
Most operations accept `detail`. **Default is `full`.** Reduced levels **drop keys** only — surviving fields keep the same names and paths as `full`. Pricing does not change with `detail`; this is about **response token cost** (development packages are heavy).
### search_developments / retrieve_development / retrieve_event_developments
Levels: `full` | `standard` | `essential`.
| Level | What you get | Rough token savings vs `full` |
|-------|----------------|-------------------------------|
| `essential` | Identity, timing, name/description, stakeholder impacts (no confidence/sources), thin event refs | ~75% (search/retrieve development); ~68% (`retrieve_event_developments`) |
| `standard` | essential + type/status, heuristic scores, citable sources (title/url; no quotes), fuller event summaries | ~39% (search/retrieve development); ~38% (`retrieve_event_developments`) |
| `full` | Every field including rationale and source quotes | — |
**Prefer `detail: "standard"`** for normal agent calls. Use `essential` for scanning many packages; use `full` when you need rationale or quoted evidence in the payload.
```json
{
"symbols": ["TSLA"],
"min_impact_score": 0.5,
"max_impact_score": -0.5,
"limit": 8,
"detail": "standard"
}
```
### search_events
Levels: `full` | `essential` only (no `standard` — the middle tier barely saved tokens on this shape).
| Level | What you get | Rough token savings vs `full` |
|-------|----------------|-------------------------------|
| `essential` | Event id/name/description + recent development summaries (id / occurrence / name / description) | ~33% |
| `full` | Includes `event_type` and richer recent-development fields (scores, types, …) | — |
Prefer `detail: "essential"` when scanning events; use `full` when you need event type or summary scores.
---
## search_developments
Optional `query`: semantic over development descriptions, ranked by cosine (cosine not returned in the response). No query: latest version per `development_id` matching filters, ordered by `timestamp` DESC.
Returns development packages shaped by `detail` (default `full`; prefer `standard` — see **detail** above). You do not need `retrieve_development` after a search hit unless you need as-of reconstruction for a known id.
| Param | Notes |
|-------|-------|
| `query` | Optional. Max 2000 chars. |
| `symbols` | Tickers, max 8. Match any. **Exact** as stored (`TSLA`, `GOOGL`, `SGRO.L`). `tsla` → `[]`. Not Ultralayer canonical names. |
| `min_impact_score` / `max_impact_score` | Alone: threshold. **Together: directional OR** (`impact >= min OR impact <= max`) — requires `min >= max` (e.g. `0.5` + `-0.5`). |
| `min_importance_score` / `min_surprise_score` / `min_confidence_score` | Importance ~0.8+ is a strong desk filter |
| `development_type` | Exact free-form string (`financial_update`, `corporate_action`, `geopolitical_security`, …). Invented values silently return `[]`. Discover types from results. |
| `start_timestamp` / `end_timestamp` | On development `timestamp`. Future start → 422. Future end → realtime. |
| `start_occurrence_timestamp` / `end_occurrence_timestamp` | Real-world occurrence clock |
| `limit` | Default 5, max 20 |
| `detail` | Default `full`. Prefer `standard`. |
Packages are large at `full` (rationale + per-stakeholder quotes). Prefer tight `limit` (3–10) and `detail: "standard"`; expand event context with `retrieve_event_developments` when you need the storyline.
`occurrence_status` values seen: `occurred`, `scheduled`, `announced`, `ongoing`, `rumored` — no status filter param.
---
## retrieve_development
Required: `development_id`. Optional: `end_timestamp` for as-of (latest version with `timestamp <= end`). Optional: `detail` (default `full`; prefer `standard`).
Use when you already have an id (from an alert, prior run, or citation) or need as-of reconstruction. Search results already include the package at the requested `detail` — do not re-fetch the same id after `search_developments` unless you need a different `detail` or as-of.
Missing id → 404. As-of before the development existed → 404. Future `end_timestamp` → realtime.
---
## search_events
Optional `query`: semantic over event descriptions. No query: ordered by most recent development activity.
Timestamp filters gate on **development activity**: an older event still appears if it had a development recorded in-window. No activity → `[]`.
| Param | Notes |
|-------|-------|
| `query` | Optional. Max 2000 chars. |
| `symbols` | Tickers, max 8. Match any. Exact as stored. Gates events via development stakeholder involvement; does not filter embedded `recent_developments`. |
| `event_type` | Exact free-form (`merger_acquisition`, `earnings`, `product_launch`, `executive_succession`, …) |
| `limit` | Default 5, max 10 |
| `developments_per_event` | Default 3, max 5, **0 allowed** (event cards only — cheap scanning) |
| `include_future_developments` | Default true. Filters on `occurrence_timestamp` vs now/end — does not drop past-dated `scheduled` items |
| `detail` | `full` \| `essential` only (no `standard`). Prefer `essential` when scanning. |
Embedded `recent_developments` are summaries (no rationale/stakeholders/sources). Escalate with `retrieve_event_developments` or `search_developments` for development packages.
---
## retrieve_event_developments
Required: `event_id`. Returns event metadata + developments ordered by `occurrence_timestamp` DESC. Packages follow `detail` (default `full`; prefer `standard`).
| Param | Notes |
|-------|-------|
| `limit` | Default 5, max 20 |
| `start_timestamp` / `end_timestamp` | Filter on development **recording** time (useful for polling new packages) |
| `include_future_developments` | Default true |
| `detail` | Default `full`. Prefer `standard`. |
Missing event → 404.
---
## Workflow
| User intent | Approach |
|-------------|----------|
| “Who is affected by X?” | `search_developments` → read stakeholder impacts; cite quotes |
| “What’s the Tesla earnings story this year?” | `search_developments` or `search_events` → take `event_id` → `retrieve_event_developments` |
| “Any big M&A?” | `search_events` with `event_type: merger_acquisition` |
| “Negative for GOOGL?” | `symbols: ["GOOGL"]`, `max_impact_score: -0.5` |
| “What just printed that’s important?” | No-query search + `min_importance_score: 0.8` |
| “Headline triage / first print” | Wire first; escalate here for structured impact |
| “Reconstruct this development as of T” | `retrieve_development` with `end_timestamp` |
1. Decide grain: atomic impact update (developments) vs storyline cluster (events).
2. Prefer ticker + score filters for desk questions; prefer semantic query for themes.
3. Keep `limit` small; set `detail: "standard"` (or `essential` on `search_events`); set `developments_per_event` low (or 0) when scanning events.
4. `search_developments` already returns packages at your chosen `detail` — do not call `retrieve_development` on those ids unless you need as-of or a richer `detail`. Expand storylines with `retrieve_event_developments`.
5. Collapse near-duplicate developments under the same event before briefing.
6. Hand off to Wire for live novelty, your native web search tool for open-web research, `retrieve_entity` for identity packages.
---
## Limitations
- Near-duplicate developments can exist as separate ids for the same real-world fact — dedupe by event + occurrence window + name similarity.
- Stakeholders are **PUBLIC_COMPANY + ticker only** — no countries/commodities/people as stakeholders.
- Ticker strings are exact and case-sensitive (`TSLA` ≠ `tsla`), max 8 chars.
- `development_type` / `event_type` are not closed enums — inventing labels yields empty results.
- Cosine not exposed for thresholding.
- Packages are heavy at `full` — bad default for large scans without `detail: "standard"` / `essential`, tight limits, or `developments_per_event: 0`.
- `scheduled` status can linger after occurrence time.
- Not filterable by Ultralayer entity ids; use tickers or semantic query text.
---
## FAQ
**Q: Wire already has Tesla headlines — why developments?**
A: Developments add multi-ticker impact scores, rationales, and event clustering. Wire tells you it printed; developments tell you who is in the blast radius and why.
**Q: Why did `development_type: "earnings"` return nothing?**
A: Earnings prints are often typed `financial_update`; `earnings` appears more as an event_type. Discover types from hits.
**Q: `include_future_developments: false` still showed “scheduled” items.**
A: Filter is on `occurrence_timestamp` vs now, not on status label. Past-dated schedules remain.
**Q: Can I filter by Ultralayer entity name `Tesla, Inc.`?**
A: No. Use `symbols: ["TSLA"]` or semantic query text.
**Q: search_events with a July window returned an older long-running event — bug?**
A: Timestamps gate development activity. Old events with new developments in-window correctly appear.
**Q: retrieve_development as-of before the print 404s.**
A: Expected — no version existed yet.
**Q: search_events vs search_developments?**
A: Events for clusters/lifecycles (summaries); developments for atomic updates + stakeholder math (full packages). Typical flow: search either → expand with `retrieve_event_developments` when you need the timeline; use `retrieve_development` only for a known id or as-of.
entity-retrieval4.58 KB
View saved version →
---
name: entity-retrieval
description: Realtime context package for one entity — identity, recent high-relevance headlines, 14-day sentiment, and top co-mentions. Operation is retrieve_entity.
---
# Entity Retrieval
`retrieve_entity` returns a realtime context package for one Ultralayer entity. Single required param: `entity`. No time window, no `top_k` — the package shape is fixed.
| Operation | Role |
|-----------|------|
| `retrieve_entity` | Realtime dossier for one entity |
---
## When to use
**Use `retrieve_entity` when you need to:**
- Bootstrap a company / person / commodity / country / institution briefing
- Read 14-day mention sentiment without hand-rolling Wire aggregation
- Discover who co-moves in the news with the target
**Do not use when you need:**
- A filtered multi-entity news firehose → Wire
- Open-web research (article body, quotes, filings, prices) → your native web search tool
- Point-in-time / as-of packages → not supported (realtime only)
- Sparse / quiet entities → fails with `insufficient_entity_activity`
---
## Use cases
**Company dossier seed** — One call for recent headlines, 14-day sentiment, and who else is in the story.
```json
{ "entity": "Tesla, Inc." }
```
**Person → affiliated universe** — See which companies and projects dominate the news around a person.
```json
{ "entity": "Elon Musk" }
```
Follow co-mentions (`Tesla, Inc.`, `SpaceX`, `xAI`) with more `retrieve_entity` or Wire.
**Commodity / macro driver** — Brief a commodity and discover the geopolitics and related markets moving with it.
```json
{ "entity": "Brent Crude" }
```
Use co-mentions (Iran, Hormuz, WTI) to choose Wire entity filters and semantic queries.
**Institution** — Quick context pack for a policy body that drives markets.
```json
{ "entity": "Federal Reserve" }
```
**Country** — High-volume national tape: recent prints, sentiment trend, and co-moving names.
```json
{ "entity": "Iran" }
```
---
## What you get back
| Section | Notes |
|---------|-------|
| `entity` | `entity_id`, `canonical_name`, `entity_type` |
| `recent_wire_items` | Up to 5 teasers; novelty `new\|update\|correction`; entity is `primary` or `significant`; includes `wire_id` for storyline |
| `sentiment_chart` | Exactly 14 UTC calendar-day bars, oldest → newest. Relevance-weighted mean ∈ [-1, 1], weighted std, `mention_count`. Empty days stay with `weighted_sentiment: null`. Current day is a partial bar. |
| `co_mentions` | Top peers with `share` (fraction of recent high-relevance wire that also mentions them at primary/significant) |
Requires sufficient recent wire activity; sparse entities return 422 `insufficient_entity_activity`.
---
## How to read each section
**Recent wire items.** Decision-grade headlines. Duplicates stripped. Use `wire_id` → `wire_storyline` for story evolution.
**Sentiment chart.** `end_timestamp` is the exclusive end of the UTC day (bar for 2026-07-23 ends at `2026-07-24T00:00:00Z`). Interpret with `mention_count` and `weighted_std` — one-mention days and high std are noisy. Mega-entities (countries) show flatter averages.
**Co-mentions.** “Who shares the recent high-relevance tape?” Near-duplicate registry rows often both appear (`SpaceX` + `Space Exploration Technologies Corp.`, `United States` + `United States of America`). Collapse when briefing.
Works well for `COMPANY`, `PERSON`, `COMMODITY`, `COUNTRY`, `GOVERNMENT`. Products (e.g. `"ChatGPT"`) often fail the activity gate.
---
## Workflow
| User intent | Approach |
|-------------|----------|
| “Brief me on X” | Package → recent wires + sentiment turn + co-mentions |
| “Who is moving with oil / AI / this CEO?” | Read `co_mentions`; optionally package those peers |
| “Is tape tone improving?” | Walk `sentiment_chart` with mention_count/std |
| “Watch every mention going forward” | Use Wire (and alerts) |
1. Call `retrieve_entity`. Brief from: recent wires → sentiment turn → co-mentions.
2. Hand off: Wire for monitoring/storylines; your native web search tool for open-web research.
---
## Limitations
- Realtime only — no as-of.
- One entity per call.
- Activity gate hides quiet names.
- Public input is name only (passing `entity_id` as a string does not work).
- Recent strip is fixed at 5 non-duplicate high-relevance items.
- Co-mentions surface unmerged duplicate identities.
- Not a substitute for Wire novelty clustering or semantic passage retrieval.
---
## FAQ
**Q: Why do SpaceX and “Space Exploration Technologies Corp.” both show as co-mentions?**
A: Incomplete entity merges. Treat as one org in the narrative unless you need registry fidelity.
guidance17.3 KB
View saved version →
---
name: guidance
description: Official company outlooks, how they revised, how they compared to the reported actual, and the aggregate score of that. Operations are list_guidance, list_guidance_outcomes, and guidance_bias.
---
# Guidance
`list_guidance` is the official outlook tape: what the company said it expects, when it said it, and how that number moved vs the last observation of the same series.
`list_guidance_outcomes` is company guidance versus the reported actual. One pair per series after that period reported.
`guidance_bias` is the aggregate score of those results. One point per report period.
| Operation | Role |
|-----------|------|
| `list_guidance` | Current and past outlooks, with revision history |
| `list_guidance_outcomes` | Company guidance versus the reported actual |
| `guidance_bias` | Average of those results, one score per report |
Every filter works **without a ticker list**, so these are cross-sectional screens as much as single-name lookups: who moved an outlook today, which peers guide the same period, who missed their own guide this cycle. `end_timestamp` rebuilds any of it as of a past day, so a screen can be backtested.
---
## When to use
**`list_guidance`** — What they expect now, who just guided, who raised or cut, the history of one line, guidance for the same metric across companies, or the book as of a past day.
**`list_guidance_outcomes`** — What they guided versus what they reported. Empty until that period reports; the live outlook stays on `list_guidance`.
**`guidance_bias`** — Whether a name habitually guides below what it prints, which is a prior on the next guide.
**Not these tools:** sell-side consensus, rumor, or reaction → Wire / developments / your own web search. Wording changes in the release → `list_changes`. A company dossier → `retrieve_entity`.
---
## Detail
API default is `full`. **Set `standard` unless you need ranges, revision deltas, `observation_count`, or `cik`.** `detail` does not change price. `guidance_bias` has no `detail`.
**`list_guidance`**
| Level | What you get |
|-------|----------------|
| `standard` | Quote, cite, `revision_direction`, `value_midpoint`, `unit`, `yoy_value_midpoint`, `yoy_unit`. What an LLM should read. |
| `full` | Ranges, `revision_midpoint_delta_pct`, `observation_count`, `cik`, `source_metadata` |
| `essential` | Quote, identity, `source_type`, `revision_direction`. No company name, ingest timestamp, URL, or numbers. |
**`list_guidance_outcomes`**
| Level | What you get |
|-------|----------------|
| `standard` | Quotes, labels, cites |
| `full` | Guided range, actual, deltas, `rationale`, `cik` |
| `essential` | Identity and outcome label |
---
## Clocks and shared filters
Time filters use when **we recorded** the row, not publication time. `end_timestamp: null` = now. A future end is treated as now.
| Tool | `start_timestamp` / `end_timestamp` |
|------|--------------------------------------|
| `list_guidance` | When the outlook was recorded. `start` only picks which series appear; history inside a series goes up to `end` |
| `list_guidance_outcomes` / `guidance_bias` | When the **result** was recorded, not when they guided |
For “that quarter,” use `guided_period_end_from` / `_to` or `guided_fiscal_year` / `guided_fiscal_quarter`. A May print of Q1 is not an Apr–Jun window. `guided_fiscal_quarter=4` is the Q4 outlook, not every pair that printed in Q4.
AND across fields; OR inside a list. Same names on `list_guidance` and `list_guidance_outcomes` where the field exists.
| Param | Notes |
|-------|-------|
| `symbols` | Tickers, max 8 |
| `metric_keys` | Substring, case does not matter. `revenue` also matches `revenue_growth`. Pin `metric_key_exact_match: true` for one key |
| `metric_basis` | `gaap` / `non_gaap` / `unspecified`. One sentence is often two series (GAAP and non-GAAP) — do not double-count |
| `segments` | Named cuts, or `"null"` for company-wide. `"consolidated"` will miss |
| `guided_period_end_*` | Calendar day the outlook period ends — use this to line up companies |
`guidance_bias` is one `symbol` and an optional window. No metric filter, no `limit`, no `detail`.
---
## list_guidance
One object per series: ticker × metric × GAAP/non-GAAP × segment × period. `values[]` is that line’s history, newest first.
Default `limit` is 10 (max 100). Default `values_mode` is `all`. Pin a metric or raise `limit` so one name does not fill the page.
`latest` is the newest observation **per series** (often the call), not “current slide only.” For the **printed number**, use `values_mode: "all"` and take the latest `earnings_release` row in `values[]`. If the call and an 8-K disagree, still use that release row. Keep the call for color.
### Use cases
**Realtime guidance tape** — Every series that just moved, market-wide, minutes after the print. No tickers. This is the desk feed.
```json
{
"values_mode": "latest",
"sort": "timestamp",
"detail": "standard",
"limit": 40
}
```
**Who raised or cut, market-wide** — Cross-sectional revision screen, no ticker list. `revision_delta` puts the biggest midpoint moves first. Read `metric_key` before calling a raise good: OpEx, tax, and cost guides go up on bad news. Sanity-check the top rows against the quote — an enormous `revision_midpoint_delta_pct` usually means the two observations were stated at different scales, not that the outlook moved that much.
```json
{
"revision_direction": ["raised", "lowered"],
"values_mode": "latest",
"sort": "revision_delta",
"detail": "full",
"limit": 40
}
```
**Peer cohort on one metric** — Same metric, same calendar period-end, ranked like-for-like. Fiscal labels do not align across companies; `guided_period_end_*` does. `comparable` ranks on the more common comparison in the match set (growth % vs rate level); rows without that number sort last.
```json
{
"metric_keys": ["revenue"],
"metric_key_exact_match": true,
"guided_period_end_from": "2026-12-01",
"guided_period_end_to": "2027-01-31",
"values_mode": "latest",
"sort": "comparable",
"detail": "full",
"limit": 40
}
```
**One company’s outlook pack** — Every open line. Split rows by quarter vs year on `guided_period_type` / `guided_period_end_date`.
```json
{
"symbols": ["NVDA"],
"values_mode": "latest",
"detail": "standard",
"limit": 40
}
```
**The number they printed** — `latest` can be the call; the release row is the citable figure. History keeps both.
```json
{
"symbols": ["NVDA"],
"metric_keys": ["revenue"],
"metric_key_exact_match": true,
"values_mode": "all",
"detail": "full"
}
```
**Off-cycle revisions** — An 8-K that moves the outlook away from an earnings date. Rare and high-signal. `values[]` still holds the release it changed; pick rows by `values[].source_type`.
```json
{
"source_types": ["guidance_update"],
"values_mode": "all",
"sort": "timestamp",
"detail": "standard",
"limit": 20
}
```
**The book as of a past day** — PIT. What the outlook was on date D, no later leakage. This is how a guidance signal gets backtested.
```json
{
"end_timestamp": "2026-06-30T20:00:00Z",
"values_mode": "latest",
"sort": "timestamp",
"detail": "standard",
"limit": 40
}
```
### What you get back
| Field | Notes |
|-------|-------|
| `values[]` | Newest first |
| `guided_period_end_date` | Use this to line up peers |
**At `standard`, each value:** `quote`, `timestamp`, `source_type`, `value_midpoint`, `unit`, `yoy_value_midpoint`, `yoy_unit`, `revision_direction`, `source`. Trust the quote if a label disagrees. A floor/ceiling midpoint is the stated bound, not a range center.
`revision_direction` is vs the last observation of **this** series (`new` / `raised` / `lowered` / `maintained` / `withdrawn`), not good/bad. It can be `null` — that is not `new`.
**Full only:** `revision_midpoint_delta_pct` (percent of the prior midpoint: 4.0 → 4.5 is +12.5, not +0.5), ranges (`value_low`/`value_high`), `observation_count` (length as of `end_timestamp`, not always `len(values)`), `cik`, `source_metadata`.
**Source:** `earnings_release` / `guidance_update` / `earnings_call`. At `standard`, `source_metadata` is null; the URL is still on the source. At `full`, `source_metadata.fiscal_year` / `fiscal_quarter` are the **document’s** completed period (a Q2 release guiding Q3 has Q2 here). To join `list_changes`, bump this call to `full` and use those fields — not `guided_*`.
### Filters and sort
`revision_direction` matches the **latest** observation only.
`source_types` includes a series if **any** observation has that class. `values[]` stays the full history. `earnings_release` + `latest` can still return a later **call**. Read `values[].source_type`.
| `sort` | Order |
|-------|--------|
| `timestamp` (default) | Most recently updated series first |
| `guided_period_end` | Period-end, oldest first |
| `comparable` | Strongest like-for-like number in the match set (growth % or rate level, whichever is more common). Pin period-end dates for a fair cohort |
| `revision_delta` | Largest latest midpoint move |
---
## list_guidance_outcomes
Company guidance versus the reported actual. One pair per series after that period reported.
This is an estimate-vs-actual record where the estimate is **the company’s own**, not the street’s — scored, quoted, and cited. Run it without tickers for a market-wide beat/miss screen.
If the same outlook is on the press release and the next-day call, the release is kept. Then the newest remaining guide against that actual is kept. A preannouncement and a later full release stay two rows.
Default `outcomes` is the scored results only. Pass `indeterminate` to see rows that could not be scored. Omit does not mean all rows.
Default `limit` is 10. Raise it — 10 is a page, not the whole print.
### Use cases
**One name’s track record** — Every guide they set and what printed against it. The company’s own estimate table.
```json
{
"symbols": ["AMZN"],
"detail": "standard",
"limit": 40
}
```
**Market-wide beat/miss screen** — No tickers. Who blew through or fell short of their own guide this cycle. `outcome_abs` puts the extremes first.
```json
{
"outcomes": ["significantly_exceeded", "significantly_missed"],
"sort": "outcome_abs",
"detail": "standard",
"limit": 40
}
```
**Read-across cohort** — One metric, one calendar period-end, across peers. Names that already reported give the base rate for names that have not. Reporting dates are staggered, so this window is where the lag lives.
```json
{
"metric_keys": ["revenue"],
"metric_key_exact_match": true,
"guided_period_end_from": "2026-06-01",
"guided_period_end_to": "2026-07-31",
"detail": "full",
"limit": 40
}
```
**That period for one name** — Pin the outlook period, not `start_timestamp`.
```json
{
"symbols": ["NVDA"],
"guided_period_end_from": "2026-07-01",
"guided_period_end_to": "2026-08-31",
"detail": "standard"
}
```
**Why a label looks wrong** — `indeterminate` rows are guides with no comparable actual (a segment cost call, a capacity target). `full` carries the `rationale`.
```json
{
"symbols": ["AMZN"],
"outcomes": ["indeterminate"],
"detail": "full",
"limit": 20
}
```
### What you get back
| Field | Notes |
|-------|-------|
| `outcome` | Vs **this** guide, not good/bad for the stock. Read the metric and the quotes |
| `guidance_quote` / `actual_quote` | Ground truth. Trust these over `outcome` and over `rationale`, which can disagree with each other |
| `actual_source_type` | `earnings_release` or `earnings_preannouncement` |
`standard` has the quotes and links. `full` adds the guided range, the actual, the deltas, and `rationale` (why that label).
Match to `list_guidance` on ticker + metric + GAAP/non-GAAP + segment + period. There is no shared id.
| `sort` | Order |
|-------|--------|
| `timestamp` (default) | Newest result first |
| `outcome_abs` | Largest miss or beat first (by label, not by dollars) |
---
## guidance_bias
One name. Oldest report first. The whole series in the window.
The pattern is the point, and it is **forward-looking**: a company that scores positive report after report guides low and beats, so its next guide is probably a floor. Persistently negative means the guide runs optimistic and should be discounted. A single point is a scorecard; the run is a prior on the next print.
```
significantly_exceeded = +2
exceeded = +1
in_line = 0
missed = -1
significantly_missed = -2
```
Average of those scores. Unscored rows are left out.
Each point: `bias_score`, `resolved_count`, `label_counts`, and `fiscal_year` / `fiscal_quarter` of the **report that printed the actual**, not the guided period. Several lines can land in one report (revenue and operating income, GAAP and non-GAAP, a quarter guide and a year guide). They share one point. `resolved_count` of 2 is normal. The latest point is the last report, not the next print.
The outcomes list keeps only the newest guide per line. Bias averages every guide that closed that night, so `resolved_count` will not always match the outcomes list.
Do not rank many names from this tool (one symbol per call). Do not treat a single vote as a pattern.
### Use cases
**Sandbagger or over-promiser** — Read the run of `bias_score`, then pull the pairs behind it with `list_guidance_outcomes` on the same ticker.
```json
{
"symbol": "AMZN"
}
```
**As of a past day** — PIT the score so a backtest only sees reports that had already printed.
```json
{
"symbol": "AAPL",
"end_timestamp": "2026-08-01T00:00:00Z"
}
```
---
## Workflow
Chains worth more than a single call.
**Earnings-night brief on one name**
1. `list_guidance` — ticker, `values_mode: "all"`, `full`. Printed figures come from the latest `earnings_release` row per series; the call row is color.
2. `list_guidance_outcomes` — same ticker. The period that just closed is now scored against the guide they gave a quarter ago.
3. `list_changes` — ticker + the fiscal year/quarter from step 1’s `source_metadata`. This is how the wording moved around those numbers: non-GAAP definitions, segment cuts, outlook assumptions.
4. Wire (legal name, `Nvidia Corporation`) for how the tape read it; your own web search for sell-side reaction.
**Read-across before the laggard prints**
1. `list_guidance_outcomes` — one metric + a `guided_period_end_*` window covering the cohort. Peers that already reported show whether guides for that period ran hot or cold.
2. `list_guidance` — same metric and window, `values_mode: "latest"`. The names still open, with the guide they are about to be measured against.
3. `guidance_bias` — on each open name. A habitual sandbagger into a hot cohort is a different setup than an over-promiser into a cold one.
4. `identify_stakeholders` or `search_developments` — when the driver is a shared shock (tariffs, memory pricing, freight rates) rather than a company story.
**Cross-sectional revision screen**
1. `list_guidance` — no tickers, `revision_direction: ["raised","lowered"]`, `sort: "revision_delta"`, `full`. The largest outlook moves in the market.
2. Split the results yourself on `metric_key` and `metric_basis`. A raised cost guide is not a raised revenue guide, and one sentence can be both GAAP and non-GAAP.
3. `list_changes` — `guidance_basis` on the same names, to separate real demand from a re-based outlook (a deal folded in, a tariff assumption added).
4. `market_signal` or Wire — whether the tape has already priced it.
**Backtest a guidance signal**
1. `list_guidance` — `end_timestamp` = decision date, `values_mode: "latest"`. The book as it stood, with no leakage.
2. `list_guidance_outcomes` — a later window, same filters. What those guides turned into.
3. `guidance_bias` — with `end_timestamp` at each decision date, so the score only knows prior reports.
**Leave it running**
`create_alert` on `list_guidance` (revisions) or `list_guidance_outcomes` (beats and misses), arguments minus timestamps — the alert owns the window. Keep `values_mode: "all"` so each delivery carries the prior print to compare against.
---
## Combine with
- **Wire / developments** — Why it matters. Wire wants the legal name (`Nvidia Corporation`), not `NVDA`.
- **`list_changes`** — How they wrote the release. Same ticker; match the document’s fiscal period from `source_metadata` (`list_guidance` at `full`).
- **Alerts** — `list_guidance` and `list_guidance_outcomes` only; `guidance_bias` is not alertable. See **Workflow**.
---
## Limitations
- Not every listed company is in the data. Empty is not “no outlook” and not “they always hit.”
- `latest` can still show an old child series next to a current print. Assemble the pack; don’t treat the first N rows as the slide.
- Empty `revenue` after a substring search ≠ no outlook. Read the pack.
- `source_types` does not filter `values[]`.
- Transcripts use an Ultralayer URL; press releases use the SEC URL.
---
## FAQ
**Why did `source_types: ["earnings_release"]` return a call?**
The series once had a release. The newest row can still be the call. Read `values[].source_type`.
**Why is WMT `revenue` empty?**
They may not guide a revenue-like line. Substring is the default (`revenue` also matches `revenue_growth`). Do not say they have no outlook. Pin `metric_key_exact_match: true` if you only want the level.
**Why doesn’t `resolved_count` match the outcomes list?**
The list keeps the newest guide per line. Bias averages every guide that closed that night.
signals5 KB
View saved version →
---
name: signals
description: Daily market signal bars for a sector, country, or asset class. Operation is market_signal.
---
# Signals
`market_signal` aggregates Wire activity into contiguous daily or multi-day bars. Each bar carries wire-item attention and the net sentiment of entity mentions for one market scope.
| Operation | Role |
|-----------|------|
| `market_signal` | Attention and net sentiment bars for one sector, country, or asset class |
---
## When to use
**Use `market_signal` when you need to:**
- Track how much Wire coverage a market scope receives over time
- Measure the aggregate direction and magnitude of entity-mention sentiment
- Backtest attention and sentiment over a historical window
- Roll daily activity into coarser multi-day bars
**Do not use when you need:**
- The headlines behind a move → `list_wire`
- A company dossier or entity-specific sentiment → `retrieve_entity`
- Ticker-level impact narratives → developments and events
---
## Use cases
**Sector activity** — Read the latest 14 bars of information-technology attention and net sentiment.
```json
{
"value": "information_technology"
}
```
**Original energy coverage** — Exclude syndication duplicates when measuring energy activity.
```json
{
"value": "energy",
"novelty": ["new", "update", "correction"]
}
```
**Historical country signal** — Backtest US coverage over an explicit system-time window.
```json
{
"value": "us",
"start_timestamp": "2026-07-15T00:00:00Z",
"end_timestamp": "2026-08-01T00:00:00Z"
}
```
**Weekly asset-class bars** — Roll crypto activity into stable 7-day buckets.
```json
{
"value": "crypto",
"resolution": "7d",
"start_timestamp": "2026-07-01T00:00:00Z"
}
```
---
## What you get back
| Field | Notes |
|-------|-------|
| `bars` | Oldest → newest; empty buckets are present, never omitted |
| `bar` | Exclusive UTC bucket end |
| `count` | Distinct Wire items about the scope |
| `sentiment` | Net sum of every entity-mention sentiment on those items; `0` when empty or when no mentions exist |
| `sentiment_std` | Population standard deviation across those mention sentiments; `null` when there are no mentions |
| `partial` | `true` when the latest bucket is still in progress |
| `resolution` | Bucket length used |
| `methodology_version` | Signal definition version |
Floats are rounded to 2 decimal places. History is capped at 60 days; omitting `start_timestamp` returns the last 14 bars.
---
## Scope values
`value` is a single string; the dimension is inferred:
| Kind | Examples |
|------|----------|
| Sector | `information_technology`, `energy`, `financials`, `health_care` |
| Asset class | `equities`, `fixed_income`, `currencies`, `commodities`, `crypto`, `real_estate` |
| Country | Lowercase ISO alpha-2, such as `us`, `cn`, or `gb` |
`novelty` defaults to all four classes (`new`, `update`, `duplicate`, `correction`). Narrow it when you want originals/updates only.
---
## Workflow
| User intent | Approach |
|-------------|----------|
| “Is tech coverage increasing?” | Call with `value: information_technology`; read `count` over time |
| “What is the direction of energy sentiment?” | Call with `value: energy`; read the sign and magnitude of `sentiment` |
| “How has US attention changed?” | Call with `value: us` and an explicit window |
| “Show weekly crypto activity” | Call with `value: crypto`, `resolution: 7d` |
1. Pick one scope `value` (sector, country, or asset class).
2. Omit `start_timestamp` for the latest 14 bars, or set an explicit historical window.
3. Read `count` as coverage and `sentiment` as unnormalized net mention tone; use `sentiment_std` to assess disagreement.
4. For narrative detail, follow up with Wire using the same scope filters.
---
## Limitations
- One scope value per call — no multi-value baskets in a single request.
- Daily (or multi-day) bars only — no intraday resolution yet.
- Sentiment is an unnormalized net sum across entity mentions; magnitude rises with mention volume and should be compared primarily within the same scope over time.
- `count` is Wire items, not entity mentions, so it cannot be used to derive average mention sentiment.
- Country codes are free-form two-letter strings; invalid codes may return empty bars rather than a vocabulary error.
- Max lookback 60 days.
---
## FAQ
**Is `sentiment` an average?** No. It is the net sum of entity-mention sentiments. Positive and negative mentions offset each other; larger absolute values reflect direction plus mention volume.
**Why is `sentiment` 0 on a quiet day?** Empty or mention-less bars use `0` for this sum-type statistic. Check `count` and `sentiment_std` for context.
**What does `bar` mean?** Exclusive bucket end in UTC. A `1d` bar ending `2026-08-11T00:00:00Z` covers `[2026-08-10, 2026-08-11)`.
**Can I pass a company name?** No — use sectors, asset classes, or country codes. For a company, use Wire or `retrieve_entity`.
**How do I backtest?** Set `start_timestamp` / `end_timestamp` (system timestamps). `end_timestamp: null` means realtime.
stakeholder-identification8.99 KB
View saved version →
---
name: stakeholder-identification
description: Map a market situation to ranked public-company winners and losers with verified tickers, signed impact scores, cited quotes, and a factor comparison matrix. Operation is identify_stakeholders.
---
# Stakeholder identification
`identify_stakeholders` answers “who matters for this situation, and why?” It retrieves finance-specific evidence, returns structured public-company impacts with cited quotes, verifies tickers, and ships a factor comparison matrix.
| Operation | Role |
|-----------|------|
| `identify_stakeholders` | Situation → ranked stakeholders + factor matrix |
**Latency:** commonly ~2 minutes. Budget for that. Do not treat timeouts as “empty universe.” Do not spam parallel calls.
**Approval for Agents:** If a user is waiting on this turn (chat), tell them it takes ~2 minutes and get explicit approval before calling. If no one is waiting (one-shot / autonomous / unattended), call and wait.
---
## When to use
**Use when you need:**
- Ranked public-company winners/losers for a market situation, with direction + magnitude
- Why each name is exposed (rationale) plus auditable quotes
- A factor matrix to compare the returned names at a glance
- Backtest-safe identification as-of a historical `end_timestamp`
**Do not use when you need:**
- Fast headline triage → Wire
- Open-web research (article body, quotes, filings, prices) → your native web search tool
- One company’s live dossier → `retrieve_entity`
- Already-stored development packages → `search_developments` (SI creates fresh assessments; developments store prior ones)
- Non-company stakeholders (countries, commodities, people, private cos) → out of scope (`PUBLIC_COMPANY` only)
Generic LLMs invent tickers; this endpoint retrieves evidence, cites exact quotes, verifies symbols, and returns a reusable factor table — with optional point-in-time mode.
---
## Use cases
**Realtime supply shock** — Map who wins and loses if a concrete market shock hits, with verified tickers and cited reasons.
```json
{
"query": "Strait of Hormuz near-total closure and oil supply shock"
}
```
**Realtime with steering** — Same exposure map, but steer coverage toward second-order names and keep the list tight.
```json
{
"query": "Tesla Q2 2026 earnings miss and margin compression",
"context": "EPS well below consensus; operating margin ~1.4%; negative FCF; energy storage strong.",
"instructions": "Prioritize clear second-order exposures (EV peers, suppliers, AI compute). Prefer fewer high-confidence names."
}
```
**Historical / backtest** — Ask who mattered as of a past date, without live-web leakage after that cutoff.
```json
{
"query": "Apple CEO succession Tim Cook to John Ternus",
"end_timestamp": "2026-04-25T00:00:00Z"
}
```
**Constrained universe** — Force a short, sector-balanced list instead of a long undifferentiated dump.
```json
{
"query": "who benefits from rising oil prices",
"instructions": "Return at most 6 public companies spanning upstream, midstream, and airlines as losers."
}
```
**Regulation / tariffs** — Identify listed companies with clear regulatory exposure for a policy action.
```json
{
"query": "EU Digital Markets Act fines on Big Tech self-preferencing",
"instructions": "Focus on listed platforms and ad-tech peers with clear regulatory exposure."
}
```
---
## Response detail
`identify_stakeholders` accepts `detail`. **Default is `full`.** Reduced levels **drop keys** only — surviving fields keep the same names and paths as `full`. Pricing does not change with `detail`; this is about **response token cost** in the agent context (especially valuable here — SI payloads are large).
| Level | What you get | Rough token savings vs `full` |
|-------|----------------|-------------------------------|
| `essential` | Stakeholders with impact + rationale; factor matrix with name/description/value/rationale (no sources, no confidence, no rubrics/scale) | ~80% |
| `standard` | essential + confidence, factor scale/rubric, and citable sources (no quotes) | ~31% |
| `full` | Every field including source quotes and full factor definitions | — |
**Prefer `detail: "standard"`** for normal agent calls. Use `essential` for a cheap ranked map; use `full` when you need auditable quotes in the payload.
```json
{
"query": "Strait of Hormuz near-total closure and oil supply shock",
"detail": "standard"
}
```
---
## Params
| Param | Role |
|-------|------|
| `query` (required) | The situation. Non-empty after strip; blank → 422. Max **2000** characters. |
| `context` | Extra facts about the situation (what happened, numbers, constraints). Max **12000** characters. |
| `instructions` | How to shape the answer (coverage, count, sectors to prefer/avoid) — not treated as the search subject. Max **2000** characters. |
| `end_timestamp` | Omit/null = **realtime**. Past = **backfill**. Future → realtime. No `start_timestamp`. |
| `detail` | Default `full`. Prefer `standard` (see **detail** above). |
Prefer a concrete situation over a vague theme. Put hard facts in `context`; put process prefs in `instructions` (`"Prefer fewer high-confidence names"`, `"At most 6 names"`). Instructions work — they change count and composition.
Only verified public tickers are returned as stakeholders.
---
## Realtime vs backfill
| Mode | Trigger | Behavior |
|------|---------|----------|
| **Realtime** | `end_timestamp` null/future | Uses live web retrieval plus historical structured SI context |
| **Backfill** | past `end_timestamp` | No live web. Evidence from indexed corpus and historical SI context clamped to `end_timestamp` — backtest-safe |
Use backfill for “what would an analyst have concluded knowing only info ≤ T?” Use realtime for “given the live tape, who is in the blast radius?”
Returned tickers are verified; unverified names are dropped.
---
## What you get back
### `stakeholder_impacts[]`
- `stakeholder`: `{ name, stakeholder_type: "PUBLIC_COMPANY", symbol }`
- `impact_score` ∈ [-1, 1]
- `confidence_score` ∈ [0, 1]
- `rationale`
- `sources_with_quotes[]` — exact quotes with source metadata
Scan strongest positives and strongest negatives first.
### `factor_matrix[]`
Rows = situation-specific factors. Each has `name` (snake_case), `description`, `factor_scale`, `rubric`, optional `allowed_values`, and `stakeholder_assessments` keyed by **symbol**.
Scales: `BINARY` | `CATEGORICAL` | `CONTINUOUS` [0,1] | `SIGNED_CONTINUOUS` [-1,1].
Use the matrix for “who is more exposed on dimension X?” Factor names are meant to be reusable across similar situations. A factor row may occasionally omit a symbol — treat missing cells as unknown, not zero.
---
## Workflow
| User intent | Approach |
|-------------|----------|
| “Who wins/loses if X?” | Realtime SI on a precise query; brief from impact extremes + factor matrix |
| “As of date D, who mattered?” | Same query + past `end_timestamp` |
| “Keep it short / sector-focused” | Put constraints in `instructions` |
| “Drill one ticker after SI” | `retrieve_entity`, Wire, or developments with `symbols` |
| “Just give me headlines” | Wire — do not pay SI latency for firehose |
1. Confirm the user wants situation → public-company exposure.
2. Craft a specific `query`; add `context` / `instructions` only when they sharpen the job.
3. Get approval if applicable: If you are an interactive chat agent, and there is a user waiting, get approval for the ~2 min wait before calling.
4. Call once; wait. On timeout, retry once — do not fan out parallel SI calls.
5. Brief: top ± impacts → factor matrix highlights → cite 1–2 quotes per key name.
6. Offer follow-ups via Wire / developments / `retrieve_entity` / your native web search tool using returned symbols.
---
## Limitations
- Slow — plan for ~2 minutes; avoid speculative retries and fan-out.
- Public companies only; listing suffixes vary (`SMSN.IL`, `BYDDF`, `AMKBY`).
- Verification can drop proposed names — final list ⊆ verified survivors.
- Not a price target or trading signal — impact scores are reasoned exposures with citations.
- Backfill quality depends on indexed corpus ≤ T.
- Factor matrix is built per call — read names/rubrics; don’t assume identical every time.
- Does not return countries/commodities as stakeholders even when they dominate the narrative.
---
## FAQ
**Q: Why is this better than asking a normal agent?**
A: Retrieval + quote binding + ticker verification + factor matrix + backtest mode.
**Q: Future `end_timestamp` — historical or live?**
A: Treated as realtime.
**Q: Can I get private cos / OPEC / Brent as stakeholders?**
A: Not as structured stakeholders. They may appear in rationales/sources only.
**Q: How do I continue after SI?**
A: Take symbols → Wire filters, `search_developments(symbols=…)`, `retrieve_entity`, or your native web search tool.
**Q: Empty / whitespace query?**
A: 422 `query must be a non-empty string.`
**Q: Query / context / instructions too long?**
A: 422. Caps are 2000 chars (`query` / `instructions`) and 12000 chars (`context`).
wire12.6 KB
View saved version →
---
name: wire
description: Realtime and backtestable financial news wire — novelty-clustered headlines with entity mentions, sector and asset tags, and trust/importance scores. Operations are list_wire and wire_storyline.
---
# Wire
The Wire is Ultralayer’s structured news firehose: short, fact-dense headlines with novelty links, entity mentions, sector/asset tagging, and trust/importance scores. Public surface exposes **metadata + headline only** (no article body).
| Operation | Role |
|-----------|------|
| `list_wire` | Filter + return the most recent matching wire items |
| `wire_storyline` | Expand one item into its novelty ancestor chain + first-degree branches |
---
## When to use
**Use the Wire when you need to:**
- Scan what is moving now (earnings, guidance, geopolitics, rates, M&A)
- Monitor a company, commodity, country, sector, or publisher
- Deduplicate the firehose via `novelty` (`new` / `update` vs `duplicate`)
- Reconstruct how a story evolved (updates, corrections, cross-publisher copies)
- Backtest a window with `start_timestamp` / `end_timestamp`
- Build alert-ready conditions (same filter fields power `list_wire` alerts)
**Do not use the Wire when you need:**
- Open-web research (article body, quotes, filings, prices) → your native web search tool
- A full entity package → `retrieve_entity`
- Semantic “find similar stories by meaning” — `list_wire` is filter/recency, not embedding search
---
## Use cases
**Realtime desk scan** — See the latest material earnings and guidance prints without the syndication noise.
```json
{
"max_records": 25,
"novelty": ["new", "update", "correction"],
"categories": ["earnings", "guidance"],
"min_importance_score": 0.5,
"min_trustworthiness_score": 0.7
}
```
**Company name watch** — Pull only headlines where a specific company is a primary or major subject.
```json
{
"max_records": 20,
"entities": ["Tesla, Inc."],
"entity_relevance": ["primary", "significant"],
"novelty": ["new", "update", "correction"]
}
```
**Strong ± sentiment on a name** — Surface mentions that are clearly bullish or bearish on the company, not mild noise.
```json
{
"entities": ["easyJet plc"],
"entity_relevance": ["primary", "significant"],
"min_entity_sentiment": 0.3,
"max_entity_sentiment": -0.3,
"max_records": 20
}
```
**Geopolitics → commodities** — Catch geopolitics that matter for energy and commodities.
```json
{
"max_records": 20,
"sectors": ["energy"],
"asset_classes": ["commodities"],
"categories": ["geopolitics"],
"novelty": ["new", "update"],
"min_importance_score": 0.5
}
```
**Issuer originals only** — Read what the company itself released, not second-hand rewrites.
```json
{
"content_type": ["press_release"],
"source_relationship": ["first_party"],
"novelty": ["new", "update", "correction"],
"max_records": 20
}
```
**Scheduled / future events** — Find upcoming earnings and policy dates, not just what already printed.
```json
{
"recency": ["report_of_future"],
"categories": ["earnings", "monetary"],
"max_records": 20
}
```
**Backtest a window** — Reconstruct what looked important during a specific trading session.
```json
{
"start_timestamp": "2026-07-21T14:00:00Z",
"end_timestamp": "2026-07-21T18:00:00Z",
"novelty": ["new", "update"],
"min_importance_score": 0.6,
"max_records": 50
}
```
**Storyline with syndication** — See how a story evolved and which outlets copied it.
```json
{
"wire_id": 67337,
"novelty": ["new", "update", "duplicate", "correction"]
}
```
---
## Response detail
Both operations accept `detail`. **Default is `full`.** Reduced levels **drop keys** only — surviving fields keep the same names and paths as `full`. Pricing does not change with `detail`; this is about **response token cost** in the agent context (wire lists can be large).
| Level | What you get | Rough token savings vs `full` |
|-------|----------------|-------------------------------|
| `essential` | `wire_id`, `source_timestamp`, `headline`, `publisher`, `novelty`, thinned `entities` (name / relevance / sentiment) | Large — drops url, scores, `about`, taxonomy, most entity identifiers |
| `standard` | essential + `url` for citation | Between essential and full (url only vs essential) |
| `full` | Every field (`about`, scores, content type, categories, full entity detail, …) | — |
Exact wire percentages are not published yet; treat essential as the big cut and standard as the usual cite-ready middle. **Prefer `detail: "standard"`** for normal agent calls. Use `essential` for dense scans; use `full` when you need scores, `about`, or full entity identifiers.
```json
{
"max_records": 25,
"novelty": ["new", "update", "correction"],
"detail": "standard"
}
```
---
## What you get back
Each item is a compact decision object. Headlines are usually one dense sentence with numbers, entities, and the delta.
| Field | Notes |
|-------|-------|
| `headline` | Primary content |
| `wire_id` | Pass to `wire_storyline` |
| `timestamp` | Wire clock — **filters** use this |
| `source_timestamp` | Publisher time — **list_wire sorts by this descending** |
| `novelty` + `prior_wire_id` | Cluster membership. `new` usually has `prior_wire_id: null` |
| `importance_score` / `trustworthiness_score` | 0–1 |
| `factuality` | `confirmed` / `reported` / `rumor` / `speculation` / `forecast` |
| `content_type` | `news`, `analysis`, `opinion`, `press_release`, `data_release` |
| `recency` | `realtime` / `report_of_past` / `report_of_future` |
| `source_relationship` | `first_party` / `reporting` / `second_hand` |
| `about` | `sectors`, `industries`, `countries` (ISO alpha-2 lowercase), `asset_classes` |
| `entities[]` | `canonical_name`, `entity_type`, `relevance`, `sentiment` (−1..1), `identifiers` |
| `publisher` | Exact string for filters; values are inconsistent (`bloomberg`, `seeking alpha`, `dow_jones`) |
Prefer `novelty: ["new","update","correction"]` and `max_records` 10–30 with tight filters.
---
## list_wire
Returns up to `max_records` (1–100, default 20) matching items, newest by `source_timestamp`. Pass `detail` (default `full`; prefer `standard` — see **detail** above).
### Filtration vs sort
- **Filters** apply on `timestamp` (wire clock).
- **Response order** is `source_timestamp` descending.
- A tight time window can include items whose source time looks slightly outside the window. Prefer slightly wider windows when backtesting.
Future `end_timestamp` values are treated as realtime (no upper bound).
### Novelty
| Value | Meaning | Typical `prior_wire_id` |
|-------|---------|-------------------------|
| `new` | First material print of a cluster | `null` |
| `update` | Material change / next beat | prior in chain |
| `duplicate` | Same substance, often another publisher | prior (often a `new`) |
| `correction` | Number/fact fix; rare but market-critical | prior wrong print |
Default monitoring set: `["new", "update", "correction"]` — cuts roughly half the firehose noise from cross-publisher copies while keeping beats and fixes.
Example: Lundbeck FDA Fast Track — `pr_newswire` item `novelty=new`, Reuters copy minutes later `novelty=duplicate` with `prior_wire_id` → the PR.
### Entity filter
`entities` is include-any.
Pair with `entity_relevance` and `min_entity_sentiment` / `max_entity_sentiment`. When both sentiment bounds are set, `min` must be **greater than** `max` (directional OR: strong positive **or** strong negative).
Sentiment bounds apply to the matching mention, not the whole item.
### Other high-value filters
| Filter | Notes |
|--------|-------|
| `categories` | Free-form. Common: `earnings`, `guidance`, `geopolitics`, `trade`, `m&a`, `regulation`, `macro`, `monetary`, `product`, `tech`, `litigation`. Wrong tags silently return fewer hits. |
| `sectors` | Closed GICS-like enum (`information_technology`, `energy`, …) |
| `industries` | Free-form as stored (e.g. `"semiconductors"`) |
| `countries` | Lowercase ISO-3166-1 alpha-2 |
| `asset_classes` | `equities`, `fixed_income`, `commodities`, `currencies`, `crypto`, `real_estate` |
| `publisher` | Exact match; discover from results |
| `content_type` + `source_relationship` | `press_release` + `first_party` for issuer originals |
| `factuality` | `rumor` / `speculation` for soft takes |
| `recency` | `report_of_future` for scheduled/future prints |
| `min_importance_score` | Unfiltered stream is full of 0.2–0.3 items |
| `min_trustworthiness_score` | Filters thin social sources |
Filters combine with AND across dimensions; within multi-value arrays, include-any (OR).
Keep filter lists tight: across `categories`, `entities`, `sectors`, `industries`, `countries`, `asset_classes`, and `publisher`, at most **12 values total** are allowed in one request.
---
## wire_storyline
Given a `wire_id`, returns the novelty storyline: linear `prior_wire_id` ancestors plus first-degree children of every chain node.
```json
{
"seed_wire_id": 67583,
"root_wire_id": 49200,
"items": [ ]
}
```
Items are chronological by `source_timestamp` ascending.
| Param | Notes |
|-------|-------|
| `max_ancestor_depth` | Default 32, max 64. Caps the linear prior walk (including the seed). |
| `max_children` | Default 32, max 64. Caps first-degree children across the whole chain. |
| `detail` | Default `full`. Prefer `standard`. |
### Topology
1. Walk seed → `prior_wire_id` → … until root, time-window break, or `max_ancestor_depth`.
2. Ancestors are walked even through duplicates so the chain stays connected; novelty filtering is applied when projecting the response (seed always kept).
3. Children: only direct children of chain nodes, capped by `max_children`.
4. `root_wire_id` is set only if the walk reached a row with `prior_wire_id: null`. **`root_wire_id: null` means truncated** (time window or depth).
5. Seed outside the requested time window → **404**. Unknown `wire_id` → **404**.
### Default novelty trap
`wire_storyline` defaults to `novelty: ["new", "update", "correction"]` — **duplicates excluded**. That hides cross-publisher fanout.
- Default: good for “how did the story evolve?”
- Include `"duplicate"` when you need “who else printed this?”
Example — easyJet earnings: default novelty → only the Reuters `new` seed; with duplicates → Reuters + Bloomberg + FT copies.
Example — earnings correction chain: `new` → `correction` → `update` → later conflicting `correction`. Storyline is how you catch conflicting prints.
Example — multi-day geopolitics: seed linked through consecutive updates to a root days earlier; a tight time window truncates the chain and returns `root_wire_id: null`.
---
## Workflow
| User intent | Approach |
|-------------|----------|
| “What’s moving markets right now?” | `list_wire` with novelty without duplicates, `min_importance_score` ≥ 0.5 |
| “Any news on Company X?” | `entities` + primary/significant → storyline on the best hit |
| “Did guidance change?” | `categories: ["guidance","earnings"]`, then storyline |
| “Is this a correction?” | `novelty: ["correction"]` or storyline and look for correction nodes |
| “Who reported it first?” | Storyline with duplicates; earliest `new` / first_party press release is usually the root |
| “Oil / Red Sea / rates?” | `asset_classes` + `sectors` + geopolitics/macro categories |
| “What looked important on date D?” | Timestamp window + importance floor + novelty new/update |
1. Clarify scope (entity / sector / theme / time).
2. `list_wire` with novelty `new|update|correction`, an importance floor, and the tightest true filters.
3. Pick the highest-importance hit → `wire_storyline` (add `duplicate` if coverage breadth matters).
4. Brief from headlines + novelty path; escalate to your native web search tool (or the URL) for body text.
---
## Limitations
- No full article text on the public wire surface.
- `publisher`, `industries`, and `categories` are messy real-world strings.
- Storyline is shallow by design (linear ancestors + one hop of children).
- Unfiltered `list_wire` is noisy — bias novelty + importance.
- `importance_score` is relative rank, not a guarantee.
---
## FAQ
**Q: Why doesn’t storyline show Bloomberg/FT copies?**
A: Default novelty drops `duplicate`. Add it explicitly.
**Q: `root_wire_id` is null but items exist.**
A: Ancestry was truncated by time window or `max_ancestor_depth`. Widen `start_timestamp`, raise the depth cap, or treat as a partial chain.
**Q: Sort order looks wrong vs IDs.**
A: `list_wire` sorts by `source_timestamp` desc, not `wire_id`. Filtration still uses `timestamp`.
**Q: list_wire vs alerts?**
A: Same filter vocabulary. The Wire is the pull API; alerts can poll `list_wire` conditions on a schedule.