Ask the record
in SQL.
For researchers who want more than the endpoints: read-only SQL over the same launches, outcomes, scans, flags and labels the site publishes. One statement, views only, every limit stated.
Who can
query.
The Pro tier, by session or by a Pro API key, or a wallet given a research grant. Researchers without Pro can ask for a grant through the contact page; grants are for published or publishable work.
Limits: stated by the API at /v1/research/schema, which is not reachable right now. Over the quota the API answers 429 with Retry-After.
One
statement.
curl -X POST https://cyclopslabs.dev/api/v1/research/sql \
-H "x-api-key: $CYCLOPS_API_KEY" -H 'content-type: application/json' \
-d '{"sql": "select outcome, count(*) as launches, round(avg(volume_eth)::numeric, 3) as avg_volume_eth from research_launches group by outcome order by launches desc", "limit": 100}'{
columns: string[], // in select order
rows: unknown[][], // one array per row, same order as columns
rowCount: number, truncated: boolean, limit: number,
cost: number, ms: number, // planner estimate, run time
views: string[], // the research views the query read
quotaRemaining: number
}select g.verdict, count(*) as launches,
avg(s.score) as mean_score,
count(*) filter (where s.flag_keys like '%bundled%') as with_bundled_flag
from research_ground_truth g
join research_scans s on s.token = g.token
where g.reviewed
group by g.verdicttruncated is true when there were more rows than limit; narrow the query or aggregate. cost is the planner’s estimate the query was admitted on.
What is
allowed.
- 01One SELECT, or WITH … SELECT. No semicolons, comments, quoted identifiers, dollar quotes or backslashes.
- 02Only the research_* views below (and your own CTEs) after FROM and JOIN. No other table, schema or catalogue.
- 03Common aggregate, window, maths, text and date functions (count, avg, percentile_cont, date_trunc, row_number, string_agg and similar). Anything else is refused with its name.
- 04Casts to plain types only (integer, numeric, double precision, text, date, timestamptz, interval, boolean).
- 05No recursive CTEs, no FOR UPDATE, no INTO. Every query runs in a read-only transaction.
A refused query answers 400 with error: "query_rejected" and the reason, as does a query the database rejects (an unknown column, a syntax error).
What you
can read.
It is read from GET /v1/research/schema and appears here when the API answers. Nothing is listed from memory.
The views are public projections of chain-derived data. They carry no emails, sessions, keys, account settings, Telegram ids or reviewer identities. Outcomes follow the methodology; scores are the latest stored scan, with its score version.