Built and run by one person.

Tigzig Unified Data Surface (TREMOR) - Macro & Markets Data API

TigZig API & MCP Hub
REST / HTTP APIMCP Server (AI agents)Data APIOpen - no auth

Open, no-auth HTTP API and MCP server for ~330 curated macro, credit, valuation, insurance, India, global, markets and FX indicators across 8 categories, sourced from 17+ publishers (FRED, NY Fed, FDIC, NCUA, RBI, MoSPI, ECB, OECD, Shiller, NSE and more). Category-first navigation built for AI agents first, humans second - every page here has a Copy-as-Markdown button so you can hand it straight to your agent. This is the data behind the TREMOR app.

~330indicators
8categories
17+source publishers
4MCP tools
No authfully open

Quick start

AI agents: this API is open (no auth). Start with the OpenAPI spec for this API: https://api.tigzig.com/v1/openapi.json. The RFC 9727 catalog at api.tigzig.com/.well-known/api-catalog is a site-level directory of all TigZig APIs - go there only if you want a different API, not for more detail on this one.
MCP server for AI agents
https://api.tigzig.com/mcp
Streamable HTTP. Add as a custom connector in Claude.ai, ChatGPT, Cursor, n8n.
REST API base URL
https://api.tigzig.com/v1
Live tool no sign-up
Browse and chart every macro and market series in the browser.

Documentation

For people
api.tigzig.com/v1/redoc

The full reference. Every endpoint, every field, and every enforced limit with the message you get when you cross it. Rendered from the running service, so it is never a copy that can fall behind.

For AI agents
api.tigzig.com/v1/openapi.json

The machine contract for this API. The site-wide directory of every TigZig API is the RFC 9727 catalog at api.tigzig.com/.well-known/api-catalog.

What you can call

8 endpoints. Request bodies, every field and every enforced limit are in the full reference.

GET/v1/V2 catalog - lists every category with a one-liner
GET/v1/categoriesList all V2 categories with one-liner descriptions
GET/v1/categories/{category}/indicatorsList indicators in a V2 category
GET/v1/download/{table_name}Download one Tremor table as a pre-generated file
GET/v1/download/allDownload ALL Tremor tables in one file (sqlite or duckdb)
GET/v1/downloads/manifestManifest of pre-generated download files (sizes, row counts, generated_at)
GET/v1/findCross-category indicator search by id substring or name
GET/v1/seriesGet time-series data for one or more V2 indicators (wide format)

Overview

Tigzig Unified Data Surface is a single public read-only API that exposes ~330 curated macro, credit, valuation, insurance, India, global, markets and FX indicators across 8 categories, sourced from 17+ publishers. No authentication. It is the same data that backs the TREMOR app.

