# Get Entity
Source: https://docs.gildea.ai/api-reference/entities/get
GET /v1/entities/{name_or_id}
Retrieve full entity profile with co-occurring entities
Public entity ID (`gld:/…`) or URL-encoded display name (e.g., `NVIDIA` or `gld:/a1b2c3d4e5f6`). Internal prefix-encoded IDs are rejected with a 400.
Stable, opaque public entity ID (e.g., `gld:/a1b2c3d4e5f6`).
Human-readable entity name.
Entity type. See [Entities](/concepts/entities) for all 8 types.
Total signals mentioning this entity.
Trend analytics.
Entity's share of total corpus over the trailing 4 weeks.
Consecutive weeks of growth.
Signal count this week.
Signal count last week.
Count of distinct source domains.
`Large`, `Medium`, or `Small`.
`Rising`, `Stable`, `Declining`, or `New`. Null if fewer than 8 mentions.
`Significant` or `Insignificant`.
`Volatile` or `Steady`.
`High`, `Medium`, `Low`, or `Negligible`. How much this entity warrants attention right now.
Explanation of the notability assignment.
Signal count by content type (e.g., `{"analysis": 90, "event": 66}`).
Signal count by value chain theme.
Signal count by market force theme.
Co-occurring entities ranked by frequency.
Public ID of the related entity.
Display name.
Entity type.
Number of signals both entities appear in.
```bash cURL theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/entities/NVIDIA"
```
```python Python theme={null}
import requests
entity = requests.get(
"https://api.gildea.ai/v1/entities/NVIDIA",
headers={"X-API-Key": "gld_your_key"},
).json()
```
```javascript JavaScript theme={null}
const resp = await fetch(
"https://api.gildea.ai/v1/entities/NVIDIA",
{ headers: { "X-API-Key": "gld_your_key" } }
);
const entity = await resp.json();
```
```json 200 theme={null}
{
"entity_id": "gld:/a1b2c3d4e5f6",
"name": "NVIDIA",
"type": "organization",
"wikipedia_url": "https://en.wikipedia.org/wiki/Nvidia",
"signal_count": 156,
"first_seen": "2025-10-03T00:00:00Z",
"last_seen": "2026-02-14T00:00:00Z",
"trend": {
"share_of_voice": 0.12,
"streak": 4,
"current_week": 15,
"prior_week": 10,
"source_diversity": 12
},
"scale": "Large",
"direction": "Rising",
"confidence": "Significant",
"stability": "Steady",
"notability": "High",
"notability_reasoning": "Large-scale entity with confirmed upward trend and consistent coverage; notable upward shift reliably gaining share.",
"content_type_mix": {"analysis": 90, "event": 66},
"value_chain_distribution": {"Infrastructure": 80, "Foundation Models": 45},
"market_force_distribution": {"Competitive Dynamics": 70, "Capital & Investment": 50},
"related_entities": [
{
"entity_id": "gld:/b2c3d4e5f6a7",
"name": "TSMC",
"type": "organization",
"co_occurrence_count": 28
},
{
"entity_id": "gld:/c3d4e5f6a7b8",
"name": "AMD",
"type": "organization",
"co_occurrence_count": 22
}
]
}
```
```json 404 theme={null}
{
"error": {
"code": "not_found",
"message": "Entity 'nonexistent' not found",
"status": 404
}
}
```
# List Entities
Source: https://docs.gildea.ai/api-reference/entities/list
GET /v1/entities
Retrieve a paginated list of entities with trend stats
Filter by theme label (see [Themes](/concepts/themes) for valid labels). An unknown label returns `404`, not an empty list.
Filter by entity type (e.g., `organization`, `person`, `model`, `hardware`, `other`). See [Entities](/concepts/entities) for all 8 types.
Filter entities by name (matches names containing this text). For natural-language semantic retrieval, use [`GET /v1/search`](/api-reference/search/search).
Sort field: `signal_count`, `first_seen`, `trend`.
Filter by trend direction: `Rising`, `Stable`, `Declining`, `New`.
Filter by trend significance: `Significant`, `Insignificant`.
Filter by coverage consistency: `Volatile`, `Steady`.
Filter by share-of-voice scale: `Large`, `Medium`, `Small`.
Filter by notability: `High`, `Medium`, `Low`, `Negligible`.
Results per page (1-50).
Opaque pagination cursor from a previous response.
List of entity objects.
Stable, opaque public entity ID (e.g., `gld:/a1b2c3d4e5f6`).
Human-readable entity name.
Entity type (e.g., `organization`, `model`). See [Entities](/concepts/entities) for all 8 types.
Wikipedia link, if available.
Total signals mentioning this entity.
ISO 8601 date of first mention.
ISO 8601 date of most recent mention.
Trend analytics. See [Entities](/concepts/entities#trend-analytics) for field descriptions.
`Large`, `Medium`, or `Small`.
`Rising`, `Stable`, `Declining`, or `New`. Null if fewer than 8 mentions.
`High`, `Medium`, `Low`, or `Negligible`. How much this entity warrants attention right now.
Explanation of the notability assignment.
Signal count by content type (e.g., `{"analysis": 90, "event": 66}`).
Signal count by value chain theme (e.g., `{"Infrastructure": 80}`).
Signal count by market force theme (e.g., `{"Competitive Dynamics": 70}`).
Whether more results exist.
Cursor for the next page.
```bash cURL theme={null}
# List organizations
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/entities?type=organization&limit=10"
# Find rising entities with statistical significance
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/entities?direction=Rising&confidence=Significant&sort=trend&limit=10"
```
```python Python theme={null}
import requests
headers = {"X-API-Key": "gld_your_key"}
# List organizations
resp = requests.get(
"https://api.gildea.ai/v1/entities",
headers=headers,
params={"type": "organization", "limit": 10},
)
entities = resp.json()
# Find rising entities with statistical significance
resp = requests.get(
"https://api.gildea.ai/v1/entities",
headers=headers,
params={"direction": "Rising", "confidence": "Significant", "sort": "trend", "limit": 10},
)
rising = resp.json()
```
```javascript JavaScript theme={null}
const headers = { "X-API-Key": "gld_your_key" };
// List organizations
const resp = await fetch(
"https://api.gildea.ai/v1/entities?type=organization&limit=10",
{ headers }
);
const entities = await resp.json();
// Find rising entities with statistical significance
const rising = await fetch(
"https://api.gildea.ai/v1/entities?direction=Rising&confidence=Significant&sort=trend&limit=10",
{ headers }
).then(r => r.json());
```
```json 200 theme={null}
{
"entities": [
{
"entity_id": "gld:/a1b2c3d4e5f6",
"name": "NVIDIA",
"type": "organization",
"wikipedia_url": "https://en.wikipedia.org/wiki/Nvidia",
"signal_count": 156,
"first_seen": "2025-10-03T00:00:00Z",
"last_seen": "2026-02-14T00:00:00Z",
"trend": {
"share_of_voice": 0.12,
"streak": 4,
"current_week": 15,
"prior_week": 10,
"source_diversity": 12
},
"scale": "Large",
"direction": "Rising",
"confidence": "Significant",
"stability": "Steady",
"notability": "High",
"notability_reasoning": "Large-scale entity with confirmed upward trend and consistent coverage; notable upward shift reliably gaining share.",
"content_type_mix": {"analysis": 90, "event": 66},
"value_chain_distribution": {"Infrastructure": 80, "Foundation Models": 45},
"market_force_distribution": {"Competitive Dynamics": 70, "Capital & Investment": 50}
}
],
"has_more": true,
"next_cursor": "eyJzaWduYWxfY291bnQiOjE1Nn0="
}
```
# Health Check
Source: https://docs.gildea.ai/api-reference/health/check
GET /v1/health
Returns service status and API version
No authentication required.
```bash cURL theme={null}
curl "https://api.gildea.ai/v1/health"
```
```json 200 theme={null}
{
"status": "ok",
"version": "0.1.0"
}
```
# Search
Source: https://docs.gildea.ai/api-reference/search/search
GET /v1/search
Search Gildea's verified text units. Two modes, text query (`q`) or similarity to a known unit (`similar_to`).
For how retrieval works under the hood (dense + sparse + RRF + cross-encoder rerank), see [How search works](/concepts/search).
Free-text search query. Required unless `similar_to` is provided.
A text unit ID (e.g. a `unit.id` from a `q` search; the two chain naturally). Returns the units most similar in meaning, useful for cross-source corroboration and "find more like this." Required unless `q` is provided (exactly one of `q` / `similar_to`).
Similarity is *topical*, not *agreement*: results are ranked by `relevance_score` and decay from genuine corroboration into adjacent topics, and can even include a contradicting unit. To use it for corroboration, keep the high-scoring hits, check `citation.domain` for source independence, and read `unit.text` to confirm they actually say the same thing. It's a similarity signal, not a consensus verdict.
Filter by unit role: `thesis` / `synopsis` (the central statement of an analysis / event), `argument` (a supporting analysis sentence), or `claim` (an atomic fact).
Entity public ID (e.g. `gld:/a1b2c3d4e5f6`) or exact display name. Returns only units whose text literally contains a known surface form of the entity, for high-precision entity attribution. Pass the public ID (from any `entity_id` field, or via [`GET /v1/entities`](/api-reference/entities/list)) for guaranteed precision; a name resolves to its family-level canonical entity. An unknown entity returns `404` (not an empty list).
Theme label (one of 12; see [Themes](/concepts/themes)). Returns units from articles tagged with that theme. An unknown label returns `404`, not an empty list.
Filter by `content_type` (source kind): `analysis` (expert interpretation, a source's argued position) or `event` (a factual report of what happened). This is the opinion-vs-fact axis, orthogonal to `role`: because `role=claim` returns claims from both kinds, pair `content_type=analysis` with `role=claim` for verified claims from expert analysis only.
ISO 8601 date. Only return results from articles published after this date.
ISO 8601 date. Only return results from articles published before this date.
Recency weight from 0 to 1. `0` ignores publication date; `1` maximally favors newer signals. Soft preference; does not exclude older results.
Maximum units per source article in the returned set (1-100). Default 2 enforces source diversity; raise (e.g. 20) when a single in-depth article should be allowed to contribute more units.
Max results to return (1-100). Raise when doing strategic / deep retrieval; the retrieval pool scales accordingly.
Ranked search results.
The matched verified unit, the same object shape returned by signal detail.
Unit identifier (stable; the same unit returns the same `id` from signal detail).
`thesis` · `synopsis` · `argument` · `claim`. Use `GET /v1/signals/{citation.signal_id}` for the unit in its full context.
The verified text content.
Public IDs of entities named in this unit.
Present only when human-reviewed: `{ "human_reviewed": true }`. Omitted otherwise; every returned unit already passed verification, and the baseline trust signal is the cited evidence, not this flag.
Verbatim evidence `snippets` (each with `text` + `truncated`). Each snippet is a short (\~100-character) locator into the source, not the full passage: proof the unit is grounded, and the span to find if you re-verify. Follow `citation.url` for the full source.
Source signal attribution.
Parent signal identifier.
Signal headline.
Original source URL.
Source domain.
Publication timestamp (ISO 8601).
Per-result relevance score (higher = more relevant). Results are ranked by it with no fixed floor, so let the score decide how many to use rather than assuming every result up to `limit` is equally relevant.
The search query (when using `q`).
The source unit ID (when using `similar_to`).
```bash cURL theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/search?q=AI%20chip%20supply%20chain&limit=5"
```
```python Python theme={null}
import requests
resp = requests.get(
"https://api.gildea.ai/v1/search",
headers={"X-API-Key": "gld_your_key"},
params={"q": "AI chip supply chain", "limit": 5},
)
results = resp.json()
```
```javascript JavaScript theme={null}
const resp = await fetch(
"https://api.gildea.ai/v1/search?q=AI+chip+supply+chain&limit=5",
{ headers: { "X-API-Key": "gld_your_key" } }
);
const results = await resp.json();
```
```bash "Similar to" (cURL) theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/search?similar_to=0004c6d0e2f1a3b5c7d9e1f3a5b7c9d1e3f5a7b9&limit=5"
```
```json 200 theme={null}
{
"results": [
{
"unit": {
"id": "0004c6d0e2f1a3b5c7d9e1f3a5b7c9d1e3f5a7b9",
"role": "claim",
"text": "NVIDIA increased H200 shipments by 40% quarter-over-quarter as supply constraints eased.",
"evidence": {
"snippets": [
{ "text": "NVIDIA shipped over 400,000 H200 units in Q4, a 40% increase from the prior quarter…", "truncated": true }
]
}
},
"citation": {
"signal_id": "0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
"title": "NVIDIA Q4 2025 Supply Chain Analysis",
"url": "https://reuters.com/nvidia-supply-chain",
"domain": "reuters.com",
"published_at": "2026-03-15T00:00:00+00:00"
},
"relevance_score": 0.8235
}
],
"query": "AI chip supply chain"
}
```
# Get Signal
Source: https://docs.gildea.ai/api-reference/signals/get
GET /v1/signals/{signal_id}
Retrieve a signal's full flat list of verified units
Unique signal identifier (e.g., `0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7`).
`title`, `url`, and `published_at` always describe the full source. The `units` below may reflect only a segment of that source (e.g., a five-minute exchange in a two-hour podcast). See [Signal scope vs. source scope](/concepts/signals#signal-scope).
Unique signal identifier.
Source title. Describes the full source, not necessarily the extracted segment.
Source URL. Links to the full source.
ISO 8601 publication date of the full source.
`analysis` or `event`.
Source registrable domain (e.g. `reuters.com`).
Number of verified units; equals the length of `units`. The honest depth signal; use it, not statement length, to gauge analytical depth.
Themes with `value_chain` and `market_force` arrays.
Entities mentioned in this signal (`entity_id`, `name`, `type`).
Flat list of verified units, grouped by role (central statement → arguments → claims) in document order. **List position is the order**; there is no separate index field.
Unique unit identifier (stable; the same unit returns the same `id` from search).
`thesis` (analysis statement) · `synopsis` (event statement) · `argument` (supporting analysis sentence) · `claim` (atomic fact).
The verified text content.
Present only on `role=argument`. Group the units sharing this label, in list order, to reconstruct one argument as a paragraph.
Public IDs (`gld:/…`) of entities named in this unit.
Present only when a human reviewer signed off: `{ "human_reviewed": true }`. Omitted otherwise; baseline trust is the cited evidence.
Verbatim evidence `snippets` (each with `text` + `truncated`), returned by default.
```bash cURL theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/signals/0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7"
```
```python Python theme={null}
import requests
signal = requests.get(
"https://api.gildea.ai/v1/signals/0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
headers={"X-API-Key": "gld_your_key"},
).json()
```
```javascript JavaScript theme={null}
const resp = await fetch(
"https://api.gildea.ai/v1/signals/0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
{ headers: { "X-API-Key": "gld_your_key" } }
);
const signal = await resp.json();
```
```json 200 Analysis signal theme={null}
{
"signal_id": "0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
"title": "NVIDIA H200 Shipments Surge as Supply Eases",
"url": "https://reuters.com/article",
"published_at": "2026-01-15T10:00:00Z",
"content_type": "analysis",
"domain": "reuters.com",
"verified_unit_count": 3,
"themes": {
"value_chain": ["Infrastructure"],
"market_force": ["Competitive Dynamics"]
},
"entities": [
{ "entity_id": "gld:/a1b2c3d4e5f6", "name": "NVIDIA", "type": "organization" }
],
"units": [
{
"id": "0005a1b2c3d4e5f60718293a4b5c6d7e8f9a0b1c",
"role": "thesis",
"text": "NVIDIA's H200 shipments increased significantly in Q4 as supply constraints eased.",
"verification": { "human_reviewed": true },
"evidence": {
"snippets": [
{ "text": "NVIDIA shipped over 400,000 H200 units in Q4, a 40% increase from…", "truncated": true }
]
}
},
{
"id": "0005d4e5f607182939a4b5c6d7e8f9a0b1c2d3e4",
"role": "argument",
"text": "Supply chain bottlenecks eased following TSMC capacity expansion.",
"argument_id": "a1",
"evidence": {
"snippets": [{ "text": "TSMC brought new CoWoS capacity online in late Q3…", "truncated": true }]
}
},
{
"id": "0004c6d0e2f1a3b5c7d9e1f3a5b7c9d1e3f5a7b9",
"role": "claim",
"text": "NVIDIA increased H200 shipments by 40% quarter-over-quarter.",
"evidence": {
"snippets": [{ "text": "…a 40% increase from the prior quarter.", "truncated": false }]
}
}
]
}
```
```json 200 Event signal theme={null}
{
"signal_id": "0001ace1234567890abcdef0123456789abcdef0",
"title": "EU Reaches Political Agreement on AI Act Implementation",
"url": "https://reuters.com/eu-ai-act",
"published_at": "2026-01-20T14:00:00Z",
"content_type": "event",
"domain": "reuters.com",
"verified_unit_count": 2,
"themes": {
"value_chain": ["Applications"],
"market_force": ["Regulatory & Legal"]
},
"entities": [
{ "entity_id": "gld:/7c4e1a90b2d3", "name": "EU AI Act", "type": "regulation_policy" }
],
"units": [
{
"id": "00057a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f",
"role": "synopsis",
"text": "The European Union reached a political agreement on implementing the AI Act.",
"evidence": {
"snippets": [{ "text": "EU member states reached agreement on the AI Act's implementation timeline…", "truncated": true }]
}
},
{
"id": "0004fed987654321ba9876543210fedcba987654",
"role": "claim",
"text": "General-purpose AI models must meet transparency requirements by August 2026.",
"evidence": {
"snippets": [{ "text": "…transparency obligations take effect in August 2026.", "truncated": false }]
}
}
]
}
```
```json 404 theme={null}
{
"error": {
"code": "not_found",
"message": "Signal 'sig_nonexistent' not found",
"status": 404
}
}
```
# List Signals
Source: https://docs.gildea.ai/api-reference/signals/list
GET /v1/signals
Retrieve a paginated list of signals. Without filters, returns the most recent signals.
Each result is a lightweight **card** (identity + the central statement). For a signal's full
verified decomposition (the flat `units[]` with evidence), call
[**Get signal**](/api-reference/signals/get) with the `signal_id`.
# Get Theme
Source: https://docs.gildea.ai/api-reference/themes/get
GET /v1/themes/{axis}/{label}
Retrieve a single theme with trend stats and co-occurring themes
Theme axis: `value_chain` or `market_force`.
Theme label (e.g., `Foundation Models`).
`value_chain` or `market_force`.
Theme name.
Total signals tagged with this theme.
Trend analytics.
Theme's share of total corpus over the trailing 4 weeks.
Consecutive weeks of growth.
Signal count this week.
Signal count last week.
`Rising`, `Stable`, or `Declining`.
`Significant` or `Insignificant`.
`Volatile` or `Steady`.
`High`, `Medium`, `Low`, or `Negligible`. How much this theme warrants attention right now.
Explanation of the notability assignment.
Co-occurring themes from both axes.
Axis of the related theme.
Theme name.
Number of signals both themes appear in.
```bash cURL theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/themes/value_chain/Foundation%20Models"
```
```python Python theme={null}
import requests
theme = requests.get(
"https://api.gildea.ai/v1/themes/value_chain/Foundation Models",
headers={"X-API-Key": "gld_your_key"},
).json()
```
```javascript JavaScript theme={null}
const resp = await fetch(
"https://api.gildea.ai/v1/themes/value_chain/Foundation%20Models",
{ headers: { "X-API-Key": "gld_your_key" } }
);
const theme = await resp.json();
```
```json 200 theme={null}
{
"axis": "value_chain",
"label": "Foundation Models",
"signal_count": 245,
"trend": {
"share_of_voice": 0.22,
"streak": 3,
"current_week": 28,
"prior_week": 24
},
"direction": "Rising",
"confidence": "Significant",
"stability": "Steady",
"notability": "High",
"notability_reasoning": "Theme with confirmed upward trend and consistent coverage; notable upward shift reliably gaining traction.",
"related_themes": [
{
"axis": "market_force",
"label": "Competitive Dynamics",
"co_occurrence_count": 132
},
{
"axis": "market_force",
"label": "Capital & Investment",
"co_occurrence_count": 87
},
{
"axis": "value_chain",
"label": "Infrastructure",
"co_occurrence_count": 76
}
]
}
```
```json 404 theme={null}
{
"error": {
"code": "not_found",
"message": "Theme 'value_chain/nonexistent' not found",
"status": 404
}
}
```
# List Themes
Source: https://docs.gildea.ai/api-reference/themes/list
GET /v1/themes
Retrieve all themes with signal counts and trend stats
Filter by axis: `value_chain` or `market_force`.
List of theme objects.
`value_chain` or `market_force`.
Theme name (e.g., `Foundation Models`).
Total signals tagged with this theme.
Trend analytics including `share_of_voice`, `streak`, `current_week`, and `prior_week`.
`Rising`, `Stable`, or `Declining`.
`Significant` or `Insignificant`.
`Volatile` or `Steady`.
`High`, `Medium`, `Low`, or `Negligible`. How much this theme warrants attention right now.
Explanation of the notability assignment.
```bash cURL theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/themes?axis=value_chain"
```
```python Python theme={null}
import requests
resp = requests.get(
"https://api.gildea.ai/v1/themes",
headers={"X-API-Key": "gld_your_key"},
params={"axis": "value_chain"},
)
themes = resp.json()
```
```javascript JavaScript theme={null}
const resp = await fetch(
"https://api.gildea.ai/v1/themes?axis=value_chain",
{ headers: { "X-API-Key": "gld_your_key" } }
);
const themes = await resp.json();
```
```json 200 theme={null}
{
"themes": [
{
"axis": "value_chain",
"label": "Foundation Models",
"signal_count": 245,
"trend": {
"share_of_voice": 0.22,
"streak": 3,
"current_week": 28,
"prior_week": 24
},
"direction": "Rising",
"confidence": "Significant",
"stability": "Steady",
"notability": "High",
"notability_reasoning": "Theme with confirmed upward trend and consistent coverage; notable upward shift reliably gaining traction."
},
{
"axis": "value_chain",
"label": "Infrastructure",
"signal_count": 198,
"trend": {
"share_of_voice": 0.18,
"streak": 2,
"current_week": 22,
"prior_week": 20
},
"direction": "Rising",
"confidence": "Significant",
"stability": "Steady",
"notability": "High",
"notability_reasoning": "Theme with confirmed upward trend and consistent coverage; notable upward shift reliably gaining traction."
}
]
}
```
# Signal-to-noise
Source: https://docs.gildea.ai/concepts/context-engineering
Your agent runs on a finite attention budget, so we spend it well
Frontier models can now *see* millions of tokens, but they still can't reliably *reason* across them. The million-token window is a marketing stat; the effective window is the reality, and it's far smaller.
Beyond a few thousand tokens, a model succumbs to [**context rot**](https://www.trychroma.com/research/context-rot): recall and reasoning degrade even when every fact the model needs is present. Fill your context window with raw web text and you don't empower your agent, you drown it in noise. The impact shows up in two ways:
* **Positional neglect.** Evidence is ignored for where it sits, not whether it's there.
* **Synthesis collapse.** The model can't connect facts scattered across the context, even when every one is present.
## Maximize signal, minimize noise
According to [Anthropic](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents), the fix is better context engineering, where the goal is finding *the smallest possible set of high-signal tokens that maximize the likelihood of some desired outcome*. Every design choice Gildea has made serves that goal:
* **Curated at the source.** The cost of generating text has fallen to zero, and the open web is filling with AI slop. Gildea ingests only high-signal sources, so your agent never builds on confidently wrong source material.
* **Decomposed to atoms.** Each source is broken into individual [units](/concepts/signals): a thesis sentence, an argument line, an atomic claim. Your agent pulls the three facts it needs, not the document they were buried in.
* **Spine, not transcript.** We keep only the strategically relevant segment of a source and discard the rest. A two-hour podcast becomes the five minutes worth keeping.
* **Verified before it ships.** Every unit cleared [verification](/concepts/verification) against its source, so the agent can reason over the context instead of adjudicating it.
* **Queryable, so the agent scopes itself.** [Search](/concepts/search) with entity and theme filters lets an agent retrieve only the units that bear on its question, instead of loading a corpus and hoping.
The result is the input reasoning agents are actually starved for: every signal structured, verified, and cited, and nothing in the window that isn't earning its place.
Follow a source through decomposition into the verified atoms your agent queries.
# Entities
Source: https://docs.gildea.ai/concepts/entities
8 entity types with trend analytics and disambiguation
Entities are named things extracted from signals and resolved to canonical identities. Gildea classifies entities into 8 types across the AI ecosystem:
| Type | Examples |
| ------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `organization` | NVIDIA, Anthropic, OpenAI |
| `person` | Sam Altman, Dario Amodei, Jensen Huang |
| `model` | GPT-5, Claude Opus 4.7, Llama 4 |
| `hardware` | H100, A100, TPU v5e |
| `location` | Countries, regions, cities |
| `event` | Conferences, product launches |
| `regulation_policy` | EU AI Act, Executive Order 14110 |
| `other` | Everything else: products, software, frameworks, datasets, benchmarks, publications, and named technical concepts |
Use `type` as the authoritative type. The `other` bucket is a deliberate catch-all: entities that aren't one of the seven specific types live here rather than in a long tail of sparsely-populated categories. To find a specific product or framework, search by name rather than filtering on type.
This means you can track not just which companies are trending, but which models, hardware, and regulations are gaining attention.
## Entity extraction and disambiguation
Gildea uses a two-pass entity extraction system to ensure accurate identification:
```mermaid theme={null}
graph TD
S[Signal text] --> P1[Entity extraction]
P1 --> M[Raw mentions]
M --> P2[Domain-specific disambiguation]
P2 --> R[Resolved mentions]
R --> C[Canonical identity]
C --> DB[(Entity store)]
style S fill:#000,color:#fff,stroke:#333
style P1 fill:#1a1a1a,color:#fff,stroke:#444
style M fill:#2a2a2a,color:#fff,stroke:#555
style P2 fill:#1a1a1a,color:#fff,stroke:#444
style R fill:#2a2a2a,color:#fff,stroke:#555
style C fill:#1a1a1a,color:#fff,stroke:#444
style DB fill:#000,color:#fff,stroke:#333
```
### Pass 1: Entity extraction
Signals are processed to extract entity mentions with knowledge-graph linking, type classification, and salience scoring.
### Pass 2: Domain-specific disambiguation
A curated rule set disambiguates AI-specific entities that general NLP models struggle with:
* **Model families**: "Claude Opus 4.7", "GPT-5", "Llama 4" resolve to specific model entries, not generic company mentions
* **Hardware**: "H100", "A100", "TPU v5e" resolve to specific chips
* **Contextual disambiguation**: "Claude" + context mentioning "sonnet" resolves to the model, not a person
### Entity identifiers
Every entity has a stable, opaque public ID of the form `gld:/` (e.g., `gld:/a1b2c3d4e5f6`). It is the only entity identifier the API exposes: it appears in every `entity_id` field, and you pass it to `GET /v1/entities/{name_or_id}` or any `entity` filter. The ID stays the same over time, even if the entity's classification is later corrected.
Behind the scenes, "Meta", "Meta Platforms", and "Facebook" all resolve to the same entity, and therefore the same ID.
### Noise filtering
Generic concepts ("AI", "market", "industry") are excluded and corporate suffixes ("Inc", "LLC", "Corp") are normalized so "NVIDIA Corporation" and "NVIDIA" resolve to the same entity.
## Entity profiles
Each entity has a rich profile including:
* **Signal count**: total signals mentioning this entity
* **Trend stats**: share of voice, weekly counts, growth streak, source diversity
* **Content type mix**: breakdown of expert analysis vs. event signals
* **Theme distributions**: which value chain segments and market forces this entity appears in
* **Related entities**: co-occurrence relationships
## Trend analytics
Every entity includes a `trend` object:
| Field | Description |
| ------------------ | -------------------------------------------------------- |
| `share_of_voice` | Entity's share of total corpus over the trailing 4 weeks |
| `streak` | Consecutive weeks of growth |
| `current_week` | Signal count this week |
| `prior_week` | Signal count last week |
| `source_diversity` | Count of distinct source domains |
The discrete interpretation labels below (`direction`, `confidence`, `stability`, `notability`) are derived from the underlying statistics so you can act on them without doing the statistics yourself.
## Interpretation fields
Each entity includes interpretation fields derived from the raw trend stats. These are discrete labels that agents can act on without statistical expertise.
| Field | Values | What it tells you |
| ---------------------- | -------------------------------------- | ---------------------------------------------------------------------------- |
| `scale` | `Large`, `Medium`, `Small` | How prominent is this entity relative to the corpus |
| `direction` | `Rising`, `Stable`, `Declining`, `New` | Which way is coverage trending |
| `confidence` | `Significant`, `Insignificant` | Is the trend statistically reliable |
| `stability` | `Volatile`, `Steady` | How consistent is coverage week to week |
| `notability` | `High`, `Medium`, `Low`, `Negligible` | How much this entity warrants attention right now: foreground vs. background |
| `notability_reasoning` | Free text | Human-readable explanation of the notability assignment |
The interpretation labels are computed over a rolling 12-week window: the current week plus 11 prior weeks. Entities with fewer than 8 mentions in that window return `scale` only; `direction`, `confidence`, `stability`, and `notability` will be `null`. The `notability_reasoning` field will contain "Insufficient data for trend analysis."
An entity whose `first_seen` date is within the last 30 days is classified as `direction: "New"` regardless of its underlying slope; this overrides the `Rising`/`Stable`/`Declining` classification until enough history accumulates. `confidence` is forced to `Insignificant` and `stability` is `null` for new entities. As a result, filtering `?direction=Rising` will not surface genuine breakouts younger than 30 days; use `?direction=New` to find recent arrivals.
```json theme={null}
{
"entity_id": "gld:/a1b2c3d4e5f6",
"name": "NVIDIA",
"scale": "Large",
"direction": "Rising",
"confidence": "Significant",
"stability": "Steady",
"notability": "High",
"notability_reasoning": "Large-scale entity with confirmed upward trend and consistent coverage; notable upward shift reliably gaining share.",
"trend": { "..." : "..." }
}
```
## Entity matching is literal
Entity filters and attribution match at the **unit** level, not the article level: a result is a unit whose own text names the entity, not just any unit from an article that mentions it elsewhere.
* **`GET /v1/signals/{id}`**: each unit in `units[]` carries an `entities` array of the public entity IDs (`gld:/…`) named in that unit's text.
* **`GET /v1/search?entity=`**: returns only units whose text actually contains the entity, not every unit from an article that happens to mention it.
A few consequences worth knowing:
* **High precision.** A result for `?entity=gld:/a1b2c3d4e5f6` literally names that entity.
* **No coreference resolution.** A unit that refers to an entity only by pronoun or description ("the company shipped a 200K-context model") won't match an entity filter, even when the referent is obvious from context.
* **Article-level counts.** Trend and co-occurrence statistics count at the article level: an entity mentioned several times in one article counts once.
## Composable filtering
The list endpoint filters by any combination of interpretation fields, so you can express precise discovery queries:
| Filter | Finds |
| --------------------------------------------- | ---------------------------------------- |
| `direction=Rising` + `confidence=Significant` | Entities reliably trending up |
| `direction=New` + `sort=first_seen` | Recently tracked entities |
| `stability=Volatile` + `sort=trend` | Entities with the most variable coverage |
Combine freely: `?direction=Rising&scale=Large&sort=trend` finds high-prominence entities with upward trends.
## Co-occurrences
The entity detail endpoint includes `related_entities`: entities that frequently appear together in signals. This reveals industry relationships, competitive dynamics, and supply chain connections.
```json theme={null}
{
"related_entities": [
{
"entity_id": "gld:/b2c3d4e5f6a7",
"name": "TSMC",
"type": "organization",
"co_occurrence_count": 28
}
]
}
```
# Search
Source: https://docs.gildea.ai/concepts/search
How Gildea search retrieves and ranks verified text units
`GET /v1/search` retrieves the most relevant verified text units for a query. It is hybrid: it matches on meaning (paraphrases and related concepts) and on keywords (exact terms and close variants), then ranks the results for relevance. One query in, one ranked, source-attributed list out.
Because every returned unit has already passed [verification](/concepts/verification), the results are trusted content: an LLM can reason over `unit.text` without re-checking it against the source.
## How filters scope results
`theme`, `content_type`, and the date filters (`published_after` / `published_before`) are applied before ranking, so no relevance is wasted on candidates that would be filtered out later.
The `entity` filter is **precise**: it returns only units whose text literally names the entity, matching its known surface forms. A unit about NVIDIA inside an article that also mentions Anthropic won't surface under `?entity=`. **Coreference is not resolved**: a unit that refers to an entity only by pronoun or description ("the company shipped a 200K-context model") won't match the entity filter, even when the referent is obvious from context.
## What it's optimized for
* **Short, fact-dense units.** Every unit is sentence-level, so you get compact, citable atomic facts, not raw document chunks.
* **Precision at the top.** Results are ordered to surface the most relevant units first.
* **No hallucination surface.** Every returned unit has passed verification, so consumers can treat `unit.text` as trusted without re-checking the source.
* **Predictable depth.** Raising `limit` (up to 100) genuinely widens the candidate pool rather than truncating to the same small set.
## When to use which mode
| Goal | Approach |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| Find a specific factual answer | `/v1/search?q=...` with `limit=10`. |
| Strategic synthesis (broad coverage) | `/v1/search?q=...&limit=50`; raise `diversity_cap` if one in-depth article should contribute more units. |
| Find units similar to a known unit | `/v1/search?similar_to=` for cross-source corroboration. |
| Time-scoped retrieval | `published_after` / `published_before` for precise windows; `recency_boost` for a soft preference toward newer content. |
## Reading a result
Each result is a verified `unit` plus its `citation`. Three fields do three different jobs:
* **`unit.text`** is the verified claim. Cite it and reason over it directly; it has already passed verification, so there is no need to re-check it against the source.
* **`evidence.snippets`** are a short (\~100-character) locator into the source, not the full passage. They let an agent confirm a unit is grounded; the full passage lives at `citation.url`.
* **`citation.url`** is the audit path: follow it to the original source to re-verify.
Results are ranked by `relevance_score` (higher = more relevant), with no fixed floor: the list always fills to `limit`, so the lower-ranked tail of a narrow query can taper into weaker matches. Let the score, not `limit`, decide how many results to use.
See [`GET /v1/search`](/api-reference/search/search) for the full parameter list and response shape.
`/v1/search` is a retrieval primitive: one query in, one ranked list out. Richer workflows come from composing several calls, most naturally orchestrated by an agent. The [Recipes](/guides/search) walk through those patterns.
# Signals
Source: https://docs.gildea.ai/concepts/signals
Events and expert analysis, decomposed into verified text units
A **signal** is a structured takeaway drawn from the most strategically relevant parts of a source. It may be a whole short article, a five-minute exchange from a two-hour podcast, or a single section of an SEC filing. Gildea processes signals daily, prioritizing what materially changes the strategic picture.
## Signal scope
The `title`, `url`, and `published_at` fields point to the full source, but the decomposition (central statement, arguments, and claims) reflects only the extracted segment. So when a podcast signal's statement reads narrowly, that is expected: treat the decomposition as authoritative for what the signal covers, and the source metadata as a pointer to where it came from.
## What gets ingested
Gildea ingests from a curated set of 500+ sources across these formats:
| Format | Examples |
| ------------------------ | ---------------------------------------------------- |
| **Essays** | Blog posts, newsletters, long-form analysis |
| **News articles** | Industry reporting, first-party announcements |
| **Podcasts** | Transcribed and decomposed |
| **SEC filings** | 10-Ks, 10-Qs, 8-Ks, proxy statements |
| **Research papers** | Academic and industry research |
| **Social media** | Expert discourse and announcements |
| **Earnings transcripts** | Quarterly earnings calls |
| **Press releases** | Product launches, partnerships, policy announcements |
## Two types of signals
Every signal is classified by `content_type` into one of two kinds:
### Event signals (`content_type: "event"`)
Key events sourced from global reporting and first-party announcements.
| Role | Description |
| ---------- | ---------------------------------------------------------------------------- |
| `synopsis` | The central factual recap of what happened, as individual verified sentences |
| `claim` | Specific factual assertions extracted from the source |
### Expert analysis signals (`content_type: "analysis"`)
Expert analysis from leading researchers, operators, investors, and analysts who explain what the events mean.
| Role | Description |
| ---------- | ------------------------------------------------------------------------------------- |
| `thesis` | The author's central argued position, as individual verified sentences |
| `argument` | Supporting reasoning lines; group by `argument_id` to reconstruct each as a paragraph |
| `claim` | Specific verifiable facts extracted from the article |
## The unit model
Signal detail is a flat list of verified **units**, the fundamental atom of Gildea's data model. Every unit shares one shape, whether it comes back from signal detail or from [search](/concepts/search):
```json theme={null}
{
"id": "0004c6d0e2f1",
"role": "claim",
"text": "Roughly a third of the Fortune 500 run production AI.",
"entities": ["gld:/e52b6fd2c6e6"],
"evidence": { "snippets": [{ "text": "…30% of the Fortune 500…", "truncated": true }] }
}
```
`role` is the single axis that says what a unit is:
| `role` | Appears in | Meaning |
| ---------- | ---------- | ------------------------------------------------------ |
| `thesis` | analysis | a sentence of the author's central argued position |
| `synopsis` | events | a sentence of the central factual recap |
| `argument` | analysis | a supporting-argument sentence (carries `argument_id`) |
| `claim` | both | an atomic verifiable fact |
Reconstruct prose by role: concatenate the `thesis` (or `synopsis`) units in order for the central statement; group `argument` units by `argument_id`, in order, to rebuild each argument as a paragraph. Units come back grouped by role (thesis/synopsis → arguments → claims) in document order. **List position is the order**; there is no separate index field.
Every unit:
* Has **passed verification**: only verified units are served (see [Verification](/concepts/verification)).
* Carries its cited **`evidence`** snippets by default.
* May carry `verification: { "human_reviewed": true }` when a human reviewer signed off (omitted otherwise).
* Is retrievable through semantic search (see [Search](/concepts/search)).
## Decomposition structure
### Expert analysis signals
```mermaid theme={null}
graph TD
S["Signal · units[]"] --> T["role: thesis"]
S --> A["role: argument · grouped by argument_id"]
S --> C["role: claim"]
T -.- V[all verified · evidence by default]
A -.- V
C -.- V
style S fill:#000,color:#fff,stroke:#333
style T fill:#1a1a1a,color:#fff,stroke:#444
style A fill:#1a1a1a,color:#fff,stroke:#444
style C fill:#1a1a1a,color:#fff,stroke:#444
style V fill:none,stroke:none,color:#666,font-size:11px
```
### Event signals
```mermaid theme={null}
graph TD
S["Signal · units[]"] --> Su["role: synopsis"]
S --> C["role: claim"]
Su -.- V[all verified · evidence by default]
C -.- V
style S fill:#000,color:#fff,stroke:#333
style Su fill:#1a1a1a,color:#fff,stroke:#444
style C fill:#1a1a1a,color:#fff,stroke:#444
style V fill:none,stroke:none,color:#666,font-size:11px
```
## Signal card vs. signal detail
The **list endpoint** returns lightweight signal cards: identity, classification, a depth signal (`verified_unit_count`), and the central statement served whole: a `thesis` field on analysis signals, a `synopsis` field on event signals.
The **detail endpoint** returns the full flat `units[]`: every verified unit with its evidence (included by default). Concatenating the `thesis`/`synopsis` units reproduces the card's statement, so the two never disagree. Pull cards from the list endpoint for discovery; fetch detail when you need the verified atoms.
# Themes
Source: https://docs.gildea.ai/concepts/themes
Two-axis theme system with trend analytics for value chain segments and market forces
Gildea classifies every signal into a two-axis theme system. Signals can have multiple themes per axis.
```mermaid theme={null}
graph LR
S[Every signal] --> VC[Value Chain]
S --> MF[Market Force]
VC --> I[Infrastructure]
VC --> FM[Foundation Models]
VC --> O[Orchestration]
VC --> DL[Data & Labeling]
VC --> A[Applications]
VC --> D[Distribution]
MF --> CI[Capital & Investment]
MF --> RL[Regulatory & Legal]
MF --> CD[Competitive Dynamics]
MF --> TL[Talent & Labor]
MF --> GS[Geopolitical Strategy]
MF --> TS[Trust & Societal Impact]
style S fill:#000,color:#fff,stroke:#333
style VC fill:#1a1a1a,color:#fff,stroke:#444
style MF fill:#1a1a1a,color:#fff,stroke:#444
style I fill:#2a2a2a,color:#fff,stroke:#555
style FM fill:#2a2a2a,color:#fff,stroke:#555
style O fill:#2a2a2a,color:#fff,stroke:#555
style DL fill:#2a2a2a,color:#fff,stroke:#555
style A fill:#2a2a2a,color:#fff,stroke:#555
style D fill:#2a2a2a,color:#fff,stroke:#555
style CI fill:#2a2a2a,color:#fff,stroke:#555
style RL fill:#2a2a2a,color:#fff,stroke:#555
style CD fill:#2a2a2a,color:#fff,stroke:#555
style TL fill:#2a2a2a,color:#fff,stroke:#555
style GS fill:#2a2a2a,color:#fff,stroke:#555
style TS fill:#2a2a2a,color:#fff,stroke:#555
```
## Value chain (`value_chain`)
Where in the AI value chain does this signal sit?
| Theme | Description |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Infrastructure** | The compute layer: GPUs, TPUs, custom chips, and cloud infrastructure that make large-scale model training and inference possible. |
| **Foundation Models** | The core models that define capability: trained systems like GPT, Claude, Gemini, and Llama that serve as the base for downstream products. |
| **Orchestration** | The software layer that makes models usable: frameworks, agents, vector stores, and developer tools for building and managing model-powered systems. |
| **Data & Labeling** | The data layer: how models are trained, evaluated, and refined, from raw datasets to synthetic data and human feedback loops. |
| **Applications** | The product layer: AI features and experiences built for real users, from enterprise copilots to consumer agents. |
| **Distribution** | The delivery layer: how AI capabilities reach users, through APIs, platforms, partnerships, and ecosystems. |
## Market force (`market_force`)
What external pressure or catalyst is shaping the value chain?
| Theme | Description |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **Capital & Investment** | Tracks the allocation of financial resources: who's funding whom, how capital moves across stages, and how valuations shape incentives. |
| **Regulatory & Legal** | Tracks how rules, policies, and court decisions set the boundaries for innovation and competition. |
| **Competitive Dynamics** | Examines how firms position themselves (via product strategy, data moats, or market timing) to gain or defend share. |
| **Talent & Labor** | Follows the human factor: hiring trends, executive shifts, skill shortages, and how automation reshapes work. |
| **Geopolitical Strategy** | Analyzes the interplay between national interests, technology policy, and access to compute and talent. |
| **Trust & Societal Impact** | Captures public sentiment, safety debates, and the ethics shaping adoption and regulation. |
## Interpretation fields
Each theme includes interpretation fields derived from the raw trend stats. These are discrete labels that agents can act on without statistical expertise.
| Field | Values | What it tells you |
| ---------------------- | ------------------------------------- | --------------------------------------------------------------------------- |
| `direction` | `Rising`, `Stable`, `Declining` | Which way is this theme trending |
| `confidence` | `Significant`, `Insignificant` | Is the trend statistically reliable |
| `stability` | `Volatile`, `Steady` | How consistent is coverage week to week |
| `notability` | `High`, `Medium`, `Low`, `Negligible` | How much this theme warrants attention right now: foreground vs. background |
| `notability_reasoning` | Free text | Human-readable explanation of the notability assignment |
Themes do not have a `scale` field; all 12 themes are always active.
The interpretation labels are computed over a rolling 12-week window: the current week plus 11 prior weeks.
```json theme={null}
{
"axis": "value_chain",
"label": "Foundation Models",
"direction": "Rising",
"confidence": "Significant",
"stability": "Steady",
"notability": "High",
"notability_reasoning": "Theme with confirmed upward trend and consistent coverage; notable upward shift reliably gaining traction.",
"trend": { "..." : "..." }
}
```
## Theme intelligence
Each theme has a rich profile including:
* **Signal count**: total signals tagged with this theme
* **Trend stats**: analytics across four dimensions (see below)
* **Related themes**: themes that frequently co-occur across both axes
## Trend analytics
Every theme includes a `trend` object:
| Field | Description |
| ---------------- | ------------------------------------------------------- |
| `share_of_voice` | Theme's share of total corpus over the trailing 4 weeks |
| `streak` | Consecutive weeks of growth |
| `current_week` | Signal count this week |
| `prior_week` | Signal count last week |
The discrete interpretation labels above (`direction`, `confidence`, `stability`, `notability`) are derived from the underlying statistics so you can act on them without doing the statistics yourself.
## Using themes as filters
Themes work as filters across the API. Use the exact theme labels above:
```bash theme={null}
# Signals about Infrastructure
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/signals?theme=Infrastructure"
# Entities in the Foundation Models space
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/entities?theme=Foundation%20Models"
# Search within a theme
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/search?q=chip+shortage&theme=Competitive%20Dynamics"
```
## Theme detail
The theme detail endpoint returns co-occurring themes from both axes:
```json theme={null}
{
"axis": "value_chain",
"label": "Foundation Models",
"signal_count": 45,
"trend": { "share_of_voice": 0.22, "streak": 3, "current_week": 28, "prior_week": 24 },
"related_themes": [
{
"axis": "market_force",
"label": "Capital & Investment",
"co_occurrence_count": 32
}
]
}
```
# Verification
Source: https://docs.gildea.ai/concepts/verification
If we can't prove it, we don't serve it
For decades, market intelligence sold trust through reputation. You trusted the report because you trusted the name on the cover.
That kind of trust doesn't survive the handoff to a machine. An agent doesn't buy a name; it only trusts what it can verify.
So that's what we built. Gildea follows the AI race as it happens and hands your agents structured intelligence with receipts attached. Every sentence we serve is grounded in its source and verified before it reaches you, giving you intelligence you can build on instead of read and forget.
Gildea is built for teams where one hallucinated claim blows up the deck, the deal, or the trade. We give teams agent speed without the loss of analyst-grade rigor.
## Grounding, then verification
Every unit Gildea serves pairs one claim or sentence with the evidence that backs it. Before that pair is served, two things must be true:
1. **Grounded.** The evidence appears word-for-word in the source.
* Evidence we can't match verbatim is treated as a hallucinated quote and discarded; the unit survives only if real, verbatim evidence backs it.
2. **Verified.** That pairing runs through a loop built to break the match between the text and the underlying evidence.
```mermaid theme={null}
graph TD
TU[Text unit] --> V[Verify: ground, score, run checks]
V --> Q{Clean pass?}
Q --> |Yes| Served[Served]
Q --> |Not yet| R[Repair: find better evidence,
then rewrite if needed]
R --> V
Q --> |Genuine judgment call| HR[Human review]
HR --> |Approve| Served
HR --> |Reject| Dropped[Dropped]
style TU fill:#000,color:#fff,stroke:#333
style V fill:#1a1a1a,color:#fff,stroke:#444
style R fill:#1a1a1a,color:#fff,stroke:#444
style Served fill:#1a3a1a,color:#fff,stroke:#2a5a2a
style HR fill:#3a3a1a,color:#fff,stroke:#5a5a2a
style Dropped fill:#3a1a1a,color:#fff,stroke:#5a2a2a
```
**1. Verify.** Each unit is scored against its evidence: claims to a strict entailment standard, sentences to a faithfulness standard. Then a battery of deterministic checks runs on every pair, regardless of score: contradictions, negation flips, quantity and date mismatches, misquotes, missing entities, and a bidirectional check that catches a claim or sentence quietly *overstating* what its evidence supports. These checks only ever downgrade a pass. They never talk a failure up. When in doubt, the unit doesn't pass.
**2. Repair.** A weak unit isn't dropped on the first try. The system hunts the source for better verbatim evidence and keeps it only if the score actually improves. If better evidence isn't enough, it rewrites the unit and runs it back through the *entire* loop. Repair before rejection.
**3. Triage.** What survives in the gray zone gets adjudicated by two model judges, blind. A unit is only cleared when they fully agree.
**4. Human review.** Only the genuine judgment calls reach a person, never the easy passes. Reviewers can override a verdict, correct the evidence and trigger a re-score, or fix a theme. Every override carries an audit trail.
The result is the contract that matters: **only `verdict=pass` data is served, and presence is the verdict.** If a unit is in the response, it earned its way there.
## Trust contract
What you get back is the verified part of a source, not all of it. The claims and sentences in a [signal](/concepts/signals) are the ones that cleared the loop; the rest were pruned. Read a signal as Gildea's verified view of a source, not a transcript of it.
Thesis and synopsis text is the exception: it's always served whole.
## What the API exposes
By default a unit carries **no** verification block at all. It doesn't need one: being served already means it passed. The block shows up in exactly one case, when a human reviewer signed off.
```json theme={null}
// human-reviewed unit (a flat entry in units[]):
{ "id": "…", "role": "claim", "text": "…", "verification": { "human_reviewed": true } }
// every other (auto-verified) unit: no verification key at all
{ "id": "…", "role": "claim", "text": "…" }
```
That's the whole contract. Raw scores, scoring modes, thresholds, and reason codes stay internal. They're the machinery used to decide pass or fail, not something you need to read. What you get instead is the part that lets you check the work yourself: every unit ships with its `evidence`, and every search result ships with a `citation`.
## Don't trust us. Verify us.
That `evidence` is a short verbatim quote from the source, roughly 100 characters. We keep it short out of respect for the author's work. Gildea points to the original; it doesn't reproduce it.
The evidence snippet acts as a pointer for agents that need more proof before trusting the verdict. Paired with its `citation`, it leads back to the full source, where an agent can confirm Gildea's verification for itself.
You don't have to take our verdict on faith. Check the verifier, then build on it.
Follow a unit's evidence and citation back to the source and confirm the verdict yourself.
# Authentication
Source: https://docs.gildea.ai/guides/authentication
API key setup and tier limits
All API endpoints (except `/v1/health`) require an API key passed in the `X-API-Key` header.
## Getting a key
Sign up at [gildea.ai](https://gildea.ai) to receive your API key. Keys are prefixed with `gld_`.
## Using your key
Include the key in every request:
```bash cURL theme={null}
curl -H "X-API-Key: gld_your_key_here" \
"https://api.gildea.ai/v1/signals?keyword=test"
```
```python Python theme={null}
import requests
headers = {"X-API-Key": "gld_your_key_here"}
resp = requests.get("https://api.gildea.ai/v1/signals", headers=headers, params={"keyword": "test"})
```
```javascript JavaScript theme={null}
const resp = await fetch("https://api.gildea.ai/v1/signals?keyword=test", {
headers: { "X-API-Key": "gld_your_key_here" }
});
```
## Tiers
Every tier has access to all endpoints, including hybrid search. Tiers differ only in
request volume.
| Tier | Rate limit | Monthly limit |
| -------- | ---------- | ---------------------- |
| **Free** | 20 req/min | 250/month |
| **Pro** | 60 req/min | 5,000/month |
| **Team** | Custom | Custom (contact sales) |
## Error responses
An invalid, revoked, or expired API key returns `401`:
```json theme={null}
{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key",
"status": 401
}
}
```
If the `X-API-Key` header is omitted entirely, the API returns `422` (missing required header). If the header is present but the key is invalid, the API returns `401`.
## Security
* Keys are hashed with SHA-256 before storage; we never store plaintext keys
* Need a key rotated or revoked? Contact us and we'll revoke it immediately
* All requests are logged for usage tracking
# Embed signals
Source: https://docs.gildea.ai/guides/embed
Vectorize verified units into the same space as your own data, queryable by one similarity metric.
**Embed** verified signals into the same vector space as your own data, so your agent can retrieve across both at once. Gildea serves the verified units; you embed the text with your own model and store the vectors next to your internal notes, docs, and past analyses. Now a single query reaches your private context and the verified market record together, with no second retrieval system to reconcile and no lock-in.
## The recipe
You pull the verified units for your territory, embed their text with your own embedder, and persist the vectors next to their provenance. Use the same model you embed your own documents with, so every vector is comparable and one nearest-neighbor search spans both.
Take the verified units for your territory (from [Search](/guides/search) or your context store), keeping each unit's `id` and `citation` as provenance.
Embed the unit text with your embedder (Cohere, OpenAI, Voyage, your choice). Use the *same* model everywhere, so every vector is comparable and search across your own data and Gildea's is meaningful.
Store each vector next to its `id` and `citation`, so you embed once and reuse across runs. This is the index you query alongside your own documents.
Install `gildea`, `cohere`, and `numpy`, set `GILDEA_API_KEY` and `COHERE_API_KEY`, then:
```python theme={null}
import os
import json
import numpy as np
import cohere
from gildea import Gildea
co = cohere.ClientV2(api_key=os.environ["COHERE_API_KEY"]) # your embedder
gildea = Gildea() # reads GILDEA_API_KEY
# 1. Pull the verified units for your territory; keep id + citation as provenance.
hits = gildea.search("NVIDIA data center moat durability competition", limit=30)["results"]
units = [{"id": h["unit"]["id"], "text": h["unit"]["text"], "citation": h["citation"]}
for h in hits]
# 2. Embed the unit text with your own model -- the SAME embedder you use for your
# own documents, so every vector is comparable in one shared space.
emb = co.embed(texts=[u["text"] for u in units], model="embed-english-v3.0",
input_type="search_document", embedding_types=["float"])
vectors = np.array(emb.embeddings.float_)
# 3. Persist vectors next to their metadata, so you embed once and reuse across runs.
with open("embeddings.jsonl", "w") as f:
for u, v in zip(units, vectors):
f.write(json.dumps({"id": u["id"], "citation": u["citation"], "vector": v.tolist()}) + "\n")
# Sanity check: nearest neighbors in your own store -- the similarity a query
# across your data and Gildea's would rank on.
def near(i, k=3):
cos = vectors @ vectors[i] / (np.linalg.norm(vectors, axis=1) * np.linalg.norm(vectors[i]))
return [j for j in cos.argsort()[::-1] if j != i][:k]
print(f"embedded {len(units)} units -> {vectors.shape[1]}-dim, persisted to embeddings.jsonl")
print("nearest to:", units[0]["text"][:60])
for j in near(0):
print(" ~", units[j]["text"][:60])
```
## What you get
A persisted vector for every verified unit, each carrying its `id` and `citation`, sitting in the same space as your own documents. One similarity search now spans your private context and Gildea's verified market record. You embed once with your own model and hold the vectors, so there's no lock-in and no second retrieval system to reconcile. Keep the set current with [Update](/guides/update).
# Errors
Source: https://docs.gildea.ai/guides/errors
Error codes and response format
All errors follow a consistent envelope format.
## Error response shape
```json theme={null}
{
"error": {
"code": "not_found",
"message": "Signal '0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7' not found",
"status": 404,
"request_id": "req_8f3a1c9e"
}
}
```
| Field | Type | Description |
| ------------- | ------- | ------------------------------------------------------------------------------------------------ |
| `code` | string | Machine-readable error code |
| `message` | string | Human-readable description |
| `status` | integer | HTTP status code |
| `request_id` | string | Correlation ID, also returned in the `X-Request-Id` header. Include it when reporting a failure. |
| `field` | string | Present on `422` errors: the parameter that failed validation. |
| `retry_after` | integer | Present on `429` and `503`: seconds to wait before retrying (also the `Retry-After` header). |
## Error codes
| Status | Code | Description |
| ------ | --------------------- | ---------------------------------------------------------------------------------------------- |
| 400 | `bad_request` | Invalid request parameters (some endpoints return a more specific code, e.g. `invalid_params`) |
| 401 | `unauthorized` | Invalid or missing API key |
| 403 | `forbidden` | Insufficient permissions |
| 404 | `not_found` | Resource not found |
| 409 | `conflict` | Resource already exists (e.g. duplicate API key) |
| 422 | `validation_error` | Request validation failed; `field` names the offending parameter |
| 429 | `rate_limit_exceeded` | Rate limit exceeded (check `Retry-After`) |
| 503 | `service_unavailable` | A dependency is temporarily unavailable; retry after `Retry-After` |
## Handling errors
```python Python SDK theme={null}
import time
from gildea import Gildea, RateLimitError, APIError
client = Gildea()
try:
client.signals.list(keyword="AI")
except RateLimitError as e:
time.sleep(e.retry_after or 60)
except APIError as e:
print(f"Error ({e.status}): {e}")
```
```python Python (requests) theme={null}
resp = requests.get(url, headers=headers)
if resp.status_code == 429:
retry_after = int(resp.headers.get("Retry-After", 60))
time.sleep(retry_after)
elif resp.status_code >= 400:
error = resp.json()["error"]
print(f"Error {error['code']}: {error['message']}")
```
```javascript JavaScript theme={null}
const resp = await fetch(url, { headers });
if (resp.status === 429) {
const retryAfter = parseInt(resp.headers.get("Retry-After") || "60");
await new Promise(r => setTimeout(r, retryAfter * 1000));
} else if (!resp.ok) {
const { error } = await resp.json();
console.error(`Error ${error.code}: ${error.message}`);
}
```
# MCP Server
Source: https://docs.gildea.ai/guides/mcp
Connect Gildea to Claude Code, Cursor, and other MCP clients
Gildea provides an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server so AI assistants can use Gildea's verified intelligence as a tool. We host it publicly at **`https://api.gildea.ai/mcp/`**.
It speaks the streamable-HTTP MCP transport and auths via the `x-api-key` header. Most clients let you paste these two values (URL + key) and you're done.
### Claude Code
```bash theme={null}
claude mcp add gildea --transport http https://api.gildea.ai/mcp/ --header "x-api-key: gld_your_key_here"
```
Verify with `claude mcp list`; you should see `gildea ✓ Connected` with 7 tools. To avoid hardcoding the key, use `--header "x-api-key: ${env:GILDEA_API_KEY}"`.
### Cursor
Add Gildea to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (per project):
```json theme={null}
{
"mcpServers": {
"gildea": {
"url": "https://api.gildea.ai/mcp/",
"headers": { "x-api-key": "gld_your_key_here" }
}
}
}
```
Gildea's 7 tools then appear in Cursor's MCP settings.
### Other MCP clients
Any client that supports remote, streamable-HTTP MCP servers with custom headers can connect with the same two values (URL + key). Common config shape:
```json theme={null}
{
"type": "http",
"url": "https://api.gildea.ai/mcp/",
"headers": { "x-api-key": "gld_your_key_here" }
}
```
See the [MCP client list](https://modelcontextprotocol.io/clients) for per-client syntax (VS Code via Cline or Continue, and others).
### Claude Desktop
Not supported yet. Claude Desktop's config file does not read custom headers for remote MCP servers, and its Connectors UI accepts only OAuth, so an API-key server like Gildea cannot connect there today. Use Claude Code or Cursor for now. Claude Desktop support will follow if it adds custom-header auth (or once Gildea offers OAuth).
## REST API vs MCP
Both access the same data. Choose based on your use case.
| | REST API | MCP Server |
| --------------- | ------------------------------------------ | ----------------------------------- |
| **Best for** | Apps, dashboards, pipelines, custom agents | Claude Code, Cursor, any MCP client |
| **Protocol** | HTTP/JSON | streamable-HTTP (remote) |
| **Auth** | `X-API-Key` header | `x-api-key` header |
| **Rate limits** | Shared quota | Shared quota |
| **Pagination** | Cursor-based | Cursor-based |
| **Data** | Identical | Identical |
Rate limits are shared across REST and MCP. A request from an MCP client and a request from your app count toward the same per-minute and monthly quota.
## Available tools
The MCP server exposes 7 tools that mirror the REST API.
### `search_text_units`
Search across Gildea's verified text units: thesis, synopsis, and argument sentences, plus atomic claims. Every unit has been verified against source evidence; results are not direct quotes but sentence-level extractions.
Two modes:
* **`q`**: free-text search. Returns the most relevant units across the corpus.
* **`similar_to`**: pass a text unit ID; returns the most similar units (useful for cross-source corroboration and "find more like this").
Exactly one of `q` or `similar_to` is required.
**Parameters:**
| Param | Type | Required | Description |
| ------------------ | ------- | ------------------------- | ----------------------------------------------------------------------------------------------- |
| `q` | string | One of `q` / `similar_to` | Free-text search query |
| `similar_to` | string | One of `q` / `similar_to` | Text unit ID; finds the most similar units |
| `role` | string | No | Filter: `thesis`, `synopsis`, `argument`, or `claim` |
| `entity` | string | No | Entity public ID (e.g. `gld:/a1b2c3d4e5f6`). Returns only units literally mentioning the entity |
| `theme` | string | No | Theme label (1 of 12). Returns units from articles tagged with that theme |
| `published_after` | string | No | ISO 8601 date; only results from articles published after this date |
| `published_before` | string | No | ISO 8601 date; only results from articles published before this date |
| `window` | string | No | Relative time shortcut (e.g. `7d`, `2w`, `1m`) |
| `recency_boost` | number | No | 0.0-1.0. Soft preference for newer results; default 0 (off) |
| `diversity_cap` | integer | No | Max units per source article (1-100, default 2) |
| `limit` | integer | No | Max results (default 10, max 100) |
**Example prompt:** *"Search for verified claims about GPU supply constraints"*
```json theme={null}
// Keyword search
{ "q": "GPU supply constraints", "role": "claim", "limit": 5 }
```
**Example prompt:** *"Find text units similar to this claim"*
```json theme={null}
// Similar-to search
{ "similar_to": "0004c6d0e2f1a3b5c7d9e1f3a5b7c9d1e3f5a7b9", "limit": 5 }
```
### `list_signals`
Find intelligence signals about the AI economy from 500+ expert sources. Each signal is a structured analysis or event report decomposed into verified components; use `get_signal_detail` to access the full tree. All filters are optional; without filters, returns the most recent signals.
**Parameters:**
| Param | Type | Required | Description |
| ------------------ | ------- | -------- | -------------------------------------------------------------------- |
| `entity` | string | No | Entity ID filter |
| `theme` | string | No | Theme label filter |
| `keyword` | string | No | Literal keyword filter on title + unit text |
| `content_type` | string | No | `analysis` or `event` |
| `published_after` | string | No | ISO date (e.g. `2026-02-01`) |
| `published_before` | string | No | ISO date |
| `window` | string | No | Relative time shortcut (e.g. `7d`, `2w`, `1m`) |
| `sort` | string | No | `published` (default) or `changed` (change feed; page with `cursor`) |
| `cursor` | string | No | Opaque cursor from a previous response; pages the change feed |
| `limit` | integer | No | Max results (default: 25, max: 50) |
**Example prompt:** *"Show me recent analysis signals about OpenAI"*
```json theme={null}
{ "entity": "gld:/e5f6a7b8c9d0", "content_type": "analysis", "limit": 5 }
```
### `get_signal_detail`
Get the full verified breakdown of a signal as a flat `units[]` list. This is where Gildea's value lives. Each unit carries a `role`: `thesis`/`synopsis` (the central statement), `argument` (supporting analysis sentences; group by `argument_id` to reconstruct each as a paragraph), and `claim` (atomic facts). Every unit has been independently verified against source evidence, which is included by default. Use this tool liberally; it's the difference between showing metadata and showing actual verified intelligence.
**Parameters:**
| Param | Type | Required | Description |
| ----------- | ------ | -------- | ----------- |
| `signal_id` | string | Yes | Signal ID |
**Example prompt:** *"Get the full verified breakdown of that signal"*
```json theme={null}
{ "signal_id": "0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7" }
```
### `list_entities`
Discover which companies, people, and models are getting expert attention in the AI economy. Filter by trend direction, notability, coverage scale, and more. Use this for discovery: finding what's worth paying attention to.
**Parameters:**
| Param | Type | Required | Description |
| ------------ | ------- | -------- | ----------------------------------------------------- |
| `name` | string | No | Filter by entity name (substring match) |
| `theme` | string | No | Filter by theme label |
| `type` | string | No | Filter by entity type |
| `sort` | string | No | `signal_count` (default), `first_seen`, or `trend` |
| `direction` | string | No | `Rising`, `Stable`, `Declining`, `New` |
| `confidence` | string | No | `Significant`, `Insignificant` |
| `stability` | string | No | `Volatile`, `Steady` |
| `scale` | string | No | `Large`, `Medium`, `Small` |
| `notability` | string | No | `High`, `Medium`, `Low`, `Negligible` |
| `cursor` | string | No | Opaque cursor from a previous response for pagination |
| `limit` | integer | No | Max results (default: 25, max: 50) |
**Example prompt:** *"Show me reliably rising entities"*
```json theme={null}
{ "direction": "Rising", "confidence": "Significant", "sort": "trend", "limit": 10 }
```
### `get_entity_profile`
Get an intelligence profile for a company, person, or model. Returns whether the entity is rising, stable, or declining in expert coverage; how much attention it's getting relative to others; whether the trend is statistically significant; and a notability assessment. Use this to understand an entity's trajectory before diving into specific signals.
**Parameters:**
| Param | Type | Required | Description |
| ------------ | ------ | -------- | ------------------------------------------ |
| `name_or_id` | string | Yes | Entity name (fuzzy matched) or entity UUID |
**Example prompt:** *"Show me NVIDIA's entity profile"*
```json theme={null}
{ "name_or_id": "NVIDIA" }
```
Entities with fewer than 8 mentions in the 12-week window return `scale` only. The `direction`, `confidence`, `stability`, and `notability` fields will be `null` due to insufficient data for statistical significance.
### `get_themes`
List all taxonomy themes across two axes that categorize the AI economy. Each theme includes signal counts, trend direction, and notability. Use `get_theme_detail` for full trend analytics and co-occurring themes.
**Parameters:**
| Param | Type | Required | Description |
| ------ | ------ | -------- | ------------------------------- |
| `axis` | string | No | `value_chain` or `market_force` |
**Taxonomy:**
* **Value chain:** Infrastructure, Foundation Models, Orchestration, Data & Labeling, Applications, Distribution
* **Market force:** Capital & Investment, Regulatory & Legal, Competitive Dynamics, Talent & Labor, Geopolitical Strategy, Trust & Societal Impact
**Example prompt:** *"What value chain themes are trending?"*
```json theme={null}
{ "axis": "value_chain" }
```
### `get_theme_detail`
Get a specific theme's full trend analytics and co-occurring themes from both axes. Returns trend direction, statistical confidence, stability, notability with reasoning, and which themes from the other axis most frequently co-occur. Use this to understand how themes interconnect.
**Parameters:**
| Param | Type | Required | Description |
| ------- | ------ | -------- | ----------------------------------- |
| `axis` | string | Yes | `value_chain` or `market_force` |
| `label` | string | Yes | Theme label (e.g. `Infrastructure`) |
**Example prompt:** *"Tell me about the Geopolitical Strategy theme"*
```json theme={null}
{ "axis": "market_force", "label": "Geopolitical Strategy" }
```
## Authentication & rate limits
The MCP server uses the same API key and rate limits as the REST API. Provide your key via the `x-api-key` header in your client's MCP config (see the examples above).
| Tier | Per-minute | Monthly |
| ---- | ---------- | ---------------------- |
| Free | 20 | 250 |
| Pro | 60 | 5,000 |
| Team | Custom | Custom (contact sales) |
Rate limits are shared: requests from MCP and REST count toward the same quota. When you exceed the limit, the tool returns an error message with the retry-after interval.
## Troubleshooting
### "Authentication failed"
The API key is missing, invalid, or revoked.
1. Check that the `x-api-key` header is set in your MCP config
2. Verify the key starts with `gld_`
3. Check your key status at [gildea.ai](https://gildea.ai)
### "Rate limit exceeded"
You've hit the per-minute or monthly quota.
1. Check your current tier's limits in the table above
2. Wait for the retry-after interval (returned in the error message)
3. Consider upgrading your tier if you consistently hit limits
### Tools not appearing
1. Reload your client's MCP servers (or restart it) after editing the config
2. Verify the config is valid JSON (no trailing commas) and the `x-api-key` header is set
3. Confirm your key is active at [gildea.ai](https://gildea.ai)
4. Check the client's MCP logs for connection errors. For Claude Code, `claude mcp list` shows the connection status
### Connection issues
1. Confirm the URL is exactly `https://api.gildea.ai/mcp/`
2. Check the service is up: `curl https://api.gildea.ai/v1/health`
3. Check for network/firewall issues if your client can't reach it
# Pagination
Source: https://docs.gildea.ai/guides/pagination
Cursor-based pagination for list endpoints
List endpoints use **cursor-based keyset pagination** for consistent, efficient paging through large result sets.
## How it works
1. Make your first request (no cursor):
```bash theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/signals?keyword=AI&limit=10"
```
2. Check `has_more` and `next_cursor` in the response (the list itself is under a resource key: `signals` for `/v1/signals`, `entities` for `/v1/entities`):
```json theme={null}
{
"signals": [...],
"has_more": true,
"next_cursor": "c2cudjEuOGYzYTFjOWUuNDU2"
}
```
3. Pass `next_cursor` as the `cursor` parameter for the next page:
```bash theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/signals?keyword=AI&limit=10&cursor=c2cudjEuOGYzYTFjOWUu..."
```
4. Repeat until `has_more` is `false`.
## Parameters
| Parameter | Type | Default | Range | Description |
| --------- | ------- | ------- | ----- | ------------------------------------ |
| `limit` | integer | 25 | 1-50 | Results per page |
| `cursor` | string | n/a | n/a | Opaque cursor from previous response |
## Paginated endpoints
* `GET /v1/signals`: signals list
* `GET /v1/entities`: entities list
## Why cursor-based?
Cursor pagination is more efficient and consistent than offset-based pagination:
* **No skipped/duplicated results** when data changes between pages
* **Consistent performance** regardless of page depth (no `OFFSET N` scan)
* **Opaque cursors**: the format may change without breaking clients
# Rate Limits
Source: https://docs.gildea.ai/guides/rate-limits
Fixed-window rate limiting by tier
Gildea uses fixed-window rate limiting on both per-minute and monthly windows.
## Limits by tier
| Tier | Requests/min | Requests/month |
| ---- | ------------ | ---------------------- |
| Free | 20 | 250 |
| Pro | 60 | 5,000 |
| Team | Custom | Custom (contact sales) |
Monthly limits use a rolling 30-day window.
## Rate limit headers
Every authenticated response includes rate limit headers (limit, remaining, and the
reset time in unix epoch seconds) for each window:
```
X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 58
X-RateLimit-Reset-Minute: 1749945600
X-RateLimit-Limit-Monthly: 5000
X-RateLimit-Remaining-Monthly: 4847
X-RateLimit-Reset-Monthly: 1752537600
```
## When you're rate limited
If you exceed your limit, the API returns `429`, with the same `X-RateLimit-*`
headers above (so you can see which window was hit and when it resets), plus a
`Retry-After` header in seconds:
```
Retry-After: 47
```
The retry timing is also echoed into the body, so clients that only read JSON
don't have to inspect headers. `retry_after` is the seconds to wait; `reset` is the
unix epoch second when the exceeded window clears:
```json theme={null}
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded: 60 requests per minute",
"status": 429,
"retry_after": 47,
"reset": 1749945600
}
}
```
`Retry-After` reflects the actual time to the window reset, not a fixed value: for
the per-minute window it ranges from 1-60s depending on when in the window you hit
the cap. (A `429` from the monthly window can have a much larger `Retry-After`; if
you're hitting the monthly cap, upgrading your tier is usually the fix.)
## Best practices
1. **Check remaining counts**: use the `X-RateLimit-Remaining-*` headers to throttle proactively
2. **Respect Retry-After**: wait the indicated time before retrying
3. **Use pagination**: fetch fewer, larger pages instead of many small requests
4. **Cache responses**: signal data doesn't change frequently
# Scope context
Source: https://docs.gildea.ai/guides/scope
Define the territory you track: the themes and entities every later step operates over.
**Scope** your territory before you chase anything. Which entities and themes actually matter to your question is rarely obvious up front, and pinning it down by hand means days of reading around to learn who is moving and where the conversation sits. Gildea makes it a few calls. A live theme map shows the market's structure and its momentum, faceted entity navigation surfaces who is rising and who is fading, and a full profile on any entity anchors your scope to real, tracked data. The output is your **territory**: the themes and entities every later step searches, monitors, and verifies against.
## The recipe
Scoping is pure navigation over Gildea's structured layer, with no model calls. You read the theme map, facet the entity space down to the ones you care about, profile your central entity, then lock the result into a `scope` the other recipes reuse.
Pull the theme vocabulary. Themes sit on two axes: `value_chain` (the structural layers, from infrastructure up to applications) and `market_force` (the dynamics acting on them). Each carries weekly momentum, so you see what is heating up and what is cooling. See [Themes](/concepts/themes).
`entities.list` exposes nine facets (`type`, `theme`, `scale`, `direction`, `confidence`, `stability`, `notability`, `name`) plus `sort`. Slice the entity space down to your territory, and contrast who is rising against who is declining. See [Entities](/concepts/entities).
`entities.get` returns the full picture for one entity: its trend and reach, where it operates across the value chain, the market forces touching it, and the entities it is most discussed alongside.
Combine the themes, entities, and a time window into the territory every later recipe operates over.
Install `gildea`, set `GILDEA_API_KEY`, then (pure SDK, no model calls):
```python theme={null}
from gildea import Gildea
gildea = Gildea()
# 1. The market map: themes sit on two axes -- value_chain (structural layers,
# infra -> apps) and market_force (the dynamics on them). Each carries momentum.
themes = gildea.themes.list()["themes"]
def by_axis(axis):
rows = [t for t in themes if t["axis"] == axis]
return sorted(rows, key=lambda t: t["signal_count"], reverse=True)
for axis in ("value_chain", "market_force"):
print(f"\n{axis}:")
for t in by_axis(axis):
delta = t["trend"]["current_week"] - t["trend"]["prior_week"]
print(f" {t['label']:26} {t['signal_count']:>4} signals "
f"{t['direction'] or '-':9} wk {delta:+d}")
# Anchor your territory on the busiest structural theme.
theme = by_axis("value_chain")[0]["label"]
# 2. Faceted entity navigation: nine facets + sort. Contrast two slices.
def orgs(theme, **facets):
return gildea.entities.list(
theme=theme, type="organization", sort="trend", limit=50, **facets
)["entities"]
rising = orgs(theme, direction="Rising")
declining = orgs(theme, direction="Declining", notability="High")
print(f"\nIn '{theme}': {len(rising)} rising / {len(orgs(theme))} total orgs")
print(" rising: ", ", ".join(e["name"] for e in rising[:6]) or "(none this week)")
print(" declining:", ", ".join(e["name"] for e in declining[:6]))
# 3. Central entity profile: the full intelligence picture for one entity.
e = gildea.entities.get("NVIDIA")
tr = e["trend"]
print(f"\n{e['name']} ({e['entity_id']}) -- {e['type']}, scale={e['scale']}, "
f"{e['direction']}, notability={e['notability']}")
print(f" reach: share_of_voice={tr['share_of_voice']:.0%}, "
f"{tr['source_diversity']} distinct sources, wk {tr['current_week']} vs {tr['prior_week']}")
def top(dist, n=3):
return ", ".join(f"{k} ({v})" for k, v in sorted(dist.items(), key=lambda x: -x[1])[:n])
print(f" operates in: {top(e['value_chain_distribution'])}")
print(f" forces: {top(e['market_force_distribution'])}")
mix = e["content_type_mix"]
print(f" coverage: {mix.get('event', 0)} events / {mix.get('analysis', 0)} analyses")
print(f" alongside: {', '.join(r['name'] for r in e['related_entities'][:6])}")
# 4. Lock the scope: themes + entities + window = the territory every later
# recipe (search, update, verify, embed) operates over.
scope = {
"themes": [theme],
"entities": [e["entity_id"]] + [r["entity_id"] for r in e["related_entities"][:5]],
"window": "90d",
}
print(f"\nscope locked: {len(scope['entities'])} entities, theme '{theme}', window {scope['window']}")
```
## What you get
Your **territory**: the themes that frame the question, the entities worth tracking within them, and a profile of your central entity, every field from real tracked data. It is a plain object the rest of the loop reuses. [Search](/guides/search) pulls verified signals across it, [Update](/guides/update) keeps it current, [Verify](/guides/verify) traces any unit back to its source, and [Embed](/guides/embed) stores it beside your own data. Because scope is built from live theme and entity intelligence, re-running it re-checks who is moving before you commit.
# Python SDK
Source: https://docs.gildea.ai/guides/sdk
Install and use the official Python client library
The `gildea` package is a thin Python client that wraps the REST API with typed errors, auto-pagination, and resource namespaces.
## Installation
```bash theme={null}
pip install gildea
```
Requires Python 3.9+ and has a single dependency (`httpx`).
## Quick start
```python theme={null}
from gildea import Gildea
client = Gildea() # reads GILDEA_API_KEY from env
signals = client.signals.list(entity="NVIDIA", limit=5)
for s in signals["signals"]:
print(s["title"])
```
You can also pass the key explicitly:
```python theme={null}
client = Gildea(api_key="gld_your_key")
```
## Resources
The client organizes endpoints into resource namespaces.
### Signals
```python theme={null}
# List signals (all filters optional; defaults to most recent)
client.signals.list(entity="NVIDIA", limit=5)
client.signals.list(keyword="GPU supply chain", content_type="analysis")
# Get the full verified units (evidence included by default)
client.signals.get("0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7")
```
### Entities
```python theme={null}
# List entities
client.entities.list(type="organization", limit=10)
client.entities.list(name="OpenAI", sort="trend")
# Get entity profile with related entities
client.entities.get("NVIDIA")
# Filter by interpretation fields (composable)
client.entities.list(direction="Rising", confidence="Significant", sort="trend", limit=5)
client.entities.list(scale="Large", stability="Steady")
client.entities.list(direction="New", sort="first_seen", limit=10)
```
### Themes
```python theme={null}
# List all themes or filter by axis
client.themes.list()
client.themes.list(axis="value_chain")
# Get theme detail with related themes
client.themes.get("value_chain", "Foundation Models")
```
### Search
```python theme={null}
# Hybrid dense + sparse search with cross-encoder rerank, over all verified text units
client.search("AI chip supply constraints", limit=5)
client.search("AI chip supply constraints", role="claim", entity="NVIDIA")
```
## Auto-pagination
List endpoints return one page at a time. Use `list_all` to iterate through every result automatically:
```python theme={null}
for signal in client.signals.list_all(entity="NVIDIA"):
print(signal["title"])
for entity in client.entities.list_all(type="organization"):
print(entity["name"])
```
`list_all` is a generator: it fetches pages lazily as you iterate, so you can break early without wasting requests.
## Error handling
The SDK maps HTTP errors to typed exceptions:
```python theme={null}
from gildea import (
Gildea,
AuthenticationError,
NotFoundError,
RateLimitError,
BadRequestError,
APIError,
)
client = Gildea()
try:
client.signals.get("sig_nonexistent")
except NotFoundError as e:
print(f"Not found: {e}")
except RateLimitError as e:
print(f"Rate limited; retry after {e.retry_after}s")
except AuthenticationError as e:
print(f"Auth failed: {e}")
except APIError as e:
print(f"API error ({e.status}): {e}")
```
| HTTP Status | Exception | Description |
| ----------- | --------------------- | ------------------------------------------------ |
| 400 | `BadRequestError` | Invalid parameters |
| 401 / 403 | `AuthenticationError` | Invalid or missing API key |
| 404 | `NotFoundError` | Resource not found |
| 429 | `RateLimitError` | Rate limit exceeded (`.retry_after` has seconds) |
| 5xx | `APIError` | Server error |
## Configuration
```python theme={null}
client = Gildea(
api_key="gld_...", # or set GILDEA_API_KEY env var
base_url="https://api.gildea.ai", # override for self-hosted
timeout=30.0, # request timeout in seconds
)
```
The client can be used as a context manager to ensure the connection is closed:
```python theme={null}
with Gildea() as client:
signals = client.signals.list(keyword="AI", limit=5)
```
# Search for signals
Source: https://docs.gildea.ai/guides/search
Pull the verified, cited units for your territory, sliced by entity, theme, role, and similarity.
**Search** your territory for the verified signals that bear on your question. By hand this is hours across newsletters, filings, and X, and the real work is not finding *a* source but finding the right slice: the central positions, the dissent, the most recent moves, across many independent sources. Gildea's search is semantic and faceted, so one call returns the on-topic, already-cited units, and you narrow by entity, theme, time, role, or similarity until the slice is exactly what you need.
## The recipe
Search is a retrieval primitive: a natural-language query in, a ranked list of verified units out. The power is in the facets you compose over it. You scope each query to your territory, pull a specific layer of the decomposition, find more units like one that matters, tune for recency and source diversity, then drill any signal to its full set of units.
A natural-language query, narrowed by `entity`, `theme`, and `window` to the scope you defined. Retrieval is semantic, so phrase the query like a question, not a keyword string.
Pull one layer of the decomposition with `role`: `thesis` / `synopsis` (the central position), `argument` (the reasoning), or `claim` (atomic factual assertions).
Pass `similar_to` a unit `id` to get embedding-backed "more like this": the cluster of units making the same point, across independent sources.
`recency_boost` favors newer signals; `diversity_cap` limits units per source, so one prolific author can't dominate the page.
`signals.list` takes `content_type` to separate `event` (what happened) from `analysis` (what experts think). Pull either, then fetch any signal's full verified decomposition as a flat `units[]` with roles and evidence.
Install `gildea`, set `GILDEA_API_KEY`, then (pure SDK, no model calls):
```python theme={null}
from gildea import Gildea
gildea = Gildea()
# Your scope from the previous recipe, inlined so this block runs on its own.
scope = {"themes": ["Infrastructure"], "entities": ["NVIDIA"], "window": "6m"}
# 1. Semantic + faceted retrieval: a natural-language query narrowed to your
# territory (entity + theme + window). Retrieval is semantic, not keyword.
hits = gildea.search(
"data center moat durability and competitive threats",
entity=scope["entities"][0], theme=scope["themes"][0], window=scope["window"],
limit=10,
)["results"]
print(f"{len(hits)} verified units in scope. top:")
for h in hits[:5]:
u, c = h["unit"], h["citation"]
print(f" [{u['role']:9}] {u['text'][:62]} <- {c['domain']}")
# 2. Role facet: pull one layer of the decomposition -- thesis/synopsis (the
# central position), argument (reasoning), claim (atomic factual assertions).
theses = gildea.search("AI infrastructure spending", role="thesis", window="3m", limit=5)["results"]
print(f"\n{len(theses)} thesis-level units (positions experts are taking):")
for h in theses[:3]:
print(f" - {h['unit']['text'][:80]}")
# 3. similar_to: embedding-backed "more like this" off any unit id. Find the
# cluster making the same point, across sources.
seed = hits[0]["unit"]["id"]
similar = gildea.search(similar_to=seed, limit=5)["results"]
print(f"\nunits similar to the top hit ({len(similar)} found):")
for h in similar[:3]:
print(f" ~ {h['unit']['text'][:66]} <- {h['citation']['domain']}")
# 4. Tune the ranking: recency_boost favors newer signals; diversity_cap limits
# units per source so one prolific author can't dominate the page.
fresh = gildea.search(
"frontier model competition", recency_boost=1, diversity_cap=1, window="1m", limit=8,
)["results"]
print(f"\nrecency-boosted, source-diversified: {len(fresh)} hits across "
f"{len({h['citation']['domain'] for h in fresh})} domains")
# 5. Split the feed by content_type -- event (what happened) vs analysis (what
# experts think) -- then drill a signal to its full verified decomposition
# as a flat units[] with roles + evidence.
theme = scope["themes"][0]
events = gildea.signals.list(theme=theme, content_type="event", window="3w", limit=5)["signals"]
analyses = gildea.signals.list(theme=theme, content_type="analysis", window="3w", limit=5)["signals"]
print(f"\n{len(events)} event / {len(analyses)} analysis signals in '{theme}'")
detail = gildea.signals.get((events or analyses)[0]["signal_id"])
roles = ", ".join(sorted({u["role"] for u in detail["units"]}))
print(f"drilled '{detail['title'][:48]}' -> {len(detail['units'])} units ({roles})")
```
## What you get
The verified, cited units for your territory, sliced exactly how you need them: by entity and theme, by decomposition layer, by similarity, by recency and source spread. Every unit is already verified and carries its citation, so the set you assemble is one you can [trace to source](/guides/verify) and [embed beside your own data](/guides/embed). Retrieval is semantic, so phrasing the query like a question works better than keyword matching.
# Update context
Source: https://docs.gildea.ai/guides/update
Pull only what's changed into your context store.
**Update** your context layer incrementally as signals land and change. Rebuilding the store from scratch is wasteful, and re-reading by hand misses things. A **cursor** remembers exactly where you left off, so each refresh pulls only what's changed into your store, in order, with nothing missed or double-counted.
## The recipe
`sort=changed` is a change feed: signals ordered by when they last changed. You page it with a cursor, and the cursor is a bookmark you keep between runs. Poll hourly, daily, or after a week away, and you always pick up exactly where you left off.
Pass your saved `cursor` to `signals.list(sort="changed")`. It returns everything that changed since that point. The first run has no cursor, so it does a full initial sync; every run after is just the delta.
Replace each changed signal in your store by its `signal_id`: newest wins, wholesale. A signal's entities can change over time as they're merged or renamed, so you replace the whole record; merging would leave stale parts behind.
Persist the updated store and the new cursor. Poll on any cadence (hourly, daily, after a week away) and your territory stays current, so [Search](/guides/search) and the rest of your loop always read fresh, verified data.
Install `gildea`, set `GILDEA_API_KEY`, then (pure SDK, no model calls):
```python theme={null}
import json
import pathlib
from gildea import Gildea
gildea = Gildea()
CURSOR = pathlib.Path("update_cursor.txt") # remembers exactly where the last sync ended
STORE = pathlib.Path("signals.jsonl") # your local copy of the signals you track
# 1. Resume from your saved cursor (none on the first run -> a full initial sync).
cursor = None
if CURSOR.exists():
cursor = CURSOR.read_text().strip() or None
# 2. Page the change feed: everything changed since last sync, in document order.
# The first run has no cursor, so it backfills; we cap the initial pull to keep the demo
# quick (raise MAX_PAGES, or drop the cap, to backfill the full history). Steady-state runs
# resume from the saved cursor and only pull the small delta. Pull the whole feed (not
# filtered by entity) so you also catch signals that *lost* an entity (merge/rename); route
# to your tracked scope client-side from each signal's entities.
changed, MAX_PAGES = [], 5
for _ in range(MAX_PAGES):
page = gildea.signals.list(sort="changed", cursor=cursor, limit=50)
changed.extend(page["signals"])
cursor = page.get("next_cursor") or cursor # advance; keep old if nothing newer
if not page["has_more"]:
break
# 3. Upsert by signal_id: newest version wins, replace the whole record (don't merge: a
# signal's entities can change (merge/rename), so stale parts must drop out).
store = {}
if STORE.exists():
store = {s["signal_id"]: s for s in map(json.loads, STORE.read_text().splitlines()) }
for s in changed:
store[s["signal_id"]] = s
# 4. Persist the store and the cursor for next time.
STORE.write_text("\n".join(json.dumps(s) for s in store.values()))
CURSOR.write_text(cursor or "")
print(f"{len(changed)} signals changed this sync; {len(store)} tracked total")
```
## What you get
A self-healing watch on your scope: poll on any cadence (hourly, daily, after a week off) and you always get exactly what changed since last time, with nothing missed or repeated. The cursor makes it incremental; the upsert keeps every record current. It writes to the same `signals.jsonl` your other recipes read, so your context layer stays current without a full rebuild.
# Verify claims
Source: https://docs.gildea.ai/guides/verify
Confirm every sentence is evidence-backed.
**Verify** a claim before you act on it. Knowing it's real and backed by a source today means chasing it down by hand, or trusting that an LLM hasn't fabricated a citation. Gildea does that work up front: every sentence it serves is tied to one or more verbatim evidence snippets from the cited source, and rigorously audited for hallucinated entities, numbers, and dates, as well as epistemic drift. That's a different bar from LLM-as-a-judge: entailment against the source, deterministic checks, and human review where flagged. [See how it works](/concepts/verification).
## The recipe
Every unit (a single sentence) returned by search or signal detail has passed verification (`verdict = pass`). Gildea never serves unverified text, so there's no "filter the hallucinations" step. See [Verification](/concepts/verification).
Each unit carries `evidence.snippets`, verbatim text from the source that supports it. The snippet is a short preview (about the first 100 characters): a locator into the source, not the full passage. `citation.url` is the full audit path, and `verification.human_reviewed` appears when a human signed off.
You don't have to take the verdict on faith. Point your agent at `citation.url`, have it find the passage the snippet locates, and confirm the source entails the sentence. This is "verify us," not "trust us."
Install `gildea` and `anthropic`, set `GILDEA_API_KEY` and `ANTHROPIC_API_KEY`, then:
```python theme={null}
import re
import httpx
import anthropic
from pydantic import BaseModel
from gildea import Gildea
claude = anthropic.Anthropic() # reads ANTHROPIC_API_KEY
gildea = Gildea() # reads GILDEA_API_KEY
# 1. Grab a served unit, its evidence snippet, and its citation
hits = gildea.search("AI data center power and compute constraints", limit=20)["results"]
hit = next(h for h in hits if "substack.com" in (h["citation"].get("url") or ""))
unit, citation = hit["unit"], hit["citation"]
snippet = unit["evidence"]["snippets"][0]["text"] # ~100-char locator, not the full passage
# 2. Fetch the cited source yourself and strip it to text
html = httpx.get(citation["url"], timeout=20, follow_redirects=True,
headers={"User-Agent": "Mozilla/5.0"}).text
source = re.sub(r"\s+", " ", re.sub(r"<[^>]+>", " ", html))[:20000]
# 3. Confirm independently: is the snippet really in the source, and does the source entail the sentence?
class Check(BaseModel):
snippet_in_source: bool # the 100-char snippet is genuinely a substring of the source
entailed: bool # the source supports the served sentence
supporting_quote: str # the full passage the snippet was a preview of
result = claude.messages.parse(
model="claude-opus-4-8",
max_tokens=2000,
system=("You are independently verifying a sentence an API served. Given the source text, the "
"evidence snippet, and the sentence: confirm whether the snippet appears in the source, "
"quote the supporting passage, and judge whether the source entails the sentence."),
messages=[{"role": "user", "content":
f"SOURCE:\n{source}\n\nEVIDENCE SNIPPET: {snippet}\n\nSERVED SENTENCE: {unit['text']}"}],
output_format=Check,
).parsed_output
print(f"served sentence: {unit['text']}")
print(f"snippet genuinely in source: {result.snippet_in_source} | source entails sentence: {result.entailed}")
print(f"full passage: {result.supporting_quote[:160]}")
```
## What you get
A working set you can stand behind: free of the fabricated and mis-cited claims that plague the LLM + web search path. The trust is the **evidence**, with every sentence traceable to one or more verbatim evidence snippets.
# Introduction
Source: https://docs.gildea.ai/introduction
Verified intelligence on the AI race. Built for agents.
Building an agent? Load the entire docs as one file from [`/llms-full.txt`](https://docs.gildea.ai/llms-full.txt).
Gildea is the market data API for AI. We transform raw events and expert analysis on the AI economy into atomic intelligence your agent can query. We do this by sourcing, structuring, and verifying signals from 500+ leading sources worldwide. Gildea data is served through a REST API and an MCP server, with new signals added daily.
## Make your first call
Base URL `https://api.gildea.ai/v1`, authenticated with an `X-API-Key` header. One request returns verified, source-cited claims:
```bash theme={null}
curl -H "X-API-Key: $GILDEA_API_KEY" \
"https://api.gildea.ai/v1/search?q=AI%20chip%20export%20controls&role=claim&limit=5"
```
## What you get
Built for agents that need to know what experts know, not what the web indexes. Gildea curates 500+ of the highest-signal AI sources that crawlers miss or bury in SEO sludge. Each is hand-picked by people who track AI for a living.
Built for agents that need to reason, not just retrieve. A model's reasoning degrades as its context fills with noise, so Gildea distills each source to its strategic spine, giving your agent dense, relevant input instead of bloat.
Built for agents that need to filter, route, and connect, not just read. Every signal is classified by content type, tagged to themes, and linked to the entities it names with stable IDs, so your agent can scope, pivot, and trace relationships instead of parsing prose.
Built for the teams where a hallucinated claim blows up the deck, the deal, or the trade. Every sentence is scored against verbatim evidence and run through safety checks for fabricated entities, numbers, and dates. Only evidence-backed sentences are served.
## Built for
Gildea is purpose-built for enabling continuous monitoring use cases. Keep your view current as the AI landscape evolves:
* Create a context layer that compounds with every new signal
* Pressure-test a thesis against value-chain and market-force shifts
* Track how expert consensus shifts on a contested question
* Build category authority with fully cited content
## Design principles
* **Fresh daily.** New signals are sourced, verified, and indexed every day.
* **Verified by default.** Only evidence-cited content is ever served, so there is no unverified text to filter.
* **Structured and typed.** One unit shape across search and detail, with consistent field names and typed enums.
* **Stable identifiers.** Entities resolve to opaque `gld:/` IDs that stay constant as the corpus grows.
* **Machine-first.** Built for programmatic use: cursor pagination, `window` shortcuts, an OpenAPI spec, and `llms-full.txt`.
## Data model
A signal is an expert analysis or an event report. Gildea decomposes each into verified units: a central thesis or synopsis, the supporting argument sentences, and atomic claims, each tied to verbatim evidence from its source. Every unit is tagged to the entities it names (companies, people, and models, with stable `gld:/` IDs) and to themes (the AI value chain and market forces), so an agent can search, scope, and trace relationships across the whole corpus.
## Next steps
First request in 5 minutes
Build a verified view step by step, from question to cited answer
Every endpoint
Use Gildea in Claude & more
# OpenAPI Spec
Source: https://docs.gildea.ai/openapi-spec
The complete OpenAPI 3.1 spec for client generation and agent discovery
Building an agent? Load the entire docs as one file from [`/llms-full.txt`](https://docs.gildea.ai/llms-full.txt) first.
The Gildea API publishes a complete **OpenAPI 3.1** specification covering every endpoint, with full request and response schemas, authentication, and parameters.
View or download the raw machine-readable specification.
## What you can do with it
Feed the spec to [`openapi-generator`](https://openapi-generator.tech) to scaffold a typed client in any language.
Load it into Postman, Insomnia, or Bruno to explore the endpoints interactively.
Hand the spec to an agent so it can discover endpoints, parameters, and schemas on its own.
Use the schemas to validate payloads against the contract at build or runtime.
# Quickstart
Source: https://docs.gildea.ai/quickstart
From API key to first request in 5 minutes
## 1. Get your API key
Sign up at [gildea.ai](https://gildea.ai) to get your API key. Keys are prefixed with `gld_`.
## 2. List signals
Filter by `entity`, `theme`, or `keyword`, or omit all filters to get the most recent signals.
```python Python SDK theme={null}
from gildea import Gildea
client = Gildea() # reads GILDEA_API_KEY from env
signals = client.signals.list(entity="NVIDIA", limit=3)
for signal in signals["signals"]:
print(f"{signal['title']}: {signal['verified_unit_count']} verified units")
```
```bash cURL theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/signals?entity=NVIDIA&limit=3"
```
```python Python (requests) theme={null}
import requests
resp = requests.get(
"https://api.gildea.ai/v1/signals",
headers={"X-API-Key": "gld_your_key"},
params={"entity": "NVIDIA", "limit": 3},
)
for signal in resp.json()["signals"]:
print(f"{signal['title']}: {signal['verified_unit_count']} verified units")
```
```javascript JavaScript theme={null}
const resp = await fetch(
"https://api.gildea.ai/v1/signals?entity=NVIDIA&limit=3",
{ headers: { "X-API-Key": "gld_your_key" } }
);
const { signals } = await resp.json();
signals.forEach(s => console.log(`${s.title}: ${s.verified_unit_count} units`));
```
Response: lightweight signal cards with metadata:
```json theme={null}
{
"signals": [
{
"signal_id": "0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
"title": "NVIDIA H200 Shipments Surge as Supply Eases",
"url": "https://reuters.com/article",
"published_at": "2026-01-15T10:00:00Z",
"content_type": "analysis",
"domain": "reuters.com",
"verified_unit_count": 12,
"thesis": "NVIDIA's H200 shipments increased significantly in Q4...",
"themes": {
"value_chain": ["Infrastructure"],
"market_force": ["Competitive Dynamics"]
},
"entities": [
{"entity_id": "gld:/a1b2c3d4e5f6", "name": "NVIDIA", "type": "organization"}
]
}
],
"has_more": true,
"next_cursor": "eyJwdWJsaXNoZWRfYXQiOi..."
}
```
Event signals carry a flat `synopsis` field here instead of `thesis`.
## 3. Get the full verified units
This is Gildea's core value: the complete verified breakdown of a signal as a flat list of units. Pass any `signal_id` from your Step 2 response; the one below is a live example:
```bash theme={null}
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/signals/d67e4e83d32e1db358c8e03d14f3877c6e35a0d6"
```
Response: a flat `units[]`, each carrying a `role` (`thesis` / `synopsis` / `argument` / `claim`) and its cited evidence by default:
```json theme={null}
{
"signal_id": "d67e4e83d32e1db358c8e03d14f3877c6e35a0d6",
"content_type": "analysis",
"domain": "bvp.com",
"verified_unit_count": 25,
"themes": { "value_chain": ["Infrastructure"], "market_force": ["Capital & Investment"] },
"entities": [
{ "entity_id": "gld:/28193456262a", "name": "NVIDIA", "type": "organization" },
{ "entity_id": "gld:/e02d80668c57", "name": "Digital Realty Trust Inc.", "type": "organization" }
],
"units": [
{
"id": "e8edd00cef2b66398b78cd4413619272fb4b7362",
"role": "thesis",
"text": "The private and public demand for AI is creating one of the largest infrastructure investment cycles, offering a massive opening for startups.",
"evidence": {
"snippets": [
{ "text": "The private and public demand for AI is creating one of the largest infrastructure investment cycles…", "truncated": true }
]
}
},
{
"id": "35019e4be886b1e4dc3159a6afb1ed7a8b2ef0d7",
"role": "argument",
"text": "Obtaining permission to operate data centers involves diverse local regulations and timelines, with 16 data center developments delayed or denied between March 2024 and 2025 due to permitting restrictions.",
"argument_id": "a1",
"evidence": { "snippets": [{ "text": "Each permissioning process runs on different timelines and varies at the local jurisdiction. Between…", "truncated": true }] }
},
{
"id": "7ec0c9d34de97766e5d04c786c3f112890c49f36",
"role": "claim",
"text": "By early 2026, 777 hyperscale data center projects totaling 190 GW of capacity have been announced.",
"evidence": { "snippets": [{ "text": "AI is the most power-intensive workload in computing history. As of early 2026, 190 GW of hyperscale…", "truncated": true }] }
}
]
}
```
Reconstruct prose by role: concatenate the `thesis` (or `synopsis`) units for the central statement, and group `argument` units by `argument_id`. Event signals use `synopsis` instead of `thesis` and have no `argument` units. See [Signals](/concepts/signals) for details.
## 4. Explore entities and themes
```python Python SDK theme={null}
from gildea import Gildea
client = Gildea()
# Rising entities with statistical significance
rising = client.entities.list(direction="Rising", confidence="Significant", sort="trend", limit=5)
# Entity profile
nvidia = client.entities.get("NVIDIA")
# Themes
themes = client.themes.list(axis="value_chain")
# Semantic search
results = client.search("GPU supply constraints", limit=5)
```
```bash cURL theme={null}
# Rising entities with statistical significance
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/entities?direction=Rising&confidence=Significant&sort=trend&limit=5"
# Entity profile
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/entities/NVIDIA"
# Themes
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/themes?axis=value_chain"
# Semantic search
curl -H "X-API-Key: gld_your_key" \
"https://api.gildea.ai/v1/search?q=GPU%20supply%20constraints&limit=5"
```
```python Python (requests) theme={null}
import requests
headers = {"X-API-Key": "gld_your_key"}
# Rising entities with statistical significance
rising = requests.get(
"https://api.gildea.ai/v1/entities",
headers=headers,
params={"direction": "Rising", "confidence": "Significant", "sort": "trend", "limit": 5},
).json()
# Entity profile
nvidia = requests.get(
"https://api.gildea.ai/v1/entities/NVIDIA",
headers=headers,
).json()
# Themes
themes = requests.get(
"https://api.gildea.ai/v1/themes",
headers=headers, params={"axis": "value_chain"},
).json()
# Semantic search
results = requests.get(
"https://api.gildea.ai/v1/search",
headers=headers, params={"q": "GPU supply constraints", "limit": 5},
).json()
```
```javascript JavaScript theme={null}
const headers = { "X-API-Key": "gld_your_key" };
// Rising entities with statistical significance
const rising = await fetch(
"https://api.gildea.ai/v1/entities?direction=Rising&confidence=Significant&sort=trend&limit=5",
{ headers }
).then(r => r.json());
// Entity profile
const nvidia = await fetch(
"https://api.gildea.ai/v1/entities/NVIDIA",
{ headers }
).then(r => r.json());
// Themes
const themes = await fetch(
"https://api.gildea.ai/v1/themes?axis=value_chain",
{ headers }
).then(r => r.json());
// Semantic search
const results = await fetch(
"https://api.gildea.ai/v1/search?q=GPU%20supply%20constraints&limit=5",
{ headers }
).then(r => r.json());
```
## Next steps
Install the official client library
Understand the verified-unit model
Value chain and market force themes
API key setup and tiers
Connect via MCP