Referencia de la API · v1
Búsqueda
Referencia del endpoint de búsqueda de XEYE: POST /search con clave API, parámetros, respuesta, respuestas degradadas y /target.
Claves API
Las claves API autentican todas las llamadas a la API, la búsqueda incluida. Créalas desde la página Claves API con el permiso de búsqueda, etiquétalas según dónde se usan y rótalas creando una nueva y borrando la antigua.
Una clave da acceso a las listas públicas de tu cuenta, y solo a ellas. Las listas privadas se prueban desde la página Búsqueda de la consola (que usa tu sesión, no una clave). Para que una integración pueda consultar una lista, márcala como pública.
El endpoint de búsqueda
La búsqueda es una única llamada HTTP POST a /search con cuerpo JSON, autenticada con la cabecera X-API-Key. Solo sirve listas públicas.
El cuerpo es estricto: un campo desconocido, un término en blanco o un valor fuera de rango responden 422 con el detalle por campo.
Buscar
https://api.xeye.es/v1/searchÁmbito: search| Campo | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| list_name | cuerpo | string | sí | Nombre exacto de la lista (pública) donde buscar (máx. 100 caracteres). |
| search_term | cuerpo | string | sí | La consulta del usuario (1–500 caracteres). Las erratas y palabras parciales no son problema. |
| limit | cuerpo | integer | no | Número máximo de resultados, de 1 a 1000. Por defecto 50. |
| session | cuerpo | string | no | Identificador libre de la sesión del usuario final (máx. 255); agrupa sus búsquedas y enlaza con /target. |
| include_score_breakdown | cuerpo | boolean | no | true = cada resultado incluye text_score y semantic_score además de score. |
| register_log | cuerpo | boolean | no | Obsoleto e ignorado; se acepta por compatibilidad. |
Petición
curl -X POST https://api.xeye.es/v1/search \
-H "X-API-Key: $XEYE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"list_name": "products",
"search_term": "wireless headphones",
"limit": 5
}'Respuesta
{
"success": true,
"results": [
{
"item": "Sony WH-1000XM5 wireless headphones",
"score": 0.93,
"params": { "sku": "SONY-XM5", "url": "/products/sony-wh-1000xm5", "price": 348 },
"text_score": 0.71,
"semantic_score": 0.96
}
],
"total_results": 1,
"search_term": "wireless headphones",
"list_name": "products",
"duration_ms": 42,
"degraded": false,
"degradation_reasons": []
}La respuesta
Los resultados vienen ordenados por puntuación (0–1, cuanto más alta mejor). Cada uno incluye el texto del elemento («item»), sus parámetros intactos y, si lo pediste, el desglose texto/semántica. duration_ms es el tiempo de búsqueda en el servidor.
Respuestas degradadas
Toda respuesta lleva degraded y degradation_reasons. Si degraded es true, la búsqueda se ha servido con menos calidad y el motivo lo dice: no_embeddings (la lista no tiene entrenamiento en uso: solo texto), model_unavailable (el modelo de embeddings no pudo cargarse), model_mismatch (los vectores no cuadran con el modelo: reentrena) o stale_data (datos caducos que no se pudieron refrescar). La cabecera X-Search-Degraded: true lo indica también.
Registrar la elección: /target
Opcional. Cuando el usuario final elige un resultado, envía POST /target con list_name, target_term (el texto del elemento elegido) y la misma session de la búsqueda. Solo registra la elección en el historial; no busca nada. Responde {"success": true}.
Registrar la elección
https://api.xeye.es/v1/targetÁmbito: search| Campo | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| list_name | cuerpo | string | sí | Nombre exacto de la lista (pública) donde buscar (máx. 100 caracteres). |
| target_term | cuerpo | string | sí | Texto del elemento que el usuario eligió. |
| session | cuerpo | string | no | Identificador libre de la sesión del usuario final (máx. 255); agrupa sus búsquedas y enlaza con /target. |
Petición
curl -X POST https://api.xeye.es/v1/target \
-H "X-API-Key: $XEYE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"list_name": "products",
"target_term": "Sony WH-1000XM5 wireless headphones",
"session": "b1f2-…"
}'Respuesta
{ "success": true }Límites de uso
El cupo de búsquedas por minuto es por cuenta: todas tus claves API (y el playground de la consola) lo comparten. Por defecto son 120 búsquedas/min; un administrador puede fijar otro valor para tu cuenta. Además hay un límite por dirección IP que se aplica antes de validar la clave.
Cada respuesta autenticada incluye X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset (segundos hasta la siguiente ventana). Al agotarse el cupo recibes 429 con Retry-After.
HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 23
{
"status": 429,
"error": "Too Many Requests",
"code": "RATE_LIMITED",
"message": "Rate limit of 120 requests per minute per account exceeded; retry in 23 seconds"
}Errores
Todos los errores comparten el mismo cuerpo JSON: status, error (frase HTTP), code (identificador estable para tu código) y message (texto en inglés que puede cambiar); los 422 añaden details con el motivo por campo. Decide por code, no por message.
| HTTP | code | Significado | Qué hacer |
|---|---|---|---|
| 400 | INVALID_HOST | La cabecera Host no es la del servicio. | Llama a la URL pública del servicio de búsqueda, sin proxies que reescriban Host. |
| 401 | API_KEY_MISSING · API_KEY_INVALID | Falta la cabecera X-API-Key, o la clave no existe o fue revocada. | Revisa la clave o crea una nueva. |
| 403 | LIST_NOT_PUBLIC | La lista es privada. | Haz la lista pública desde sus ajustes; las privadas solo se prueban desde la consola. |
| 404 | LIST_NOT_FOUND | No hay ninguna lista con ese nombre en tu cuenta. | Revisa list_name: debe coincidir exactamente con el nombre de la lista. |
| 413 | REQUEST_TOO_LARGE | El cuerpo de la petición supera el tamaño máximo (16 KB). | Envía solo los campos documentados; search_term admite hasta 500 caracteres. |
| 422 | VALIDATION_FAILED | Cuerpo inválido: campo desconocido, término en blanco o valor fuera de rango. | Mira details: indica el campo y el motivo. |
| 429 | RATE_LIMITED | Cupo de búsquedas por minuto de tu cuenta (o de tu IP) agotado. | Espera los segundos de Retry-After y reintenta; usa X-RateLimit-Remaining para no llegar al límite. |
| 503 | SERVICE_NOT_READY · BACKEND_UNAVAILABLE | El buscador aún está cargando sus catálogos (SERVICE_NOT_READY) o no pudo cargar los datos de la lista (BACKEND_UNAVAILABLE). | Reintenta pasados los segundos de Retry-After; si persiste, consulta la página de estado (/status). |
Recomendaciones
Llama a la API desde tu backend y guarda la clave en una variable de entorno, no en código cliente.
Usa una clave por entorno o integración: así puedes revocar una sin romper el resto.
Controla el 429 con un pequeño reintento/backoff respetando Retry-After: el cupo es por cuenta y por minuto.
Envía session e informa de la elección con /target: el historial de búsquedas te dirá qué consultas no encuentran lo que esperan tus usuarios.