costQL
offline-firstTry the playground
GraphQL cost, quoted offline

Price GraphQL queries before they run.

Point costQL at your API once.
It writes a pricing pack: one small file your app can use to price any query, instantly, with no calls to a server.

costql quote
tmdb_t3.json · fully offline
movie(id)4.0
cast(limit:8)12.5
person.name ×834.0
confidencehigh
typical (work-ms)36.4
safe max (work-ms)50.5

Build once. Quote anywhere.

Three steps take you from a live endpoint to a pricing pack your app carries with it.

step 1

Adapt

Tell costQL where your API lives and give it a few real IDs to query with. That's a short adapter file, about 90 lines. Three finished examples ship in the repo.

The adapter guide →
step 2

Build

Run costql build. It sends calibration queries to your API, times the answers, and saves everything it learned as one JSON file: the pricing pack.

schema + rates + fees → one JSON
step 3

Quote

Load the pack in Python or JavaScript and price queries right where your code runs, with no more calls to your API. Both languages give the exact same answer.

Quote your first pack →
Outside calls, too:some fields call an outside service for you: an LLM, a licensed data feed. costQL can't know what that service charges, so it names the call and your app puts the price on it. External calls shows how.
from costql import PricingPack

pack = PricingPack.load("tmdb_t3.json")          # one static file
quote = pack.quote('{ movie(id:"27205"){ cast(limit:8){ person{ name } } } }')

quote["price"]         # 50.5   safe max: price on this to never undercharge
quote["typical_price"] # 36.4   typical: what the query usually costs
quote["confidence"]    # "high"

Three fidelities. Match the tier to your API.

Every price is in work-time (ms): how much real work a query causes on your server. The tiers are how much of that work costQL can see. No tier is better than another: the right one is a fact about your API and what it does.

T1

Works with any API

costQL puts one stopwatch on the whole query from the outside, with no server changes. It fits an API that does its work one step at a time, where outside timing already tells the whole story.
T2

Sees parallel work

Your server times each resolver as it runs, so work done in parallel stops hiding inside one stopwatch. The price counts the real work, not just elapsed time. It fits an API that runs work side by side.
T3

Sees shared work

Your server also reports what it batches and reuses, so costQL counts shared work once instead of many times. It fits an API that batches its reads or funnels queries onto a few shared entities.
Where to start:T1 needs no server changes and works today, so it's the easy way in: you get a safe max right away. Already emit per-resolver timings, or ready to add them? Start at T2 or T3 and see parallel or shared work from day one. (The packs in the playground are T3 because the demo servers are instrumented to report their sharing.) The tiers guide walks through the one server change the higher tiers ask for.

Which tier fits your API?

Five yes-or-no questions. The right tier depends on your API and what you need from it.

Do you run the server?you could deploy a change to it
Does your API batch or reuse reads?DataLoader, SELECT … WHERE id IN (…), an entity cache
Does your API do work in parallel inside one request?concurrent downstream calls
Does your API call paid outside services?an LLM, a licensed data feed; your app adds their price
Do you want a per-field cost breakdown in every quote?
T1

Three demo APIs, priced live in your browser

no signup, no server

These are three real demo APIs, each already calibrated into a pack and loaded on this page. Build a query from the schema on the left, or type your own. The price moves with what you ask for. To point costQL at your own API, the Quickstart gets you a pricing oracle in about a minute.