GraphQL
The same API as GraphQL: operations, the schema, limits, errors and persisted queries.
Inicie sesión para ver su propio ID de cliente de prueba en los ejemplos.
POST https://developers.aton-network.org/api/graphql (or GET for a persisted query), with an API key as Authorization: Bearer. The same functions answer it as the REST API, so the data, the rights and the quota are the same: a request takes its cost from the api bucket. Subscriptions go over wss://developers.aton-network.org/api/graphql/ws (graphql-transport-ws).
- The schema: https://developers.aton-network.org/graphql/schema.graphql, versioned; a field is removed only after six months deprecated.
- The playground runs your queries with your key.
- Every code block on the REST reference pages has a REST and a GraphQL side: pick one and the site remembers it.
Operations
| Field | REST twin | Right | Cost | What it does |
|---|---|---|---|---|
Query.app | GET /api/v1/app | app:read | 1 | Your application as registered, for the environment the key belongs to. The same fields as the REST call, in camelCase; ask only for the ones you need. |
Query.usage | GET /api/v1/usage | usage:read | 1 | Calls, errors and latency per day and bucket for the key's environment, 1 to 90 days (anything else is brought within, as REST does). |
Query.app, Query.usage | none | app:read and usage:read | 2 | Two REST calls in one request. It costs two, as the two calls would, and a key with only one of the rights gets that half and a missing_right error for the other. |
Subscription.events | GET /api/v1/events | events:read | 1 | The events your webhooks hear, over a WebSocket (graphql-transport-ws). Filter by type; resume after the last id you were sent, within 30 days. Costs one when it starts; events are not counted. |
Read your app
Read your usage
Your app and today's usage in one request
Hear events as they happen
# Your app as registered, for the environment this API key belongs to. Needs app:read.
curl https://developers.aton-network.org/api/v1/app \
-H "Authorization: Bearer $ATHERON_API_KEY"{
"name": "Price Check",
"state": "live",
"kind": "confidential",
"quota": "free",
"env": "live",
"client_id": "live-1a2b3c4d5e6f7a8b",
"redirect_uris": ["https://app.example.com/callback"],
"scopes": ["openid", "profile", "email"],
"approved_scopes": ["openid", "profile", "email"],
"privacy_url": "https://app.example.com/privacy",
"homepage_url": "https://app.example.com",
"credentials": 2,
"testers": 0,
"webhooks": 1
}# Your app as registered, through GraphQL: ask for the fields you need. Needs app:read; costs 1.
curl https://developers.aton-network.org/api/graphql \
-H "Authorization: Bearer $ATHERON_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"query App {\n app {\n name\n state\n env\n clientId\n redirectUris\n scopes\n }\n}\n"}'# Calls, errors and latency per day and bucket, for the last seven days. Needs usage:read.
curl "https://developers.aton-network.org/api/v1/usage?days=7" \
-H "Authorization: Bearer $ATHERON_API_KEY"{
"env": "live",
"days": 7,
"usage": [
{ "day": "2026-10-14", "bucket": "token", "calls": 1203, "errors": 4, "ms_avg": 38, "ms_max": 412 },
{ "day": "2026-10-14", "bucket": "userinfo", "calls": 2210, "errors": 0, "ms_avg": 22, "ms_max": 190 }
]
}# Calls, errors and latency per day and bucket for the last seven days. Needs usage:read; costs 1.
curl https://developers.aton-network.org/api/graphql \
-H "Authorization: Bearer $ATHERON_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"query Usage($days: Int = 7) {\n usage(days: $days) {\n env\n days\n usage {\n day\n bucket\n calls\n errors\n msAvg\n msMax\n }\n }\n}\n","variables":{"days":7}}'# Your app and today's usage in one request: two REST calls' worth, so it costs 2.
# Persisted: send the hash alone once the document is known (see the persisted queries guide).
curl https://developers.aton-network.org/api/graphql \
-H "Authorization: Bearer $ATHERON_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"query Overview {\n app {\n name\n state\n quota\n }\n usage(days: 1) {\n usage {\n bucket\n calls\n errors\n }\n }\n}\n"}'# curl does not speak WebSocket. The same events come as Server-Sent Events: -N keeps the stream open.
# Needs events:read. Each event: id, event (its type) and data (the body a webhook would get).
curl -N "https://developers.aton-network.org/api/v1/events?types=user.signed_in,consent.revoked" \
-H "Authorization: Bearer $ATHERON_API_KEY"Limits
| Limit | Value |
|---|---|
| Request body | 16,384 bytes |
| Tokens in a document | 2,000 |
| Depth | 5 (introspection 15) |
| Fields selected, aliases and fragments counted | 300 |
| Cost | 25 (introspection 5) |
| Variables | 4,096 bytes |
| Operations in a request | 1; batches are refused |
| Subscriptions on a socket | 5 |
| Event streams per app | 10 |
Errors
Errors carry extensions.code, the same code the REST API uses where there is one.
| code | REST code | HTTP |
|---|---|---|
| `invalid_key` | invalid_key | 401 |
| `missing_right` | missing_right | 200, beside the data |
| `not_found` | not_found | 200, beside the data |
| `rate_limited` | rate_limited | 429 |
| `invalid_request` | invalid_request | 400 |
| `query_too_complex` | none | 400 |
| `persisted_query_not_found` | none | 200 |
| `server_error` | server_error | 200, beside the data |
invalid_key
Cause: No API key was sent, or it is not one of ours, has expired or was revoked.
Fix: Send a live key as Authorization: Bearer ath_test_... or ath_live_... (over WebSocket, in connection_init's payload).
missing_right
Cause: The key does not carry the right a field needs. That field is null; the rest of the answer is there.
Fix: Make a key with the right (app:read, usage:read, events:read) in the portal, or ask only for what this key may read.
not_found
Cause: The application the key belongs to has been removed, or an events after id is not this app's or is older than 30 days.
Fix: Use a key of an app that still exists; resume from an id you were sent within 30 days, or start without after.
rate_limited
Cause: Over your api quota for this minute or day. A request takes its cost from the quota; too many open event streams also answer this.
Fix: Wait the seconds in Retry-After. Ask for fewer fields that reach the database, or fewer aliases.
invalid_request
Cause: The request could not run: not JSON, a batch (an array), a syntax error, a field or argument the schema does not have, more than one operation without operationName, or a subscription sent over HTTP.
Fix: Check the message; the schema is at /graphql/schema.graphql. Send one operation per request; subscriptions go over the WebSocket.
query_too_complex
Cause: Over a limit: depth, fields selected (aliases and fragments counted where they appear), introspection depth, or cost.
Fix: Split the request, or ask for less in one go. The limits are listed on this page.
persisted_query_not_found
Cause: A persisted query's hash is not one we know yet (message PersistedQueryNotFound).
Fix: Send the same request again with the query as well as the hash; it is then kept, and the hash alone works.
server_error
Cause: Something went wrong at our end. Nothing about it is shown.
Fix: Try again in a moment. If it keeps happening, tell us on the support page with the time.
Pregunte a Atlas
Asistente de IAPregunte lo que quiera sobre Iniciar sesión con Atheron, la API o el portal. La respuesta sale de nuestra documentación, con enlaces a las páginas usadas.