Consuming via API
A published data product is consumable two ways: from inside QRY by humans (via the Nexus explorer) and from outside by external systems through the API Gateway. This page covers the external path: issuing keys, calling the gateway, handling rate limits and errors.
The gateway is built for downstream consumers — BI tools, dashboards in other apps, internal services, partners — that need to read curated data products without giving them direct datasource access.
Goal
You finish this page with a working API key, a successful test call against a published data product, and a clear sense of the rate-limit and audit boundaries.
Prerequisites
- A published data product. Drafts can't be consumed via API. See Publishing a data product.
- The issue API keys permission in your role (often the data product's owner role).
Steps
1. Issue an API key
Open Nexus, expand API Gateway in the left sidebar, click + New Key. QRY asks for:
- Name — what shows up in the audit log and key list. Use a meaningful name like partner-acme-prod, not test.
- Scope — which data products this key can read. You can scope to a single product, several specific products, or all products you own. Tighter scope is safer.
- Rate limit — requests per minute, per hour, or per day. Defaults are tenant-set; overrides go down (more restrictive), not up.
- Expiration (optional) — a date after which the key stops working.
Click Create Key. QRY shows the plaintext key once. Copy it; you won't see it again. Server-side, only the SHA-256 hash is stored.
Keys are prefixed qry_. The full format is qry_<random> — easy to spot in logs and CI configs.
2. Call the gateway
Calls go to your tenant's gateway endpoint (usually https://api.<your-tenant>.qry.dev/v1/).
Authentication
Pass the key as a Bearer token:
GET /v1/products/customers HTTP/1.1
Authorization: Bearer qry_REPLACE_ME_WITH_YOUR_KEY
Accept: application/json
Or with curl:
curl -sS \
-H "Authorization: Bearer $QRY_KEY" \
-H "Accept: application/json" \
"https://api.your-tenant.qry.dev/v1/products/customers?limit=100"
Reading a product
The default response is a paginated list of rows, in the order the data product's underlying query produces them:
{
"rows": [
{ "customer_id": "C001", "country": "ES", "balance": 12500.00 },
{ "customer_id": "C002", "country": "DE", "balance": 8300.00 }
],
"page": { "next": "eyJvZmZzZXQiOiAyfQ==", "size": 100 }
}
Use ?page=<token> to follow the cursor for the next page.
Filtering and projection
Most products accept query parameters that map to row filters the publisher exposed:
?country=ES&limit=500
Anything not exposed by the publisher is rejected with 400 Bad Request — you can't push arbitrary WHERE into the underlying SQL.
3. Handle rate limits
The gateway uses sliding-window rate limiting. When you exceed the window, the response is:
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1730812345
Honour Retry-After (in seconds). Avoid blasting until you get a 429 — your key may be globally throttled by the publisher if you're abusive.
For predictable bulk reads, prefer:
- A per-day quota with steady pacing.
- The publisher exposing a batch / export product variant if available.
4. Audit and observability
Every gateway call writes an entry to the audit log with:
- Timestamp
- Key id (not the plaintext)
- IP address
- HTTP method / path
- Response status code
- Bytes returned
- Latency
The data product's owner sees the audit log under the product details page. If a key is misbehaving (DDoS pattern, scraping the entire product), the owner can revoke the key immediately — the next call gets 401 Unauthorized.
Revoking a key
In the API Gateway sidebar, click the key → Revoke. The key is immediately invalidated. Any in-flight requests in the consumer side fail with 401. Re-issue a new key with the same scope to swap it out.
The hash is kept in the database for audit purposes — you can still see which revoked key was responsible for past calls.
Common issues
401 Unauthorized even with a valid-looking key.
The key was revoked, or it was scoped to a different product than the one you called. Check the Scope of the key.
403 Forbidden on an endpoint that exists.
The key is scoped to specific products and you called outside that scope.
429 Too Many Requests you didn't expect.
The window is sliding, not aligned to the wall clock. A burst of 60 requests at second 0 still counts at second 30 — so the next minute isn't fully fresh until 60s after your last burst.
Rows are missing that exist in the source table. The data product's row filter or column mask is hiding them. That's by design — the consumer sees the curated view, not the raw table.
My key works locally but not in CI.
Common cause: someone copy-pasted only qry_ and missed the suffix, or stripped trailing whitespace. Confirm the full key including all characters between qry_ and the end is in the CI secret.
Where do I find the gateway endpoint URL exactly? The data product's API tab in Nexus shows the canonical URL for that product, plus a curl snippet you can copy.
See also
- Publishing a data product — pre-requisite. The product has to exist first.
- QRY Nexus reference — full feature reference, including the audit log schema and per-product hook configuration.