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

# Search products by text

`GET https://pricto.dev/v1/products/search`

Hybrid text and semantic search over canonical products. Accepts natural queries such as "leche entera 1 litro" or a GTIN. Each result includes a price summary across retailers so a single call is often enough to answer "how much does X cost".

| Credits | MCP |
|---|---|
| 1 per page of up to 20 results; 0 when nothing is found | [`search_products`](/docs/mcp#search_products) |

## Parameters

| Parameter | In | Type | Description |
|---|---|---|---|
| `q` **required** | query | `string` | Free text or a GTIN/EAN. |
| `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`. |
| `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. |
| `retailer` | query | `string` | One or more retailer IDs, comma separated (e.g. `cl-jumbo,cl-unimarc`). |
| `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: `10`. |
| `cursor` | query | `string` | Opaque cursor from `pagination.next_cursor`. |

## Response

`200` Matching products ranked by relevance.

| Field | Type | Description |
|---|---|---|
| `data` **required** | `ProductSummary[]` |  |
| `data[].id` **required** | `string` |  |
| `data[].name` **required** | `string` |  |
| `data[].brand` **required** | `BrandRef` |  |
| `data[].brand.id` **required** | `string` |  |
| `data[].brand.name` **required** | `string` |  |
| `data[].category` **required** | `CategoryRef` |  |
| `data[].category.id` **required** | `string` |  |
| `data[].category.label` **required** | `string` |  |
| `data[].category.path` | `string[]` |  |
| `data[].size` | `object` |  |
| `data[].gtin` | `string[]` |  |
| `data[].image_url` | `string \| null` |  |
| `data[].price_summary` **required** | `PriceSummary` |  |
| `data[].price_summary.currency` **required** | `string` |  |
| `data[].price_summary.min` **required** | `number \| null` |  |
| `data[].price_summary.max` **required** | `number \| null` |  |
| `data[].price_summary.median` | `number \| null` |  |
| `data[].price_summary.offers_count` **required** | `integer` |  |
| `data[].price_summary.retailers_count` **required** | `integer` |  |
| `data[].price_summary.best` | `object \| null` |  |
| `data[].price_summary.best.retailer` | `RetailerRef` |  |
| `data[].price_summary.best.offer_id` | `string` |  |
| `data[].price_summary.best.price` | `number` |  |
| `data[].price_summary.observed_at` | `string (date-time) \| null` |  |
| `data[].price_summary.converted` | `object` |  |
| `data[].price_summary.converted.currency` | `string` |  |
| `data[].price_summary.converted.min` | `number \| null` |  |
| `data[].price_summary.converted.max` | `number \| null` |  |
| `data[].price_summary.converted.fx_rate` | `number` |  |
| `data[].price_summary.converted.fx_date` | `string (date)` |  |
| `data[].price_summary.converted.fx_source` | `string` |  |
| `data[].price_summary.converted.fx_method` | `string` | Valores / values: `direct`, `cross`. |
| `data[].score` | `number` | Relevance score, search only. |
| `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)
- [`insufficient_credits`](/docs/errores#insufficient_credits)
- [`spend_cap_reached`](/docs/errores#spend_cap_reached)
- [`rate_limited`](/docs/errores#rate_limited)

## Example

```bash
curl "https://pricto.dev/v1/products/search?q=leche+entera&limit=2" \
  -H "Authorization: Bearer sk_test_sandbox"
```
```python
import requests

API_KEY = "sk_test_sandbox"

r = requests.get(
    "https://pricto.dev/v1/products/search",
    params={"q": "leche entera", "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/products/search?${new URLSearchParams({"q":"leche entera","limit":"2"})}`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
});
console.log(res.status, await res.json());
```

```json
{
  "data": [
    {
      "id": "prd_01colu",
      "name": "Leche entera Colun 1 L",
      "brand": {
        "id": "colun",
        "name": "Colun"
      },
      "category": {
        "id": "food.dairy.milk",
        "label": "Leche",
        "path": [
          "Alimentos y bebidas",
          "Lácteos",
          "… 1 más / more"
        ]
      },
      "size": {
        "value": 1,
        "unit": "l",
        "pack_count": 1,
        "text": "1 L"
      },
      "gtin": [
        "2000070000007"
      ],
      "image_url": null,
      "price_summary": {
        "currency": "CLP",
        "min": 1090,
        "max": 1290,
        "median": 1190,
        "offers_count": 3,
        "retailers_count": 3,
        "best": {
          "retailer": {
            "id": "cl-unimarc",
            "name": "Unimarc"
          },
          "offer_id": "ofr_01nuni",
          "price": 1090
        },
        "observed_at": "2026-10-23T11:00:00Z"
      },
      "score": 1
    },
    {
      "id": "prd_04colu",
      "name": "Leche entera Colun pack 6 x 1 L",
      "brand": {
        "id": "colun",
        "name": "Colun"
      },
      "category": {
        "id": "food.dairy.milk",
        "label": "Leche",
        "path": [
          "Alimentos y bebidas",
          "Lácteos",
          "… 1 más / more"
        ]
      },
      "size": {
        "value": 6,
        "unit": "l",
        "pack_count": 6,
        "text": "6 x 1 L"
      },
      "gtin": [
        "2000070001110"
      ],
      "image_url": null,
      "price_summary": {
        "currency": "CLP",
        "min": 7290,
        "max": 7290,
        "median": 7290,
        "offers_count": 2,
        "retailers_count": 2,
        "best": {
          "retailer": {
            "id": "cl-jumbo",
            "name": "Jumbo"
          },
          "offer_id": "ofr_004jum",
          "price": 7290
        },
        "observed_at": "2026-10-23T11:00:00Z"
      },
      "score": 1
    }
  ],
  "pagination": {
    "has_more": true,
    "next_cursor": "eyJvIjoyfQ"
  },
  "meta": {
    "request_id": "req_c86f421ca364426eb33a",
    "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": 0,
    "credits_remaining": 14999,
    "period_resets_at": "2026-11-01T00:00:00.000Z",
    "usage": {
      "credits_charged": 1,
      "credits_deduplicated": 0,
      "truncated": false,
      "truncated_reason": null,
      "dry_run": false,
      "units": {
        "search_pages": 1
      }
    },
    "lang": "es",
    "currency": "local",
    "data_as_of": "2026-10-23T11:00:00Z",
    "query_lang": "es",
    "warnings": [
      "synthetic_data: datos sintéticos de ejemplo / synthetic sample data"
    ]
  }
}
```
