> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mka1.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Limitación de tasa

> Límites de tasa por clave con cuotas configurables por segundo, minuto, hora o día. Incluye demostración real de HTTP 429 y patrones de reintento.

La API de MKA1 aplica límites de tasa en **base a cada clave**.
Cada clave de API tiene su propia cuota configurada de manera independiente — solicitudes por segundo, minuto, hora o día.
Cuando una clave supera su límite, la puerta de enlace devuelve `429 Too Many Requests` antes de que la solicitud llegue al modelo. No se consumen tokens ni se factura el uso.

## Configuración de límites de tasa

Los límites de tasa se establecen por clave de API en el momento del aprovisionamiento. Las granularidades disponibles son:

| Ventana     | Ejemplo                |
| ----------- | ---------------------- |
| Por segundo | 10 solicitudes/segundo |
| Por minuto  | 60 solicitudes/minuto  |
| Por hora    | 1,000 solicitudes/hora |
| Por día     | 10,000 solicitudes/día |

Los límites pueden combinarse — por ejemplo, 10 solicitudes/segundo **y** 5,000 solicitudes/hora en la misma clave.

## Demostración: limitación de tasa en acción

El siguiente ejemplo utiliza una clave de API real configurada con un límite de tasa de **1 solicitud por minuto**. La primera solicitud tiene éxito, y la segunda — enviada inmediatamente después — es rechazada con HTTP 429.

### Solicitud 1 — exitosa

```bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer mk-YfcgFr...BsFLzg' \
  --data '{
    "model": "meetkai:functionary-es-mini",
    "input": "Hello, how are you?",
    "stream": false
  }'
```

**Respuesta: HTTP 200**

```json theme={null}
{
  "id": "resp_5ab19d58984940c88a971c6829ae201c",
  "object": "response",
  "status": "completed",
  "model": "meetkai:functionary-es-mini",
  "output": [
    {
      "type": "message",
      "role": "assistant",
      "content": [{ "type": "output_text", "text": "Hello! I'm doing well..." }]
    }
  ]
}
```

### Solicitud 2 — limitada por tasa (enviada inmediatamente después)

```bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer mk-YfcgFr...BsFLzg' \
  --data '{
    "model": "meetkai:functionary-es-mini",
    "input": "This should be rate limited",
    "stream": false
  }'
```

**Respuesta: HTTP 429**

```json theme={null}
{
  "error": "Rate limit exceeded"
}
```

La puerta de enlace rechaza la solicitud antes de que llegue al modelo — no se consumen tokens ni se factura el uso.

### Ejemplo programático

