Aller au contenu principal

Importer vos données métier

Kaleidr peut répondre aux questions à partir des propres données de votre organisation — vos établissements, annonces, chambres, tarifs, horaires d’ouverture et documents — parallèlement à sa connaissance générale du monde.

Deux points méritent d’être précisés avant tout le reste, car ils influencent chaque décision ci-dessous.

Vos données sont renvoyées uniquement à votre organisation. Elles sont isolées au niveau de la base de données, et non par la logique applicative, et elles n’atteignent jamais une réponse sur le Kaleidr Map destiné aux consommateurs. Elles sont disponibles uniquement sur vos propres surfaces B2B.

Un modèle de langage n’écrit jamais vos données. Il lit le header de votre export et quelques sample rows et propose un column mapping ; du code déterministe applique ensuite ce mapping à chaque row. Un mapping incorrect est une correction que vous effectuez dans un formulaire. Demander à un modèle de transcrire 500 lignes créerait 500 occasions d’inventer un prix qui pourrait ensuite être cité avec un timestamp convaincant, et un prix inventé serait impossible à distinguer d’un prix réel.

Disponibilité

L’import de vendor data est une fonctionnalité Enterprise-tier. L’UI d’import et l’API vérifient toutes deux VENDOR_UPLOAD_TIERS = {"enterprise"} — un owner ou admin Pro-tier reçoit 403 vendor_data_requires_enterprise pour tout appel d’import.

La vendor-data UI est actuellement désactivée en production (vendorDataEnabled config flag). Contactez le support Kaleidr si vous êtes sur Enterprise et souhaitez l’activer pour votre organisation.

De plus, un rôle owner ou admin Enterprise est requis — il s’agit de données au niveau de l’organisation, et non du projet.

Deux méthodes

La page d’import. Connectez-vous sur kaleidr.com et ouvrez Your Data dans votre espace de compte (chemin nav /vendor-data, à côté de Billing et API keys). Elle suit les mêmes quatre étapes que l’API : choisir un fichier, vérifier le mapping proposé, prévisualiser ce qui a été compris, publier. C’est la bonne approche pour une feuille de calcul.

L’API, documentée ci-dessous. Utilisez-la lorsque vos données existent déjà dans un système capable de push, ou lorsque vous souhaitez planifier les imports.

Authentification

Tous les appels prennent un access token Cognito comme bearer, le même que votre session détient déjà :

Authorization: Bearer <access token>

Pas une platform API key. Les Platform Keys identifient une intégration ; l’import de données est un acte d’administration de l’organisation, il s’authentifie donc comme une personne disposant d’un rôle. Tous les chemins ci-dessous se trouvent sous https://api.kaleidr.com.

Structure d’un import

Un import produit un ingest (le job) et un release (le résultat versionné). Un release reste draft jusqu’à sa publication, et la publication remplace atomiquement le précédent — les lecteurs ne voient jamais une mise à jour partiellement appliquée et il n’existe aucune période durant laquelle votre organisation ne possède aucune donnée.

1. Proposer un mapping

Envoyez le début de votre fichier — la ligne d’en-tête et quelques lignes de données, pas la totalité de l’export.

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

csv_head est limité à 16 KB et le sample est découpé server-side — envoyer un fichier plus volumineux n’augmente pas ce que le modèle peut voir.

sample_result est la partie à lire. Le mapping proposé est exécuté en dry-run sur vos propres sample rows avant même de vous être présenté, et sample_result indique ce qu’il a produit par section. Sans cela, vous pourriez ne découvrir qu’après l’import qu’un mapping apparemment plausible ne produit rien.

Si la proposition ne peut pas être appliquée, vous recevez tout de même 200 avec errors renseigné, pas une erreur 5xx. Le mapping est modifiable et corriger une colonne constitue l’ensemble de l’interaction. errors rapporte également tout ce qui peut être déterminé en une seule passe — un champ obligatoire manquant et un nom de colonne absent de votre feuille arrivent ensemble plutôt qu’un par round trip.

Ce qui est détecté avant l’import : une section à laquelle manque un champ requis par chaque ligne (stay_date, price_amount, units_available, le name ou timezone d’un lieu), une timezone {"const": …} qui n’est pas une véritable zone IANA, une currency const qui ne comporte pas trois lettres et toute règle d’objet qui n’est pas un conteneur const. Sinon, chacun de ces problèmes échouerait une fois par ligne après l’import.

Limité à 30 propositions par utilisateur et par heure.

