From factiq
Answer economic and financial data questions with real data from FactIQ (worlddb): US indicators (BLS employment/CPI, BEA GDP, Census trade, EIA energy, USDA ERS, BTS transport), international data (China NBS, China customs, India MOSPI/RBI/trade, Singapore, IMF, World Bank), stock quotes and fundamentals, commodities/forex, and earnings-call intelligence. Use when the user asks about unemployment, inflation, GDP, trade flows, energy, wages, markets, or wants a shareable economic chart or a full multi-section research report. You orchestrate the whole analysis yourself — discover series, query SQL, compute, then publish either a single chart or a fully formed report as a share link.
How this skill is triggered — by the user, by Claude, or both
Slash command
/factiq:factiqThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are the analyst. FactIQ provides authenticated HTTP data tools (catalog
You are the analyst. FactIQ provides authenticated HTTP data tools (catalog search, read-only SQL, series lookup, market data, earnings search) and two publishing endpoints — a single shareable chart, or a fully formed multi-section report. There is no server-side agent in this loop: you decompose the question, find the data, do the math with your own tokens, and author the output.
Two output modes:
share-chart) — one focused chart. Default for questions
about a single metric or comparison.share-report) — summary + sections of narrative and
charts + methodology, rendered on FactIQ's share-report page exactly like
the in-house agent's reports. For broad or analytical questions. See
Detailed reports below.All access goes through the bundled CLI — no codebase or database access is needed:
python3 scripts/factiq.py <subcommand> ... # path relative to this skill dir
Shell working directory resets between calls — resolve the script's absolute path once (from this skill's directory) and use it in every invocation.
Every subcommand prints JSON to stdout. Errors go to stderr with a non-zero exit code (2 = HTTP error, 3 = rate limit / quota, 4 = server-reported tool error such as a SQL failure or statement timeout).
Auth is API-key based (fiq_... keys). The CLI looks for FACTIQ_API_KEY
in the environment first, then api_key in ~/.factiq/config.json.
Check whether auth works: python3 scripts/factiq.py whoami. If it fails,
tell the user exactly how to get a key — sign in at https://factiq.com,
open Settings → Security (https://factiq.com/settings/security), and
click Generate API key (or Regenerate; keys are shown only once,
so a key that was never copied can only be replaced). Then store it:
# Prompts securely for the key, verifies it against the API, stores it:
python3 scripts/factiq.py set-key
# Non-interactive: --key fiq_... also works
If this skill is installed as a plugin, /factiq:set-key walks the user
through the same steps.
The API defaults to https://api.worlddb.ai and the web origin (for share
links) to https://www.factiq.com. For local development override with
FACTIQ_API_URL=http://localhost:8000 and
FACTIQ_WEB_URL=http://localhost:3000 (or --base-url / --web-url,
which work before or after the subcommand).
| Command | Purpose |
|---|---|
context [--schemas bls,bea] [--full] | Lean per-schema index + the shared table DDL. Call once per session before anything else. --full returns the heavy per-dataset description dump (rarely needed — use describe instead). |
search-datasets --query "rare earth imports" [--schemas mospi,rbi] [--limit N] | Keyword (BM25, not semantic) ranking of datasets across all schemas. The first discovery step — find the right schema+dataset_code. |
describe SCHEMA DATASET_CODE | Full metadata for one dataset: topic, methodology, release dates, base-change notice, available dimensions, example series. Call after search-datasets. |
search --schema bls --terms "unemployment rate" | Series-level title-substring search within a schema (repeat --schema/--terms pairs). Includes COMPOUND:: series. |
sql --schema bls --query "..." [--explore] [--full] [--max-rows N] [--out f.json] | Read-only SELECT against one schema. Default output is a sampled preview. |
series SCHEMA SERIES_ID [--from-year Y] [--to-year Y] [--full] [--out f.json] | Fetch one series — timeseries, tabular, or COMPOUND:: ids all work. |
market FUNCTION [--symbol AAPL] [--interval] [--outputsize full] | Quotes, daily/weekly/monthly series, fundamentals (OVERVIEW, INCOME_STATEMENT, EARNINGS), FX, commodities (WTI, BRENT, GOLD), SYMBOL_SEARCH. |
earnings "QUERY" [--target sections|themes|qa_exchanges] [--companies AAPL,MSFT] [--quarter 2025Q4] | Full-text search over earnings-call intelligence. |
share-chart --spec chart.json [--question "..."] | Publish a ChartSpec, returns {shareUrl}. |
share-report --report report.json [--question "..."] [--model "..."] | Publish a multi-section report as a public shared run, returns {shareUrl, ...}. |
context once to get the compact per-schema index
and the table DDL. This is lean by design — it tells you what each schema
covers, not every dataset. Schemas listed under schemas_without_data have
no rows loaded; skip them. (You rarely need --full; use describe for
detail on a specific dataset.)search-datasets --query "..." to
rank datasets across all schemas by keyword — this is the primary discovery
step. Survey every schema that could be relevant before committing: for
India check both mospi and rbi (pass --schemas mospi,rbi); for the US
check bls, bea, census; energy means eia. Once a dataset looks
right, describe SCHEMA DATASET_CODE for its dimensions and example
series, then find the exact series with search --schema ... --terms ...
(series-level, substring — prefer short stems like rare, not rare earth) or exploration SQL (sql --explore) on the series and
dimensions tables. For multi-source stories, actually fetch data from 2+
schemas, don't just survey them.series for
1–2 known ids; sql with a CASE-WHEN pivot for 3+ series or joins.--out file. Do not look
for a server-side code interpreter; there is none in this loop.market for current quotes, commodities, and FX.references/chart-spec.md) with wide-format data rows, then
share-chart --spec chart.json. Report mode: write a report JSON (see
references/report-spec.md and Detailed reports below), then
share-report --report report.json. Either way, return the shareUrl
to the user.A report is a public, fully rendered FactIQ research page: a bulleted
summary up top, then sections that pair narrative with charts, then
methodology notes. You author the whole thing — every chart's data rows,
every narrative claim — from data you actually fetched in this session.
The JSON format, per-chart fields, and a worked example live in
references/report-spec.md. Read that file before writing the report.
Ground rules:
**bold** shows up as literal asterisks.sources (the
datasets behind it) and lineage (the SQL/computation steps you actually
ran). Charts without lineage get a generic "uploaded data" stub — fine,
but real lineage makes the "How we built this" panel meaningful. Lineage
code renders verbatim in a code block, so write it as formatted
multi-line SQL/Python — never collapsed onto one line — and list every
series the step touched in series_refs, not a single representative one.share-report validates locally, POSTs to /tools/report, and prints the
server response plus a shareUrl composed from your configured web origin.
The report appears in your FactIQ history and can be forked by anyone who
opens the share link.
--outDefault output for sql, series, and market is the same down-sampled
preview the production agent sees: enough to verify shape and values, not the
full result. For chart building you need full rows — but never dump them into
your own context:
python3 scripts/factiq.py sql --schema bls --query "..." --full --out /tmp/unemp.json
--out writes the complete JSON to disk and prints only a stub
({out, columns, row_count, written_rows, ...}). Then build the chart's
data array from the file with a local Python script. SQL --full returns up
to --max-rows rows (default 500); raise it (e.g. --max-rows 5000) to
fetch more. When the result is cut, the response sets truncated: true plus a
note, both of which the stub now echoes — and written_rows (rows actually
on disk) will be below row_count (the server's pre-truncation total). If you
see truncation, narrow the query (date range, fewer series), aggregate
server-side, or raise --max-rows.
set-key.{"error": "..."} body
(syntax errors, timeouts, bad column names). The CLI surfaces these on
stderr with exit code 4 and never writes an --out file for them.
Revise the query and rerun.references/sql-guide.md). --auto-retry opts into a server-side LLM
reviser, but you can usually revise better and cheaper yourself.series_id, dataset_code) instead of scanning titles across the table,
and never pattern-match series_id on data_points — resolve ids from
series first (see the pitfall in references/sql-guide.md).sections[1].charts[0].x_column). Fix the named fields in the JSON and
re-run; nothing was published.references/sql-guide.md — table structure, query idioms, pitfalls
(frequency literals, national vs sub-national, pivots, tabular data).references/chart-spec.md — ChartSpec format, chart-type selection, a
worked share-chart example.references/report-spec.md — report JSON format for share-report:
sections, per-chart fields, sources/lineage authoring, limits, a worked
example.references/schemas.md — what lives in each schema. The context
subcommand is the live, authoritative version; search-datasets /
describe drill into individual datasets on demand.Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Searches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
npx claudepluginhub defog-ai/factiq-claude-code-plugin --plugin factiq