Flarebird

Referencia de la API

Todo lo que necesitas para enviar notificaciones. Tu URL es la única credencial: mantenla en privado y rótala desde la app si se filtra.

Empieza en 10 segundos

La petición más sencilla posible:

curl "https://flarebird.app/k7Qm2x9LpR4sTvWz8aBcDe/Build%20terminada"

Enviar una notificación

Haz POST con JSON al endpoint de envío. Solo el título o el cuerpo son obligatorios. POST /api/v1/push/{key}

curl -X POST "https://flarebird.app/api/v1/push/k7Qm2x9LpR4sTvWz8aBcDe" \
  -H "content-type: application/json" \
  -d '{"title":"Build terminada","body":"Los 84 tests pasaron en 42 s","url":"https://github.com","group":"ci","level":"timeSensitive"}'

Campos

CampoTipoNotas
titlestringEs obligatorio el título o el cuerpo. Hasta 250 caracteres.
subtitlestringAparece bajo el título. Hasta 250 caracteres.
bodystringEl mensaje. Alias: message. Se recorta con … si supera el límite de 4 KB de Apple.
urlhttps URLSolo https://, hasta 2048 caracteres. Se abre al tocar la notificación.
imagehttps URLSolo https://. Se descarga en el dispositivo (máx. 10 MB, 5 s) y se adjunta.
groupstringAgrupa notificaciones e historial. Hasta 64 caracteres.
soundenumdefault, aviso o none.
levelenumpassive, active (por defecto) o timeSensitive. critical no está disponible.
badgeintegerNúmero del globo del icono de la app (0–99999).
ttlintegerSegundos que Apple sigue reintentando si el móvil está desconectado (por defecto 86400; 0 = ahora o nunca).
copystringTexto que copia la acción «Copiar». Por defecto, el cuerpo.
collapsestringLas notificaciones con el mismo valor se sustituyen entre sí.

GET con parámetros en la URL

Los mismos campos como parámetros de consulta. Perfecto para el navegador y los Atajos.

curl "https://flarebird.app/api/v1/push/k7Qm2x9LpR4sTvWz8aBcDe?title=Build%20terminada&body=Los%2084%20tests%20pasaron%20en%2042%20s&group=ci"

Atajos de URL

Aún más corto. Los segmentos de la ruta se decodifican.

GET /{key}/{body}Solo el cuerpo
GET /{key}/{title}/{body}Título y cuerpo
POST /{key}POST con texto, JSON o formulario
curl "https://flarebird.app/k7Qm2x9LpR4sTvWz8aBcDe/Los%2084%20tests%20pasaron%20en%2042%20s"
echo "Los 84 tests pasaron en 42 s" | curl -X POST --data-binary @- "https://flarebird.app/k7Qm2x9LpR4sTvWz8aBcDe"

Respuestas

Las peticiones correctas devuelven el id de APNs. truncated aparece cuando hubo que recortar el texto.

{ "ok": true, "id": "8C6F1B7A-5B9E-4C1D-9F3A-2E7D6B0A1C44" }

Errores

Los mensajes de error siguen tu cabecera Accept-Language (inglés o español).

{ "ok": false, "error": { "code": "rate_limited", "message": "…" } }
CódigoHTTPSignificado
invalid_key404URL desconocida o rotada
rate_limited429Demasiadas peticiones: mira Retry-After
invalid_payload400Validación fallida: mira fields
critical_not_supported400El nivel critical no está disponible
device_gone410El iPhone ya no está registrado
unavailable503No disponible temporalmente

Límites

Navegadores y CORS

Los endpoints de envío aceptan cualquier origen, así que puedes llamarlos desde una página web.

Ejemplos

curl "https://flarebird.app/k7Qm2x9LpR4sTvWz8aBcDe/Build%20terminada/Los%2084%20tests%20pasaron%20en%2042%20s"

# or with every option
curl -X POST "https://flarebird.app/k7Qm2x9LpR4sTvWz8aBcDe" \
  -H "content-type: application/json" \
  -d '{"title":"Build terminada","body":"Los 84 tests pasaron en 42 s","url":"https://github.com","group":"ci"}'

Usa Flarebird desde tus propios proyectos

Guarda tu URL en una variable de entorno llamada FLAREBIRD_URL y llámala cuando pase algo. La función de abajo nunca lanza excepciones, así que un aviso fallido no puede romper tu script.

import json, os, urllib.request

FLAREBIRD_URL = os.environ.get("FLAREBIRD_URL", "https://flarebird.app/k7Qm2x9LpR4sTvWz8aBcDe")

def ping(title: str, body: str = "", **extra) -> bool:
    """Send a push to your iPhone. Never raises."""
    data = json.dumps({"title": title, "body": body, **extra}).encode()
    req = urllib.request.Request(FLAREBIRD_URL, data=data,
                                 headers={"content-type": "application/json"})
    try:
        with urllib.request.urlopen(req, timeout=10) as res:
            return res.status == 200
    except Exception:
        return False

ping("Build terminada", "Los 84 tests pasaron en 42 s")