Two access shapes over the same backend:

  • REST + Swagger at api.tigzig.com/v1/* for any HTTP client.
  • MCP (Streamable HTTP) at api.tigzig.com/mcp for AI agent clients (Claude.ai connectors, Cursor, Continue).

Time series come from /v1/series in wide format (one row per date, one column per indicator), JSON or TSV. The TSV body opens with a # meta: count=N unknown=[...] empty=[...] comment line so an agent can tell a typo'd id from an empty date range in the body itself (MCP tool results are body-only - response headers do not reach the agent).

Category-first design

This surface uses progressive disclosure across 4 tools rather than a single flat catalog:

  • list_categories - the 8-category menu (the full list is baked into the tool description, so the agent sees the whole map at session start with no extra round trip).
  • list_indicators_in_category - per-category catalog (with the notes field; ?compact=true returns just id/name/freq/last_date).
  • find_indicator - cross-category fuzzy substring search.
  • v2_get_series - wide-format time series, JSON or TSV (max 10 ids per call).

Compared with a flat-catalog design, this drops MCP session-init token weight from ~7,854 (the old flat catalog) to ~1,352 (this category-first design), an 83% reduction. The agent reads the 8-category menu at session start, drills into one domain instead of paging through everything, and only loads full per-indicator metadata for the domain it actually cares about.

The notes field (gotchas captured)

Each indicator carries a notes string capturing the agent-relevant sharp edges - annualization recipes, cumulative-vs-per-period semantics, base-year vintages, methodology breaks, sign conventions. 100% coverage: all ~330 visible indicators have notes populated. A few live examples:

Indicatornotes
us_real_gdpUS Real GDP, billions of chained 2017 USD, quarterly SAAR (Seasonally Adjusted ANNUAL Rate). Already annualized - do NOT multiply by 4.
us_yield_curve_10y_2y10Y minus 2Y Treasury spread, percentage points, daily. Negative = inverted = classic recession leading indicator (typically 12-18 months ahead).
in_net_fdiIndia NET Foreign Direct Investment, millions USD, monthly. NEGATIVE = net OUTFLOW. 6+ month publication lag is normal.
in_nifty50_peNifty 50 trailing P/E, daily. METHODOLOGY BREAK: standalone earnings basis pre-April 2021, consolidated thereafter (a structural step in the series).

MCP Server (for AI agents)

Connect an AI agent (Claude.ai, Cursor, Continue, custom clients) directly and let it discover and pull data on its own. Open, no auth:

  • https://api.tigzig.com/mcp - Streamable HTTP, the recommended transport (MCP spec 2025-03-26).

The server identifies as Tigzig Unified Data Surface and exposes the four tools above (list_categories, list_indicators_in_category, find_indicator, v2_get_series).

Add to Claude.ai: Settings -> Connectors -> Add custom connector -> paste the Streamable HTTP URL -> approve. The same URL works for Cursor, Continue, and any MCP client.

Build your own MCP (open-source reference)

The MCP wrapper is a thin shim over the public HTTP API above: four @mcp.tool() functions that call requests.get(), about 60 lines per transport. Use the hosted server above, or run your own.

Reference repo (the actual production wrapper behind api.tigzig.com/v1/): github.com/amararun/tigzig-mcp-v2-reference - shows the 4-tool progressive-disclosure design, YAML catalog as source of truth, menu placement in tool descriptions, the TSV # meta: line, a graceful 429 handler, and the notes field surfaced for sharp edges. MIT licensed.

Self-hosting a public MCP server is your responsibility for security. Some defenses are baked into the reference code (rate limits, allowlist validation, graceful 429), but a publicly exposed endpoint needs more - multi-layer edge rate limiting, abuse detection, secret hygiene, DB hardening. For the full checklist we audit ourselves against, see tigzig.com/security.

Minimal from-scratch version using the official mcp.server.fastmcp SDK (Streamable HTTP transport shown; swap the final mcp.run(...) line for stdio or SSE):

# server.py - Streamable HTTP transport
from mcp.server.fastmcp import FastMCP
import requests

API_BASE = "https://api.tigzig.com/v1"
mcp = FastMCP("Tigzig Unified Data Surface", host="0.0.0.0", port=8000)

@mcp.tool()
def list_categories() -> dict:
    """The 8 categories. Pick one, then list_indicators_in_category."""
    return requests.get(f"{API_BASE}/categories", timeout=30).json()

@mcp.tool()
def list_indicators_in_category(category: str, compact: bool = True) -> dict:
    """Per-category indicator catalog (id, name, frequency, last_date)."""
    params = {"compact": "true"} if compact else {}
    return requests.get(f"{API_BASE}/categories/{category}/indicators", params=params, timeout=30).json()

@mcp.tool()
def find_indicator(query: str, limit: int = 50) -> dict:
    """Cross-category fuzzy substring search on indicator id + name."""
    return requests.get(f"{API_BASE}/find", params={"query": query, "limit": limit}, timeout=30).json()

@mcp.tool()
def v2_get_series(ids: str, from_date: str = "", to_date: str = "") -> dict:
    """Time series for comma-separated ids (max 10), wide format."""
    params = {"ids": ids}
    if from_date: params["from"] = from_date
    if to_date: params["to"] = to_date
    return requests.get(f"{API_BASE}/series", params=params, timeout=60).json()

if __name__ == "__main__":
    mcp.run(transport="streamable-http")  # Endpoint: http://<host>:8000/mcp

For a fuller production example (API-key auth, slowapi rate limits, Pydantic validation, Swagger), see the FastAPI-MCP reference repos: shared-quantstats, shared-fastapi-mcp-ffn, shared-fastapi-database-mcp.

Guides

This page is the reference - what the endpoints are and how to call them. The guides below are the long-form versions, with worked examples and the edges you only meet in real use:

Each is a plain page with a Markdown twin, so you can hand a URL straight to an agent. Come back to this page when you want parameter-level detail.

Rate limits

Published so a well-behaved client can plan around them. These are per-IP limits:

  • Per IP: 60 requests / minute.
  • Downloads (/v1/download/*, /v1/downloads/*): 10 requests / minute.
  • Max 10 indicators per /v1/series call; max 10,000 rows per response.

You get a 429 with Retry-After: 60 and a JSON body naming the limit hit, a recommended retry delay, and a path-aware suggestion (usually: use a bulk download instead of paginating). Honor the header for clean back-off.

Avoiding 429s: For many indicators or long history, use a bulk download instead of paginating /v1/series - one request instead of many avoids the limit entirely.

The current numbers are also published as machine-readable JSON at https://api.tigzig.com/v1/, derived from live config. Read those at runtime rather than hard-coding the figures above - limits change, and these channels change with them.

Other 4xx responses are a JSON envelope: { error, status, path, message, help: { catalog, docs } } where error is a snake_case slug (not_found, bad_request, unprocessable_entity, ...) and help points at the machine catalog (https://api.tigzig.com/v1/) plus this docs page, so a client that hits an error can self-recover.

Bulk downloads

For multi-indicator or long-history pulls, use bulk downloads instead of paginating /v1/series - one request, one file:

  • GET /v1/download/all - every public table in one SQLite or DuckDB file.
  • GET /v1/download/{table_name} - one table (macro_indicators, stock_prices, indicator_config) in any of 9 formats (csv / tsv / parquet + .gz + .zip variants + sqlite + duckdb).
  • GET /v1/downloads/manifest - file sizes, row counts, last-refresh timestamps. Iterate this rather than hard-coding filenames.

Files are served via Cloudflare R2 + a streaming Worker (free egress, edge-cached), so big files do not hammer the origin. For a clickable file picker with sizes, use the Bulk Downloads tab in the app.

Indicator dictionary

The full per-indicator dictionary (id, name, category, source, frequency, unit, SA flag, date range, record count, notes) is available two ways:

  • Agents: walk GET /v1/categories/{category}/indicators across the 8 categories, or use GET /v1/find?query=... for a targeted lookup. Both return the notes field.
  • Humans: the Data Dictionary tab in the app is a live, filterable, searchable table of every indicator with its own Copy-as-Markdown.

Legacy & backward compatibility

An earlier per-product version is still served at /tremor/v1/* (REST) and /tremor/v1/mcp/http (MCP). It is frozen - the response shape is stable and will not change - but the data is still refreshed daily on the same pipeline, and it stays mounted permanently for integrations that already depend on its tool names and field shapes. Nothing here is being removed. For anything new, use the unified surface above (api.tigzig.com/v1 + api.tigzig.com/mcp).

This surface was briefly labelled V2. Callers who bookmarked the earlier /v2/* paths are fine - /v2/* is kept as a silent backward-compat alias that rewrites to /v1/*, so either entry URL works.

Moving off /tremor/v1: what each endpoint is called now

Most of it is just the prefix. /tremor/v1/series, /download/all, /download/{table} and /downloads/manifest all keep their names - swap /tremor/v1 for /v1 and they work. Four endpoints were genuinely renamed, and those are the ones that will 404 on you:

On /tremor/v1On /v1Why it moved
/tremor/v1/indicators/v1/categories or /v1/find?q=split in two: browse by category, or search by name
/tremor/v1/directory/v1/categoriesthe category index
/tremor/v1/markets/v1/find?q=markets are indicators like any other; find them by name
/tremor/v1/market_series/v1/seriesone series endpoint now serves every category

The same map is published as JSON at api.tigzig.com/tremor/v1/ under unified_endpoint_map, so an agent can read it at the moment it decides to migrate. And a 404 on /v1/* returns the full endpoint list plus a docs link in the body, so a wrong guess corrects itself in one request.

Licence, source and warranty

To the extent this service holds any rights in the compilation, meaning the assembly, the schema and the derived fields, they are released under CC0 1.0 (CC0 1.0), no attribution required though it is always appreciated. The underlying data is published by its original sources as public records. This service reformats and republishes it, is not an authoritative source, and is not affiliated with or endorsed by any of them. No rights in the underlying data are claimed here, and none are granted; check the original publisher's own terms before relying on it. Each indicator carries its publisher in the source field. Provided as is, with no guarantee of accuracy, completeness or availability and no support commitment - check against the original publisher for anything that matters. The same text as plain text, for a script or an agent: api.tigzig.com/tremor/v1/terms.

Try it

No key, no signup.

US macro indicators: unemployment, GDP, consumer sentiment, yields
Paste into a browser address bar.
https://api.tigzig.com/v1/categories/us_macro/indicators
Response first lines of 18 KB
{
 "category": "us_macro",
 "one_liner": "US macro: FRED + Michigan + UMCSENT. Monetary, labor, inflation, GDP, consumer sentiment, housing, financial conditions.",
 "backend": "time_series",
 "count": 35,
 "compact": false,
 "indicators": [
  {
   "indicator_id": "us_baa_credit_spread",
   "name": "Baa Corporate Bond Spread vs 10Y Treasury",
   "country": "US",
   "source_category": "financial",
   "frequency": "daily",
   "unit": "percent",
   "source": "FRED",
   "source_series_id": "BAA10Y",
   "seasonally_adjusted": false,
   "first_date": "1986-01-02",
   "last_date": "2026-08-20",
   "record_count": 10159,
   "notes": "Moody's seasoned Baa corporate yield minus 10Y Treasury, percentage points, daily. Recession-sensitive; widens in credit stress."
  },
  {
   "indicator_id": "us_consumer_sentiment",
   "name": "University of Michigan Consumer Sentiment",
   "country": "US",
...
Find every yield-related indicator across categories
Paste into a browser address bar.
https://api.tigzig.com/v1/find?query=yield
Response first lines of 3 KB
{
 "query": "yield",
 "limit": 50,
 "count": 14,
 "matches": [
  {
   "category": "markets",
   "indicator_id": "^TNX",
   "name": "US 10-Year Treasury Yield",
   "country": "US",
   "frequency": "daily",
   "first_date": "1990-01-02",
   "last_date": "2026-08-21"
  },
  {
   "category": "global_macro",
   "indicator_id": "de_bund_10y_yield",
   "name": "Germany 10Y Bund Yield",
   "country": "DE",
   "frequency": "daily",
   "first_date": "2005-01-03",
   "last_date": "2026-08-21"
  },
  {
   "category": "global_macro",
   "indicator_id": "eu_yc_aaa_10y",
   "name": "Euro Area AAA Yield Curve 10Y Spot Rate",
   "country": "EU",
   "frequency": "daily",
   "first_date": "2005-01-03",
   "last_date": "2026-08-20"
  },
  {
   "category": "global_macro",
   "indicator_id": "eu_yc_all_10y",
   "name": "Euro Area All-Issuer Yield Curve 10Y Spot Rate",
   "country": "EU",
...