Paginación y sincronización
Los listados se recorren con un cursor. Y para no tener que leerlo todo cada vez, obras, presupuestos y proveedores admiten updated_since, y lo borrado se consulta en /deleted.
Paginación por cursor
Parámetros de cualquier listado
| Parámetro | Tipo | Descripción |
|---|---|---|
| limit integer | integer | Elementos por página, de 1 a 200. Por defecto, 50. |
| cursor string | string | El next_cursor de la página anterior. Sin él, la primera página. |
Cada respuesta de un listado trae:
json
"pagination": {
"limit": 50,
"next_cursor": "eyJ2IjpbIjIwMjYtMTAtMDJUMDg6MDE6MTAuMTEyKzAwOjAwIiwiLi4uIl19"
}- Si
next_cursoresnull, no hay más páginas. - El cursor es opaco: no lo construyas ni lo modifiques, solo reenvíalo.
- Pide la página siguiente con los mismos filtros que la primera. Un cursor que no vale da
400 invalid_cursor. - La paginación es estable: aunque se creen elementos mientras recorres, no se repiten ni se saltan filas.
async function todas(ruta) {
const filas = []
let cursor = null
do {
const url = new URL('https://app.buildnexion.com/api/v1' + ruta)
url.searchParams.set('limit', '200')
if (cursor) url.searchParams.set('cursor', cursor)
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.BUILDNEXION_API_KEY}` },
})
if (!res.ok) throw new Error((await res.json()).error.message)
const { data, pagination } = await res.json()
filas.push(...data)
cursor = pagination.next_cursor
} while (cursor)
return filas
}
const obras = await todas('/projects')Sincronizar solo lo que cambia
/projects, /estimates y /providers aceptan updated_since (fecha y hora ISO 8601). Devuelven lo creado o modificado desde entonces, del más antiguo al más reciente (por updated_at). Cuenta como cambio:
- En obras y presupuestos: cualquier cambio de sus datos o de su estado, y añadir o quitar miembros.
- En proveedores: sus datos y sus contactos.
Lo borrado no aparece ahí: está en /deleted. Una sincronización completa es:
Sincronización incremental
// 1. Guarda la hora ANTES de empezar (un poco antes, por si acaso)
const inicio = new Date(Date.now() - 60_000).toISOString()
// 2. Lo creado o cambiado desde la última vez (ordenado por updated_at)
const cambiadas = await todas(`/projects?updated_since=${ultimaSync}`)
for (const obra of cambiadas) await guardar(obra)
// 3. Lo borrado desde la última vez
const borradas = await todas(`/deleted?entity=project&since=${ultimaSync}`)
for (const b of borradas) await borrar(b.id)
// 4. La próxima vez, desde aquí
ultimaSync = inicioGuarda la hora en que empieza cada sincronización y úsala como
updated_since la siguiente vez. Si guardas la de cuando termina, puedes perder lo que cambió mientras leías.Si prefieres que te avisemos en vez de preguntar, usa los webhooks. Lo más robusto es combinar las dos cosas: webhooks para enterarte al momento y una sincronización con
updated_since de vez en cuando, por si se perdió algún aviso.