<!-- https://pricto.dev/docs/api/list-offers · Spanish version: https://pricto.dev/docs/api/list-offers.md -->

# List retailer offers

`GET https://pricto.dev/v1/offers`

Listings as published by retailers. Filter by retailer, category, promotion or recent change. `changed_since` returns offers whose price or availability changed after a time, which is the cheapest way to keep a mirror up to date.

| Credits | MCP |
|---|---|
| 1 per offer returned | [`list_offers`](/docs/mcp#list_offers) |

## Parameters

| Parameter | In | Type | Description |
|---|---|---|---|
| `max_credits` | query | `number` | Spend at most this many credits on this call. Results are cut to fit and `meta.usage.truncated` is true. |
| `dry_run` | query | `boolean` | Return the quote in `meta.usage` with `data` set to null, without charging. Default: `false`. |
| `retailer` | query | `string` | One or more retailer IDs, comma separated (e.g. `cl-jumbo,cl-unimarc`). |
| `country` | query | `string` | ISO 3166-1 alpha-2 country code. Defaults to all covered countries. |
| `category` | query | `string` | Category ID; includes subcategories (e.g. `food.dairy`). |
| `brand` | query | `string` | Brand ID or name. |
| `product_id` | query | `string` |  |
| `gtin` | query | `string` |  |
| `on_promotion` | query | `boolean` | Only offers with a sale price, card price or promotion. |
| `changed_since` | query | `string (date-time)` |  |
| `matched` | query | `boolean` | Filter by whether the offer is matched to a canonical product. |
| `lang` | query | `string` | Response language as a BCP 47 tag (`es`, `es-CL`, `en`, `en-US`...). Supported today: es, en. An unsupported language falls back to English with a warning, never an error. Falls back to `Accept-Language`, then to the account default. The resolved value is in `meta.lang`. |
| `currency` | query | `string` | Add converted amounts in this ISO 4217 currency. `local` (default) returns source currency only. Default: `local`. |
| `limit` | query | `integer` |  Default: `50`. |
| `cursor` | query | `string` | Opaque cursor from `pagination.next_cursor`. |
| `format` | query | `string` | `json` (default) or `csv`. Equivalent to `Accept: text/csv`. Valores / values: `json`, `csv`. Default: `json`. |

## Response

`200` Offers.

| Field | Type | Description |
|---|---|---|
| `data` **required** | `Offer[]` |  |
| `data[].id` **required** | `string` |  |
| `data[].retailer` **required** | `RetailerRef` |  |
| `data[].retailer.id` **required** | `string` |  |
| `data[].retailer.name` **required** | `string` |  |
| `data[].product_id` | `string \| null` |  |
| `data[].store_id` | `string \| null` |  |
| `data[].title_original` **required** | `string` |  |
| `data[].title_lang` | `string` | BCP 47 language of title_original. |
| `data[].url` **required** | `string (uri)` |  |
| `data[].retailer_sku` | `string \| null` |  |
| `data[].retailer_product_id` | `string \| null` | Parent product in the store (groups variants and sizes). Availability is measured per product: available if any of its SKUs is in stock. |
| `data[].seller` | `Seller` | Who sells the offer. On marketplaces it is a third party; `name` is null when the seller is a natural person (no personal data). |
| `data[].seller.id` **required** | `string` |  |
| `data[].seller.name` **required** | `string \| null` |  |
| `data[].seller.is_retailer_itself` **required** | `boolean` |  |
| `data[].gtin` | `string \| null` |  |
| `data[].brand` | `string \| null` |  |
| `data[].category` | `object` |  |
| `data[].match` | `object` |  |
| `data[].current` **required** | `PriceQuote` | A price as observed. `price` is the best price any customer pays without conditions (sale price if present, otherwise list price). Conditional prices are separate: `card_price` requires a payment method and `promotions` require a quantity or bundle. |
| `data[].current.currency` **required** | `string` |  |
| `data[].current.price` **required** | `number` |  |
| `data[].current.list_price` **required** | `number` |  |
| `data[].current.sale_price` | `number \| null` |  |
| `data[].current.card_price` | `number \| null` | Convenience: the lowest price in conditional_prices that requires a payment method or membership. |
| `data[].current.card_label` | `string \| null` |  |
| `data[].current.conditional_prices` | `ConditionalPrice[]` | Every price that requires a condition other than quantity (payment method, loyalty tier, app, coupon), as published. |
| `data[].current.conditional_prices[].kind` **required** | `string` | Valores / values: `payment_method`, `membership`, `app_only`, `coupon`, `other`. |
| `data[].current.conditional_prices[].label` **required** | `string` | As shown by the retailer. |
| `data[].current.conditional_prices[].price` **required** | `number` |  |
| `data[].current.conditional_prices[].payment_method` | `string \| null` |  |
| `data[].current.conditional_prices[].membership_tier` | `string \| null` |  |
| `data[].current.conditional_prices[].installments_count` | `integer \| null` |  |
| `data[].current.conditional_prices[].interest_free` | `boolean \| null` |  |
| `data[].current.unit_price` | `object \| null` |  |
| `data[].current.unit_price.amount` **required** | `number` |  |
| `data[].current.unit_price.per` **required** | `string` | Valores / values: `kg`, `l`, `unit`, `m`, `m2`. |
| `data[].current.promotions` | `Promotion[]` |  |
| `data[].current.promotions[].type` **required** | `string` | Valores / values: `multi_buy`, `nth_unit`, `percent_off`, `amount_off`, `bundle`, `gift`, `other`. |
| `data[].current.promotions[].label` **required** | `string` | As shown by the retailer, e.g. "2 x $2.990". |
| `data[].current.promotions[].min_quantity` | `integer \| null` |  |
| `data[].current.promotions[].effective_unit_price` | `number \| null` | Price per item when the promotion applies. |
| `data[].current.promotions[].requires_card` | `string \| null` | Payment method required, if any. |
| `data[].current.promotions[].valid_until` | `string (date) \| null` |  |
| `data[].current.availability` **required** | `string` | Valores / values: `in_stock`, `out_of_stock`, `limited`, `unknown`. |
| `data[].current.tax_included` | `boolean` | As shown by the retailer (observed). |
| `data[].current.tax_rate` | `number \| null` | Derived. Main VAT rate for this country and category, null when not known. |
| `data[].current.price_ex_tax` | `number \| null` | Derived from price and tax_rate. Null when tax_rate is null. |
| `data[].current.tax_rule_id` | `string \| null` | Versioned rule used to derive tax_rate. |
| `data[].current.other_taxes_included` | `boolean \| null` | True when other taxes remain in price_ex_tax (e.g. Chile IABA on sweetened drinks). |
| `data[].current.installments` | `object` |  |
| `data[].current.observed_at` **required** | `string (date-time)` |  |
| `data[].current.observed_local_date` | `string (date)` | Capture date in the retailer time zone. Daily series use this date. |
| `data[].current.capture_method` **required** | `string` | How the price was obtained, part of the provenance with `url` and `observed_at`. `public_page`: read from the retailer's public web page (HTML, JSON-LD or the page payload). `public_api`: an open, unauthenticated JSON endpoint of the retailer's own site. `retailer_feed`: delivered by the retailer under an agreement. `open_data`: a public dataset published by a government or third party. Valores / values: `public_page`, `public_api`, `retailer_feed`, `open_data`. |
| `data[].current.quality_status` | `string` | `warning` when a validation flagged the observation (price jump, zero, unusual unit). Quarantined observations are never served. Valores / values: `ok`, `warning`. |
| `data[].current.quality_flags` | `string[]` | Why the price was flagged. The price is delivered as published, never corrected. `discount_over_85`: more than 85% off the list price. `round_price_low`: a round price of CLP 1,000 or less. Both often mean a placeholder price or a store error. |
| `data[].current.corrected` | `boolean` | True when the observation was amended after capture (the original is kept). |
| `data[].current.converted` | `Converted` |  |
| `data[].current.converted.currency` **required** | `string` |  |
| `data[].current.converted.price` **required** | `number` |  |
| `data[].current.converted.list_price` | `number \| null` |  |
| `data[].current.converted.card_price` | `number \| null` |  |
| `data[].current.converted.unit_price` | `number \| null` |  |
| `data[].current.converted.fx_rate` **required** | `number` | Units of target currency per unit of source currency. |
| `data[].current.converted.fx_date` **required** | `string (date)` | Publication date of the rate used (last published on or before the observation date). |
| `data[].current.converted.fx_source` | `string` |  |
| `data[].current.converted.fx_method` | `string` | Valores / values: `direct`, `cross`. |
| `data[].first_seen` | `string (date-time)` |  |
| `data[].last_changed` | `string (date-time) \| null` |  |
| `pagination` **required** | `Pagination` |  |
| `pagination.has_more` **required** | `boolean` |  |
| `pagination.next_cursor` **required** | `string \| null` |  |
| `meta` **required** | `Meta` |  |

`meta` carries the cost, the source line to quote, the language, the currency and notices (see [Conventions](/docs/convenciones)).

## Errors

- [`invalid_parameter`](/docs/errores#invalid_parameter)
- [`unauthorized`](/docs/errores#unauthorized)

## Example

```bash
curl "https://pricto.dev/v1/offers?retailer=cl-jumbo&on_promotion=true&limit=2" \
  -H "Authorization: Bearer sk_test_sandbox"
```
```python
import requests

API_KEY = "sk_test_sandbox"

r = requests.get(
    "https://pricto.dev/v1/offers",
    params={"retailer": "cl-jumbo", "on_promotion": "true", "limit": 2},
    headers={"Authorization": f"Bearer {API_KEY}"},
)
print(r.status_code, r.json())
```
```js
const API_KEY = "sk_test_sandbox";

const res = await fetch(`https://pricto.dev/v1/offers?${new URLSearchParams({"retailer":"cl-jumbo","on_promotion":"true","limit":"2"})}`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
});
console.log(res.status, await res.json());
```

```json
{
  "data": [
    {
      "id": "ofr_001jum",
      "retailer": {
        "id": "cl-jumbo",
        "name": "Jumbo"
      },
      "product_id": "prd_01colu",
      "store_id": null,
      "title_original": "Leche Entera Colun 1 L",
      "title_lang": "es-CL",
      "url": "https://example.com/cl-jumbo/leche-entera-colun-1-l",
      "retailer_sku": "347860",
      "retailer_product_id": null,
      "seller": {
        "id": "cl-jumbo",
        "name": "Jumbo",
        "is_retailer_itself": true
      },
      "gtin": "2000070000007",
      "brand": "Colun",
      "category": {
        "id": "food.dairy.milk",
        "label": "Leche",
        "path": [
          "Alimentos y bebidas",
          "Lácteos",
          "… 1 más / more"
        ]
      },
      "match": {
        "method": "gtin",
        "confidence": 0.99,
        "kind": "identical",
        "pack_ratio": null
      },
      "current": {
        "currency": "CLP",
        "price": 1290,
        "list_price": 1290,
        "sale_price": null,
        "card_price": 1190,
        "card_label": "Tarjeta Cencosud",
        "conditional_prices": [
          {
            "kind": "payment_method",
            "label": "Tarjeta Cencosud",
            "price": 1190,
            "payment_method": "tarjeta-cencosud",
            "membership_tier": null,
            "installments_count": null,
            "interest_free": null
          }
        ],
        "unit_price": {
          "amount": 1290,
          "per": "l"
        },
        "promotions": [],
        "availability": "in_stock",
        "tax_included": true,
        "tax_rate": 0.19,
        "price_ex_tax": 1084,
        "tax_rule_id": "CL-IVA-19-2026",
        "other_taxes_included": false,
        "installments": null,
        "observed_at": "2026-10-23T11:00:00Z",
        "observed_local_date": "2026-10-23",
        "capture_method": "public_page",
        "quality_status": "ok",
        "quality_flags": [],
        "corrected": false
      },
      "first_seen": "2026-06-26T08:00:00Z",
      "last_changed": "2026-10-19T11:00:00Z"
    },
    {
      "id": "ofr_003jum",
      "retailer": {
        "id": "cl-jumbo",
        "name": "Jumbo"
      },
      "product_id": "prd_03lonc",
      "store_id": null,
      "title_original": "Leche Semidescremada Sin Lactosa Loncoleche 1 L",
      "title_lang": "es-CL",
      "url": "https://example.com/cl-jumbo/leche-semidescremada-sin-lactosa-loncoleche-1-l",
      "retailer_sku": "797289",
      "retailer_product_id": null,
      "seller": {
        "id": "cl-jumbo",
        "name": "Jumbo",
        "is_retailer_itself": true
      },
      "gtin": "2000070000748",
      "brand": "Loncoleche",
      "category": {
        "id": "food.dairy.milk",
        "label": "Leche",
        "path": [
          "Alimentos y bebidas",
          "Lácteos",
          "… 1 más / more"
        ]
      },
      "match": {
        "method": "gtin",
        "confidence": 0.99,
        "kind": "identical",
        "pack_ratio": null
      },
      "current": {
        "currency": "CLP",
        "price": 1490,
        "list_price": 1490,
        "sale_price": null,
        "card_price": null,
        "card_label": null,
        "conditional_prices": [],
        "unit_price": {
          "amount": 1490,
          "per": "l"
        },
        "promotions": [
          {
            "type": "multi_buy",
            "label": "2 x $2.590",
            "min_quantity": 2,
            "effective_unit_price": 1295,
            "requires_card": null,
            "valid_until": null
          }
        ],
        "availability": "in_stock",
        "tax_included": true,
        "tax_rate": 0.19,
        "price_ex_tax": 1252,
        "tax_rule_id": "CL-IVA-19-2026",
        "other_taxes_included": false,
        "installments": null,
        "observed_at": "2026-10-23T11:00:00Z",
        "observed_local_date": "2026-10-23",
        "capture_method": "public_page",
        "quality_status": "ok",
        "quality_flags": [],
        "corrected": false
      },
      "first_seen": "2026-06-26T08:00:00Z",
      "last_changed": "2026-10-20T11:00:00Z"
    }
  ],
  "pagination": {
    "has_more": true,
    "next_cursor": "eyJvIjoyfQ"
  },
  "meta": {
    "request_id": "req_b8cbeeb9e5d64587b8cb",
    "attribution": {
      "text": "Fuente: Pricto · 23-10-2026 08:00 CLST",
      "source": "Pricto",
      "as_of": "2026-10-23T11:00:00Z",
      "resource_id": null,
      "url": null,
      "capture_method": null,
      "source_url": null
    },
    "credits_charged": 1,
    "credits_deduplicated": 1,
    "credits_remaining": 14988,
    "period_resets_at": "2026-11-01T00:00:00.000Z",
    "usage": {
      "credits_charged": 1,
      "credits_deduplicated": 1,
      "truncated": false,
      "truncated_reason": null,
      "dry_run": false,
      "units": {
        "offers": 2
      }
    },
    "lang": "es",
    "currency": "local",
    "data_as_of": "2026-10-23T11:00:00Z",
    "warnings": [
      "synthetic_data: datos sintéticos de ejemplo / synthetic sample data"
    ]
  }
}
```