<CodeGroup>
  ```bash CLI theme={null}
  # Primera solicitud — exitosa (HTTP 200)
  mka1 llm responses create \
    --model meetkai:functionary-es-mini \
    --input '"Hello"' \
    --include-headers \
    -H 'X-On-Behalf-Of: <end-user-id>'

  # Segunda solicitud — limitada por tasa (HTTP 429)
  mka1 llm responses create \
    --model meetkai:functionary-es-mini \
    --input '"This will be rate limited"' \
    --include-headers \
    -H 'X-On-Behalf-Of: <end-user-id>'
  ```

  ```ts OpenAI SDK theme={null}
  import OpenAI from 'openai';

  const openai = new OpenAI({
    apiKey: '<mka1-api-key>',
    baseURL: 'https://apigw.mka1.com/api/v1/llm/',
  });

  // Primera solicitud — exitosa
  const response = await openai.responses.create({
    model: 'meetkai:functionary-es-mini',
    input: 'Hello',
    stream: false,
  });
  console.log(response.status); // "completed"

  // Segunda solicitud — limitada por tasa
  try {
    await openai.responses.create({
      model: 'meetkai:functionary-es-mini',
      input: 'This will be rate limited',
      stream: false,
    });
  } catch (err) {
    if (err instanceof OpenAI.RateLimitError) {
      console.log(err.status);   // 429
      console.log(err.message);  // "429 Rate limit exceeded"
      console.log(err.error);    // { error: "Rate limit exceeded" }
    }
  }
  ```

  ```ts MKA1 SDK theme={null}
  import { SDK } from '@meetkai/mka1';
  import { APIError } from '@meetkai/mka1/models/errors';

  const mka1 = new SDK({
    bearerAuth: `Bearer <mka1-api-key>`,
  });

  // Primera solicitud — exitosa
  const response = await mka1.llm.responses.create({
    model: 'meetkai:functionary-es-mini',
    input: 'Hello',
  });
  console.log(response.status); // "completed"

  // Segunda solicitud — limitada por tasa
  try {
    await mka1.llm.responses.create({
      model: 'meetkai:functionary-es-mini',
      input: 'This will be rate limited',
    });
  } catch (err) {
    if (err instanceof APIError && err.statusCode === 429) {
      console.log(err.statusCode); // 429
      console.log(err.body);       // '{"error":"Rate limit exceeded"}'
    }
  }
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;
  using MeetKai.MKA1.Types.Errors;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  // Primera solicitud — exitosa
  var response = await sdk.Llm.Responses.CreateAsync(new ResponsesCreateRequest()
  {
      Model = "meetkai:functionary-es-mini",
      Input = ResponsesCreateRequestInput.CreateStr("Hello"),
  });

  // Segunda solicitud — puede ser limitada por tasa
  try
  {
      await sdk.Llm.Responses.CreateAsync(new ResponsesCreateRequest()
      {
          Model = "meetkai:functionary-es-mini",
          Input = ResponsesCreateRequestInput.CreateStr("This will be rate limited"),
      });
  }
  catch (APIException ex) when ((int)ex.Response.StatusCode == 429)
  {
      Console.WriteLine(ex.Response.StatusCode); // TooManyRequests
      Console.WriteLine(ex.Body);               // "Rate limit exceeded"
  }
  ```

  ```python Python SDK theme={null}
  import time
  from mka1 import SDK
  from mka1.errors import SDKDefaultError

  sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

  try:
      res = sdk.llm.responses.create(
          model="meetkai:functionary-es-mini",
          input="Summarize this document.",
      )
  except SDKDefaultError as e:
      if e.status_code == 429:
          time.sleep(int(e.headers.get("retry-after", 1)))
          res = sdk.llm.responses.create(
              model="meetkai:functionary-es-mini",
              input="Summarize this document.",
          )
      else:
          raise
  ```

  ```bash bash theme={null}
  # Primera solicitud — exitosa (HTTP 200)
  curl -s -w "\nHTTP %{http_code}" https://apigw.mka1.com/api/v1/llm/responses \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --data '{ "model": "meetkai:functionary-es-mini", "input": "Hello", "stream": false }'

  # Segunda solicitud — limitada por tasa (HTTP 429)
  curl -s -w "\nHTTP %{http_code}" https://apigw.mka1.com/api/v1/llm/responses \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --data '{ "model": "meetkai:functionary-es-mini", "input": "This will be rate limited", "stream": false }'
  ```
</CodeGroup>

## La respuesta 429

Cuando una solicitud es limitada por tasa, la puerta de enlace devuelve:

| Campo                 | Valor                                  |
| --------------------- | -------------------------------------- |
| **HTTP status**       | `429 Too Many Requests`                |
| **Content-Type**      | `application/json`                     |
| **Body**              | `{"error": "Rate limit exceeded"}`     |
| **Tokens consumidos** | 0 — la solicitud nunca llega al modelo |
| **Uso facturado**     | Ninguno                                |

El SDK de OpenAI muestra esto como un `OpenAI.RateLimitError` con `err.status === 429`.
El SDK de MKA1 lanza un `APIError` con `err.statusCode === 429`.

## Manejo de límites de tasa en tu aplicación

Cuando tu aplicación recibe una respuesta 429, reintenta con retroceso exponencial:

```ts theme={null}
async function requestWithRetry(fn: () => Promise<any>, maxRetries = 3): Promise<any> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (err: any) {
      if (err.status === 429 && attempt < maxRetries - 1) {
        const waitMs = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
        await new Promise((r) => setTimeout(r, waitMs));
        continue;
      }
      throw err;
    }
  }
}

const response = await requestWithRetry(() =>
  openai.responses.create({ model: 'meetkai:functionary-es-mini', input: 'Hello', stream: false })
);
```

## Ver también

* [Autenticación](/es/docs/authentication) para la configuración de la clave de API y el patrón `X-On-Behalf-Of`.
* [Autorización](/es/docs/authorization) para control de acceso a nivel de recurso.
* [Generar una respuesta](/es/docs/generate-a-response) para la estructura básica de solicitudes de Responses.
