La API
Una sola dirección, un token en la cabecera y ya tienes la notificación en el móvil. Sin SDK: si tu lenguaje sabe hacer una petición HTTP, sabe usar esto.
Empieza
Crea un token en Mis tokens y mándalo en la cabecera Authorization. Sin más, la notificación llega a tu propia bandeja.
curl https://api.achtung-app.com/v1/notify \
-H "Authorization: Bearer achtung_token" \
-d "El backup nocturno ha fallado"Ese atajo usa la primera línea como título. Cuando quieras más control, manda JSON.
Enviar una notificación
POST /v1/notify — acepta JSON, formulario o texto suelto. Responde 202 con el identificador de la notificación.
curl https://api.achtung-app.com/v1/notify \
-H "Authorization: Bearer achtung_token" \
-H "Content-Type: application/json" \
-d '{
"title": "Tests fallando en main",
"content": "## 3 de 44\n\n- checkout\n- pagos\n- envíos",
"content_type": "markdown",
"url": "https://ci.example.com/build/8412",
"priority": "high"
}'| Campo | Qué hace |
|---|---|
| title | Obligatorio. Lo que se lee en la pantalla bloqueada. |
| content | El cuerpo. Hasta 100 000 caracteres. |
| content_type | text, markdown o html. Por defecto text. |
| url | Lo que se abre al tocar la notificación. |
| priority | normal o high. Lo marcado como high se entrega al momento y atraviesa los modos de concentración del móvil. |
| attachments | Hasta 10: imágenes, documentos, audio o vídeo. |
Adjuntar cosas
Los adjuntos se mandan por URL: la notificación guarda el enlace y la app lo descarga al abrirlo.
{
"title": "Programa de la feria",
"content_type": "html",
"content": "<h2>Feria 2026</h2><p>Del 12 al 15 de septiembre.</p>",
"attachments": [
{ "kind": "image", "url": "https://ayto.es/feria/cartel.jpg" },
{ "kind": "document", "url": "https://ayto.es/feria/programa.pdf",
"filename": "programa.pdf" }
]
}El HTML se limpia antes de guardarlo: se quedan los enlaces, las imágenes, las tablas y el formato, y se van los scripts y los manejadores de eventos.
Comprobar un token
GET /v1/me dice si el token vale y a dónde escribe. Útil al configurar un servicio nuevo.
curl https://api.achtung-app.com/v1/me \
-H "Authorization: Bearer achtung_token"Radarr y Sonarr
Radarr y Sonarr mandan su webhook como ellos quieren y no dejan cambiarlo, así que es Achtung quien aprende a leerlo. Crea un token en Mis tokens con el formato «Radarr y Sonarr»: ese token entiende lo que le llega de cualquiera de los dos y te lo deja en tu bandeja. Es un solo formato porque los dos mandan lo mismo; de cuál viene se sabe por si habla de una película o de una serie.
En Radarr o Sonarr: Settings → Connect → +, elige Webhook y pega esto en URL, con el método POST. Marca los eventos que quieras recibir: no se filtra nada por nuestra parte.
https://api.achtung-app.com/v1/notify?token=achtung_tokenEl token va en la dirección porque el webhook no deja poner cabeceras. Si tu versión sí deja, mejor en Authorization: Bearer y la dirección limpia.
Pulsa Test y te llega una notificación de prueba. Desde ahí, cada evento marcado llega con su título —qué se ha descargado, con qué calidad, de qué indexer— y, si en los ajustes generales del servicio tienes puesta su dirección, con el enlace a la ficha. Los avisos de salud de nivel error y los que piden intervenir llegan con prioridad alta.
App Store Connect
App Store Connect avisa por webhook de por dónde va una versión —esperando revisión, en revisión, rechazada, publicada—, de si una build se ha procesado o ha fallado, y de lo que pasa en TestFlight. Crea un token en Mis tokens con el formato «App Store Connect» y ponle el nombre de la app: el webhook de Apple no dice de qué app habla, sólo manda identificadores, así que el nombre del token es el que sale en el título de la notificación. Un token por app.
En App Store Connect: Usuarios y acceso → Integraciones → Webhooks. Pega esto en Payload URL, elige la app y marca los eventos que quieras recibir: no se filtra nada por nuestra parte. El campo Secret String es obligatorio, pero Achtung no lo usa: quien autentica es el token de la dirección.
https://api.achtung-app.com/v1/notify?token=achtung_tokenPulsa Test en la ficha del webhook y te llega una notificación de prueba. Los rechazos, un binario no válido y una build que falla al procesarse llegan con prioridad alta.
Cargadores V2C
V2C Cloud avisa por webhook cuando uno de tus cargadores empieza una carga y cuando la termina, con la energía que ha entregado. Crea un token en Mis tokens con el formato «V2C» y ponle el nombre del cargador: el webhook de V2C no dice cómo se llama, sólo manda su identificador, así que el nombre del token es el que sale en el título de la notificación. El webhook es de la cuenta, no del cargador: si tienes varios, el identificador de cada uno va en el cuerpo del aviso.
En v2c.cloud, en la sección API del menú de usuario, pega esto en la dirección del webhook. V2C no firma sus webhooks ni deja poner cabeceras: quien autentica es el token de la dirección.
https://api.achtung-app.com/v1/notify?token=achtung_tokenNo hay botón de prueba: el primer aviso llega con la primera carga. El de inicio dice a qué hora ha empezado y con qué tarjeta; el de fin, cuánta energía ha entregado y cuánto ha durado, con una gráfica de los kWh de cada hora.
Gasto en Vercel
El Spend Management de Vercel avisa por webhook cuando el gasto del equipo llega al 50 %, al 75 % y al 100 % del presupuesto, y cuando empieza un ciclo de facturación nuevo. Crea un token en Mis tokens con el formato «Vercel».
En Vercel, en Settings → Billing → Spend Management, pega esto en la dirección del webhook. Vercel firma el cuerpo, pero Achtung no lo comprueba: quien autentica es el token de la dirección.
https://api.achtung-app.com/v1/notify?token=achtung_tokenNo hay botón de prueba: el primer aviso llega con el primer umbral. El del 100 % llega con prioridad alta. Si tienes activado Pause Production Deployments, a esa altura Vercel ya está pausando tus proyectos.
Cuando algo va mal
| 400 | invalid_request | Falta el título o algún campo no encaja. |
| 401 | invalid_token | El token no existe, se revocó o caducó. |
| 410 | channel_gone | El canal del token ya no existe. |
| 429 | rate_limited | Más de 600 notificaciones en una hora con el mismo token. |
Canales privados
Un canal privado no sale en el directorio y no se puede seguir adivinando su dirección. Se entra con un enlace de acceso, que se crea desde Canales.
El enlace vale para varias personas a propósito: el caso normal es pegarlo en el chat del equipo para que se suscriban quienes tengan que estar, no repartirlo de uno en uno. Si acaba donde no debe, se cambia y el anterior deja de valer al momento — quien ya se suscribió sigue dentro, porque su suscripción no depende del enlace.
Para los errores de un equipo de operaciones, lo habitual es un canal privado y un token por servicio publicando en él.
Si se te filtra un token
Rótalo desde Mis tokens. Rotar crea el sustituto y revoca el viejo en ese orden, así que copias el nuevo, lo pones en su servicio y ya está. Los tokens de tus otros servicios no se enteran: por eso conviene darle uno distinto a cada uno.