<!-- https://pricto.dev/docs/limites · versión en inglés: https://pricto.dev/docs/limites.en.md -->

# Límites y costos

Pagas por dato entregado, en créditos. Un crédito es el precio de un producto en una tienda. Cada respuesta dice cuánto costó y cuánto te queda.

## Créditos por operación

| Operación | Herramienta MCP | Créditos |
|---|---|---|
| `GET /v1/products/search` | `search_products` | 1 per page of up to 20 results; 0 when nothing is found |
| `GET /v1/products` | — | 1 per 20 products returned |
| `GET /v1/products/{product_id}` | — | 1 |
| `GET /v1/products/{product_id}/prices` | `get_prices` | 1 per retailer offer returned |
| `GET /v1/products/{product_id}/history` | `get_price_history` | 1 per 30 points per series (minimum 1 per series) |
| `POST /v1/prices/compare` | `compare_prices` | 1 per price in the matrix (product × retailer with data) |
| `POST /v1/prices/batch` | — | 1 per offer price returned; items not found cost 0 |
| `GET /v1/offers` | `list_offers` | 1 per offer returned |
| `GET /v1/offers/{offer_id}` | — | 1 |
| `GET /v1/offers/{offer_id}/history` | — | 1 per 30 points (minimum 1) |
| `GET /v1/retailers` | — | 0 |
| `GET /v1/retailers/{retailer_id}` | — | 0 |
| `GET /v1/stores` | — | 0 |
| `GET /v1/categories` | — | 0 |
| `GET /v1/brands` | — | 0 |
| `GET /v1/coverage` | `get_coverage` | 0 |
| `GET /v1/countries` | — | 0 |
| `GET /v1/fx` | — | 0 |
| `GET /v1/status` | — | 0 |
| `GET /v1/public/coverage` | — | 0 |
| `GET /v1/account` | — | 0 |
| `GET /v1/usage` | — | 0 |
| `POST /v1/data-requests` | `request_data` | 0 |

Lo mismo cuesta lo mismo por API, MCP o CLI. Los errores no cobran.

## Planes y límites

| Plan | Precio al mes | Créditos al mes | Consultas por segundo | Consultas al día | Historial |
|---|---|---|---|---|---|
| Free | USD 0 | 100 | 1 | 300 | 30 días |
| Builder | USD 29 | 15.000 | 5 | sin límite diario | 365 días |
| Pro | USD 99 | 75.000 | 15 | sin límite diario | completo |
| Business | USD 299 | 300.000 | 40 | sin límite diario | completo |
| Scale | USD 999 | 1.500.000 | 100 | sin límite diario | completo |
| Sandbox | Gratis | Sin cobro | 5 | 5.000 (y 60 por minuto) | Datos de ejemplo |

Pago por uso: USD 3 por 1.000 créditos, desde USD 10; duran 12 meses desde tu última compra. Precios completos en [/precios](/precios) y, para máquinas, en [/pricing.json](/pricing.json).

