Batch issuance
When you need to issue many documents consecutively (month-end close, importing historical sales, an overnight generation run), it’s worth controlling concurrency so you don’t overload the endpoint or hit the rate limit.
The pattern below processes a list of items with a maximum of N simultaneous issuances, collecting successes and errors without aborting the whole batch on a single failure.
async function emitirEnLote(items, concurrencia = 5) {
const cola = [...items];
const enProceso = new Set();
const resultados = [];
while (cola.length > 0 || enProceso.size > 0) {
while (cola.length > 0 && enProceso.size < concurrencia) {
const item = cola.shift();
const promesa = emitirFactura(item)
.then(r => resultados.push({ ok: true, data: r }))
.catch(e => resultados.push({ ok: false, error: e, item }))
.finally(() => enProceso.delete(promesa));
enProceso.add(promesa);
}
if (enProceso.size > 0) await Promise.race(enProceso);
}
return resultados;
}Important: You must respect the rate limit (120 req/min). With concurrency of 5 and latency of ~1 s, a burst reaches ~300/min and the rate limit kicks in. Reduce the concurrency or add
await sleep(500)between emissions.
We recommend combining this recipe with exponential retries and idempotency so that a 429 or 503 doesn’t interrupt the batch.