napnap

La API

Todo lo que hace la app pasa por aquí, así que todo lo que hace la app lo puedes hacer tú. No hay una versión recortada para gente de fuera: es la misma puerta.

La base

https://napnap.es/api/v1

La llave

Se crea en Ajustes → Este dispositivo → Atajos, y se enseña una sola vez: lo único que se guarda aquí es su hash. Viaja en la cabecera, nunca en la dirección — una clave en una URL acaba en un registro, en un historial y en la barra de alguien.

Authorization: Bearer nap_…

La llave es de una casa. Nunca hace falta decir de qué casa es una petición: se deduce de la llave, y por eso no se puede pedir el bebé de otro escribiendo su identificador.

Con Siri, en dos pasos

Un atajo de iPhone sabe pedir una dirección, mandar una cabecera y leer lo que vuelve. Con eso basta: «Oye Siri, cómo va la peque» son estas dos líneas.

curl -H "Authorization: Bearer $NAP" \ https://napnap.es/api/v1/say Aurora lleva 1:52 despierta. Le toca siesta sobre las 19:30.

La puerta de voz contesta texto plano, que es lo que un atajo sabe hablar. Añade «?format=json» si prefieres leerlo tú.

Cuando algo sale mal

El código HTTP dice qué pasó y el cuerpo lleva siempre la misma forma: una clave, no una frase. El servidor dice qué falló y quien llama lo dice en el idioma que hable.

{ "error": "baby.unknown" }

400
lo que mandaste no se sostiene
401
sin llave, o la llave ya no vale
403
la llave vale pero no para esto
404
eso no existe, o no es de tu casa
409
la pantalla iba con retraso: alguien se te adelantó

Las puertas

Todas cuelgan de /api/v1. Las marcadas son las que de verdad se usan desde fuera; el resto están porque la app las usa y no hay motivo para escondértelas.

76 puertas en 10 grupos.

Entrar

POST/auth/link
Manda al correo un enlace de acceso y un código de ocho caracteres. Cinco por dirección y hora.
POST/auth/session
Canjea ese código y abre sesión. Es la única forma de entrar en la app instalada, que tiene su propio tarro de galletas.
DELETE/auth/session
Cierra la sesión de este dispositivo y solo la de este.
POST/auth/handoff
Genera un código de un solo uso para pasar la sesión a la app instalada sin volver al correo. Solo desde una sesión de navegador: una llave de API que repartiera sesiones dejaría de estar acotada.
GET/me
Quién eres, qué casas son tuyas y qué bebés hay en ellas. Es la primera llamada que hace la app.

El bebé y su día

GET/babies
Los bebés de tus casas.
POST/babies
Da de alta un bebé: nombre y fecha de nacimiento.
GET/babies/{baby}
Un bebé y sus ajustes.
PATCH/babies/{baby}
Cambia nombre, nacimiento, hora de acostarse, aviso previo, avisos, silencio nocturno o qué se apunta de cada toma.
DELETE/babies/{baby}
Lo archiva. No lo borra: un año de noches de alguien no desaparece porque se toque un botón a las cuatro de la mañana.
GET/babies/{baby}/statela que buscas
El día entero tal y como lo pinta la app: la previsión, lo dormido, la noche de esta casa y las notas. Si solo vas a llamar a una cosa, llama a esta.
GET/babies/{baby}/forecast
Hasta dos semanas por delante, cada día con su margen y cuánta confianza hay detrás.
GET/babies/{baby}/pulse
Una cadena corta que cambia cuando cambia cualquier cosa de este bebé. Es lo que mira la otra pantalla para enterarse, cada diez segundos y solo mientras se la está mirando.
GET/babies/{baby}/week
Los siete días terminados, resumidos: cuánto durmió de media, cuántas siestas, cómo se movió la ventana y qué alimentos estrenó.
GET/babies/{baby}/export
Todo lo apuntado, para llevártelo: `format=json` lo saca entero, `format=csv&what=sleeps|feeds|food|measurements` saca una tabla.
GET/babies/{baby}/report
Una página lista para imprimir con lo que pregunta una revisión: sueño de dos semanas, medidas con su percentil, cómo va la alimentación y las reacciones. Con `format=pdf` se descarga el PDF.

