Saltar al contenido principal

Subir los datos de tu empresa

Kaleidr puede responder preguntas utilizando los datos propios de tu organización — tus propiedades, listados, habitaciones, tarifas, horarios de apertura y documentos — junto con su conocimiento base del mundo.

Hay dos aspectos que conviene dejar claros antes que cualquier otra cosa, porque condicionan cada decisión posterior.

Tus datos solo se sirven de vuelta a tu organización. Están aislados a nivel de base de datos, no mediante lógica de aplicación, y nunca llegan a una respuesta del Kaleidr Map para consumidores. Solo están disponibles en tus propias superficies B2B.

Un modelo de lenguaje nunca escribe tus datos. Lee el header de tu exportación y unas pocas sample rows y propone un column mapping; después, código determinista aplica ese mapping a cada row. Un mapping incorrecto es una corrección que haces en un formulario. Hacer que un modelo transcriba 500 filas supondría 500 oportunidades de inventar un precio que después podría citarse con un timestamp convincente, y un precio inventado sería indistinguible de uno real.

Disponibilidad

La carga de vendor data es una función de Enterprise-tier. Tanto la UI de carga como la API comprueban VENDOR_UPLOAD_TIERS = {"enterprise"} — un owner o admin de Pro-tier recibe 403 vendor_data_requires_enterprise en cualquier llamada de carga.

La vendor-data UI está actualmente deshabilitada en production (vendorDataEnabled config flag). Contacta con soporte de Kaleidr si estás en Enterprise y necesitas activarla para tu organización.

Además, se requiere un rol de owner o admin de Enterprise — son datos a nivel de organización, no por proyecto.

Dos formas de entrada

La página de carga. Inicia sesión en kaleidr.com y abre Your Data en el área de tu cuenta (ruta nav /vendor-data, junto a Billing y API keys). Recorre los mismos cuatro pasos que la API: elegir un archivo, revisar el mapping propuesto, previsualizar lo que se entendió y publicar. Esta es la ruta adecuada para una hoja de cálculo.

La API, documentada a continuación. Úsala cuando tus datos ya estén en un sistema que pueda hacer push, o cuando quieras programar cargas periódicas.

Autenticación

Todas las llamadas utilizan un access token de Cognito como bearer, el mismo que tu sesión ya mantiene:

Authorization: Bearer <access token>

No una platform API key. Las platform keys identifican una integración; subir datos es una acción de administración de la organización, por lo que se autentica como una persona con un rol. Todas las rutas siguientes están bajo https://api.kaleidr.com.

Estructura de una carga

Una carga produce un ingest (el job) y un release (el resultado versionado). Un release permanece como draft hasta que se publica, y publicar sustituye atómicamente al anterior — los lectores nunca ven una actualización aplicada a medias y no hay ningún intervalo en el que tu organización se quede sin datos.

1. Proponer un mapping

Envía el comienzo de tu archivo — la fila de encabezado y unas pocas filas de datos, no toda la exportación.

MethodPathBodyReturns
POST/inference-api/vendor/mapping/propose{ csv_head }{ mapping_spec, columns, sample_result, notes, errors[] }

csv_head está limitado a 16 KB y el sample se recorta server-side — enviar un archivo mayor no amplía lo que ve el modelo.

sample_result es la parte que debes leer. El mapping propuesto se prueba mediante dry-run sobre tus propias sample rows antes incluso de mostrártelo, y sample_result informa de lo que produjo por sección. Un mapping que parece plausible pero no produce nada sería algo que, de otro modo, quizá descubrirías solo después de subirlo.

Si la propuesta no puede aplicarse, sigues recibiendo 200 con errors rellenado, no un 5xx. El mapping es editable y corregir una columna constituye toda la interacción. errors además informa de todo lo que puede conocerse en una pasada — un campo obligatorio ausente y un nombre de columna que tu hoja no contiene llegan juntos en lugar de uno por cada round trip.

Qué detecta antes de subir: una sección a la que le falta un campo necesario en todas las filas (stay_date, price_amount, units_available, el name o timezone de un lugar), una timezone {"const": …} que no sea una zona IANA real, una currency const que no tenga tres letras y cualquier regla de objeto que no sea un contenedor const. De lo contrario, cada uno de estos casos fallaría una vez por fila después de la carga.

Limitado a 30 propuestas por usuario y hora.

2. Preparar una preview

MethodPathBodyReturns
POST/shared-api/vendor-data/ingests{ filename, artifact, source, mapping_spec?, preview?, org_id? }{ ingest_id, release_id, status, status_url, dispatched }
  • filename debe terminar en .json o .csv.
  • artifact es el texto bruto del archivo.
  • source es csv, json o manual.
  • mapping_spec es lo devuelto por el paso 1, opcionalmente editado. Omítelo si envías un bundle JSON ya normalizado o un CSV solo de places.
  • preview: true prepara sin publicar — muy recomendable para una primera carga y para cualquier modificación del mapping.
  • org_id es opcional; de forma predeterminada se usa la organización que administras.

