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 Tokens y mándalo en la cabecera Authorization. Sin más, la notificación llega a tu propia bandeja.

curl https://achtung-app.com/api/v1/notify \
  -H "Authorization: Bearer acht_tu_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 /api/v1/notify — acepta JSON, formulario o texto suelto. Responde 202 con el identificador de la notificación.

curl https://achtung-app.com/api/v1/notify \
  -H "Authorization: Bearer acht_tu_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"
  }'
CampoQué hace
titleObligatorio. Lo que se lee en la pantalla bloqueada.
contentEl cuerpo. Hasta 100 000 caracteres.
content_typetext, markdown o html. Por defecto text.
urlLo que se abre al tocar la notificación.
prioritynormal o high. Lo marcado como high se entrega al momento y atraviesa los modos de concentración del móvil.
attachmentsHasta 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 /api/v1/me dice si el token vale y a dónde escribe. Útil al configurar un servicio nuevo.

curl https://achtung-app.com/api/v1/me \
  -H "Authorization: Bearer acht_tu_token"

Cuando algo va mal

400invalid_requestFalta el título o algún campo no encaja.
401invalid_tokenEl token no existe, se revocó o caducó.
410channel_goneEl canal del token ya no existe.
429rate_limitedMá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 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.