API
Productos
Lee tu catálogo de productos y búsqueda semántica
# Productos > Lee tu catálogo de productos y búsqueda semántica - Página: https://tbit.app/es/docs/api/products - URL base: `https://rest-api.tbit.app/v1` - Autenticación: encabezado `X-API-Key` con tu clave en cada solicitud (los ejemplos la leen de la variable de entorno `TBIT_API_KEY`) ## Descripción General Los endpoints de productos exponen el catálogo de tu agente: listarlo, obtener un producto individual o hacer búsqueda semántica sobre él. Solo se devuelven productos activos (publicados): los borradores nunca se exponen. Clave publicable: para los endpoints de lectura del catálogo la clave API funciona como una clave publicable (identifica tu cuenta y mide el uso; los datos del catálogo son públicos). Es seguro usarla desde código del navegador, igual que una clave publicable de Stripe. ## Endpoints | Método | Ruta | Descripción | | --- | --- | --- | | `GET` | `/v1/products` | List active products | | `GET` | `/v1/products/:id` | Get a single product | | `GET` | `/v1/products/search` | Semantic search over the catalog | ## Listar Productos Devuelve una lista paginada de productos activos. Filtra por etiqueta de categoría o por tipo: | Parámetro | Tipo | Descripción | | --- | --- | --- | | `limit` | `number` | 1-100, default 50 | | `offset` | `number` | Pagination offset, default 0 | | `tag` | `string` | Filter by category tag | | `kind` | `string` | 'product' or '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" ``` Respuesta: ```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 } } ``` ## Obtener un Producto Obtén un producto por id. Los borradores, ids desconocidos y productos de otro agente devuelven 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" ``` Respuesta: ```json { "error": { "code": "NOT_FOUND" } } ``` ## Búsqueda Semántica La búsqueda usa embeddings vectoriales, no coincidencia de palabras clave: una consulta como "fiesta de dinosaurios" encuentra productos de fiesta con temática de dinosaurios aunque ningún título contenga esas palabras exactas. La búsqueda tiene un límite de 30 solicitudes por minuto por clave (además del límite global de 100/min). Cada resultado puede incluir un score de relevancia: `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" ``` Respuesta: ```json { "data": [ { "_id": "prod_id_1", "kind": "product", "title": "Kit fiesta dinosaurios", "currency": "COP", "base_price": 95000, "score": 0.91 } ] } ``` ## El Objeto Producto Todos los endpoints devuelven objetos producto con la siguiente forma. base_price es un número simple en la moneda del catálogo (p. ej. COP, sin unidades menores). compare_at_price solo está presente cuando el producto está en oferta y siempre es mayor que base_price: | Campo | Tipo | Descripción | | --- | --- | --- | | `_id` | `string` | Product id | | `kind` | `string` | 'product' or 'service' | | `title` | `string` | Product title | | `description` | `string` | Product description | | `media` | `array` | Array of { url, alt?, type: 'image' \| 'video', position? } | | `category_tags` | `string[]` | Category tags | | `currency` | `string` | ISO 4217 currency code | | `base_price` | `number` | Price as a plain number (e.g. COP, no minor units) | | `compare_at_price` | `number?` | Only when on sale; always higher than base_price | | `variants` | `array` | Array of { id, title, price, compare_at_price?, selected_options: [{ name, value }] } | | `created_at` | `string` | ISO 8601 timestamp | | `updated_at` | `string` | ISO 8601 timestamp |Los endpoints de productos exponen el catálogo de tu agente: listarlo, obtener un producto individual o hacer búsqueda semántica sobre él. Solo se devuelven productos activos (publicados): los borradores nunca se exponen.
Clave publicable: para los endpoints de lectura del catálogo la clave API funciona como una clave publicable (identifica tu cuenta y mide el uso; los datos del catálogo son públicos). Es seguro usarla desde código del navegador, igual que una clave publicable de Stripe.
| Método | Ruta | Descripción |
|---|---|---|
| GET | /v1/products | List active products |
| GET | /v1/products/:id | Get a single product |
| GET | /v1/products/search | Semantic search over the catalog |
Devuelve una lista paginada de productos activos. Filtra por etiqueta de categoría o por tipo:
| Parámetro | Tipo | Descripción |
|---|---|---|
limit | number | 1-100, default 50 |
offset | number | Pagination offset, default 0 |
tag | string | Filter by category tag |
kind | string | 'product' or 'service' |
/v1/productscurl "https://rest-api.tbit.app/v1/products?limit=20&tag=fiestas&kind=product" \
-H "X-API-Key: $TBIT_API_KEY"const response = await fetch('https://rest-api.tbit.app/v1/products?limit=20&tag=fiestas&kind=product', {
headers: {
'X-API-Key': process.env.TBIT_API_KEY,
},
});
const data = await response.json();import axios from 'axios';
const { data } = await axios.get(
'https://rest-api.tbit.app/v1/products?limit=20&tag=fiestas&kind=product',
{
headers: {
'X-API-Key': process.env.TBIT_API_KEY,
},
},
);import os
import requests
response = requests.get(
'https://rest-api.tbit.app/v1/products?limit=20&tag=fiestas&kind=product',
headers={'X-API-Key': os.environ['TBIT_API_KEY']},
)
data = response.json()<?php
$ch = curl_init('https://rest-api.tbit.app/v1/products?limit=20&tag=fiestas&kind=product');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . getenv('TBIT_API_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"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
}
}Obtén un producto por id. Los borradores, ids desconocidos y productos de otro agente devuelven 404:
/v1/products/prod_id_1curl "https://rest-api.tbit.app/v1/products/prod_id_1" \
-H "X-API-Key: $TBIT_API_KEY"const response = await fetch('https://rest-api.tbit.app/v1/products/prod_id_1', {
headers: {
'X-API-Key': process.env.TBIT_API_KEY,
},
});
const data = await response.json();import axios from 'axios';
const { data } = await axios.get(
'https://rest-api.tbit.app/v1/products/prod_id_1',
{
headers: {
'X-API-Key': process.env.TBIT_API_KEY,
},
},
);import os
import requests
response = requests.get(
'https://rest-api.tbit.app/v1/products/prod_id_1',
headers={'X-API-Key': os.environ['TBIT_API_KEY']},
)
data = response.json()<?php
$ch = curl_init('https://rest-api.tbit.app/v1/products/prod_id_1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . getenv('TBIT_API_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"error": {
"code": "NOT_FOUND"
}
}La búsqueda usa embeddings vectoriales, no coincidencia de palabras clave: una consulta como "fiesta de dinosaurios" encuentra productos de fiesta con temática de dinosaurios aunque ningún título contenga esas palabras exactas. La búsqueda tiene un límite de 30 solicitudes por minuto por clave (además del límite global de 100/min). Cada resultado puede incluir un score de relevancia:
/v1/products/searchcurl "https://rest-api.tbit.app/v1/products/search?q=fiesta%20de%20dinosaurios&limit=10" \
-H "X-API-Key: $TBIT_API_KEY"const response = await fetch('https://rest-api.tbit.app/v1/products/search?q=fiesta%20de%20dinosaurios&limit=10', {
headers: {
'X-API-Key': process.env.TBIT_API_KEY,
},
});
const data = await response.json();import axios from 'axios';
const { data } = await axios.get(
'https://rest-api.tbit.app/v1/products/search?q=fiesta%20de%20dinosaurios&limit=10',
{
headers: {
'X-API-Key': process.env.TBIT_API_KEY,
},
},
);import os
import requests
response = requests.get(
'https://rest-api.tbit.app/v1/products/search?q=fiesta%20de%20dinosaurios&limit=10',
headers={'X-API-Key': os.environ['TBIT_API_KEY']},
)
data = response.json()<?php
$ch = curl_init('https://rest-api.tbit.app/v1/products/search?q=fiesta%20de%20dinosaurios&limit=10');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . getenv('TBIT_API_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"data": [
{
"_id": "prod_id_1",
"kind": "product",
"title": "Kit fiesta dinosaurios",
"currency": "COP",
"base_price": 95000,
"score": 0.91
}
]
}Todos los endpoints devuelven objetos producto con la siguiente forma. base_price es un número simple en la moneda del catálogo (p. ej. COP, sin unidades menores). compare_at_price solo está presente cuando el producto está en oferta y siempre es mayor que base_price:
| Campo | Tipo | Descripción |
|---|---|---|
_id | string | Product id |
kind | string | 'product' or 'service' |
title | string | Product title |
description | string | Product description |
media | array | Array of { url, alt?, type: 'image' | 'video', position? } |
category_tags | string[] | Category tags |
currency | string | ISO 4217 currency code |
base_price | number | Price as a plain number (e.g. COP, no minor units) |
compare_at_price | number? | Only when on sale; always higher than base_price |
variants | array | Array of { id, title, price, compare_at_price?, selected_options: [{ name, value }] } |
created_at | string | ISO 8601 timestamp |
updated_at | string | ISO 8601 timestamp |