Matchai Docs

Límites de solicitudes

Los límites actuales del servidor MCP y de la búsqueda de anuncios de Matchai, cómo leerlos y cómo funcionarán los límites y encabezados RateLimit en la API.

Los límites mantienen Matchai rápido para todos. Esta página indica lo que permiten hoy los recursos públicos, y cómo la API de Matchai prevista informará y aplicará sus límites.

En los recursos públicos

Estos límites se aplican a los recursos que puedes usar hoy sin clave. Cada uno se cuenta por dirección de origen: la dirección desde la que llegan tus solicitudes. Los solicitantes que están detrás de una dirección compartida, como la red de una oficina o un asistente alojado, comparten una misma cuota.

RecursoLímiteCuando lo superas
Llamadas a herramientas del servidor MCP (tools/call en https://matchai.co/mcp)600 por minutoLa llamada devuelve un resultado de herramienta con isError: true y un mensaje que pide volver a intentarlo en un minuto. El estado HTTP sigue siendo 200.
Búsqueda de anuncios (https://matchai.co/ask, GET y POST sumados)60 por minuto429 con el error rate_limited y un Retry-After de 60 segundos.

Algunos detalles:

  • El límite de MCP cuenta solo tools/call. El handshake, tools/list y los demás métodos no se cuentan. Es una protección contra abusos, fijada lo bastante alta como para que un host de asistentes con mucho tráfico no la alcance.
  • La búsqueda de anuncios también puede responder 503. Cuando la búsqueda no está disponible temporalmente, responde 503 con el error unavailable y un Retry-After de 30 segundos. Espera ese tiempo y vuelve a intentarlo.
  • Las páginas legibles por IA no tienen una cifra por minuto, pero te piden moderación: alrededor de una solicitud por segundo por host. Para leer un sitio completo, descarga su llms-full.txt en lugar de recorrerlo página por página. Ante un 429, espera lo que indica Retry-After. Los archivos de descubrimiento cambian como máximo una vez por minuto, aproximadamente, así que consultarlos más seguido devuelve el mismo contenido.

Consulta la búsqueda de anuncios y el servidor MCP para ver el panorama completo.

Maneja un límite en el código

ask-with-wait.mjs
async function ask(query) {
  const response = await fetch(`https://matchai.co/ask?query=${encodeURIComponent(query)}`);

  if (response.status === 429 || response.status === 503) {
    const wait = Number(response.headers.get('Retry-After') ?? 60);
    await new Promise((resolve) => setTimeout(resolve, wait * 1000));
    return ask(query); // Try once more after the wait.
  }

  return response.json();
}

En el código real, agrega un contador para que una solicitud que sigue fallando termine por rendirse.

En la API de Matchai

Próximamente

La API de Matchai limita las solicitudes por conexión: una cuenta de Matchai conectada a una app. Las cifras todavía no se publican aquí. No las escribas de forma fija en tu código: la API te dice en qué punto estás en cada respuesta.

Encabezados de límite de solicitudes

Cada respuesta incluye tres encabezados:

EncabezadoSignificado
RateLimit-LimitSolicitudes permitidas en la ventana actual para esta conexión
RateLimit-RemainingSolicitudes que quedan en la ventana actual
RateLimit-ResetSegundos que faltan para que se reinicie la ventana
Response headers
RateLimit-Limit: 120
RateLimit-Remaining: 117
RateLimit-Reset: 41
Matchai-Request-Id: req_7Hq2LmZ9xV4c

Los números de arriba son una ilustración. No son el límite real.

Cuando lo superas

Una solicitud que supera el límite se rechaza con 429 y no hace nada. La respuesta incluye Retry-After, la cantidad de segundos que debes esperar:

Response (429)
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "Too many requests. Try again in 20 seconds.",
    "doc_url": "https://matchai.co/docs/developers/errors#rate_limited",
    "request_id": "req_7Hq2LmZ9xV4c"
  }
}

Un 429 se puede reintentar con seguridad. Espera lo que indica Retry-After y luego envía la solicitud de nuevo con el mismo Idempotency-Key, para que nada ocurra dos veces. Reintenta de forma segura tiene un ejemplo completo.

Quién comparte un límite

  • Todas las claves de una cuenta comparten un mismo límite, porque pertenecen a una sola conexión. Una segunda clave no te da más margen. Consulta Claves de API.
  • Dos profesionales conectados a la misma app tienen límites separados. La mañana ajetreada de un corredor no ralentiza la conexión de otro corredor.
  • Las operaciones públicas funcionan sin credenciales, con límites más bajos. Consultar el perfil publicado o los anuncios de un profesional no necesita clave. Esas solicitudes se cuentan por dirección IP, y enviar una clave o un token aumenta el límite. Están marcadas como Free (gratis) en la referencia de la API.

Los límites de solicitudes no son límites de energía

Una acción que usa Energía Matchai puede rechazarse por otros dos motivos, y ninguno es un 429:

  • La cuenta se quedó sin energía: 402 con el código insufficient_energy.
  • El titular de la cuenta fijó un límite de energía para tu conexión, y lo alcanzaste: 402 con el código energy_limit_reached.

Esperar no resuelve ninguno de los dos. Consulta errores.

Mantente muy por debajo del límite

  • Lee los encabezados. Reduce el ritmo cuando RateLimit-Remaining esté bajo, y haz una pausa hasta RateLimit-Reset cuando llegue a cero.
  • Escucha en lugar de consultar periódicamente. Los webhooks te avisan cuando llega un prospecto o cambia un anuncio, sin ninguna solicitud.
  • Sincroniza lo que cambió. Usa updated_since en los endpoints de listas, y pide páginas con limit=100, el tamaño de página más grande.
  • Distribuye el trabajo masivo. Importar cien contactos es una cola, no una ráfaga.
  • Repite solo lo que falló. Las claves de idempotencia te permiten reintentar una sola solicitud con seguridad.
paced-fetch.mjs
export async function pacedFetch(url, init) {
  const response = await fetch(url, init);

  const remaining = Number(response.headers.get('RateLimit-Remaining'));
  const reset = Number(response.headers.get('RateLimit-Reset'));

  // Nearly out of requests: wait for the window to reset before the next call.
  if (remaining <= 1 && reset > 0) {
    await new Promise((resolve) => setTimeout(resolve, reset * 1000));
  }

  return response;
}

En esta página