El botón y el sueño

POST/babies/{baby}/togglela que buscas
El botón. Un toque duerme, otro despierta, y cuál de los dos es lo decide el servidor mirando si hay un sueño abierto. Manda «expect» con lo que creías y te contesta 409 en vez de reescribir la noche si alguien se te adelantó. Dos toques en el mismo minuto son deshacer, no despertar.
GET/babies/{baby}/sleeps
Los sueños apuntados.
POST/babies/{baby}/sleeps
Apunta un sueño entero, para el que nadie tuvo una mano libre.
PATCH/babies/{baby}/sleeps/{sleep}
Corrige las horas, el tipo o la nota de un sueño.
DELETE/babies/{baby}/sleeps/{sleep}
Borra un sueño.

Las tomas

GET/babies/{baby}/feeds
La pantalla de tomas completa: las medias, la gráfica y lo apuntado.
POST/babies/{baby}/feeds
Apunta una toma que ya pasó.
POST/babies/{baby}/feeds/startla que buscas
Empieza una toma por el pecho que le digas. En modo «solo el pecho» esta misma puerta la abre y la cierra a la vez.
POST/babies/{baby}/feeds/switch
Cambia de pecho: cierra lo que corría en uno y abre el otro.
POST/babies/{baby}/feeds/stopla que buscas
Termina la toma y cuadra el reparto contra el reloj.
PATCH/babies/{baby}/feeds/{feed}
Corrige una toma.
DELETE/babies/{baby}/feeds/{feed}
Borra una toma.

La alimentación complementaria

GET/babies/{baby}/food
El plan del año entero, el catálogo de 92 alimentos, lo probado y cómo va la textura.
PUT/babies/{baby}/food/settings
Cuándo empezó y con qué estilo: triturado, trozos o los dos.
PUT/babies/{baby}/food/plan
Mueve un alimento de semana. Todo se puede mover menos las esperas por edad.
PUT/babies/{baby}/food/avoid
Retira un alimento para siempre —una alergia confirmada— o lo vuelve a poner. Sale de las semanas que quedan y de los platos de ejemplo.
POST/babies/{baby}/food/logs
Apunta una comida: qué se ofreció, cuánto entró y cómo sentó.
PATCH/babies/{baby}/food/logs/{log}
Corrige una comida apuntada.
DELETE/babies/{baby}/food/logs/{log}
Borra una comida apuntada.
GET/babies/{baby}/photos
Las fotos de una comida, con enlaces que funcionan y nada sobre el almacén.
POST/babies/{baby}/photos
Sube una foto y la cuelga de lo que le digas.
DELETE/babies/{baby}/photos/{photo}
Borra una foto.

Peso, talla y cabeza

GET/babies/{baby}/measurements
Las medidas apuntadas, cada una con su percentil de la OMS y lo que ganó desde la anterior.
POST/babies/{baby}/measurements
Apunta una medida. En gramos y milímetros enteros: `weightG`, `heightMm`, `headMm`.
PATCH/babies/{baby}/measurements/{measurement}
Corrige una medida. Lo que no mandes se queda como estaba; manda `null` para vaciar un número.
DELETE/babies/{baby}/measurements/{measurement}
Borra una medida.

Las preguntas entre casas

