Documentation
GET /api/dashboard
The verdict, the facts behind it, and where each figure came from.
| Request | GET /api/dashboard |
|---|---|
| Authentication | Session cookie required |
| Handler | backend/server.py |
What it does
Every figure is read from the resolver that owns it — `dashboard_facts` calls the same `offer_for` that `/api/offer` serves — and `source_of_truth` names the function behind each one, so a reviewer can check the dashboard is reading rather than re-deriving, and a gate can assert agreement mechanically instead of comparing numbers that happen to match today.
Authentication
Session cookie required. Send the ff_session cookie. Without one the engine treats the caller as a new visitor with no holds and no claims, and returns a new cookie to use from then on.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
ff_session | cookie | string | Optional | The session identifier. Omit it on the first call and store the value the response sets; every later call must send the same one or the engine treats the caller as a new visitor with no holds and no claims. |
Request
The cookie jar carries the session between calls. Angle-bracketed values are the parameter types from the table above.
curl -s -b cookies.txt -c cookies.txt \
"https://flowfinds.ai/api/dashboard"const res = await fetch("https://flowfinds.ai/api/dashboard", {
method: "GET",
credentials: "include",
});
const data = await res.json();import requests
s = requests.Session()
r = s.get("https://flowfinds.ai/api/dashboard")
data = r.json()Recorded example
curl -s -b cookies.txt -c cookies.txt \
"$FLOWFINDS_ORIGIN/api/dashboard"Responses
200 — A product is resolved for this session.
| Field | Type | Description |
|---|---|---|
product_id | string | The resolved product. |
verdict | object | The daily verdict — quiet or attention — computed over the facts. |
facts | object | `name`, `score`, `evidence_age_days`, `freshness`, `sample`, and when a live offer exists `our_price_usd`, `observed_low_usd`, `undercut_pct`, `undercut_basis`, `margin_pct`, `margin_basis`, `price_freshness`. When no offer exists, `offer_status` carries the refusal reason instead. |
facts.source_of_truth | object | Field name to the function that produced it: `server.score`, `server.freshness`, `server.offer_for`, `server.headline_for`, `sample_market.quote`. |
exclusivity | object | How many founders have been shown this product, and whether the claim is exclusive. |
hold | object | The session's hold state. |
market_move | object | How the market has moved since the claim. |
200 — Nothing is resolved.
| Field | Type | Description |
|---|---|---|
status | string | `not_claimed`. |
explanation | string | The store copy for the state. |
Errors
This endpoint has no failure path of its own. An uncaught exception anywhere in the engine is still returned as structured JSON by the shared guard.
Related
GET /api/offer— The researched offer for the session's product, or the refusal that says why there is none.GET /api/launch— The launch facts, each with whether it is true today.POST /api/outcome— Declare what happened with a claimed product.POST /api/product— Publish a product of the founder's own into the store engine.POST /api/product-launch— Drive the launch state machine for a product.POST /api/presence— Record which screen the operator is on.
Back to the API reference index, or read the cookbook for recipes that compose this endpoint with others.