API reference

Every endpoint answers JSON from /api/v1. Each item carries its retailintel.in page (cite it) and the link to the original report. The same contract as an OpenAPI 3.1 document: .

# Every call: your key in the header
curl -H "Authorization: Bearer $KEY" \
  /api/v1/brief

Keys

Send your key on every call as Authorization: Bearer ck_live_… (the key itself starts ck_live_). It is shown once, when you create it, and never sent by email.

read scope
Every GET endpoint.
ask scope
POST /ask, cited answers. Pro keys only.

Apply for a free key, then create, revoke and watch it on your keys page. A revoked key answers 401 invalid_key within a minute.

Limits and headers

Limits are per account (every key on it, REST and MCP together), per minute and per 24 hours from the account’s first call of the window; the numbers per tier are on . A blocked request does not use up quota. Every answer carries:

X-RateLimit-Limit
Requests allowed in the window (the day window unless a minute limit was hit).
X-RateLimit-Remaining
Requests left in the window.
X-RateLimit-Reset
Unix time (seconds, UTC) when the window resets.
X-Request-ID
Quote it when you write to us.
Retry-After
On a 429: seconds until the window that blocked you resets.

Errors

An error is JSON: { "error": "<code>", "message": "…" }. A 429 adds limit, retry_after and how_to_get_more.

Error codes
StatusCode and meaning
400invalid_request A parameter or the body is missing or malformed; the message names it.
401auth_required No key was sent.
401invalid_key The key was revoked, expired or never issued.
403insufficient_scope The key lacks the scope the endpoint needs (read or ask).
403pro_required The endpoint, or an option such as a longer Watch window, comes with Pro.
404not_found No public signal or brand has that slug.
410not_offered A surface we no longer offer (webhooks): poll /signals with since= or a cursor.
429rate_limited The minute window is full: retry after Retry-After seconds.
429quota_exhausted The day is spent: stop until X-RateLimit-Reset.
429ask_quota The account has used its questions for the day, site and API together.
500server_error Our side failed. Retry in a moment; quote X-Request-ID if you write to us.

Endpoints

GET /api/v1/signals

Latest moves in Indian retail, newest first.

Public signals, 20 per page (max 50). Resurfaced old news is left out. Pass next_cursor back as cursor for the next page; with kind set a page can hold fewer items than limit, so keep going until next_cursor is null.

Example GET /api/v1/signals?brand=zepto&limit=3

Parameters
NameWhat it does
brandstringBrand slug (as in /brand/<slug>). Stories ABOUT the brand unless mentions=true.
mentionsbooleanAlso include stories that only mention the brand
themestringTheme slug (as in /theme/<slug>), e.g. store-opening
kindMoveKind of move
sincestring (ISO 8601)ISO 8601 date or time; only moves published at or after it
limitinteger1–50 Default 20.
cursorstringnext_cursor from the previous page
Returns
FieldWhat it holds
signalsSignalItem[]See SignalItem[].
next_cursorstring or null—

Also answers 400, 401, 403, 429 (errors).

GET /api/v1/signals/{slug}

One move: what happened, why it matters, what to watch.

Parameters
NameWhat it does
slugrequiredpath segment, stringSignal slug (as in /signal/<slug>)
Returns
FieldWhat it holds
signalSignalDetailSee SignalDetail.

Also answers 301, 401, 403, 404, 429 (errors).

GET /api/v1/brands/{slug}

A brand: its coverage, last 30 days by kind of move, and its 10 latest moves.

Example GET /api/v1/brands/dmart

Parameters
NameWhat it does
slugrequiredpath segment, stringBrand slug (as in /brand/<slug>)
Returns
FieldWhat it holds
brandobject—
brand.namestring—
brand.slugstring—
brand.urlstring—
brand.storiesintegerDistinct stories that name it
brand.stories_aboutintegerStories about it
brand.first_seen_atstring or null—
brand.last_seen_atstring or null—
brand.last_30_daysobject or null—
brand.themesobject[]—
brand.related_brandsobject[]—
brand.top_outletsobject[]—
latestSignalItem[]See SignalItem[].

Also answers 301, 401, 403, 404, 429 (errors).

GET /api/v1/watch

Competitor Watch: what a set of brands did, side by side, by kind of move.

Counts of public, dated, source-cited stories about each brand (one event counts once), against the equal window before. Free keys: up to 5 brands over 7 days. Pro: up to 25 brands over 7, 30, 90 days.

Example GET /api/v1/watch?b=blinkit,zepto&days=7

Parameters
NameWhat it does
brequiredstringComma-separated brand slugs, e.g. blinkit,zepto,instamart (a retired slug resolves to the brand it now redirects to)
daysinteger: 7 | 30 | 90Window: 7 | 30 | 90 Default 7.
Returns
FieldWhat it holds
window_daysinteger—
sincestring—
untilstring—
brandsobject[]—
brands[].namestring—
brands[].slugstring—
brands[].urlstring—
brands[].totalinteger—
brands[].prior_totalinteger—
brands[].by_moveobject—
brands[].prior_by_moveobject—
brands[].citiesstring[]—
brands[].latestobject[]—
quietstring[]Brands with no story about them in twice the window

Also answers 400, 401, 403, 429 (errors).

GET /api/v1/brief

Today's brief: the most widely reported moves, each with why it matters and what to watch.

The same read as the 07:30 IST email brief, optionally narrowed to stories about the given brands and/or to themes.