GET/community/presence
Cuántas casas están despiertas ahora mismo, redondeado y solo de madrugada. Un número: no hay lista ni nadie a quien escribir.
GET/community/feed
Las preguntas: `scope=near` las de bebés de la edad del tuyo, `all` todas, `mine` las tuyas. Viene con tu alias y con lo que se adjuntaría a una pregunta tuya.
POST/community/questions
Pregunta al resto. Se adjunta tu contexto salvo que digas `context: false`.
GET/community/questions/{question}
Una pregunta con sus respuestas.
POST/community/questions/{question}/answers
Responde. `publish: true` da permiso para que tu respuesta salga de la app si la marcan como la que ayudó.
POST/community/questions/{question}/metoo
«A mí también me pasa», una vez por persona. Vuelve a llamarla para quitarlo.
POST/community/questions/{question}/close
Marca la respuesta que ayudó y cierra. `publish` es tu permiso para publicarla fuera; `reopen: true` la vuelve a abrir.
POST/community/questions/{question}/withdraw
Retira tu permiso: si eres quien preguntó, la página pública desaparece entera; si respondiste, se cae tu respuesta.
DELETE/community/questions/{question}
Borra tu pregunta con sus respuestas y sus fotos. Solo quien preguntó o quien modera.
DELETE/community/answers/{answer}
Borra tu respuesta. Si era la que resolvió el hilo, el hilo se reabre y deja de publicarse.
POST/community/reports
Avisa de una pregunta o una respuesta.
PUT/me/handle
Cambia tu alias.
GET/community/stats
Qué hacen los bebés de esa edad según lo apuntado en napnap: la ventana y las siestas. No contesta si no hay al menos veinte casas en la franja.
GET/community/questions/{question}/photos
Las fotos de una pregunta, con enlaces que caducan.
POST/community/questions/{question}/photos
Añade fotos a tu pregunta, hasta tres. Solo quien preguntó, y nunca salen en la página pública del hilo.
GET/community/answers/{answer}/photos
Las fotos de una respuesta.
POST/community/answers/{answer}/photos
Añade fotos a tu respuesta, hasta tres. Solo quien la escribió, y tampoco salen en la página pública.
GET/notifications
Las novedades que son sobre ti: quién ha respondido a tus preguntas y a quién le ha servido lo que respondiste.
POST/notifications
Marca las novedades como vistas. Lo hace la app al abrir la campana.
GET/moderation/queue
La cola de revisión: lo oculto por avisos, lo que marcó una regla y lo que espera a publicarse. Solo para quien modera.
POST/moderation/act
Ocultar, volver a mostrar, publicar o despublicar. Cada decisión queda escrita con quién la tomó.

Los avisos

GET/push
La clave pública VAPID, que es lo que el navegador necesita para suscribirse.
GET/devices
Los teléfonos suscritos a los avisos de esta casa.
POST/devices
Da de alta esta suscripción. Si el mismo teléfono entra en otra cuenta se la lleva consigo en vez de quedarse recibiendo los avisos de la anterior.
POST/devices/{device}/test
Manda un aviso de prueba a un teléfono y te cuenta qué contestó de verdad. Un botón que dice «enviado» cuando Apple respondió 403 es peor que no tener botón.
DELETE/devices/{device}
Quita un teléfono de los avisos.

La casa y las llaves

GET/home/people
Quién puede abrir esta casa.
POST/home/people
Añade una dirección a la lista. No es una invitación pendiente: quien pida un enlace desde ella entra, aunque sea meses después y aunque haya cambiado de teléfono.
DELETE/home/people/{person}
Quita la dirección y, con ella, el acceso. Un revocar que deja la puerta abierta no es un revocar.
GET/tokens
Tus llaves, por sus primeros caracteres. El secreto no se puede volver a leer.
POST/tokens
Crea una llave. El secreto se enseña una vez y ya está.
DELETE/tokens/{token}
Revoca una llave.

Para atajos y para curiosos

GET/sayla que buscas
Una frase ya escrita, en texto plano, sobre cómo va. Está pensada para que un atajo la lea en voz alta: la app decide qué se dice, no el atajo, para que cambiar el modelo no obligue a volver a tocar el iPhone.
GET/config
Las constantes del modelo. La única puerta sin sesión, porque aquí no hay nada de nadie.