Documentation
GET /api/find
Serve this session's product, minting a hold if it does not have one.
| Request | GET /api/find |
|---|---|
| Authentication | Session cookie required |
| Handler | backend/server.py |
What it does
The single-product entry point. `hold_for()` resolves the session's existing hold or mints one, and the find meter lives inside that function rather than in the handler — every caller that can create a hold is metered by the same code. The served product is recorded in `seen`, and the `find_served` and `shown_field` milestones advance. A hold lasts 30 minutes; `held_minutes` in the response states that rather than leaving the client to assume it.
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/find"const res = await fetch("https://flowfinds.ai/api/find", {
method: "GET",
credentials: "include",
});
const data = await res.json();import requests
s = requests.Session()
r = s.get("https://flowfinds.ai/api/find")
data = r.json()Recorded example
curl -s -b cookies.txt -c cookies.txt \
"$FLOWFINDS_ORIGIN/api/find"Responses
200 — A product is held or could be minted for this session.
| Field | Type | Description |
|---|---|---|
id | string | Catalog identifier for the product. |
name | string | Product name from the catalog. |
score | number | Computed by `server.score` from the evidence legs, today's date and evidence staleness. Never stored, never hand-written. |
evidence_age_days | number | Age of the oldest supporting evidence leg, in days. |
freshness | number | Decay factor derived from evidence age, rounded to three decimals. |
held_minutes | number | Length of the hold window in minutes — 30 at the time of writing, served rather than assumed. |
servable | number | How many catalog products remain servable to anyone right now. |
yours | boolean | True on the product resolved for this session. |
sample | object | Sample-order quote from `sample_market.quote`, or its refusal. |
preview_available | boolean | Whether `/preview/<id>` will resolve. False when no live offer exists, because a preview with an invented price is worse than no preview. |
preview_url | string | null | `/preview/<id>` when a preview exists, otherwise null. Served so no client hand-builds the path. |
evidence | array | The catalog evidence rows behind the find: claim, source, URL and date per leg. |
200 — Nothing can be served: the catalog is exhausted, everything is held by other founders, this session has passed on everything, or the session is at its own claim allowance.
| Field | Type | Description |
|---|---|---|
status | string | `refused`. |
reason | string | One of `all_held`, `passed_out`, `catalog_exhausted` or `claim_limit_reached`. These are deliberately distinct: being at your own allowance has a different exit from the catalog being taken. |
explanation | string | The sentence the screen shows. |
servable | number | Products still servable to somebody. |
Example response
{
"id": "…",
"name": "…",
"score": 78,
"evidence_age_days": 6,
"freshness": 0.918,
"held_minutes": 30,
"servable": 11,
"yours": true,
"preview_available": true,
"preview_url": "/preview/…"
}Errors
| Status | Reason | When |
|---|---|---|
429 | usage refusal | The find meter inside `hold_for` refuses: this session has spent its allowance for the period. The body is `_usage.refusal(...)` and names the tier and the limit. |
Related
GET /api/feed— Serve the whole field: this session's find first, then what it beat.POST /api/select— Move this session's hold onto a named product from the field.POST /api/pass— Claim the held product, or pass on it and be shown the next one.POST /api/analyze— Run the analyser over any product description, claimed or not.GET /api/analysis— The analysis of the product this session holds.POST /api/ask— Ask a question against one or more catalog products.POST /api/discover— Run the discovery script and return its terminal output verbatim.GET /api/discovery-research— Read the state of the external discovery research job.
Back to the API reference index, or read the cookbook for recipes that compose this endpoint with others.