shinnslist

faq LIVE

short answers from the real code — every one re-derived from the deployed functions before a word was written.

no invented answers. Each answer below cites the file and constant it was taken from. If a capability is planned but not built, its answer carries a DRAFT badge instead of a working example.

how do i get an api key?

POST /api/keys — self-service, no signup flow behind it today. It returns a raw key; only the hashed record is stored server-side. /api/keys only ever issues the free tier (functions/lib/api-keys.js: /api/keys only ever issues `free`).

Send the key on every call as the x-api-key header (line 80 of api-keys.js) or as ?key= (line 82). Check your own usage anytime at GET /api/keys/usage, which reports quota: { used, limit, remaining, resets_at } and rate: { per_minute }.

Tier facts, straight from the TIERS table: free = 25 intel calls/day, 10 req/min; anon (no key) = 5/day, 2/min per IP. pro (1000/day, 60/min) is reserved: true — no issuance path exists yet, so it ships with the payments track. Full detail: api keys.

what do "retrieved_at" and "data_as_of" mean?

Every record carries its own freshness stamp. retrieved_at is set by the pipeline: the moment the data was pulled from its source. data_as_of is declared by the adapter itself: how fresh the underlying source record is — and it is honestly null when the adapter can't know.

That split is deliberate: retrieved_at tells you when we fetched; data_as_of tells you when the record was true at the source. A null data_as_of is not a bug — it is the page refusing to invent a date. Full detail: data freshness.

what does a "degraded" signal status mean?

It means the signal works but its honesty conditions changed — a source went stale, a feed partial, a rate limit started throttling. The statuses are generated from the build's own docs/ADAPTER-QUEUE.md: live, degraded (with the exact reason), or pending (not built). Degraded is a staleness signal: treat those records as older than their retrieved_at suggests and re-check the freshness page before acting on them.

how do recipe pricing and credits work?

Recipes are deterministic, billable plans. calls = parcels × signals, computed by compileRecipe in functions/lib/v1-recipes.js before any data is touched. Save and estimate are unbilled; only runs bill, and only for completed evaluations — a failed evaluation is itemized with billed: false and consumes nothing.

The estimate binds the charge: for the same recipe version + parcel set, calls_estimated must equal calls_consumed. If they ever differ, the difference is credited — the billing block carries credit_calls = max(0, calls_estimated − calls_completed) and credit_usd at the modeled price. The estimate response tells you the price basis: price_per_call_usd = 0.003, explicitly modeled — no real charges exist today.

Cost figures, re-derived: the v1 supply-layer free tier is FREE_TIER_MONTHLY_CALLS = 1000 calls/month (hard cap, $0); runs above 1,000 calls require an estimate_id (no blind execution); the large-run gate answers 400 bad_params without it. Full detail: v1 recipes and usage & billing.

is this on-market or off-market data?

Off-market only — never listing data. The signals are built from public records (assessor data, county parcel rolls, public filings) to surface parcels and motivated sellers before a listing exists. The docs hub's honest-status promise applies: if a signal has no free source, the docs say so instead of fabricating results. Results are any parcel the public data supports — not on-market inventory.

what happens when a signal isn't built yet?

The api tells you honestly instead of guessing. Three cases, straight from functions/lib/v1-recipes.js contract §1.4:

Every signal's live/degraded/pending status is on the api reference, regenerated from the build's own records.

where do mcp and agent tools fit?

MCP is the agent path into the same engine. JSON-RPC 2.0 at POST /api/mcp: one tool per registered signal adapter — 270 today — each named by kebab-case slug (e.g. well-depth-drill-cost). Three methods: server/discover, tools/list, tools/call.

Same gates as REST: tools/call counts as one intel call against the same daily quota and same x-api-key auth; server/discover and tools/list are free. Protocol revision 2026-07-28, stateless — no initialize handshake. Full detail: mcp.

do i get charged for anything today?

No. There are no real charges anywhere in the build — every dollar figure in the docs ($0.003/call, the $29/$99/$349 plans in the model) is pricing math, not a price anyone has been charged. What is enforced: the quota gates. Anonymous = 5 intel calls/day per IP; a free key = 25/day; v1 free tier = 1,000 calls/month hard cap. When you exceed a cap you get an honest daily_quota_exceeded (429) with resets_at, never a bill.

rate limits, in short

Two layers (functions/lib/rate-limit.js and functions/lib/api-keys.js): a 100 req/min sliding-window edge limit per client IP, plus per-endpoint token buckets and per-tier per_min caps (anon 2, free 10, pro 60). Denied requests don't consume quota. The Retry-After header and the exact 429 shapes are on the rate limits page.

planned but not shipped DRAFT

next: docs hub · getting started · api reference · still stuck? the chat answers from the same live data.