Idempotency-Key es obligatorio en esta llamada (8–128 caracteres), y está limitado por organización. Reintentar con la misma clave devuelve el ingest existente en lugar de crear uno nuevo. Utiliza una clave nueva cuando deliberadamente vuelvas a preparar los datos después de editar un mapping — es una solicitud realmente distinta, y una clave derivada del archivo te devolvería el ingest creado con el mapping anterior.

3. Supervisarlo

MethodPathReturns
GET/shared-api/vendor-data/ingests/{ingest_id}{ status, attempts, row_counts, error_report, created_at, started_at, finished_at }

status pasa de pendingrunningsucceeded o failed. Si tiene éxito, row_counts indica lo que se entendió — "47 places, 312 rates" — y error_report contiene las filas que no pudieron leerse, junto con el motivo de cada una.

4. Publicar

MethodPathReturns
POST/shared-api/vendor-data/ingests/{ingest_id}/publish{ ingest_id, release_id, status, status_url, dispatched }

Solo para un ingest preparado con preview: true que haya terminado correctamente.

Publicar vuelve a ejecutar el job en lugar de simplemente cambiar un flag. Vuelve a leer el mismo artifact y aplica de nuevo el mismo mapping, por lo que counts e identifiers coinciden por construcción — pero geocoding es una llamada live, por lo que una coordinate puede diferir si el provider la ha corregido desde tu preview.

No envíes un Idempotency-Key aquí. Este endpoint no lo acepta, y no lo necesita: no puede producirse una segunda publicación del mismo ingest. Si tu primera solicitud agotó el tiempo de espera de tu lado pero tuvo éxito en el nuestro, el reintento devuelve 409ingest_is_not_a_preview, o publish_already_in_progress si dos intentos se solapan exactamente. Ambos significan que la publicación ya está en curso. Trátalos como éxito, no como un error que deba reintentarse.

Listar releases

MethodPathReturns
GET/shared-api/vendor-data/releases[{ id, status, published_at, superseded_at, created_at }]

Opcionalmente filtrado por ?status=. Exactamente un release por organización está published en cada momento.

Las previews caducan

Una preview que nunca apruebas se retira después de 14 días, medidos desde que terminó su staging. Se marca como superseded en lugar de eliminarse, por lo que la carga permanece en tu historial — pero ya no puede publicarse y tendrías que volver a subirla. Publicar una preview caducada devuelve 409 no_previewed_release_to_publish.

Notas sobre campos

timezone es obligatorio para cada place y es importante. Las respuestas sobre tarifas y disponibilidad se calculan utilizando el calendario local de la propiedad — "tonight" en un hotel de Sydney es un día diferente de "tonight" en el server. Si tu exportación realmente no contiene una columna timezone, mapea explícitamente una constante:

{ "timezone": { "const": "UTC" } }

Hazlo deliberadamente en lugar de dejarlo como default. UTC es una respuesta correcta para una propiedad que opera con horas UTC y sutilmente incorrecta para una que no lo hace; el error solo aparece en los límites de una stay window.

Omitir timezone o indicar una zona inexistente se rechaza ya en el paso propose, no después de la carga.

Proporciona coordinates cuando las tengas. Un place con lat/lng se utiliza tal cual — tus coordinates son autoritativas y no volveremos a derivarlas. Un place que solo tenga una address se geocodifica, y una coincidencia en la que no confiemos se rechaza en lugar de adivinarse: colocar una propiedad incorrectamente en un mapa es peor que informar que no puede resolverse. Media coordinate se trata como un error tipográfico, no como un dato ausente.

Volver a subir es barato y seguro. Los identifiers se derivan de las columnas que tu mapping define como identificadoras, por lo que la misma exportación genera las mismas referencias — volver a subir actualiza en lugar de duplicar.

Errores

StatusMeaning
401Access token ausente o caducado
403 vendor_data_requires_enterpriseLa organización no está en Enterprise tier
403Tu organización no está habilitada para carga de datos
404No existe ese ingest para tu organización
409El ingest no se encuentra en un estado que permita esta llamada — consulta las notas de publicación anteriores
413El archivo supera el límite de carga
422No se pudo leer el archivo o mapping; el body indica las filas y los motivos
429Rate limited — vuelve a intentarlo después de una pausa

Próximamente

Actualmente la API acepta un bundle completo. Cuando un mapping se convierta en un objeto almacenado y reutilizable, también aceptará tu propia exportación más un mapping id, de modo que una integración pueda enviar directamente el archivo que ya produce sin remodelarlo primero. Una delta API — upsert y delete por natural key, con cursor since — seguirá la misma ruta.