A single endpoint that fronts the whole catalog. You name the APIs you want and the fields you want from each, and one round trip returns exactly that.
query {
dadjokes { joke }
randomquote { quote author }
}POST https://api.apiverve.com/v1/graphql
GraphQL support is in alpha. The schema can change, and it is not the right choice for production traffic yet — the REST endpoints are stable and are what the SDKs, the CLI and the integrations use. Feedback is welcome while it settles.
What it is for
REST is one endpoint per call. That is the right shape when you need one thing, and the wrong shape when a single screen needs six things — six requests, six round trips, six error paths, and six responses that are mostly fields you will not render.
GraphQL collapses that into one request. It is worth reaching for when:
- A view needs several APIs at once. A dashboard tile pulling weather, an exchange rate and a timezone is one query instead of three calls to coordinate. The gateway fans them out in parallel, so the query takes about as long as its slowest member rather than the sum of all three.
- Bandwidth is expensive. Mobile clients can ask for three fields out of forty and receive three fields. On a metered connection that difference is real.
- The set of fields varies by caller. Different screens can query the same APIs differently without any endpoint work on either side.
- You want the shape documented in one place. The schema is introspectable, so editors and the explorer autocomplete field names instead of you checking a reference page per API.
It is not worth reaching for when you are calling one API. query { dadjokes { joke } } is
strictly more machinery than GET /v1/dadjokes for the same result, and it gives up the response
headers that carry your credit balance.
How it differs from REST
Three differences matter in practice.
The envelope is gone. A REST call returns { status, error, data }. A GraphQL resolver
returns the contents of data directly, keyed by the API you named. There is no status field to
check — success and failure are signalled by the presence of an errors array instead.
Field names are normalised. GraphQL field names cannot contain hyphens, dots, spaces or
colons, so any REST field name containing one of - + : . / \ is rewritten with underscores, any
remaining non-alphanumeric character is dropped, and a name starting with a digit gets a leading
underscore. So a REST field age.years is age_years in GraphQL. The explorer's docs panel shows
the real GraphQL names, which is the fastest way to check.
Root field names are the API ID, lowercased and de-hyphenated. /v1/emailvalidator is
emailvalidator; an API whose ID contains a hyphen loses it.
Limits and cost
| Free | Paid | |
|---|---|---|
| APIs per query | 1 | Several — at least 10, set by plan |
Exceeding the cap is an HTTP 403 with code: "PLAN_LIMIT_EXCEEDED", and the message names both
your ceiling and what you asked for — so the reliable way to learn your exact limit is to read it
off that message rather than to guess. Because a free-plan query is capped at one API, the
multi-API examples in these docs need a paid plan to run.
Credits are unchanged: each API named in a query costs what that API costs over REST. A query touching three 1-credit APIs costs 3 credits. There is no gateway surcharge and no orchestration fee — combining calls saves round trips, not money.
Two details worth knowing:
- The same API named twice in one query is charged once. Cost is calculated over the distinct set of APIs in the query, not the number of fields.
- Cost is checked before anything runs. If your balance will not cover the whole query, the
request fails with HTTP
402andcode: "INSUFFICIENT_CREDITS"and no API is called. You are never left having paid for half a query.
What is not supported
| Mutations | Not supported. GraphQL here is read-only. |
| Subscriptions | Not supported. There is no real-time transport. |
| File uploads | Not supported. Endpoints that take a file return 400 with code: "FILE_UPLOAD_NOT_SUPPORTED" and name the offending APIs — call those over REST. |
GET | Not supported. Queries must be POST; a GET returns 405. |
Deep or unusually broad queries may also be rejected to keep the gateway stable. If you are writing something that pushes on that, the per-query API cap will usually stop you first.
Not every door exposes GraphQL. Where it is unavailable the endpoint answers with
code: "GRAPHQL_NOT_SUPPORTED" rather than a 404, so you can tell "wrong host" from
"wrong path".
Authentication and errors
Same key, same header as everywhere else:
curl -X POST https://api.apiverve.com/v1/graphql \
-H "x-api-key: $APIVERVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"query { dadjokes { joke } }"}'Errors come back in GraphQL's shape rather than the REST envelope — an errors array, often
alongside partial data for the parts that did succeed:
{
"errors": [
{ "message": "Invalid API key", "extensions": { "code": "INVALID_API_KEY" } }
]
}Every error carries a machine-readable extensions.code, which is what your code should branch
on. message is written for a human and may be reworded. The full code list and the handling
pattern are in writing queries; the equivalent statuses on the REST side are in
error handling.
When one API in a multi-API query fails and the others succeed, the response is a 200 carrying
both data and errors. Checking the status code alone will make you treat a partial failure as
a complete success.
Where it pays off
The pattern is always the same — one screen or one job needs several unrelated facts — but it shows up in a few recognisable places.
Dashboards and summary screens. A tile grid pulling weather, an exchange rate, a stock index and a holiday calendar is four REST calls with four loading states and four failure modes. As one query it is one loading state, and partial failure degrades a tile instead of the page.
Mobile clients. Fewer requests means less radio time, which is battery as well as latency. Asking for four fields instead of forty compounds that on a metered connection.
Data enrichment jobs. Combining geocoding, timezone and demographic lookups for the same input is a natural single query — and because the gateway fans out in parallel, the job's per-record latency is the slowest lookup rather than the sum of all of them.
Gateways in front of your own services. If your architecture already speaks GraphQL, adding this schema as a remote source is less work than wrapping a few dozen REST endpoints by hand.
The common thread is several at once. For one API at a time, REST is simpler, gives you the status code and the credit header, and is the surface everything else here is built on.
Getting started
Four things, and you have already got the first two if you have made any API call.
- Use your existing key. GraphQL authenticates with the same
x-api-keyheader as REST. There is nothing separate to provision. - Point at one endpoint.
https://api.apiverve.com/v1/graphql,POST, JSON body. There is no per-API path. - Draft in the explorer. The GraphQL explorer in the dashboard has autocomplete and a schema browser, so you can find field names without guessing at how they were normalised.
- Read the schema, not a reference page. The schema is introspectable and self-documenting, which makes it the authority on what a GraphQL field returns — the REST reference pages document the REST field names, which are not always the same string.
Next
Writing queries covers syntax, arguments, multi-API queries, the explorer and the full error-code table. For per-endpoint REST detail, start at all endpoints; for the credit model behind the numbers above, see rate limits.
If what you actually need is many inputs through one endpoint rather than one input through many, that is batch requests, not GraphQL.