# Producten

> Lees je productcatalogus en zoek semantisch

- Pagina: https://tbit.app/nl/docs/api/products
- Basis-URL: `https://rest-api.tbit.app/v1`
- Authenticatie: header `X-API-Key` met je sleutel bij elk verzoek (de voorbeelden lezen hem uit de omgevingsvariabele `TBIT_API_KEY`)

## Overzicht

De product-endpoints ontsluiten de catalogus van je agent: de lijst opvragen, één product ophalen of er semantisch in zoeken. Alleen actieve (gepubliceerde) producten worden teruggegeven: concepten worden nooit getoond.

Publiceerbare sleutel: voor de lees-endpoints van de catalogus werkt de API-sleutel als een publiceerbare sleutel (hij identificeert je account en meet het gebruik; de catalogusgegevens zijn openbaar). Je kunt hem veilig in browsercode gebruiken, net als een publiceerbare sleutel van Stripe.

## Endpoints

| Methode | Pad | Beschrijving |
| --- | --- | --- |
| `GET` | `/v1/products` | Actieve producten opvragen |
| `GET` | `/v1/products/:id` | Eén product ophalen |
| `GET` | `/v1/products/search` | Semantisch zoeken in de catalogus |

## Producten opvragen

Geeft een gepagineerde lijst met actieve producten terug. Filter op categorielabel of op type:

| Parameter | Type | Beschrijving |
| --- | --- | --- |
| `limit` | `number` | 1-100, standaard 50 |
| `offset` | `number` | Paginering-offset, standaard 0 |
| `tag` | `string` | Filter op categorielabel |
| `kind` | `string` | 'product' of 'service' |

`GET /v1/products`

```bash
curl "https://rest-api.tbit.app/v1/products?limit=20&tag=fiestas&kind=product" \
  -H "X-API-Key: $TBIT_API_KEY"
```

Response:

```json
{
  "data": [
    {
      "_id": "prod_id_1",
      "kind": "product",
      "title": "Kit fiesta dinosaurios",
      "description": "Decoración completa para fiesta infantil",
      "media": [
        { "url": "https://api.tbit.app/media/dino-kit.jpg", "alt": "Kit fiesta", "type": "image", "position": 0 }
      ],
      "category_tags": ["fiestas", "infantil"],
      "currency": "COP",
      "base_price": 95000,
      "compare_at_price": 120000,
      "variants": [
        {
          "id": "var_id_1",
          "title": "Grande",
          "price": 95000,
          "selected_options": [{ "name": "Tamaño", "value": "Grande" }]
        }
      ],
      "created_at": "2024-09-01T12:00:00Z",
      "updated_at": "2024-09-01T12:00:00Z"
    }
  ],
  "pagination": {
    "total": 134,
    "limit": 20,
    "offset": 0,
    "has_more": true
  }
}
```

## Eén product ophalen

Haal een product op met zijn id. Concepten, onbekende id's en producten van een andere agent geven 404:

`GET /v1/products/prod_id_1`

```bash
curl "https://rest-api.tbit.app/v1/products/prod_id_1" \
  -H "X-API-Key: $TBIT_API_KEY"
```

Response:

```json
{
  "error": {
    "code": "NOT_FOUND"
  }
}
```

## Semantisch zoeken

Het zoeken gebruikt vector-embeddings, geen trefwoordovereenkomst: een zoekopdracht als "dinosaurusfeest" vindt feestproducten met een dinosaurusthema, ook als geen enkele titel precies die woorden bevat. Zoeken heeft een limiet van 30 verzoeken per minuut per sleutel (naast de algemene limiet van 100/min). Elk resultaat kan een relevantiescore (score) bevatten:

`GET /v1/products/search`

```bash
curl "https://rest-api.tbit.app/v1/products/search?q=fiesta%20de%20dinosaurios&limit=10" \
  -H "X-API-Key: $TBIT_API_KEY"
```

Response:

```json
{
  "data": [
    {
      "_id": "prod_id_1",
      "kind": "product",
      "title": "Kit fiesta dinosaurios",
      "currency": "COP",
      "base_price": 95000,
      "score": 0.91
    }
  ]
}
```

## Het productobject

Alle endpoints geven productobjecten terug met de volgende vorm. base_price is een gewoon getal in de valuta van de catalogus (bijv. COP, zonder kleinere eenheden). compare_at_price staat er alleen als het product in de aanbieding is en is altijd hoger dan base_price:

| Veld | Type | Beschrijving |
| --- | --- | --- |
| `_id` | `string` | Product-id |
| `kind` | `string` | 'product' of 'service' |
| `title` | `string` | Producttitel |
| `description` | `string` | Productbeschrijving |
| `media` | `array` | Array van { url, alt?, type: 'image' \| 'video', position? } |
| `category_tags` | `string[]` | Categorielabels |
| `currency` | `string` | ISO 4217-valutacode |
| `base_price` | `number` | Prijs als gewoon getal (bijv. COP, zonder kleinere eenheden) |
| `compare_at_price` | `number?` | Alleen bij een aanbieding; altijd hoger dan base_price |
| `variants` | `array` | Array van { id, title, price, compare_at_price?, selected_options: [{ name, value }] } |
| `created_at` | `string` | ISO 8601-tijdstempel |
| `updated_at` | `string` | ISO 8601-tijdstempel |
