Saltar al contenido
Odontosys para programadores Ayuda para la clínica

Límites y reintentos

La API la comparten todas las clínicas de Odontosys, así que tiene límites. Con un uso normal —un sitio de reservas, una central de citas— no se llega a ninguno. Están para frenar un error de programación (un bucle que no termina) antes de que afecte a los demás.

Los límites

Límite Valor Alcance Al pasarse
Pedidos por minuto 60, con ráfagas de hasta 5 seguidos Por clave 429 limite_por_minuto
Pedidos a la vez 3 lecturas y 1 escritura (un POST o un DELETE) Por clave 429 demasiadas_solicitudes_en_curso
Altas por día 100 citas creadas Por clínica (todas sus claves juntas) 429 cupo_diario_agotado
Bajas por día 50 citas eliminadas Por clínica 429 cupo_diario_agotado
Lecturas por día 5.000 Por clínica 429 cupo_diario_agotado
Claves equivocadas 10 por minuto desde la misma IP Por IP 401 no_autenticado, aunque la clave sea buena, hasta que pase el minuto

El día es el de la clínica: se reinicia a la medianoche de su zona horaria. GET /ping muestra los límites de tu clave y lo que la clínica lleva usado hoy.

Los "60 por minuto con ráfagas de 5" funcionan como un balde: entran 5 pedidos de golpe y después uno por segundo. Un integrador que manda de a uno, esperando cada respuesta, nunca lo toca.

La API también tiene un freno general para protegerse: si recibe más pedidos de los que puede atender, responde 503 no_disponible a cualquiera. Mandar ráfagas grandes te puede llevar a ese freno antes que a tu propio límite.

Las cabeceras

Toda respuesta a un pedido con una clave válida trae:

Cabecera Qué dice
RateLimit-Limit Pedidos por minuto de la clave
RateLimit-Remaining Cuántos podés mandar ya
RateLimit-Reset En cuántos segundos se llena el balde
Retry-After En los 429 y 503: cuántos segundos esperar antes de reintentar

Cómo reintentar

  1. Respetá Retry-After. Es el dato exacto: no reintentes antes.
  2. No reintentes en bucle los errores que no son pasajeros (400, 401, 403, 404, 409, 410, 422): el mismo pedido va a dar lo mismo, y cada rechazo cuenta.
  3. Ante un 500 o un corte de red, reintentá pocas veces y cada vez más espaciado (por ejemplo, a los 2, 4 y 8 segundos) y después rendite y registralo.
  4. Un POST se reintenta con la misma referenciaExterna: si la primera vez la cita llegó a crearse, la API devuelve esa misma en vez de duplicarla (ver Reintentar sin duplicar).
  5. Una escritura por vez por clave. Si tu sistema procesa reservas en paralelo, encolalas.
async function conReintentos(pedido, intentos = 4) {
  for (let i = 1; ; i++) {
    const r = await pedido();
    if (r.status !== 429 && r.status !== 503 && r.status < 500) return r;
    if (i === intentos) return r;
    const espera = Number(r.headers.get("Retry-After")) || 2 ** i;
    await new Promise((listo) => setTimeout(listo, espera * 1000));
  }
}

Ahorrar pedidos

Si tu integración necesita más de lo que dan estos límites, escribinos: ver Soporte.