Skip to main content

gdelt-cloud-docs — Agent Guide

The Mintlify site behind docs.gdeltcloud.com. It lives inside the gdelt-cloud monorepo and auto-deploys on push to main. This file is internal. It is deliberately not in docs.json, so it is excluded from the built site and from the llms.txt Mintlify generates from the nav — a crawling model should read the product, not our authoring conventions.

★ The spec and the reference tier are GENERATED — never hand-edit them

They come from the contract registry at nextjs_/lib/api/v2/registry/ — the same objects the server imports at request time to build its param allowlist and validate enums. That is what makes them trustworthy: a generated page cannot describe a value the API rejects, or omit one it accepts. To change one, edit the descriptor and run pnpm gen:contract in nextjs_/. prebuild runs the gate, so a hand-edit fails the Vercel deploy with the fix command in the error. Hand-write prose pages only. The emitter owns numbers and tables; humans own sentences.

Never restate a value list in a hand-written page

Not because duplication is untidy — because it drifts, and drifted docs are worse than absent ones. Measured on 2026-08-05 against a running server, hand-written pages claimed:
  • category is “an open vocabulary” that “also accepts CAMEO+ code strings” — category=TE01 returns 400 INVALID_CATEGORY.
  • story categories are “not a fixed enum” with ten prose theme buckets — the real vocabulary is 11 closed snake_case values, and a display label 400s.
  • CAMEO+ has 8 domains — it has 10; CRIME and DEMOGRAPHIC both work and were undiscoverable.
  • coverage starts January 2025 — that month holds 11 events. Usable coverage starts March 2026 (15,744 events). True, and a lie.
Link to /reference/enums instead. It is generated, and it carries the real rejection code per vocabulary (INVALID_ENUM, INVALID_CATEGORY, INVALID_REGION, INVALID_CONTINENT — they differ).

Open vocabularies are not enums

reference/enums.mdx renders three value-spaces in visibly different language, and the difference is load-bearing: closed (“the authoritative set; anything else 400s”), observed (“a dated MEASUREMENT; the API accepts values outside this list”), identifier (“a key, not a list”). The spec once declared a closed 13-value form_type enum against a corpus holding 264, where 424B2 alone was 21% of a 30-day window — wrong in both directions with a generator’s authority behind it. Never describe an observed vocabulary as though it were closed.

Mintlify gotchas that cost real time

  1. Inline { "openapi": "GET /path" } refs only resolve when the spec is declared at the tab or group level. A global api.openapi array is not enough — without the tab/group declaration every inline ref silently generates nothing. We declare it at the tab level and on each group holding inline refs.
  2. Generated page slugs come from the operation’s OpenAPI tags, not the nav group name. An op tagged Entities lands at /api-reference/entities/... wherever you place it. So tag and group names must avoid & and other URL-hostile characters — an & breaks slug generation and the pages silently disappear. Use “and”.
  3. Only top-level groups always expand; nested groups honour "expanded": false.
  4. A page not in docs.json is not built. An .mdx on disk with no nav entry is invisible, and a spec operation with no nav entry returns 200 at its slug while nothing links to it — five had accumulated that way, including three Atlas endpoints index.mdx tells readers to call. Guarded now by nextjs_/tests/docs/contract-doctrine.test.ts, both for operations and for generated MDX.
  5. mint dev ignores PORT. It probes 3000, then 3001. Check which one it actually bound.

Before pushing

And in nextjs_/: npx vitest run tests/docs — the reachability, banner and honesty-label guards all live there and ride the existing suite.

Layout

One canonical telling per fact. When you find a second copy, delete it and import or link the first. The metric reliability table existed twice with different numbers in the copy three pages imported; the duplication is the only reason anyone noticed, and also the reason it stayed wrong.