# Release 0.0.4 (/docs/release-notes/0.0.4)



Region scoping moves from a UUID list to one expression. `gpeIds` is gone; `gpeQuery` replaces it on proof-point, fact, and manifestation requests. The syntax matches [topicQuery](/docs/release-notes/0.0.2): GPE UUIDs combined with `AND` / `OR` / `NOT`, each optionally prefixed with `title:`, `summary:`, or `document:`.

These are **breaking** changes on the new routes introduced in [Release 0.0.1](/docs/release-notes/0.0.1). Deprecated `/indicators/*` routes keep nested parent-GPE filters and are mapped internally, so existing integrations on those routes are unaffected.

## Breaking request changes [#breaking-request-changes]

| Removed                                    | Replacement           |
| ------------------------------------------ | --------------------- |
| `gpeIds: [a, b]`                           | `gpeQuery: "a OR b"`  |
| `gpeIds: [a]` with title-only GPE mentions | `gpeQuery: "title:a"` |

Requests that still send `gpeIds` are **not rejected** — unknown fields are ignored, so an unmigrated caller silently returns unfiltered results. Check for `gpeIds` explicitly rather than relying on error responses.

Fact and manifestation routes now **apply** the GPE filter. Headquarters location is matched even when `gpeQuery` uses field prefixes.

## gpeQuery syntax [#gpequery-syntax]

`gpeQuery` is a Lucene-lite expression whose terms are **GPE UUIDs**, not free text. Consecutive UUIDs are combined with implicit `AND`. Quotes and `body:` are rejected.

Resolve GPE IDs with `GET /topics` (search for a country, region, or city name) and pass those IDs as terms.

| `gpeQuery`              | Meaning                                        |
| ----------------------- | ---------------------------------------------- |
| `a`                     | Mentions GPE A anywhere (or HQ in A, on facts) |
| `a OR b`                | Former `gpeIds: [a, b]`                        |
| `title:a`               | GPE A in title only (proof points)             |
| `title:a AND summary:b` | Title has A and summary has B (proof points)   |
| `a NOT b`               | Has A, excludes B                              |
| `(a OR b) AND NOT c`    | Grouping with parentheses                      |

`AND` binds tighter than `OR`, so mix them with explicit parentheses. Operators are case-sensitive: lowercase `and` is read as a term and fails UUID parsing.

Unlike `topicQuery`, a GPE term does **not** expand to child regions. Hierarchy is walked the other way: documents already store ancestor GPEs, and facts walk from the organization’s headquarters up `IS_LOCATED_IN`. Querying a country therefore matches a city mention or an HQ in that city.

## Proof points [#proof-points]

On `/proof-points/*` each term maps to indexed parent-GPE fields:

| Term                | Index field            |
| ------------------- | ---------------------- |
| `title:a`           | `parent_gpes__title`   |
| `summary:a`         | `parent_gpes__summary` |
| `a` or `document:a` | `parent_gpes`          |

## Facts and manifestations [#facts-and-manifestations]

On `/facts/*`, `gpeQuery` keeps organizations (and investment / acquisition parties) whose headquarters is in a matching GPE. Field prefixes are accepted so the same expression works across routes, but they do not change HQ matching.

Investment and acquisition `topicLink` (`investor` / `investee`, `acquirer` / `acquiree`, or both) also selects which party’s HQ is checked.

`POST /manifestations/search` uses the proof-point parent-GPE index for document-backed types and the HQ walk for fact-backed types (`organization`, `investment`, `acquisition`).

Schemas for all operations are in the [OpenAPI spec](https://connect-api.trendtracker.ai/openapi.json) and the [API reference](/docs/api-reference). Machine-readable docs: [/llms-full.txt](/llms-full.txt). See [GPE query syntax](/docs/proof-points#gpe-query-syntax) for the shared language.

## Migrate with an LLM [#migrate-with-an-llm]

Paste the prompt below into Cursor, ChatGPT, or another coding agent **in the repository that calls Connect**.

```text
Migrate this codebase off the removed Trendtracker Connect API request field `gpeIds`
onto the single `gpeQuery` expression.

Source of truth (fetch these; do not invent schemas):
- OpenAPI JSON: https://connect-api.trendtracker.ai/openapi.json
  (If CONNECT_API is set, use `{CONNECT_API}/openapi.json` instead.)
- Release note with these rules: Connect API docs "Release 0.0.4".

Scope: request bodies sent to /proof-points/*, /facts/*, and /manifestations/search.
Do NOT change callers of deprecated /indicators/* routes: those keep nested
parent-GPE filters and are mapped server-side.

Rules:
1. Find every request body, client method, type, fixture, and test that sets
   `gpeIds` on a /proof-points, /facts, or /manifestations call. These fields
   are silently ignored by the API, so there is no error to grep for: search
   the field names.
2. Replace them with a single `gpeQuery` string built from GPE UUIDs:
   - gpeIds: [a, b]     -> "a OR b"
   - title-only mentions -> "title:a OR title:b"
   - summary-only        -> "summary:a OR summary:b"
   - all fields / body   -> "a OR b"   (unprefixed)
3. Terms must be GPE UUIDs. Operators are AND / OR / NOT, uppercase only.
   AND binds tighter than OR, so add parentheses when mixing them.
   Never emit `body:` (use `document:` or no prefix) and never quote terms.
4. Do not expand a GPE to its child regions. Querying a country already
   matches city mentions and HQs in that country.
5. If a caller builds GPE filters from user input or config, add the join
   logic in one helper rather than at each call site.
6. Update tests and fixtures. Report any caller you could not map.
```
