# 3CHEAPS — AI / LLM documentation

## Overview

3CHEAPS is a Romanian price comparison website. Products are indexed from 1,500+ partner shops. Prices are stored in MySQL and refreshed in near real-time via configurable shop scrapers.

## Authentication

Public read APIs require no authentication. CMS admin and shop configuration writes are not exposed publicly.

## Product identifiers

- **Public ID**: opaque string used in URLs (e.g. `CHWYSSZWW`)
- **Internal ID**: numeric MySQL `ITEM.id`
- Convert with the API; URLs always use the public ID

## Endpoints

### Search products

```
GET /api/products-search.php?q=iphone+15&page=1&limit=24
GET /api/products-search.php?categoryId=123&page=1&limit=24
```

Response fields: `total`, `products[]` with `id`, `name`, `slug`, `url`, `image`, `price`, `currency`.

### Get product

```
GET /api/products-get.php?id={publicProductId}&country=ro
```

Returns full product: name, brand, MPN, description, categories, specifications, offers (seller, price, url), price history.

### Live prices

```
GET /api/live-prices.php?productId={publicProductId}&country=ro
GET /api/live-prices.php?productId={id}&refresh=1
```

Returns scraped live offers with cache metadata. Use `refresh=1` to bypass the 10-minute cache.

Streaming variant (Server-Sent Events):

```
GET /api/live-prices-stream.php?productId={publicProductId}&country=ro
```

### Taxonomy

```
GET /api/departments.php
GET /api/categories.php?department=electronice
GET /api/categories.php?id=42
```

### Shops

```
GET /api/shops.php
GET /api/shops.php?seller=emag.ro
```

Public shop responses exclude scraper credentials and proxy settings.

### Resolve external product URL

```
GET /api/resolve-url.php?url=https%3A%2F%2Fwww.emag.ro%2F...
```

Maps a shop product URL to a 3CHEAPS product or search URL.

## HTML page structure

Product pages include:

- `<title>`: `{product name} - Compară Prețuri | 3CHEAPS`
- Canonical URL
- Open Graph / Twitter Card metadata
- JSON-LD `Product` schema with `AggregateOffer`
- Microdata breadcrumbs

Prefer JSON APIs for structured data extraction.

## MCP server

Location: `mcp-server/`

Tools exposed to AI agents:

| Tool | Description |
|------|-------------|
| `search_products` | Search by query or category |
| `get_product` | Full product + DB offers |
| `get_live_prices` | Scraped live prices |
| `list_departments` | Top-level departments |
| `list_categories` | Categories in a department |
| `get_category` | Single category metadata |
| `list_shops` | Partner shops |
| `get_shop` | Shop summary |
| `resolve_product_url` | External URL → 3CHEAPS URL |

Configure in Cursor MCP settings:

```json
{
  "mcpServers": {
    "3cheaps": {
      "command": "node",
      "args": ["/path/to/website_ai/mcp-server/index.js"],
      "env": {
        "THREECHEAPS_API_BASE": "https://3cheaps.com"
      }
    }
  }
}
```

## Rate limiting

Public APIs are rate-limited per IP to prevent bulk scraping.

| Bucket | Limit |
|--------|-------|
| Global | 100 requests / hour |
| Catalog (search, product) | 30 / hour, max 6 / minute |
| Live prices | 25 / hour, max 4 / minute |
| Shops list | 10 / hour |
| Taxonomy | 20 / hour |
| Resolve URL | 15 / hour |
| Automated clients (curl, python-requests, etc.) | 15 / hour, max 3 / minute |

Responses include `X-RateLimit-*` headers. HTTP `429` returns `retry_after` seconds.

**Bypass:** send header `X-3CHEAPS-Api-Key` with a secret key configured in `config/api-limits.php` (server-side only).
Do not rely on User-Agent — it can be spoofed by anyone.

Please cache responses. Live price endpoints use a 10-minute server-side cache by default.

## Contact

https://3cheaps.com/contact
