Alerta
Alert API le permite aprovisionar y administrar las mismas alertas de umbral de serie única disponibles en la interfaz de usuario Telemetry.
Si le pide a un agente de codificación que proporcione alertas, comience con Crea alertas con un agente de codificación. Le brinda al agente una secuencia segura de descubrimiento y validación, un aviso de que el agente está listo y solicitudes completas para casos de uso comunes.
Operaciones soportadas:
- Lista.
GET https://api.telemetry.sh/alert - Crear.
POST https://api.telemetry.sh/alert - Editar.
PATCH https://api.telemetry.sh/alert - Eliminar.
DELETE https://api.telemetry.sh/alert
Encabezados
| Nombre | Tipo | Descripción |
|---|---|---|
Content-Type |
Cadena de texto | Debe ser application/json para solicitudes de creación, edición y eliminación. |
Authorization |
Cadena de texto | Su clave API, ya sea como clave sin formato o como Bearer <key>. |
Reglas de alcance:
GET /alertaceptaread,writeoread-and-write.POST /alert,PATCH /alertyDELETE /alertrequierenwriteoread-and-write
Listar alertas
GET /alert devuelve alertas para el equipo de claves API, ordenado por updated_at DESC.
Parámetros de consulta admitidos:
| campo | Tipo | Requerido | Contrato exacto | Predeterminado |
|---|---|---|---|---|
page |
Entero | No | Número de página positivo basado en 1. | 1 |
pageSize |
Entero | No | Tamaño de página positivo. Los valores superiores a 100 se fijan en 100. También se acepta el alias heredado page_size. |
50 |
curl "https://api.telemetry.sh/alert?page=1&pageSize=25" \
-H "Authorization: $API_KEY"
La respuesta incluye metadatos de paginación estándar y registros de alerta completos:
{
"status": "success",
"pagination": {
"page": 1,
"pageSize": 25,
"total": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
},
"alerts": [
{
"id": "d7463946-8c6a-4a54-8a47-74cc98247c54",
"team_id": "a7d4...",
"name": "API error rate",
"slug": "api-error-rate",
"description": "Notify the API on-call rotation",
"alert_type": "query",
"payload": {
"querySql": "SELECT time_bucket, error_rate FROM api_health",
"timestampColumn": "time_bucket"
},
"aggregation": "avg",
"metric": "error_rate",
"last_n_data_points": 3,
"ignore_last_data_point": true,
"check_interval_minutes": 60,
"comparison": "greater_than",
"threshold": 0.05,
"recipients": [
{ "type": "email", "recipient": "[email protected]" }
],
"status": "inactive",
"enabled": true,
"last_evaluated_at": null,
"last_value": null,
"evaluation_version": 0,
"created_by": null,
"created_by_api_key_id": "key_123",
"created_at": "2026-09-02T17:05:00.000Z",
"updated_at": "2026-09-02T17:05:00.000Z",
"url": "/team/acme/alert/api-error-rate"
}
]
}
pagination.totalPages es 0 cuando el equipo no tiene alertas. Al solicitar una página más allá de la última página, se devuelve una matriz alerts vacía.
Campos de alerta
| campo | Tipo | grabable | Contrato exacto |
|---|---|---|---|
id |
Cadena de texto | No | Identificación de alerta. |
team_id |
Cadena de texto | No | Identificación del equipo propietario. |
name |
Cadena de texto | si | Nombre para mostrar recortado y no vacío de 200 caracteres como máximo. |
slug |
Cadena de texto | si | Babosa única con alcance de equipo. Ver normalización de babosas. |
description |
Cadena o null |
si | Descripción opcional. Las cadenas vacías se almacenan como null. |
alert_type |
Cadena de texto | si | query o explorer. La carga útil debe coincidir con el tipo seleccionado. |
payload |
Objeto | si | Definición de consulta guardada. Ver cargas útiles de consulta y Cargas útiles del explorador. |
aggregation |
Cadena de texto | si | count, sum, avg, min, max, p50, p90, p95 o p99. |
metric |
Cadena o null |
si | Columna de resultados numéricos para agregar. Si null, el evaluador utiliza la primera columna numérica sin marca de tiempo. Se recomienda un valor explícito. |
last_n_data_points |
Entero | si | Uno de 1, 3, 5, 10, 20, 50 o 100. |
ignore_last_data_point |
Booleano | si | Si se debe omitir la fila de resultados más reciente, que puede representar un período de tiempo incompleto. |
check_interval_minutes |
Entero | si | Uno de 1, 60 o 1440. |
comparison |
Cadena de texto | si | greater_than, less_than, greater_than_or_equal o less_than_or_equal. |
threshold |
Número | si | Umbral de comparación finito. Se rechazan las cadenas JSON como "10". |
recipients |
matriz | si | De uno a 25 objetos de destinatario de correo electrónico únicos. Las direcciones están recortadas y en minúsculas. |
status |
Cadena de texto | No | Estado de evaluación actual: active cuando se cumple la condición; de lo contrario, inactive. |
enabled |
Booleano | si | Si el evaluador debe ejecutar la alerta. |
last_evaluated_at |
Cadena o null |
No | Marca de tiempo de la última evaluación completa. |
last_value |
Número o null |
No | Último valor agregado. |
evaluation_version |
Entero | No | Versión interna de concurrencia optimista. |
created_by |
Cadena o null |
No | Identificación de usuario para alertas creadas por la interfaz de usuario; null para alertas creadas por API. |
created_by_api_key_id |
Cadena o null |
No | ID de clave API para alertas creadas por API; null para alertas creadas por UI. |
created_at |
Cadena de texto | No | Marca de tiempo de creación. |
updated_at |
Cadena de texto | No | Marca de tiempo de la última actualización. |
url |
Cadena de texto | No | URL de alerta relativa en la interfaz de usuario Telemetry. |
Crear una alerta
POST /alert crea una alerta y devuelve 201 Created.
| campo | Requerido | Predeterminado |
|---|---|---|
name |
si | Ninguno |
slug |
No | Normalizado desde name |
description |
No | null |
alert_type |
si | Ninguno |
payload |
si | Ninguno |
aggregation |
No | avg |
metric |
No | null |
last_n_data_points |
No | 3 |
ignore_last_data_point |
No | true |
check_interval_minutes |
No | 60 |
comparison |
No | greater_than |
threshold |
si | Ninguno |
recipients |
si | Ninguno |
enabled |
No | true |
Crear una alerta de consulta
curl -X POST https://api.telemetry.sh/alert \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "API error rate",
"description": "Notify the API on-call rotation",
"alert_type": "query",
"payload": {
"querySql": "SELECT timestamp_utc AS time_bucket, error_rate FROM api_health ORDER BY timestamp_utc DESC",
"timestampColumn": "time_bucket",
"sourceUrl": "/team/acme/default/error-rate/1"
},
"aggregation": "avg",
"metric": "error_rate",
"last_n_data_points": 3,
"ignore_last_data_point": true,
"check_interval_minutes": 60,
"comparison": "greater_than",
"threshold": 0.05,
"recipients": [
{ "type": "email", "recipient": "[email protected]" }
]
}'
Respuesta exitosa:
{
"status": "success",
"alert": {
"id": "d7463946-8c6a-4a54-8a47-74cc98247c54",
"name": "API error rate",
"slug": "api-error-rate",
"created_by": null,
"created_by_api_key_id": "key_123",
"url": "/team/acme/alert/api-error-rate"
}
}
El objeto alert devuelto contiene todos los campos que se muestran en Campos de alerta; el ejemplo abreviado resalta la identidad de creación y la URL.
Cargas útiles de consulta
| campo | Tipo | Requerido | Contrato exacto |
|---|---|---|---|
querySql |
Cadena de texto | si | SQL, no vacío y de solo lectura. Se rechazan las declaraciones que contienen escrituras o DDL. |
timestampColumn |
Cadena o null |
No | Columna de resultados utilizada para ordenar las filas más nuevas primero. Cuando se omite o null, Telemetry busca columnas de marca de tiempo comunes. |
queryId |
Cadena o null |
No | ID de consulta guardada opcional para atribución. |
sourceUrl |
Cadena o null |
No | URL relativa Telemetry relativa opcional para volver a la consulta de origen. |
La consulta debe devolver una serie temporal ordenada con un valor numérico por fila. El evaluador de alertas ordena las filas por la columna de marca de tiempo, opcionalmente omite la fila más nueva, toma la cantidad de puntos solicitada, agrega metric y aplica comparison a threshold.
Cargas útiles del explorador
Las alertas del Explorador persisten en el nombre de la tabla y el estado del Explorador:
{
"name": "Checkout failures",
"alert_type": "explorer",
"payload": {
"tableName": "checkout_events",
"explorerState": {
"graphType": "line",
"aggregation": "count",
"metric": null,
"timeZone": "UTC",
"timePreset": "24h",
"granularity": "hour",
"splitBy": [],
"filters": [
{
"logic": "AND",
"conditions": [
{ "field": "outcome", "operator": "=", "value": "failed" }
]
}
],
"selectedColumns": [],
"orderBy": null,
"orderDirection": "DESC",
"limit": 200
},
"fields": [
{ "name": "outcome", "type": "Utf8" }
]
},
"metric": "count",
"threshold": 10,
"recipients": [
{ "type": "email", "recipient": "[email protected]" }
]
}
Reglas de alerta del explorador:
payload.tableNamedebe ser una cadena que no esté vacía.payload.explorerStatedebe ser un objeto y sugraphTypedebe serlinecuando se especifique.splitBydebe estar vacío porque una alerta evalúa una serie.aggregationacepta los mismos nombres de agregación que la condición de alerta de nivel superior. Una agregación de Explorer que no seacountrequiereexplorerState.metric.timePresetacepta1h,6h,24h,7d,30d,90docustom.granularityaceptaauto,minute,hour,day,weekomonth.fieldses opcional. Incluya registros{ "name", "type" }cuando los filtros o la selección de campos numéricos dependan de los tipos de esquema.- Los operadores de filtro son
=,!=,>,>=,<,<=,LIKE,NOT LIKE,IS NULLyIS NOT NULL.
Crea alertas con un agente de codificación
Un agente puede crear una alerta sintácticamente válida que aún supervisa la tabla equivocada, utiliza la unidad equivocada o envía correos electrónicos a las personas equivocadas. Déle un objetivo operativo y exígale que inspeccione y valide los datos antes de llamar a POST /alert.
Las alertas de consulta suelen ser el tipo más fácil de crear para un agente porque puede ejecutar exactamente desde SQL hasta POST /query antes de guardarlas. Las alertas del Explorador son útiles para recuentos y percentiles estándar porque Telemetry genera los depósitos de tiempo y llena los depósitos faltantes con cero.
Información que el agente necesita
Proporcione estos datos o dígale al agente que se detenga y los solicite:
- la condición que debe desencadenarse y la unidad de su umbral
- la tabla esperada o el nombre del evento, si se conoce
- el entorno, servicio, ruta, cuenta u otra población a monitorear
- la retrospectiva, el tamaño del depósito y cuántos depósitos completados deben incumplir
- un nombre de alerta estable y una babosa
- el destinatario propietario de la respuesta
- si el agente puede habilitar la entrega o solo debe crear un borrador deshabilitado
No le pida al agente que infiera una dirección de paginación de producción ni que invente un umbral a partir de unas pocas filas de muestra.
Secuencia de solicitud recomendada
- Llame a
GET /tablespara descubrir el nombre de la tabla canónica. - Llame a
GET /tables/<table>/schemay utilice sólo campos que realmente existan con tipos compatibles. - Llame a
GET /alert?page=1&pageSize=100y busque el soporte estable previsto. Si existe, utilicePATCH /alert; no cree un duplicado. - Para obtener una alerta de consulta, ejecute el SQL propuesto exactamente con
POST /query. Confirme que devuelve una columna de marca de tiempo, una columna de métrica numérica, la unidad esperada y el orden más nuevo primero. - Crea una nueva alerta con
enabled: false. Revise la alerta, la consulta, el umbral, la ventana de puntos y los destinatarios devueltos. - Habilite la alerta revisada con
PATCH /alert. Habilitar una alerta puede provocar la entrega real de correo electrónico después de una transición de estado, así que trate esto como un paso con efectos secundarios.
No hay ningún punto final de inserción de alerta. Al repetir POST /alert con un slug existente se devuelve 409 Conflict; un agente con buen comportamiento enumera primero y parchea deliberadamente la alerta existente.
Las llamadas de descubrimiento son:
curl "https://api.telemetry.sh/tables?page=1&pageSize=100" \
-H "Authorization: $API_KEY"
curl https://api.telemetry.sh/tables/http_request_completed/schema \
-H "Authorization: $API_KEY"
curl "https://api.telemetry.sh/alert?page=1&pageSize=100" \
-H "Authorization: $API_KEY"
Solicitar un agente codificador
Copie este mensaje y reemplace los valores entre corchetes:
Create a Telemetry alert for [operational condition] using https://api.telemetry.sh.
Use the API key already available as API_KEY. The expected event or table is
[table, or "unknown"]. Monitor [population] over [window and bucket size]. The
threshold is [value and unit], and the owner is [recipient]. Use the stable slug
[slug].
Before changing anything:
1. List tables and inspect the selected table's schema.
2. List existing alerts and look for the stable slug.
3. Build a single-series query and run the exact SQL through POST /query.
4. Show me the returned columns and representative rows, the proposed alert
request, and how its bucket aggregation differs from its top-level aggregation.
Do not guess field names, units, thresholds, or recipients. Do not create a
duplicate or delete an alert. If the slug does not exist, create the alert with
enabled set to false. If it exists, propose a PATCH instead. Do not enable the
alert until I confirm the query, threshold, and recipient.
Elija ambas agregaciones deliberadamente
Las alertas del explorador tienen dos capas de agregación. explorerState.aggregation calcula el valor dentro de cada período de tiempo; el aggregation de nivel superior reduce los valores recientes del depósito seleccionados por last_n_data_points. Las alertas de consulta calculan cada fila en SQL y usan solo la agregación de nivel superior en las filas recientes.
| Objetivo operativo | Valor por cubo | Condición de alto nivel |
|---|---|---|
| Tasa sostenida de errores del servidor | SQL calcula server_error_rate_pct |
Promedie los últimos tres depósitos completados y compárelos con el porcentaje 5 |
| Cualquier pico de latencia | Explorer calcula p95 duration_ms |
El máximo de los últimos cinco depósitos completados supera los milisegundos 850 |
| latido faltante | Explorer cuenta eventos y llena los depósitos faltantes con cero | La suma de los últimos cinco depósitos completados es menor que el evento 1 |
ignore_last_data_point: true es apropiado para estos ejemplos con períodos de tiempo porque el depósito más nuevo puede estar incompleto. Configúrelo en false para una consulta que devuelva solo una fila completamente calculada; de lo contrario, el evaluador descarta esa única fila.
Ejemplo: tasa sostenida de errores del servidor
Esta consulta calcula un porcentaje de tasa de error para cada segmento de cinco minutos y suprime las alertas de tasa por debajo de 100 solicitudes por segmento. Luego, la alerta promedia los tres depósitos completados más nuevos y compara ese promedio con el porcentaje 5.
Primero ejecute el SQL exacto e inspeccione el resultado:
ALERT_QUERY=$(cat <<'SQL'
SELECT
date_bin(
INTERVAL '5 minutes',
timestamp_utc,
TIMESTAMP '1970-01-01'
) AS time_bucket,
CASE
WHEN COUNT(*) >= 100 THEN
100.0 * SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0)
ELSE 0.0
END AS server_error_rate_pct
FROM http_request_completed
WHERE
timestamp_utc >= now() - INTERVAL '35 minutes'
AND environment = 'production'
GROUP BY time_bucket
ORDER BY time_bucket DESC;
SQL
)
curl -X POST https://api.telemetry.sh/query \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg query "$ALERT_QUERY" \
'{query: $query, realtime: true, json: true}')"
Después de verificar que time_bucket es una marca de tiempo y server_error_rate_pct es numérico, cree un borrador deshabilitado:
curl -X POST https://api.telemetry.sh/alert \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg query "$ALERT_QUERY" '{
name: "Production API error rate",
slug: "production-api-error-rate",
description: "Investigate recent deploys and affected routes before escalating.",
alert_type: "query",
payload: {
querySql: $query,
timestampColumn: "time_bucket"
},
aggregation: "avg",
metric: "server_error_rate_pct",
last_n_data_points: 3,
ignore_last_data_point: true,
check_interval_minutes: 1,
comparison: "greater_than",
threshold: 5,
recipients: [
{type: "email", recipient: "[email protected]"}
],
enabled: false
}')"
Reemplace el destinatario de ejemplo con el propietario revisado antes de habilitar la alerta.
Ejemplo: pico de latencia p95
Esta alerta de Explorer calcula la duración de la solicitud p95 dentro de cada minuto. El max de nivel superior significa que uno de los cinco minutos completados más recientes debe exceder los milisegundos de 850.
curl -X POST https://api.telemetry.sh/alert \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Production API p95 latency",
"slug": "production-api-p95-latency",
"description": "Inspect slow routes, dependencies, and the latest deploy.",
"alert_type": "explorer",
"payload": {
"tableName": "http_request_completed",
"explorerState": {
"graphType": "line",
"aggregation": "p95",
"metric": "duration_ms",
"timeZone": "UTC",
"timePreset": "1h",
"granularity": "minute",
"splitBy": [],
"filters": [
{
"logic": "AND",
"conditions": [
{
"field": "environment",
"operator": "=",
"value": "production"
}
]
}
],
"selectedColumns": ["duration_ms"],
"orderBy": null,
"orderDirection": "DESC",
"limit": 200
},
"fields": [
{ "name": "duration_ms", "type": "Float64" },
{ "name": "environment", "type": "Utf8" }
]
},
"aggregation": "max",
"metric": "duration_ms",
"last_n_data_points": 5,
"ignore_last_data_point": true,
"check_interval_minutes": 1,
"comparison": "greater_than",
"threshold": 850,
"recipients": [
{ "type": "email", "recipient": "[email protected]" }
],
"enabled": false
}'
Los tipos fields deben provenir de la respuesta del esquema. Permiten que el generador Explorer SQL serialice los valores del filtro correctamente e identifique medidas numéricas.
Ejemplo: falta de latido del corazón
Utilice un conteo Explorer cuando la ausencia sea la señal. Las consultas de series temporales de Explorer incluyen depósitos faltantes con valor cero, por lo que esta alerta se activa cuando la suma de los últimos cinco depósitos de un minuto completados es inferior a un evento.
curl -X POST https://api.telemetry.sh/alert \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Production worker heartbeat missing",
"slug": "production-worker-heartbeat-missing",
"description": "Check the worker process, queue, and ingestion path.",
"alert_type": "explorer",
"payload": {
"tableName": "worker_heartbeat",
"explorerState": {
"graphType": "line",
"aggregation": "count",
"metric": null,
"timeZone": "UTC",
"timePreset": "1h",
"granularity": "minute",
"splitBy": [],
"filters": [
{
"logic": "AND",
"conditions": [
{
"field": "environment",
"operator": "=",
"value": "production"
}
]
}
],
"selectedColumns": [],
"orderBy": null,
"orderDirection": "DESC",
"limit": 200
},
"fields": [
{ "name": "environment", "type": "Utf8" }
]
},
"aggregation": "sum",
"metric": "count",
"last_n_data_points": 5,
"ignore_last_data_point": true,
"check_interval_minutes": 1,
"comparison": "less_than",
"threshold": 1,
"recipients": [
{ "type": "email", "recipient": "[email protected]" }
],
"enabled": false
}'
No utilice una consulta que solo agrupe eventos de latido existentes: si no llega ningún evento, es posible que esa consulta no devuelva ninguna fila para el intervalo que falta. El formulario de series temporales de Explorer es útil aquí porque produce los depósitos de valor cero que necesita la condición.
Ejemplo: revisar y habilitar un borrador
Enumere las alertas nuevamente e inspeccione el registro guardado en busca del slug estable. Luego habilite solo esa alerta:
curl "https://api.telemetry.sh/alert?page=1&pageSize=100" \
-H "Authorization: $API_KEY"
curl -X PATCH https://api.telemetry.sh/alert \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"alertSlug": "production-api-error-rate",
"enabled": true
}'
Si el slug estable ya existía, use la misma forma PATCH /alert para cambiar solo los campos revisados. Mantenga enabled: false durante los cambios de consulta o destinatario si la entrega de notificaciones debe permanecer en pausa.
Normalización de babosas
Para solicitudes de creación y edición, Telemetry recorta y minúsculas slug, elimina caracteres que no sean letras ASCII, números, espacios y -, convierte espacios en blanco a -, contrae - repetido y recorta el - inicial o final.
Si la creación omite slug, API normaliza name. Por ejemplo, "API Errors!!!" se convierte en "api-errors". El slug normalizado debe contener al menos una letra o número y debe ser único dentro del equipo. Un duplicado devuelve 409 Conflict.
Editar una alerta
PATCH /alert es una actualización parcial. Identifique la alerta con alertId o alertSlug; todos los demás campos omitidos permanecen sin cambios.
curl -X PATCH https://api.telemetry.sh/alert \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"alertSlug": "api-error-rate",
"threshold": 0.08,
"last_n_data_points": 5
}'
Cuando se proporcionan ambos identificadores, deben resolverse en la misma alerta. Envíe payload junto con alert_type al cambiar entre query y explorer.
La actualización de la consulta, la condición, la programación o los destinatarios borra last_value y last_evaluated_at, devuelve status a inactive e incrementa evaluation_version. Cambiar el nombre, cambiar la descripción o el slug y alternar enabled no borran el estado de evaluación.
La respuesta es 200 OK con la misma forma { "status": "success", "alert": { ... } } que se creó.
Eliminar una alerta
DELETE /alert acepta alertId, alertSlug o ambos. Al eliminar una alerta también se elimina su historial de evaluación.
curl -X DELETE https://api.telemetry.sh/alert \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "alertSlug": "api-error-rate" }'
Respuesta exitosa:
{
"status": "success",
"deleted_alert": {
"id": "d7463946-8c6a-4a54-8a47-74cc98247c54",
"name": "API error rate",
"slug": "api-error-rate",
"description": "Notify the API on-call rotation",
"url": "/team/acme/alert/api-error-rate"
}
}
Errores comunes
400 Bad Requestpara JSON no válido, campos de alerta no válidos, cargas útiles incompatibles, paginación no admitida o una clave con ámbito de lectura utilizada para una mutación401 Unauthorizedcuando la clave API falta o no es válida404 Not Foundcuando un identificador de alerta no pertenece al equipo de claves API409 Conflictcuando el slug normalizado ya existe para el equipo429 Too Many Requestscuando la clave API excede el límite de velocidad de la puerta de enlace500 Internal Server Errorcuando falla una operación de persistencia válida
Las definiciones de alerta pueden generar correo electrónico. Utilice destinatarios temporales durante la prueba, verifique la condición con datos sintéticos y deshabilite o elimine las alertas de prueba después de la validación. Consulte Alertas para conocer la semántica de evaluación y Entrega de alertas y resolución de problemas para obtener orientación sobre la entrega.