2. Préparer une 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 doit se terminer par .json ou .csv.
  • artifact est le texte brut du fichier.
  • source vaut csv, json ou manual.
  • mapping_spec est ce que l’étape 1 a renvoyé, éventuellement modifié. Omettez-le si vous envoyez un bundle JSON déjà normalisé ou un CSV contenant uniquement des places.
  • preview: true prépare sans publier — fortement recommandé pour un premier import et pour toute modification du mapping.
  • org_id est facultatif ; sa valeur par défaut est l’organisation que vous administrez.

Idempotency-Key est requis pour cet appel (8–128 caractères) et son scope est limité à l’organisation. Réessayer avec la même clé renvoie l’ingest existant au lieu d’en créer un second. Utilisez une clé nouvelle lorsque vous choisissez volontairement de re-préparer après avoir modifié un mapping — il s’agit réellement d’une requête différente, et une clé dérivée du fichier vous renverrait l’ingest construit avec l’ancien mapping.

3. Suivre l’exécution

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

status passe de pendingrunningsucceeded ou failed. En cas de succès, row_counts indique ce qui a été compris — "47 places, 312 rates" — et error_report contient les lignes impossibles à lire, avec la raison pour chacune.

4. Publier

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

Uniquement pour un ingest préparé avec preview: true et terminé avec succès.

La publication réexécute le job au lieu de simplement modifier un flag. Elle relit le même artifact et réapplique le même mapping, de sorte que les counts et identifiers correspondent par construction — mais le geocoding est un appel live, donc une coordinate peut différer si le provider l’a corrigée depuis votre preview.

N’envoyez pas de Idempotency-Key ici. Cet endpoint ne l’accepte pas et n’en a pas besoin : une seconde publication du même ingest ne peut pas se produire. Si votre première requête a expiré de votre côté mais a réussi du nôtre, la nouvelle tentative renvoie 409ingest_is_not_a_preview, ou publish_already_in_progress si deux tentatives se chevauchent exactement. Les deux signifient que votre publication est déjà en cours. Traitez-les comme un succès, et non comme une erreur à réessayer.

Lister les releases

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

Filtrage facultatif avec ?status=. Un seul release par organisation est published à la fois.

Les previews expirent

Une preview que vous n’approuvez jamais est retirée après 14 jours, calculés à partir de la fin du staging. Elle est marquée superseded plutôt que supprimée, de sorte que l’import reste dans votre historique — mais elle ne peut plus être publiée et vous devez effectuer un nouvel import. Publier une preview expirée renvoie 409 no_previewed_release_to_publish.

Notes sur les champs

timezone est requis pour chaque place, et c’est important. Les réponses sur les tarifs et disponibilités sont calculées selon le calendrier local de l’établissement — "tonight" dans un hôtel à Sydney correspond à un autre jour que "tonight" sur le server. Si votre export ne possède réellement aucune colonne timezone, mappez explicitement une constante :

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

Faites-le volontairement plutôt que de laisser une valeur par défaut. UTC est une réponse correcte pour un établissement qui fonctionne en horaires UTC, mais subtilement incorrecte pour un établissement qui ne le fait pas ; l’erreur n’apparaît qu’aux limites d’une stay window.

L’absence de timezone, ou le nom d’une zone inexistante, est rejetée dès l’étape propose plutôt qu’après l’import.

Fournissez les coordinates lorsque vous les avez. Un place possédant lat/lng est utilisé tel quel — vos coordinates font autorité et nous ne les recalculerons pas. Un place ne possédant qu’une address est géocodé, et une correspondance dont nous ne sommes pas certains est refusée plutôt que devinée : placer un établissement au mauvais endroit sur une carte est pire que de le signaler comme impossible à résoudre. Une demi-coordinate est traitée comme une faute de frappe, pas comme une absence.

Réimporter est peu coûteux et sûr. Les identifiers sont dérivés des colonnes que votre mapping désigne comme identifiantes, de sorte que le même export produit les mêmes références — réimporter met à jour au lieu de dupliquer.

Erreurs

StatusMeaning
401Access token manquant ou expiré
403 vendor_data_requires_enterpriseL’organisation n’est pas sur Enterprise tier
403Votre organisation n’est pas activée pour l’import de données
404Aucun ingest correspondant pour votre organisation
409L’ingest n’est pas dans un état permettant cet appel — consultez les notes de publication ci-dessus
413Le fichier dépasse la limite d’import
422Le fichier ou le mapping n’a pas pu être lu ; le body indique les lignes et les raisons
429Rate limited — réessayez après une pause

À venir

L’API accepte aujourd’hui un bundle complet. Une fois qu’un mapping devient un objet stocké et réutilisable, elle acceptera également votre propre export accompagné d’un mapping id, afin qu’une intégration puisse envoyer directement le fichier qu’elle produit déjà sans devoir d’abord le remodeler. Une delta API — upsert et delete par natural key, avec un curseur since — suivra la même voie.