Ir al contenido
AtheronDEVELOPERS
GraphQL

Entorno de pruebas GraphQL

La misma API que REST, una sola petición para lo que necesita. Use una clave de prueba: se queda en esta pestaña y solo va a nuestra API.

Dónde está

  • Consultas: POST https://developers.aton-network.org/api/graphql
  • Suscripciones: wss://developers.aton-network.org/api/graphql/ws (graphql-transport-ws)
  • Esquema, versión 2026-10-15: schema.graphql
  • Flujo de eventos y webhooks: Descripción AsyncAPI

Cada campo es también una llamada REST, con el mismo permiso y la misma cuota. Una petición descuenta su coste de su cuota api, así que pedir dos cosas a la vez cuesta dos.

Límites

Operaciones por petición1 (sin agrupar)
Coste por petición25 (cada campo que lee nuestra base de datos cuesta 1, la introspección 5)
Profundidad5 niveles (15 dentro de la introspección)
Campos seleccionados300, alias y fragmentos contados donde aparecen
Tamaño de la petición16 KB, 2000 tokens, variables 4 KB
Suscripciones5 por socket; 10 flujos de eventos por aplicación y entorno con Server-Sent Events, y 10 con WebSockets

Errores

Cada error lleva extensions.code, el mismo código que responde REST cuando lo hay.

CódigoEstadoPor quéQué hacer
invalid_key401No se envió ninguna clave de API, o no es nuestra, ha caducado o se revocó.Envíe una clave vigente como Authorization: Bearer ath_test_... o ath_live_... (por WebSocket, en el payload de connection_init).
missing_rightjunto a los datosLa clave no tiene el permiso que necesita un campo. Ese campo es null; el resto de la respuesta está ahí.Cree una clave con el permiso (app:read, usage:read, events:read) en el portal, o pida solo lo que esta clave puede leer.
not_foundjunto a los datosLa aplicación de la clave se ha eliminado, o el id after de los eventos no es de esta aplicación o tiene más de 30 días.Use una clave de una aplicación que siga existiendo; retome desde un id que recibió en los últimos 30 días, o empiece sin after.
rate_limited429Ha superado su cuota api de este minuto o día. Una petición descuenta su coste de la cuota; demasiados flujos de eventos abiertos también dan esta respuesta.Espere los segundos de Retry-After. Pida menos campos que lleguen a la base de datos, o menos alias.
invalid_request400La petición no se pudo ejecutar: no es JSON, es un lote (un array), un error de sintaxis, un campo o argumento que el esquema no tiene, más de una operación sin operationName, o una suscripción enviada por HTTP.Revise el mensaje; el esquema está en /graphql/schema.graphql. Envíe una operación por petición; las suscripciones van por el WebSocket.
query_too_complex400Se superó un límite: profundidad, campos seleccionados (alias y fragmentos contados donde aparecen), profundidad de introspección o coste.Divida la petición, o pida menos de una vez. Los límites están en esta página.
persisted_query_not_found200Aún no conocemos el hash de una consulta persistida (mensaje PersistedQueryNotFound).Vuelva a enviar la misma petición con la consulta además del hash; entonces se guarda y luego basta con el hash.
server_errorjunto a los datosAlgo falló por nuestra parte. No se muestra nada al respecto.Vuelva a intentarlo en un momento. Si sigue pasando, díganoslo en la página de soporte con la hora.

Esquema

"""
Atheron developer API, GraphQL, version 2026-10-15. A field is never removed or changed in a way that breaks a client without first being marked @deprecated, with the date and what replaces it, at least six months before.
"""
schema {
  query: Query
  subscription: Subscription
}

"""The developer API, version 2026-10-15. Every field is a REST call too."""
type Query {
  """
  Your application as registered, for this key's environment. Needs app:read. Same as GET /api/v1/app.
  """
  app: App

  """
  Calls, errors and latency per day and bucket, for this key's environment. Needs usage:read. Same as GET /api/v1/usage.
  """
  usage(
    """1 to 90; anything else is brought within."""
    days: Int = 7
  ): Usage
}

"""
Your application as registered, for the environment the API key belongs to. The same fields as GET /api/v1/app.
"""
type App {
  """The name people see on the consent screen."""
  name: String!

  """Where the app is: development, review or live."""
  state: String!

  """confidential (a server that keeps a secret) or public (PKCE only)."""
  kind: String!

  """The quota tier: free, growth, scale or partner."""
  quota: String!

  """The environment of this key."""
  env: Environment!

  """The OAuth client ID for this environment."""
  clientId: String!

  """The redirect addresses registered for this environment."""
  redirectUris: [String!]!

  """The scopes this environment's client may ask for."""
  scopes: [String!]!

  """The scopes review approved for live."""
  approvedScopes: [String!]!

  """Your privacy policy, shown on the consent screen."""
  privacyUrl: String

  """Your homepage, shown on the consent screen."""
  homepageUrl: String

  """Client secrets and certificates in force."""
  credentials: Int!

  """Named testers on the test client."""
  testers: Int!

  """Webhooks for this environment."""
  webhooks: Int!
}

"""Which of the app's two clients a key belongs to."""
enum Environment {
  """The test client: you, your team and up to 25 named testers."""
  TEST

  """The live client, after review."""
  LIVE
}

"""
Calls, errors and latency per day and bucket. The same answer as GET /api/v1/usage.
"""
type Usage {
  """The environment of this key."""
  env: Environment!

  """How many days the answer covers, 1 to 90."""
  days: Int!

  """One row per day and bucket, oldest first."""
  usage: [UsageDay!]!
}

"""One day and bucket of calls. Days are UTC."""
type UsageDay {
  """The day, YYYY-MM-DD, UTC."""
  day: String!

  """token, userinfo, userinfo:sensitive, api, sandbox or sign-in."""
  bucket: String!

  """Requests counted. A GraphQL request counts as its cost."""
  calls: Int!

  """Of those, how many failed."""
  errors: Int!

  """Mean time taken, in milliseconds."""
  msAvg: Int

  """Longest time taken, in milliseconds."""
  msMax: Int!
}

"""
Events as they happen, over WebSocket (graphql-transport-ws). The same events as GET /api/v1/events and your webhooks.
"""
type Subscription {
  """
  Events for this key's app and environment. Needs events:read. Same as GET /api/v1/events.
  """
  events(
    """Only these kinds. All kinds when left out."""
    types: [EventType!]

    """Resume after this event id (kept 30 days)."""
    after: ID
  ): Event!
}

"""
One event, with the same five fields a webhook delivery's body carries.
"""
type Event {
  """The event's id. Send it back as after to resume."""
  id: ID!

  """The kind of event."""
  type: EventType!

  """When it was raised, ISO 8601."""
  created: String!

  """The client it concerns."""
  clientId: String!

  """What happened."""
  data: EventData!
}

"""The kinds of event, as webhooks name them."""
enum EventType {
  USER_SIGNED_IN
  CONSENT_REVOKED
  MEMBERSHIP_CHANGED
  PING
}

"""
What happened. Which fields are present depends on the type, exactly as in a webhook's data.
"""
type EventData {
  """The person, as the sub claim your app was given. Absent for ping."""
  sub: ID

  """user.signed_in: the scopes of this sign-in."""
  scopes: [String!]

  """When it happened, ISO 8601."""
  at: String
}