Cada respuesta trae las cabeceras `RateLimit-Limit`, `RateLimit-Remaining` y `RateLimit-Reset`. Al pasarte, la API responde `429` con `Retry-After` (ver [Errores](/docs/errores#rate_limited)).

## Controla el gasto

- `max_credits`: tope por llamada. La respuesta se recorta para caber (lo más barato o lo más relevante primero) y `meta.usage.truncated` vale `true`.
- `dry_run=true`: cotiza sin cobrar. Devuelve `data: null` y el costo en `meta.usage`.
- Relectura gratis: la misma observación, serie o búsqueda pedida otra vez dentro de 24 horas cuesta 0 y se informa en `credits_deduplicated`.
- Tope de gasto mensual: por defecto, 2 veces el valor de tu plan. Al llegar, `402 spend_cap_reached`.
- ¿Quieres seguir un precio en el tiempo? Pide el historial una vez a la semana o al mes: guardamos cada día por ti. Una vez al mes, el historial diario de un producto en 3 tiendas cuesta 3 créditos (1 por cada 30 puntos de cada serie), así que seguir unos 25 productos cabe en el plan Free.

```json
{
  "data": null,
  "meta": {
    "credits_charged": 3,
    "usage": {
      "credits_charged": 3,
      "credits_deduplicated": 0,
      "truncated": false,
      "truncated_reason": null,
      "dry_run": true,
      "units": {
        "offers": 3
      }
    }
  }
}
```

## Saldo en cada respuesta

Por API, en `meta.credits_charged`, `meta.credits_remaining` y `meta.period_resets_at`, y en las cabeceras `X-Credits-Charged`, `X-Credits-Deduplicated`, `X-Credits-Remaining` y `X-Credits-Period-Reset`. Por MCP, al final de cada respuesta:

```text
Costo: 4 créditos. Te quedan 82 de 100 créditos gratis de este mes.
Costo: 4 créditos. Te quedan 12 de 100 créditos gratis de este mes. Si necesitas más: USD 10 son 3.333 créditos que duran 12 meses.
```

## Cuando se acaba el saldo

Si el saldo no alcanza para todo, la API entrega lo que cabe y lo marca como recortado. Si no alcanza ni para un ítem, responde `402` y no cobra. En el plan Free el mensaje está escrito para que el agente se lo repita a la persona tal cual:

```text
Se acabaron los 100 créditos gratis de este mes (se renuevan el 1 de noviembre). Puedes comprar créditos desde USD 10, que duran 12 meses, o pasar a Builder: USD 29 al mes por 15.000 créditos.
```

```json
{
  "type": "https://pricto.dev/docs#insufficient_credits",
  "title": "Créditos insuficientes",
  "status": 402,
  "code": "insufficient_credits",
  "detail": "Se acabaron los 100 créditos gratis de este mes (se renuevan el 1 de noviembre). Puedes comprar créditos desde USD 10, que duran 12 meses, o pasar a Builder: USD 29 al mes por 15.000 créditos.",
  "hint": "No se cobró esta consulta. Repítele este mensaje a tu humano tal cual.",
  "request_id": "req_9506056d01054faea040",
  "docs_url": "https://pricto.dev/docs#insufficient_credits",
  "balance": 0,
  "credits_needed": 1,
  "usd_needed": 0.01,
  "top_up_url": "https://pricto.dev/#precios",
  "pricing": {
    "currency": "USD",
    "usd_per_1000_credits": 3,
    "min_top_up_usd": 10,
    "credits_per_min_top_up": 3333,
    "prepaid_validity_months": 12,
    "plans": [
      {
        "id": "builder",
        "usd_per_month": 29,
        "credits_per_month": 15000
      },
      {
        "id": "pro",
        "usd_per_month": 99,
        "credits_per_month": 75000
      },
      {
        "id": "business",
        "usd_per_month": 299,
        "credits_per_month": 300000
      },
      {
        "id": "scale",
        "usd_per_month": 999,
        "credits_per_month": 1500000
      }
    ],
    "top_up_url": "https://pricto.dev/#precios"
  }
}
```

## Historial según el plan

Si pides más historial del que incluye tu plan, la API entrega la parte que cabe y lo dice en `meta.usage.truncated_reason: "plan_history_window"` y en `meta.warnings`. Solo responde `403 plan_required` si todo el rango queda fuera.

```json
{
  "meta": {
    "usage": {
      "credits_charged": 3,
      "credits_deduplicated": 0,
      "truncated": true,
      "truncated_reason": "plan_history_window",
      "dry_run": false,
      "units": {
        "history_points": 15
      }
    },
    "warnings": [
      "synthetic_data: datos sintéticos de ejemplo / synthetic sample data",
      "truncated: tu plan incluye 30 días de historial; se entrega desde 2026-09-24."
    ]
  }
}
```
