Saltar al contenido principal

API pública

El helpdesk expone una única API pública: un endpoint GraphQL. Toda operación del esquema es accesible fuera del navegador con un token de acceso personal (Personal Access Token, PAT).

Esta página es el contrato: qué es estable, cómo autenticarse, qué conceden los ámbitos y qué forma tienen los errores. La CLI hdmx se construye sobre ella, y el versionado de la API explica cómo evoluciona esta superficie.

El endpoint​

POST https://<your-host>/backend/<subdomain>/api/<version>/graphql
  • <subdomain> identifica tu cuenta (el mismo identificador con el que inicias sesión).
  • <version> es una versión con fecha de la API, como 2026-07 — consulta versionado de la API. También puedes omitir el segmento de versión y llamar a …/backend/<subdomain>/graphql; entonces la petición la atiende la versión más antigua soportada y cada respuesta te indica qué versión respondió.

Autenticación​

Envía un token de acceso personal como credencial Bearer:

Authorization: Bearer hdmx_<random>

Un PAT es de larga duración (con caducidad obligatoria), está limitado por ámbitos, restringido por IP y es revocable. Está ligado a una sola cuenta: presentar un token al subdominio de otra cuenta se rechaza con HTTP 401.

Crear un token​

Crea y gestiona los tokens tú mismo en la aplicación de agente, en Settings → API tokens:

  1. Haz clic en New token.
  2. Dale un nombre que reconozcas más adelante.
  3. Elige una caducidad (hasta 365 días; no existe la opción «nunca»).
  4. Define una política de acceso: activa exactamente los recursos que este token necesita, en lectura o en lectura y escritura. Por defecto no hay acceso a nada.
  5. Añade al menos una dirección IP o CIDR a la lista de permitidas (obligatorio; consulta Lista de IP permitidas). El formulario puede añadir tu IP actual por ti.
  6. Revisa y crea. El token completo se muestra exactamente una vez: cópialo de inmediato. Solo se almacena un hash, así que nunca puede volver a mostrarse; si lo pierdes, rota el token para obtener uno nuevo.

Más adelante puedes editar la política de acceso y la lista de permitidas de un token, rotarlo (emitir un secreto nuevo mientras el antiguo sigue funcionando durante un breve periodo de gracia, para poder cambiar sin caídas) y revocarlo. Cada token muestra cuándo y desde dónde se usó por última vez, además de un registro de actividad reciente.

Ámbitos​

El acceso es de grano grueso y está organizado por familias de recursos. Un token lleva un conjunto fijo de ámbitos; cada operación de nivel superior comprueba uno.

ÁmbitoConcede
tickets:readLeer tickets, mensajes, borradores, historial, adjuntos, informes
tickets:writeCrear / actualizar / eliminar tickets, publicar mensajes, subir adjuntos. Implica tickets:read
chat:readLeer chats, conversaciones, mensajes, sesiones
chat:writeEnviar mensajes de agente, unirse / salir / cerrar / reabrir conversaciones. Implica chat:read
customers:readLeer fichas de clientes
customers:writeCrear / actualizar / fusionar fichas de clientes. Implica customers:read
settings:readLeer la configuración de la cuenta (departamentos, estados, prioridades, buzones — sin secretos)

Los campos de credenciales de los buzones (usuarios, contraseñas y hosts de IMAP/SMTP) nunca se devuelven a un token, sea cual sea el ámbito: esos secretos pertenecen a tu proveedor de correo y quedan fuera del alcance de la API pública.

Taxonomía de errores​

Las respuestas GraphQL usan errors[].extensions.code:

CódigoSignificadoHTTP
SCOPE_DENIEDAl token le falta el ámbito requerido. extensions.valid_values enumera el ámbito o ámbitos que satisfarían la operación200
RATE_LIMITEDSe agotó el presupuesto de peticiones por token. extensions.retryAfter son los segundos que faltan para el reinicio, y la cabecera Retry-After lleva el mismo número429
INVALID_API_TOKENToken no encontrado, mal formado o inutilizable por otro motivo200

Los tokens revocados, los caducados, las discrepancias entre cuentas y los rechazos por la lista de IP permitidas se rechazan antes de ejecutar la consulta y se manifiestan como HTTP 401 sin cuerpo GraphQL. Trata un 401 en una petición con token como «este token ya no es válido para esta petición: revisa su caducidad, sus ámbitos y su lista de IP permitidas».

Límites de tasa​

Cada petición con token lleva cabeceras:

X-RateLimit-Limit: 120
X-RateLimit-Remaining: 96
X-RateLimit-Reset: 1715692800

El presupuesto por defecto es de 120 peticiones por minuto y token. Cada petición cuesta 1, tanto si lee como si escribe. Superarlo devuelve HTTP 429 con una cabecera Retry-After y extensions.code = "RATE_LIMITED"; un cliente bien educado espera hasta el momento del reinicio.

Lista de IP permitidas​

Todo token de autoservicio debe llevar al menos una IP o CIDR: no existen tokens «para cualquier IP». La IP de origen de cada petición se compara con la lista del token; si no coincide, se rechaza con HTTP 401 y extensions.sub_code = "ip_not_allowed".

  • Se aceptan IPv4, IPv6 y rangos CIDR. Usa /32 (IPv4) o /128 (IPv6) para un solo host.
  • Los rangos se validan y normalizan al guardarlos.
  • La lista de permitidas se puede editar tras la creación; editarla no cambia el secreto.

Usa un token desde una salida estable: un runner de CI, una tarea programada, un NAT de oficina fijo o tus propios servidores en un rango de IP conocido. Un token filtrado es inútil desde cualquier lugar fuera de su lista de permitidas.

Actividad del token​

Cada petición autenticada que hace un token queda registrada: la hora, el nombre de la operación, la IP de origen, el resultado (éxito, error, límite de tasa, ámbito denegado, revocado o caducado) y la latencia de ida y vuelta. Este es el rastro que conviene revisar si un token se comporta de forma inesperada.

Versionado y obsolescencia​

La API se versiona con versiones con fecha YYYY-MM. Fija una en la URL y se mantendrá estable durante al menos 12 meses; las obsolescencias se anuncian en banda antes de que desaparezca nada de lo que uses. Consulta Versionado de la API para la política completa.

Descubrimiento del esquema​

El esquema se autodescribe: usa la introspección GraphQL estándar contra el endpoint versionado para generar tipos y explorar la superficie. El GraphQL Playground interactivo está disponible en …/backend/<subdomain>/playground.

Inicio rápido con curl​

Estos ejemplos asumen el host helpdesk.example.com, el subdominio acme, la versión 2026-07 y un token en $TOKEN.

Leer el usuario actual (cualquier ámbito)​

curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"{ currentUser { id email firstname lastname } }"}'

Listar tickets recientes (tickets:read)​

curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query ($first: Int!) {
ticketList(first: $first) {
edges { node { code subject status { name } updatedAt } }
}
}",
"variables": { "first": 10 }
}'

Publicar una respuesta pública (tickets:write)​

curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation ($input: SaveTicketInput!) {
saveTicket(input: $input) {
ticket { code }
error { code message }
}
}",
"variables": {
"input": {
"id": "TICKET-UUID-HERE",
"message": "Thanks — fixing this now.",
"messageType": "PUBLIC"
}
}
}'

Para el día a día, la CLI hdmx envuelve toda esta superficie tras comandos ergonómicos.