Example GET /api/v1/brief?brands=dmart,zepto

Parameters
NameWhat it does
brandsstringComma-separated brand slugs
themesstringComma-separated theme slugs
hoursintegerLook-back window, 1–72 Default 24.
Returns
FieldWhat it holds
datestringIST date, YYYY-MM-DD
labelstring—
window_hoursinteger—
filtersobject—
filters.brandsstring[]—
filters.themesstring[]—
itemsBriefItem[]See BriefItem[].

Also answers 400, 401, 403, 429 (errors).

POST /api/v1/ask

A cited answer over Indian retail moves (Pro). Pro keys only.

Pro keys with the ask scope. Counts against the account's 200 questions a day (site and API together). Set stream=true for server-sent events.

Body (JSON)
FieldWhat it holds
messagesobject[]The last message is the question
messages[].rolestring: user—
messages[].contentstring1–500 characters
streamboolean—
Returns
FieldWhat it holds
contentstringMarkdown answer; [sig_…] marks a cited signal
citationsobject[]—
confidencenumber—
request_idstring—

Also answers 400, 401, 403, 429 (errors).

Fields

Move

What kind of move: stores, deals (funding, M&A, listings), people, results (and outlook), launches (and pricing), strategy, rules (regulation, legal), other.

One of stores, deals, people, results, launches, strategy, rules, other.

BrandRef

BrandRef fields
FieldWhat it holds
namestring—
slugstring—
urlstringBrand page on retailintel.in
rolestring: primary | secondaryprimary = the story is about the brand; secondary = a mention

Source

Source fields
FieldWhat it holds
outletstring or nullPublisher name
urlstring or nullLink to the original report

SignalItem

SignalItem fields
FieldWhat it holds
idstringStable id
slugstringStable slug
urlstringCanonical page on retailintel.in — cite this
headlinestring—
deltastring or nullThe move in one figure, e.g. "+₹425 cr Series D"
summarystring or nullOne-sentence answer
moveMoveSee Move.
kindstring or nullEditorial kind, e.g. "EXPANSION · E-COMMERCE"
themeobject or null—
theme.slugstring—
theme.urlstring—
brandsBrandRef[]See BrandRef[].
citiesstring[]—
published_atstring (ISO 8601)ISO 8601, when RetailIntel published it
event_atstring or nullISO 8601, when it happened, when known
sourceSourceSee Source.
outletsintegerPublishers that reported it

SignalDetail

Everything in SignalItem, plus:

SignalDetail fields
FieldWhat it holds
deckstring or null—
why_it_mattersstring or nullWhy it matters, from the stored analysis
what_to_watchstring or nullWhat to watch next
key_factsstring[]—

BriefItem

BriefItem fields
FieldWhat it holds
headlinestring—
urlstring—
deltastring or null—
why_it_mattersstring or null—
what_to_watchstring or null—
brandstring or null—
sourceSourceSee Source.
other_outletsinteger—
published_atstring (ISO 8601)—

Error

Error fields
FieldWhat it holds
errorstringMachine-readable code
messagestringWhat happened and what to do

RateLimited

Everything in Error, plus:

RateLimited fields
FieldWhat it holds
errorstring: rate_limited | quota_exhausted | ask_quotarate_limited (the minute window; retry after Retry-After) or quota_exhausted (the day is spent)
limitobject—
limit.windowstring: minute | day—
limit.maxinteger—
limit.planstring: free | pro—
retry_afterintegerSeconds
how_to_get_morestring—
upgradestring—

MCP server

/mcp speaks MCP over Streamable HTTP, read-only. Without a key it allows 50 tool calls a day and 30 a minute per caller; from Claude, ChatGPT, Perplexity or Muse’s own servers each connector session counts on its own, inside a shared 2,000 a day per assistant. With a key (Authorization: Bearer or X-API-Key) calls count against the key’s account, as REST calls do.

Over a limit, the tool answers isError: true with a sentence that names the reset time in IST; it never answers 401 for a limit. A key that is not active gets 401 and a JSON-RPC error.

Tools
ToolWhat it answers
latest_movesWhat moved in Indian retail, newest first; by brand, theme or kind of move.
get_signalOne move in full: why it matters, what to watch, key facts, source; MCP Apps hosts show it as a card with its chart.
brand_profileOne brand's last 30 days against the 30 before, by kind, with its latest moves; MCP Apps hosts show our read, key numbers, its chart and rivals as a card.
compare_brandsCompetitors side by side (Competitor Watch); MCP Apps hosts show the table and a chart.
daily_briefThis morning's most widely reported moves, as the 07:30 IST email carries them; MCP Apps hosts show each move with its chart.
get_expansion_mapWho is opening where: one city or mall — openings by category and mall, who to pitch, and every opening with its report.
get_groupOne group (Tata, Reliance, Aditya Birla, DMart's Avenue…): its businesses' season so far, the revenue-growth chart as HTML, key numbers, moves and what to watch.
get_leadership_movesWho joined, left or was promoted at Indian retail and consumer companies: the week's count, our read for your role, the seats to watch, and every move with its report; by company, sector or lens.
searchFind brands, themes and moves.
fetchThe full text of one search result.

Each tool’s arguments come with tools/list. Discovery: server card and manifest.

get_signal is also an MCP App: it links the card ui://retailintel/signal-card.html (text/html;profile=mcp-app) and returns structuredContent for it, so a host that shows MCP Apps draws the move with its chart. Any other client reads the same text. Reading the card spends no tool call.