GET /api/v1/systems
Inventario de sistemas de IA de la organización.
Filtros: status
Campos: id, name, provider_name, status, is_agentic, created_at, updated_at
Disponible en los planes M2 y M3 y durante el periodo de prueba. La clave la crea y la revoca el Owner de la organización desde Ajustes → API.
Cada petición lleva la clave de la organización en la cabecera Authorization, como Bearer.
Authorization: Bearer alx_live_…
La clave empieza por alx_live_. Sus primeros 17 caracteres son el prefijo que ves en Ajustes → API. La clave completa se muestra una sola vez, al crearla: Alethexis guarda solo su huella SHA-256 y no puede volver a enseñártela.
Una clave revocada deja de funcionar en la petición siguiente.
Una clave ausente, desconocida, incorrecta o revocada recibe la misma respuesta 401: la API no distingue entre esos casos.
Cada clave admite 120 peticiones por minuto y 10.000 al día.
Toda respuesta autenticada lleva X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset. Al agotarse la cuota, la respuesta es 429 con Retry-After, en segundos.
Además, cada dirección IP admite 60 peticiones cada 10 segundos. Por encima, la petición se bloquea durante 10 segundos.
Los listados devuelven un objeto con data y next_cursor.
limit va de 1 a 200; si no se indica, 50.
Para la página siguiente, repite la petición con cursor igual al next_cursor recibido. En la última página, next_cursor es null.
El cursor es opaco: no lo construyas ni lo modifiques.
Todos los errores tienen la misma forma: un objeto error con code y message. El message está en inglés técnico; el code es estable.
| Estado | Código | Significado |
|---|---|---|
| 400 | invalid_cursor | El cursor no es válido para ese recurso. |
| 400 | invalid_parameter | Un parámetro no existe, está repetido o tiene un valor no admitido. |
| 401 | invalid_api_key | Clave ausente, desconocida, incorrecta o revocada. |
| 403 | module_required | La organización no tiene activo M2 ni M3. |
| 404 | not_found | El recurso no existe. |
| 429 | rate_limited | Cuota de la clave agotada. |
| 500 | internal | Error interno. |
Todos admiten limit, cursor y since (fecha ISO 8601 con zona horaria).
Inventario de sistemas de IA de la organización.
Filtros: status
Campos: id, name, provider_name, status, is_agentic, created_at, updated_at
Clasificaciones de riesgo de cada sistema, con su historial.
Filtros: system_id, current
Campos: id, system_id, level, is_current, classified_at
Controles asignados y su estado, por sistema o para toda la organización.
Filtros: system_id, status
Campos: control_id, code, title, module, kind, system_id, status, updated_at
Índice de evidencias: categoría, tamaño y fecha. No incluye el fichero.
Filtros: system_id
Campos: id, section_id, category, size_bytes, uploaded_at
Estado de cada sección de la plataforma.
Filtros: status
Campos: section_id, module, status, updated_at
Actos de envío, revisión, aprobación, rechazo, sustitución y declaración, con su huella.
Filtros: subject_type
Campos: id, subject_type, subject_id, subject_version, action, decided_at, content_hash, statement_version
Registro de auditoría de la organización, con la huella encadenada de cada fila.
Filtros: action
Campos: id, action, family, table_name, record_id, occurred_at, source, row_hash
Solicitudes de uso de IA enviadas. Los borradores no se incluyen.
Filtros: status
Campos: id, status, tool_name, provider_name, urgency, involves_personal_data, submitted_at, decided_at, system_id
La API no devuelve datos de personas ni textos escritos a mano. Por recurso, queda fuera:
systems: quién creó o editó el sistema, la persona indicada en la verificación de prácticas prohibidas, la finalidad y las notas.classifications: quién clasificó y la justificación escrita.controls: el responsable y el aprobador asignados, las notas y los enlaces a ficheros de evidencia.evidence: el fichero, su ruta de almacenamiento, el título, la descripción y quién lo subió.sections: el motivo de revisión y sus detalles.approvals: quién registró el acto, sus roles y el comentario.audit-log: quién actuó, la dirección IP, el navegador y los valores anteriores y posteriores al cambio.requests: quién la pidió, la revisó o la decidió, la finalidad, los usuarios previstos, las notas sobre datos personales, el comentario de la decisión y los comentarios.Un webhook avisa a tu sistema en cuanto pasa algo, sin que tengas que consultar la API. Los registra el Owner en Ajustes → Webhooks: una URL https, los eventos que quieres y un secreto que se muestra una sola vez.
Cada entrega es un POST con este cuerpo:
{
"id": "0f3a…", // Alethexis-Event-Id
"type": "section.closed",
"created_at": "2026-09-18T09:12:03.412Z",
"api_version": "v1",
"data": { "account_id": "…", "section_id": "GOB-2", "status": "complete", "closed_at": "…" }
}Cabeceras: Alethexis-Signature, Alethexis-Event-Id, Alethexis-Event-Type y User-Agent: Alethexis-Webhooks/1.
El valor v1 es el HMAC-SHA256 de la marca de tiempo, un punto y el cuerpo exacto que recibes, con el secreto del endpoint. Compara en tiempo constante y rechaza lo que llegue con más de cinco minutos de diferencia.
Verificación:
// Node.js
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(rawBody, header, secret, toleranceSeconds = 300) {
const [t, v1] = header.split(',').map((part) => part.split('=')[1]);
if (Math.abs(Date.now() / 1000 - Number(t)) > toleranceSeconds) return false;
const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest();
const received = Buffer.from(v1, 'hex');
return expected.length === received.length && timingSafeEqual(expected, received);
}# Python
import hashlib, hmac, time
def verify(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
if abs(time.time() - int(parts["t"])) > tolerance:
return False
expected = hmac.new(
secret.encode(), f'{parts["t"]}.'.encode() + raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, parts["v1"])Una respuesta 2xx es una entrega buena; cualquier otra cosa, o un tiempo de espera de 10 segundos, es un fallo. Se reintenta a la hora, a las dos, a las cuatro, a las ocho y a las dieciséis; tras el quinto intento la entrega queda agotada y puedes relanzarla a mano desde Ajustes → Webhooks. Las entregas agotadas aparecen en el informe diario interno de Alethexis.
Alethexis-Event-Id identifica el evento, no el intento: un reintento repite el mismo identificador. Guarda los que ya has procesado y descarta los repetidos. Un mismo evento llega una vez a cada endpoint suscrito.
v1 tiene ocho eventos, y su lista es cerrada: un evento nuevo llega con una versión nueva del catálogo.
| Evento | Cuándo se emite | Campos de data |
|---|---|---|
section.closed | Al cerrarse una sección. | section_id, status, closed_at |
section.reopened | Al reabrirse una sección o quedar en revisión. | section_id, status, reason_key, reopened_at |
system.created | Al dar de alta un sistema de IA. | system_id, system_name, created_at |
system.reclassified | Al registrarse una clasificación nueva de un sistema. | system_id, system_name, classification_from, classification_to, version, classified_at |
risk.high_registered | Al registrarse un riesgo inherente alto (15 o más) o al cruzar un riesgo ese umbral. | risk_id, system_id, system_name, risk_category, inherent_score, risk_level, registered_at |
approval.registered | Al registrarse una aprobación. | approval_id, subject_type, subject_id, subject_version, content_hash, decided_at |
evidence.uploaded | Al subirse una evidencia o registrarse un PDF como evidencia. | evidence_id, section_id, system_id, category, size_bytes, uploaded_at |
request.decided | Al decidirse una solicitud de uso de IA. | request_id, status, tool_name, system_id, decided_at |
Las cargas llevan identificadores, estados, fechas y el nombre del sistema o de la herramienta. Nunca llevan quién hizo la acción, sus roles, comentarios, motivos escritos a mano ni direcciones de correo. Si tu sistema necesita el detalle, léelo después con la API.
La URL tiene que ser https y resolver a una dirección pública: no se entregan webhooks a direcciones privadas ni internas. Responde en menos de 10 segundos; si necesitas más tiempo, acepta la entrega y procesa después.
v1 es un contrato: sus respuestas no cambian de forma incompatible. Un cambio incompatible se publica como una versión nueva, v2.
La especificación OpenAPI 3.1 se genera desde los mismos esquemas que validan cada respuesta: /api/v1/openapi.json
curl -H "Authorization: Bearer $ALETHEXIS_API_KEY" \ "https://www.alethexis.com/api/v1/systems?limit=50"