Importer les données de votre entreprise
Rôle de cette fonction
L’importation permet à Kaleidr de répondre à partir des données propres à votre organisation. C’est une fonction Enterprise. Une version publiée est utilisée dans l’assistant de Kaleidr Studio pour les membres connectés. Trois étapes supplémentaires la rendent disponible sur votre site ou backend : créer une clé autorisée à lire ces données, poser une question avec cette clé et vérifier que vos lieux figurent dans la réponse. Réponses à partir de vos données décrit le parcours entier. Cette page traite de l’étape d’importation : requêtes, champs, limites, erreurs et retrait ou suppression d’une version.
Il ne s’agit pas des fichiers que vous ajoutez au panneau Data d’une carte Kaleidr Studio (tableur, GeoJSON ou trace GPX). Il s’agit d’une fonction distincte disponible sur tous les forfaits. Voir Jeux de données sur une carte.
Deux méthodes d’importation utilisent exactement le même pipeline :
- L’interface : la section Data for AI Answers en bas du panneau Data de toute carte dans Kaleidr Studio. Les outils sont réservés aux propriétaires ou administrateurs d’organisations autorisées à importer. Voir Importer dans Studio.
- L’API décrite ici : l’interface effectue les mêmes appels. Formats, limites, états et erreurs sont identiques, et une version créée par une méthode apparaît dans l’autre.
Trois caractéristiques importantes avant de commencer :
- Vos données sont consultées lorsqu’une question reçoit une réponse. Kaleidr interroge alors la version publiée : sa dépublication empêche immédiatement toute nouvelle réponse d’utiliser ces données.
- Vos données sont accessibles uniquement à votre organisation. Elles sont isolées par organisation et n’apparaissent ni sur la carte grand public de Kaleidr ni dans les réponses d’autres organisations.
- Vos valeurs ne sont jamais inventées. Un assistant facultatif propose une correspondance de colonnes à partir de l’en-tête et d’au plus cinq lignes d’exemple. Toutes les lignes sont ensuite converties selon la correspondance approuvée. Toute erreur de correspondance doit être corrigée puis retraitée ; aucun prix, date ou nom n’est généré.
Disponibilité
| Exigence | Détails |
|---|---|
| Forfait | Enterprise. Sous Free et Pro, importer, publier, relancer et proposer une correspondance renvoient 403 vendor_data_not_on_plan. Le forfait de référence est celui de l’organisation, géré sur kaleidr.com/billing ; Studio n’a pas son propre forfait. |
| Rôle | Propriétaire ou administrateur de l’organisation, sinon 403 org_admin_required. |
| Limites | Définies par l’accord de l’organisation ; voir Limites. GET /shared-api/datahub/limits renvoie les valeurs applicables. Référence |
| Interface | La section Data for AI Answers du panneau Data de Kaleidr Studio ou cette API. Les deux suivent le même pipeline. |
Rôles et forfaits requis par opération :
| Appels | Rôle | Forfait |
|---|---|---|
| Proposer une correspondance, importer, publier, relancer | Propriétaire ou administrateur | Enterprise |
| Lire les limites, le statut d’ingestion et les versions | Propriétaire ou administrateur | Tous |
| Dépublier et supprimer une version | Propriétaire ou administrateur | Tous |
Les deux dernières lignes fonctionnent sur tous les forfaits : une organisation ayant quitté Enterprise peut toujours voir et retirer les données précédemment importées.
L’exploitation de ces données est également réservée à Enterprise. L’assistant Studio ne consulte la version publiée que tant que l’organisation est sur Enterprise. Pour consulter ces données via une clé API ou le SDK, l’autorisation vendor est requise, disponible seulement pour Enterprise. Voir Réponses à partir de vos données.
Le contenu de Data for AI Answers dépend du forfait et de votre rôle : voir Ce que la section affiche quand vous ne pouvez pas importer.
Quantités autorisées pour votre organisation
Vérifiez les limites avant d’importer. C’est l’appel effectué à l’ouverture de la section Studio.
| Champ | Détail |
|---|---|
| Requête | GET /shared-api/datahub/limits |
| Qui | Propriétaire ou administrateur, tout forfait |
| Paramètre | org_id, facultatif : sélection de l’organisation si vous en gérez plusieurs. |
curl https://api.kaleidr.com/shared-api/datahub/limits \
-H "Authorization: Bearer $KALEIDR_ACCESS_TOKEN"
Pour Enterprise, les trois valeurs de limite sont délibérément absentes de l’exemple : elles sont fixées par votre accord et aucun chiffre générique ne serait applicable. limits comporte toujours les trois champs entiers du tableau suivant.
{
"can_upload": true,
"plan": "enterprise",
"limits": { "…": "places, documents and artifact_mb: three integers, described below" },
"reason": null
}
Sous Free et Pro, l’appel renvoie tout de même 200 et précise la raison :
{
"can_upload": false,
"plan": "pro",
"limits": { "places": 0, "documents": 0, "artifact_mb": 0 },
"reason": "vendor_data_not_on_plan"
}
| Champ | Type | Signification |
|---|---|---|
can_upload | boolean | Indique si l’organisation peut importer. |
plan | string ou null | Forfait d’origine : free, pro ou enterprise. |
limits.places | integer | Nombre de lieux par importation, lignes de données pour CSV. |
limits.documents | integer | Nombre de documents par importation. |
limits.artifact_mb | integer | Taille maximale du fichier en MiB. |
reason | string ou null | vendor_data_not_on_plan si can_upload vaut false, sinon null. Lorsque l’import est interdit, toutes les limites sont à zéro. |
Ces chiffres sont propres à votre organisation : ils figurent dans son contrat. Aucun plafond ne peut dépasser ce qu'un téléversement peut techniquement accepter : la plateforme fixe une limite maximale pour chacune des trois valeurs, et le contrat ne peut la dépasser.
| Statut | Signification |
|---|---|
| 200 | Pour propriétaire ou administrateur, tout forfait. Sous Enterprise, can_upload: false est renvoyé plutôt qu’un refus. |
| 401 | Jeton d’accès manquant, expiré ou de type incorrect. |
403 org_admin_required | Le compte n’est pas propriétaire ou administrateur. |
Authentification
Chaque appel utilise le jeton d’accès de votre compte Kaleidr connecté en tant que Bearer :
Authorization: Bearer <account access token>
- Ce n’est pas une clé API. Une clé
kld_pk_…oukld_sk_…est refusée. Les clés identifient une intégration, tandis que l’importation relève de l’administration d’une organisation et doit donc être effectuée par une personne autorisée. - Fournissez le jeton d’accès, pas le jeton d’identité.
- Il appartient à un propriétaire ou administrateur connecté et expire avec sa session. Aucun identifiant durable n’existe actuellement pour cette API. Si vous souhaitez automatiser les importations, contactez Kaleidr avant de commencer.
- L’interface Studio utilise la session du membre connecté ; vous n’avez pas à gérer ce jeton vous-même.
Tous les chemins indiqués ici sont relatifs à https://api.kaleidr.com. Les exemples lisent le jeton dans une variable d’environnement :
export KALEIDR_ACCESS_TOKEN='<account access token>'
Si vous gérez plusieurs organisations, indiquez org_id dans le corps de l’importation ou en paramètre ?org_id= pour les autres appels. Sans valeur, votre organisation principale est choisie.
Données acceptées
Chaque importation correspond à un fichier texte transmis comme chaîne dans une requête JSON. L’extension du nom détermine la méthode de lecture.
| Données disponibles | Envoyer | Contenu |
|---|---|---|
| Liste de lieux | .csv avec colonnes fixes, sans correspondance | Lieux |
| Export de tableur contenant une ligne par nuit, chambre ou tarif | .csv et mapping_spec | Lieux, types de chambres, plans tarifaires, tarifs par jour et disponibilités |
| Ensemble de données déjà structuré | Paquet .json | Tous les éléments précédents, plus horaires et documents |
Chaque importation doit contenir au moins un lieu.
CSV de lieux
L’en-tête doit utiliser les noms de colonnes suivants :
| Colonne | Requis | Notes |
|---|---|---|
name | Oui | Une ligne sans nom échoue et son numéro est signalé. |
timezone | Oui | Zone IANA, par exemple Europe/London. |
lat, lng | Une des deux façons de situer le lieu | Coordonnées utilisées telles quelles. |
address | Une des deux façons de situer le lieu | Sert à rechercher les coordonnées si lat et lng sont absents. |
category | Non | Catégorie courte comme hotel ou restaurant. |
ref | Non | Votre propre identifiant ; en son absence, les lignes sont identifiées par numéro. |
name,timezone,lat,lng,address,category
Harbor Hotel,Europe/London,51.5079,-0.0877,"1 Example Street, London",hotel
Canal House,Europe/Amsterdam,,,"Example Gracht 12, Amsterdam",hotel
Tableur avec correspondance de colonnes
Un tableur dont chaque ligne représente une observation (établissement, chambre, formule, date ou prix) ne peut pas être lu avec des noms de colonnes fixes. Fournissez mapping_spec pour indiquer les champs que chaque colonne alimente.
Property,Address,Room,Plan,Date,Nightly Rate,Available
Harbor Hotel,"1 Example Street, London",Double,Flexible,2026-11-06,189.00,4
Harbor Hotel,"1 Example Street, London",Suite,Flexible,2026-11-06,320.00,1
{
"places": {
"ref_from": ["Property"],
"fields": {
"name": "Property",
"address": "Address",
"timezone": { "const": "Europe/London" },
"category": { "const": "hotel" }
}
},
"room_types": { "ref_from": ["Room"], "fields": { "name": "Room" } },
"rate_plans": { "ref_from": ["Plan"], "fields": { "name": "Plan" } },
"daily_rates": {
"fields": {
"stay_date": "Date",
"price_amount": "Nightly Rate",
"price_currency": { "const": "GBP" }
}
},
"daily_inventory": {
"fields": { "stay_date": "Date", "units_available": "Available" }
}
}
Règles de correspondance :
| Élément | Signification |
|---|---|
| Sections | places (obligatoire), room_types, rate_plans, daily_rates, daily_inventory. N’incluez que celles pour lesquelles vous avez des données. |
ref_from | Colonnes servant d’identifiant. Les lignes avec les mêmes valeurs désignent le même lieu, type de chambre ou plan. |
fields | Chaque champ est alimenté par une colonne ; certains acceptent une constante définie comme { "const": "value" }. |
Une correspondance ne peut définir que les champs suivants. La dernière colonne indique ceux qui peuvent être constants.
| Section | Champs autorisés | Constante possible |
|---|---|---|
places | name, address, timezone, category, lat, lng, overture_id | timezone, category |
room_types | name | name |
rate_plans | name, currency, cancellation_policy, board_basis | name, currency |
daily_rates | stay_date (date ISO), price_amount (nombre non négatif), price_currency (trois lettres) | price_currency |
daily_inventory | stay_date, units_available (entier non négatif) | Aucune |
Deux règles en découlent, et leur violation entraîne une erreur de validation :
- Un champ absent du tableau est refusé. L’erreur nomme le champ et les champs acceptés dans cette section :
room_types.fields.beds: not a field a mapping can set -- room_types takes name. Les attributs hors liste, comme le nombre de lits, doivent être envoyés dans un paquet JSON. - Une constante est interdite ailleurs. Prix, dates, nombres, noms des lieux et positions doivent provenir d’une colonne, par exemple
daily_rates.fields.price_amount: must name a column -- a constant cannot supply this field. Les constantes sont réservées à une valeur partagée par tout le tableur, comme un fuseau horaire ou une devise.
Ces problèmes sont signalés dans errors d’une proposition et dans error_report lorsque vous importez avec une correspondance incorrecte. L’ingestion échoue sans rien préparer.
Si daily_rates est présent, room_types et rate_plans doivent aussi figurer dans le mapping, chaque tarif appartenant à chacun des deux. Si la feuille n’a pas de colonne de plan tarifaire, définissez son nom comme constante.
Une correspondance ne s’applique qu’à un .csv. La fournir avec un .json fait échouer l’ingestion.
Paquet JSON
Un fichier .json est un objet pouvant contenir les listes ci-dessous. Leurs éléments se référencent avec ref.
{
"places": [
{
"ref": "harbor",
"name": "Harbor Hotel",
"timezone": "Europe/London",
"lat": 51.5079,
"lng": -0.0877,
"address": "1 Example Street, London",
"category": "hotel"
}
],
"room_types": [{ "ref": "double", "place_ref": "harbor", "name": "Double" }],
"rate_plans": [{ "ref": "flex", "place_ref": "harbor", "name": "Flexible" }],
"daily_rates": [
{
"place_ref": "harbor",
"room_type_ref": "double",
"rate_plan_ref": "flex",
"stay_date": "2026-11-06",
"price_amount": 189.0,
"price_currency": "GBP"
}
],
"daily_inventory": [
{ "place_ref": "harbor", "room_type_ref": "double", "stay_date": "2026-11-06", "units_available": 4 }
],
"hours": [
{ "place_ref": "harbor", "weekday": 0, "opens": "07:00", "closes": "23:00" },
{ "place_ref": "harbor", "valid_from": "2026-12-25", "valid_through": "2026-12-25", "is_closed": true }
],
"documents": [
{ "title": "Cancellation policy", "text": "Free cancellation until 18:00 on the day before arrival." }
]
}
| Liste | Champs obligatoires | Notes |
|---|---|---|
places | name, timezone, et lat avec lng ou address | ref unique ; au moins un lieu. |
room_types, rate_plans | place_ref, name | ref unique au sein de chaque liste. |
daily_rates | place_ref, room_type_ref, rate_plan_ref, stay_date, price_amount, price_currency | |
daily_inventory | place_ref, room_type_ref, stay_date, units_available | |
hours | place_ref, avec weekday ou date valid_from | weekday de 0 à 6, 0 correspondant au lundi ; opens et closes indiquent des heures. |
documents | title, text | Texte intégré seulement. |
Les listes acceptent également des champs facultatifs assortis de limites propres ; voir Limites par champ.
Précisions sur les documents :
- Un document correspond à son
titleet autextqu’il contient. Toute adresse de stockage ou clé sur un document est ignorée : il ne peut pas pointer vers un fichier externe. - Le champ facultatif
mimedécrit le texte.text/plain,text/markdownettext/htmlsont conservés ; toute autre valeur devienttext/plain.
Les nombres doivent être finis. NaN et Infinity ne sont admis ni comme coordonnées, prix ou quantités, ni dans des données JSON libres ; la ligne est alors signalée comme invalide.
Processus d’importation
Chaque importation crée une ingestion (la tâche) et une release (le résultat versionné). Une release reste draft jusqu’à sa publication. Publier remplace atomiquement l’ancienne version : personne ne lit de données partiellement mises à jour, et il n’existe aucune période intermédiaire sans données. Seule la dépublication volontaire supprime la version publiée.
propose a mapping ─► stage a preview ─► check the result ─► publish
(optional, POST /ingests GET /ingests/{id} POST /ingests/{id}/publish
for a sheet) preview: true
later, to take a release back out: unpublish ─► delete
POST /releases/{id}/unpublish DELETE /releases/{id}
1. Proposer une correspondance (facultatif)
Utilisez cette option pour une feuille sans correspondance. Envoyez uniquement le début du fichier : en-tête et quelques lignes, et non l’export entier.
| Élément | Détails |
|---|---|
| Requête | POST /inference-api/vendor/mapping/propose |
| Qui | Propriétaire ou administrateur d’une organisation Enterprise, comme pour l’importation. |
| Corps | { "csv_head": "<the first characters of your file>" } |
| Limite | csv_head de 1 à 16 384 caractères ; 30 propositions maximum par compte et par heure. |
| Coût | Chaque proposition consomme des crédits IA selon les tokens utilisés. Les autres appels de cette page n’en consomment pas. |
curl -X POST https://api.kaleidr.com/inference-api/vendor/mapping/propose \
-H "Authorization: Bearer $KALEIDR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"csv_head":"Property,Address,Room,Plan,Date,Nightly Rate,Available\nHarbor Hotel,\"1 Example Street, London\",Double,Flexible,2026-11-06,189.00,4\nHarbor Hotel,\"1 Example Street, London\",Suite,Flexible,2026-11-06,320.00,1\n"}'
{
"mapping_spec": { "places": { "ref_from": ["Property"], "fields": { "name": "Property", "address": "Address", "timezone": { "const": "Europe/London" } } }, "room_types": { "ref_from": ["Room"], "fields": { "name": "Room" } } },
"notes": "Time zone inferred from the addresses.",
"columns": ["Property", "Address", "Room", "Plan", "Date", "Nightly Rate", "Available"],
"sample_result": { "places": 1, "room_types": 2, "rate_plans": 1, "daily_rates": 2, "daily_inventory": 2 },
"errors": []
}
Comprendre la réponse :
- Examinez
sample_resulten priorité. La correspondance proposée est appliquée aux lignes d’exemple.sample_resultcompte les éléments produits par section. Une correspondance apparemment juste mais produisant zéro élément est ainsi repérée avant l’importation. errorspeut être non vide malgré une réponse 200. Toutes les erreurs d’une proposition inexploitable sont retournées pour vous permettre de la corriger : champ requis sans colonne, nom de colonne absent, fuseau IANA invalide ou devise sans trois lettres.- Seules les lignes complètes sont échantillonnées, au plus cinq. Si
csv_headne se termine pas par un retour à la ligne, la dernière ligne est ignorée pour éviter un échantillon tronqué. - Rien n’est enregistré. Modifiez la proposition puis envoyez-la lors de l’étape suivante.
| Statut | Signification |
|---|---|
403 org_admin_required | Votre compte n’est propriétaire ou administrateur d’aucune organisation. |
403 vendor_data_not_on_plan | Vous avez un rôle d’administration, mais aucune organisation Enterprise. |
| 422 | csv_head dépasse 16 384 caractères, n’a pas d’en-tête, répète un nom de colonne ou ne contient aucune ligne complète ; detail précise la cause. |
| 429 (limite de débit) | Plus de 30 propositions en une heure pour ce compte. |
| 429 (crédits IA) | Les crédits de l’organisation sont épuisés. |
502 mapping proposal unavailable | Impossible de produire une proposition ; réessayez ou écrivez-la manuellement. |
Distinguer les deux réponses 429
Les deux refus portent le statut 429. Examinez leur corps :
| Élément | Limite de débit | Crédits IA épuisés |
|---|---|---|
| Corps | { "detail": "at most 30 mapping proposals per hour" } | Réponse de quota standard |
| Reconnaissance | Pas de champ error ; detail contient la phrase indiquée. | "error": "quota_exceeded" avec limit, used, remaining, reset_at. |
| Mesure | Attendre ; la limite porte sur la dernière heure par compte. | Attendre reset_at, ajouter des crédits ou saisir la correspondance manuellement. |
{
"error": "quota_exceeded",
"detail": "Usage limit reached. Please try again later.",
"tier": "enterprise",
"remaining": 0,
"reset_at": "2026-11-01T04:00:00+00:00",
"period": "month",
"reset_in_seconds": 1296000
}
L’exemple omet quatre champs qui existent dans la vraie réponse. limit et used reflètent le quota contractuel et sa consommation. product et meter nomment le compteur de Studio, plutôt que celui de l’API, mais les crédits IA sont communs. Traitez le champ error comme pour les autres refus de quota.
Facturation des propositions :
- Les requêtes refusées (403, 422 ou 429 de limite de débit) ne coûtent rien. Une requête refusée avec 422 à cause de son échantillon compte néanmoins dans les 30 requêtes par heure.
- Une proposition impossible à produire faute de réponse (502) ne coûte rien.
- Une réponse produite mais inexploitable (également 502) est facturée selon ses tokens.
- Une proposition avec
errorsnon vide a été produite et est facturée normalement.
Dans Studio, les messages sont « You have reached the hourly limit for mapping proposals. Try again later, or edit the mapping by hand. » et « Your organization's AI credits for this period are used up. You can still write the mapping by hand. » Une correspondance écrite manuellement ne nécessite ni proposition ni crédits IA.
2. Préparer un aperçu
| Élément | Détail |
|---|---|
| Requête | POST /shared-api/datahub/ingests |
| Qui | Propriétaire ou administrateur, Enterprise |
| En-tête | Idempotency-Key obligatoire, entre 8 et 128 caractères |
| Champ du corps | Type | Valeur par défaut | Signification |
|---|---|---|---|
filename | string, 200 caractères maximum | Obligatoire | Doit finir par .csv ou .json ; l’extension choisit le parseur. |
artifact | string | Obligatoire | Contenu textuel brut du fichier. |
source | "csv", "api" ou "manual" | "csv" | Étiquette d’origine, sans effet sur le parseur. "json" est invalide et renvoie 422. |
mapping_spec | objet, 64 KB maximum | Aucun | Correspondance des colonnes CSV. À omettre pour un CSV de lieux ou un paquet JSON. |
preview | boolean | false | true prépare pour contrôle ; false publie après lecture. |
org_id | UUID | Organisation principale | Organisation destinataire. |
curl -X POST https://api.kaleidr.com/shared-api/datahub/ingests \
-H "Authorization: Bearer $KALEIDR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: places-2026-10-10-a" \
-d '{
"filename": "places.csv",
"source": "csv",
"preview": true,
"artifact": "name,timezone,lat,lng,address,category\nHarbor Hotel,Europe/London,51.5079,-0.0877,\"1 Example Street, London\",hotel\n"
}'
{
"ingest_id": "5f0c2a1e-…",
"release_id": "a81d77b0-…",
"status": "pending",
"status_url": "/shared-api/datahub/ingests/5f0c2a1e-…",
"dispatched": true
}
Idempotency-Key est propre à l’organisation. Renvoyer la même clé retourne l’ingestion déjà créée avec dispatched: false, sans en produire une autre. Pour préparer à nouveau volontairement, par exemple après avoir corrigé une correspondance, utilisez une nouvelle clé, sinon l’ancienne ingestion est retournée.
dispatched indique si le traitement a commencé avec cet appel. Pour une nouvelle ingestion, false signifie qu’elle reste pending ; démarrez-la avec l’appel de relance.
Utilisez preview: true pour la première importation et après toute modification de correspondance.
Une importation à la fois, plus une limite horaire. Une nouvelle demande est refusée lorsqu’une ingestion de la même organisation est en cours ou que l’organisation a créé 30 ingestions au cours de l’heure précédente :
| Statut | detail | Signification | Que faire |
|---|---|---|---|
| 409 | org_ingest_in_progress | Une autre ingestion de l’organisation est running. | Interrogez-la jusqu’à succeeded ou failed, puis réessayez avec le même Idempotency-Key. |
| 429 | ingest_rate_limited | L’organisation a créé 30 ingestions dans l’heure, aperçus compris. | Attendez ; vérifiez plutôt la correspondance avec la proposition que de préparer plusieurs fois. |
| 413 | request_body_too_large | La requête entière dépasse 32 MiB. | Réduisez le fichier ; voir Limites. |
Réutiliser un Idempotency-Key ne crée pas un nouvel envoi : l'ingestion existante est renvoyée, sans refus 409 ou 429 mentionné ci-dessus. Le corps n'est pas comparé au premier ; un fichier différent envoyé avec une clé déjà utilisée est donc ignoré. Toutefois, la requête est vérifiée avant la recherche de la clé : une répétition peut être refusée avec 413, avec 403 org_admin_required ou vendor_data_not_on_plan, ou avec 422 pour l'une des limites. La clé reste mémorisée tant que sa version de données existe. Après sa suppression ou son retrait automatique, la même clé lance un nouvel envoi.
3. Vérifier le résultat
| Élément | Détail |
|---|---|
| Requête | GET /shared-api/datahub/ingests/{ingest_id} |
| Qui | Propriétaire ou administrateur, tous forfaits |
curl https://api.kaleidr.com/shared-api/datahub/ingests/5f0c2a1e-… \
-H "Authorization: Bearer $KALEIDR_ACCESS_TOKEN"
{
"ingest_id": "5f0c2a1e-…",
"release_id": "a81d77b0-…",
"status": "succeeded",
"attempts": 1,
"row_counts": {
"places": 1,
"room_types": 0,
"rate_plans": 0,
"daily_rates": 0,
"daily_inventory": 0,
"hours": 0,
"documents": 0
},
"error_report": null,
"created_at": "2026-10-10T09:12:04Z",
"started_at": "2026-10-10T09:12:20Z",
"finished_at": "2026-10-10T09:12:41Z"
}
status passe de pending à running, puis à succeeded ou failed.
- En cas de
succeeded,row_countsdonne les éléments compris par catégorie. Comparez ces comptes avec vos attentes avant la publication. - En cas de
failed,error_report.errorsdécrit les lignes illisibles et les raisons. Au plus 200 erreurs sont affichées ;error_report.error_countdonne le total. Une ingestion échouée laisse la version publiée intacte.
{
"status": "failed",
"error_report": {
"errors": [
"places[1]: missing lat/lng -- supply coordinates, or an address to geocode from",
"places[2]: unknown timezone 'London'"
],
"error_count": 2
}
}
Une importation est intégrale ou nulle : une seule ligne invalide empêche toute préparation. Corrigez le fichier et recommencez avec un nouveau Idempotency-Key.
4. Publier
| Élément | Détail |
|---|---|
| Requête | POST /shared-api/datahub/ingests/{ingest_id}/publish |
| Qui | Propriétaire ou administrateur, Enterprise |
| Corps | Aucun |
curl -X POST https://api.kaleidr.com/shared-api/datahub/ingests/5f0c2a1e-…/publish \
-H "Authorization: Bearer $KALEIDR_ACCESS_TOKEN"
La réponse a la même structure que la préparation, avec status: "pending". La publication n’est possible que pour une ingestion créée avec preview: true et terminée en succeeded.
Publier relit le fichier. Le même fichier et la même correspondance produisent les mêmes comptes et identifiants que l’aperçu. Seules les coordonnées d’un lieu fourni uniquement par adresse peuvent légèrement changer si la géolocalisation se résout mieux.
Interrogez à nouveau le statut. L’ingestion revient à pending, se lance et se termine en succeeded. La nouvelle version est alors publiée et l’ancienne remplacée.
Traitez 409 comme « déjà en cours », et non comme un échec à relancer. L’appel de publication ne prend pas de Idempotency-Key. Si le premier appel a réussi côté Kaleidr mais a expiré côté client, le second peut renvoyer 409 ingest_is_not_a_preview ; deux appels simultanés peuvent renvoyer publish_already_in_progress. Cela signifie que la publication est en cours ou déjà effectuée. Consultez le statut plutôt que de la redemander.
Un code 409 a une autre signification : org_ingest_in_progress indique qu'un autre envoi de votre organisation est en cours de traitement, donc cette publication n'a pas commencé. Attendez que cet envoi passe à succeeded ou failed, puis relancez la publication.
Publier en une seule étape
Envoyez preview: false, ou omettez preview, pour publier dès que le fichier a été lu sans nouvel appel. Utilisez ce mode pour les importations récurrentes dont la correspondance est déjà vérifiée.
Relancer une ingestion bloquée
| Élément | Détail |
|---|---|
| Requête | POST /shared-api/datahub/ingests/{ingest_id}/dispatch |
| Qui | Propriétaire ou administrateur, Enterprise |
Utilisez cet appel lorsqu’une ingestion reste pending (par exemple dispatched vaut false) ou qu’elle est failed pour une cause indépendante des données. Une ingestion est traitée au maximum trois fois.
| Statut | Signification |
|---|---|
409 ingest_already_succeeded | Rien à faire. |
409 ingest_already_running | Traitement déjà en cours. |
409 ingest_attempts_exhausted | Trois essais déjà utilisés ; importez à nouveau avec un nouveau Idempotency-Key. |
409 org_ingest_in_progress | Une autre ingestion de l’organisation est en cours ; attendez sa fin. |
404 ingest_not_found | Aucune ingestion de cet identifiant dans votre organisation, ou sa version est en cours de suppression ou déjà supprimée. Rien à relancer. |
Lister les versions
| Élément | Détail |
|---|---|
| Requête | GET /shared-api/datahub/releases |
| Qui | Propriétaire ou administrateur, tous forfaits |
| Paramètres | status facultatif : draft, published, superseded, failed ou deleting ; autre valeur : 422 unknown_release_status. org_id facultatif. |
curl "https://api.kaleidr.com/shared-api/datahub/releases?status=published" \
-H "Authorization: Bearer $KALEIDR_ACCESS_TOKEN"
[
{
"id": "a81d77b0-…",
"status": "published",
"published_at": "2026-10-10T09:15:02Z",
"superseded_at": null,
"created_at": "2026-10-10T09:12:04Z",
"state": "published",
"ingest_id": "5f0c2a1e-…"
}
]
| Champ | Type | Signification |
|---|---|---|
id | UUID | Identifiant de version pour dépublier ou supprimer. |
status | string | draft, published, superseded, failed ou deleting. |
published_at | horodatage ou null | Date de publication. |
superseded_at | horodatage ou null | Date de remplacement, dépublication ou expiration de l’aperçu. |
created_at | horodatage | Acceptation de l’importation. |
state | string | Actions possibles dans l’état actuel, voir tableau suivant. |
ingest_id | UUID ou null | Identifiant de l’ingestion à utiliser pour le statut et la publication. |
state subdivise l’état draft en deux cas, afin que le client sache quelle action proposer sans nouvel appel : (status)
state | status | Signification | Actions possibles |
|---|---|---|---|
processing | draft | Importation en file ou en traitement, y compris publication en une étape et publication d’un aperçu. | Attendre ou supprimer. |
preview | draft | Aperçu préparé, en attente de décision. | Publier ou supprimer. |
published | published | Version actuellement utilisée dans les réponses. | Dépublier. |
superseded | superseded | Remplacée, dépubliée ou aperçu expiré. | Supprimer. |
failed | failed | Importation impossible à lire. | Supprimer. |
deleting | deleting | Suppression en cours. | Aucune. |
La liste contient les 50 versions les plus récentes, par ordre décroissant. Une organisation ne possède jamais plus d’une version published à la fois ; après dépublication, aucune. Les versions deleting ne figurent que dans un résultat filtré par ?status=deleting et disparaissent définitivement une fois supprimées. (Référence)
Retirer une version
Deux appels distincts retirent les données : unpublish désactive la version publiée et delete supprime une version non publiée. Tous deux sont accessibles aux propriétaires et administrateurs de tout forfait, pour que même une organisation ayant quitté Enterprise puisse retirer ses données. Aucun ne nécessite de corps ni de Idempotency-Key, et tous deux peuvent être répétés sans danger.
Dans Kaleidr Studio
Chaque ligne de Releases dans Data for AI Answers propose l’action appropriée et demande confirmation. Après avoir quitté Enterprise, un propriétaire ou administrateur voit toujours la liste tant que des versions existent, avec uniquement Unpublish et Delete ; les outils d’importation sont remplacés par « Uploading is part of the Enterprise plan. »
| Statut de ligne | Action | Confirmation | Affichage suivant |
|---|---|---|---|
| Published | Unpublish | « Unpublish this release? Kaleidr AI stops answering from this data until you publish another release. This release cannot be published again. » | « Unpublishing… » puis « Unpublished. Kaleidr AI no longer answers from this data. » ; la ligne devient Superseded. |
| Draft, Superseded, Failed | Delete | « Delete this release? This removes the release and everything made from it, and cannot be undone. » | « Deleting… », puis « Release deleted. » ; la ligne disparaît. |
| Processing | Aucune |
Chaque confirmation comporte le bouton de l’action et un bouton Cancel. Delete n’est pas proposé pour une version publiée. Une tentative API directe affiche « This release is published. Unpublish it before you delete it. » Consultez La liste des versions.
Dépublier une version
| Élément | Détail |
|---|---|
| Requête | POST /shared-api/datahub/releases/{release_id}/unpublish |
| Qui | Propriétaire ou administrateur, tous forfaits |
| Corps | Aucun |
| Paramètre | org_id facultatif |
curl -X POST https://api.kaleidr.com/shared-api/datahub/releases/a81d77b0-…/unpublish \
-H "Authorization: Bearer $KALEIDR_ACCESS_TOKEN"
{ "release_id": "a81d77b0-…", "status": "superseded" }
La version cesse d’être servie dès que l’appel renvoie sa réponse. Conséquences :
- Votre organisation n’a plus de version publiée jusqu’à la prochaine publication. Une version antérieure ne revient pas. Les réponses continuent à partir des connaissances générales sans annoncer le retrait des données.
- Cette version ne peut plus être publiée. Pour rétablir les mêmes données, réimportez le fichier et publiez une nouvelle version.
- La version reste dans la liste comme
supersededet peut être supprimée, ou sera éliminée selon la rétention.
| Statut | detail | Signification |
|---|---|---|
| 200 | La version est superseded. Un appel répété renvoie encore 200, y compris pour toute version déjà remplacée. superseded | |
| 403 | org_admin_required | Compte non propriétaire ou administrateur. |
| 404 | release_not_found | Version absente de l’organisation ou en cours de suppression. |
| 409 | release_not_published | Version draft ou failed, jamais utilisée. |
Supprimer une version
| Élément | Détail |
|---|---|
| Requête | DELETE /shared-api/datahub/releases/{release_id} |
| Qui | Propriétaire ou administrateur, tous forfaits |
| Corps | Aucun |
| Paramètre | org_id facultatif |
curl -X DELETE https://api.kaleidr.com/shared-api/datahub/releases/a81d77b0-… \
-H "Authorization: Bearer $KALEIDR_ACCESS_TOKEN"
HTTP/1.1 202 Accepted
{ "release_id": "a81d77b0-…", "status": "deleting", "dispatched": true }
La suppression retire la version, le fichier importé et tout ce que Kaleidr en a produit. L’opération est irréversible.
- Il faut d’abord dépublier une version publiée. La supprimer directement renvoie 409
release_is_published. Toute autre version peut être supprimée : aperçu, version remplacée, échouée ou encore en traitement. - La réponse est 202 et la suppression se termine peu après. Dès le retour, la version devient
deleting, disparaît de la liste ordinaire, ne peut plus être publiée et son ingestion renvoie 404ingest_not_found. Cela vaut aussi pour la lecture de l’état et la relance du traitement. dispatchedindique si cet appel a déclenché la suppression. Avecfalse, elle démarre automatiquement un peu plus tard ; vous pouvez également répéter l’appel.- Répéter est sans danger. Pendant le traitement, la réponse reste 202. Une fois la suppression terminée, 404
release_not_foundsignifie « déjà supprimée ».
| Statut | detail | Signification |
|---|---|---|
| 202 | Version deleting, répétition toujours 202 jusqu’à la fin. | |
| 403 | org_admin_required | Le compte n’a pas le rôle requis. |
| 404 | release_not_found | Version introuvable, même après suppression terminée. |
| 409 | release_is_published | Version toujours publiée : dépubliez-la d’abord. |
Pour vérifier la fin de la suppression, listez les versions avec ?status=deleting. Une liste vide signifie que plus rien n’est en cours.
Suppression automatique des anciennes versions
Vous n’avez pas à supprimer une version qui n’est plus active. Kaleidr s’en charge automatiquement, comme avec l’appel de suppression :
| Version | Suppression |
|---|---|
superseded : remplacée ou dépubliée | 30 jours après remplacement ou dépublication |
| Aperçu jamais publié | Expiration à 14 jours, suppression 30 jours après |
failed | 30 jours après la dernière tentative de traitement |
published | Jamais, tant qu’elle reste publiée |
Ce que la suppression n’efface pas
Une version totalement supprimée ne sert à aucune nouvelle réponse. En revanche, la suppression n’atteint pas les réponses mises en cache pour une durée limitée, les transcriptions de chat enregistrées, les sauvegardes ou le texte déjà envoyé à un fournisseur de modèles pendant le traitement. Voir Portée de la suppression.
Limites
Limites prévues par votre contrat
La taille et la quantité des données importées sont fixées par l’accord avec votre organisation. La plateforme applique un plafond technique à chacune de ces limites, que votre contrat ne peut pas dépasser.
| Limite | Enterprise | En cas de dépassement |
|---|---|---|
Taille de artifact | Fixée par votre contrat | 422 à l’importation |
| Lignes CSV, hors en-tête | Fixée par votre contrat | 422 à l’importation |
| Lieux dans un paquet JSON | Fixée par votre contrat | 422 à l’importation |
| Documents dans un paquet JSON | Fixée par votre contrat | 422 à l’importation |
GET /shared-api/datahub/limitsrenvoie les limites de votre organisation.- Free et Pro ne peuvent pas importer, donc n’ont pas de quotas d’importation ; les appels renvoient 403
vendor_data_not_on_plan. - Les limites s’appliquent par organisation. Une nouvelle publication remplace intégralement l’ancienne, si bien qu’elles bornent à la fois chaque importation et la version publiée.
Une valeur au-delà de ces limites renvoie 422 et une raison mentionnant la valeur limite et le forfait. Dans les exemples, <count> représente la quantité envoyée et <limit> la limite contractuelle :
{ "detail": { "errors": ["<count> places exceed the limit of <limit> (enterprise plan)"] } }
Les trois autres raisons suivent ce modèle : <count> documents exceed the limit of <limit> (enterprise plan), csv has more than <limit> rows; the places limit is <limit> (enterprise plan) et artifact is <size> MB; the limit is <limit> MB (enterprise plan). Un fichier trop grand n’est pas analysé plus loin, donc une seule raison est retournée.
Limites fixes pour toutes les organisations
| Limite | Valeur | En cas de dépassement |
|---|---|---|
| Requête d’importation complète | 32 MiB | 413 request_body_too_large |
| Types de chambres par importation | 10 000 | 422 pour JSON ; ingestion échouée pour une feuille mappée |
| Plans tarifaires par importation | 10 000 | 422 pour JSON ; ingestion échouée pour une feuille mappée |
| Lignes d’horaires dans JSON | 25 000 | 422 |
| Lignes de tarifs par nuit et de disponibilité, ensemble par import | 200 000 | Échec de l’ingestion : daily facts: <count> rows exceed the cap of 200000 |
| Texte de tous les documents d’un import | Environ 600 000 caractères au plus, moins si le texte est réparti entre de nombreux documents | Échec de l’ingestion : documents: chunk count exceeds the cap of 500 |
| Profondeur du JSON | Un JSON trop imbriqué est refusé | 422 |
mapping_spec | 64 KB | 422 |
filename | 200 caractères, suffixe .csv ou .json | 422 |
| Importations en cours par organisation | 1 | 409 org_ingest_in_progress (lors de l’envoi, de la publication et de la relance) |
| Nouvelles importations par organisation | 30 par heure | 429 ingest_rate_limited |
csv_head d’une proposition | 16 384 caractères | 422 |
| Propositions | 30 par compte et par heure, consommant chacune des crédits IA | 429 ; voir Les deux 429 |
| Tentatives par ingestion | 3 | 409 lors de la relance |
| Aperçu non publié | 14 jours | 409 à la publication |
| Version non courante | 30 jours | Suppression automatique |
La limite de la requête est supérieure à celle du fichier, car le fichier est envoyé comme chaîne dans JSON et l’échappement augmente la taille. Une requête de plus de 32 MiB est refusée avant lecture avec 413. Une requête plus petite dont le fichier dépasse la limite de l’organisation est refusée avec 422.
Un dépassement de taille ou de quantité renvoie 422 avec une liste d’au plus 200 raisons. Voici un exemple de dépassement commun à toutes les organisations :
{ "detail": { "errors": ["10001 room_types exceed the cap of 10000"] } }
Un JSON trop profondément imbriqué produit le même type de réponse :
{ "detail": { "errors": ["upload is nested too deeply"] } }
La limite CSV compte toutes les lignes du fichier, quel que soit leur sens. Un tableau avec une ligne par nuit l’atteint vite. Envoyez de gros volumes de prix et disponibilités sous forme de paquet JSON ; les lieux, documents, types de chambre, plans tarifaires et horaires y sont comptés à l’importation.
Limites par champ
Chaque valeur possède une taille maximale. Le texte est mesuré en caractères. Une valeur JSON libre (objet ou tableau) est mesurée en octets après sérialisation JSON.
| Liste | Champ | Limite |
|---|---|---|
| Toutes | ref, place_ref, room_type_ref, rate_plan_ref | 128 caractères |
places | name | 200 caractères |
places | category | 100 caractères |
places | timezone | 64 caractères |
places | overture_id (facultatif) | 128 caractères |
places | address | 2 048 octets en JSON |
places | schema_org (objet facultatif) | 16 384 octets en JSON |
room_types | name | 200 caractères |
room_types | amenities (tableau facultatif), attributes (objet facultatif) | 8 192 octets en JSON chacun |
rate_plans | name | 200 caractères |
rate_plans | currency (facultatif) | 3 caractères |
rate_plans | cancellation_policy (facultatif) | 2 000 caractères |
rate_plans | board_basis (facultatif) | 100 caractères |
rate_plans | attributes (objet facultatif) | 8 192 octets en JSON |
hours | note (facultatif) | 500 caractères |
documents | title | 300 caractères |
Le moment où la limite est vérifiée dépend du format :
- Paquet JSON : vérifié à l’importation. Le serveur renvoie 422, avec la ligne et le champ pour chaque erreur, comme
places[3]: name is longer than 200 charactersouroom_types[0]: amenities is larger than 8192 bytes as JSON. - CSV de lieux ou feuille mappée : vérifié pendant le traitement. L’ingestion termine en
failedet les raisons figurent danserror_report.errors.
Une valeur JSON libre contenant NaN ou Infinity est signalée par <list>[<row>]: <field> holds a non-finite number.
Expiration des aperçus
Un aperçu jamais publié expire 14 jours après sa préparation. Il est marqué superseded et reste temporairement dans la liste, mais sa publication n’est plus possible : elle renvoie 409 no_previewed_release_to_publish. Importez de nouveau le fichier. Comme les autres versions remplacées, il sera supprimé automatiquement 30 jours après, ou peut être supprimé avant.
Notes sur les champs
timezone est obligatoire pour chaque lieu et modifie les réponses. Les tarifs et disponibilités s’interprètent selon le calendrier du lieu ; « ce soir » dans un hôtel de Sydney ne correspond pas à la même date qu’à Londres. Si la feuille n’a pas de colonne de fuseau horaire, mappez une constante :
{ "timezone": { "const": "Australia/Sydney" } }
Choisissez le fuseau avec soin. Un mauvais fuseau semble fonctionner presque toute la journée mais produit des erreurs près de minuit. Les fuseaux absents ou non reconnus par IANA déclenchent une erreur.
Fournissez les coordonnées si vous en disposez. Un lieu doté de lat et lng utilise exactement ces nombres. Si seule l’adresse est donnée, Kaleidr cherche les coordonnées et refuse toute correspondance insuffisamment certaine, en vous demandant de fournir une position plutôt que d’en inventer une. Un lieu mal placé sur la carte est pire qu’un lieu non résolu.
Renvoyer le même export est sans danger. Pour une feuille mappée, les identifiants proviennent des colonnes nommées dans ref_from ; un même export génère les mêmes identifiants. La nouvelle release remplace l’ancienne au lieu de s’y ajouter.
Chaque release est complète en elle-même. Aucune donnée n’est héritée de la précédente. Si vous omettez les lieux du mois dernier, ils disparaissent des réponses après publication.
Envoyez du texte UTF-8. Une archive ZIP, un fichier gzip ou un PDF renommé en .csv ou .json est refusé.
Erreurs
Sauf lorsqu’une liste de raisons est renvoyée, les erreurs d’importation ont la structure { "detail": "<code>" }.
| Statut | detail | Signification |
|---|---|---|
| 401 | Jeton d’accès absent, expiré ou de mauvais type. | |
| 403 | org_admin_required | Le compte n’est pas propriétaire ou administrateur. |
| 403 | vendor_data_not_on_plan | Organisation sans Enterprise. Importer, publier et relancer sont refusés, mais lire, dépublier et supprimer restent possibles. |
| 404 | ingest_not_found | Ingestion inexistante, ou version en cours de suppression ou déjà supprimée. |
| 404 | release_not_found | Version inexistante dans l’organisation, y compris après suppression terminée. |
| 409 | release_not_published | Dépublication demandée sur une version brouillon ou échouée. |
| 409 | release_is_published | Suppression demandée sur une version publiée ; dépublier d’abord. |
| 409 | ingest_conflict | Deux importations avec le même Idempotency-Key sont entrées en conflit ; réessayer. |
| 409 | ingest_is_not_a_preview | Ingestion non préparée comme aperçu, ou publication déjà demandée. |
| 409 | ingest_already_running | Ingestion en cours. |
| 409 | no_previewed_release_to_publish | Aperçu échoué, non terminé ou expiré. |
| 409 | publish_already_in_progress | Deux publications se chevauchent ; une est en cours. |
| 409 | ingest_already_succeeded | Relance demandée sur une ingestion terminée. |
| 409 | ingest_attempts_exhausted | Trois tentatives de traitement déjà utilisées. |
| 409 | org_ingest_in_progress | Une autre ingestion de l’organisation est en cours ; attendre. |
| 413 | request_body_too_large | Importation de plus de 32 MiB ; publication, relance et lecture limitées à 1 MiB. |
| 422 | { "errors": [ … ] } | Fichier ou correspondance hors limites, JSON trop imbriqué ou illisible en CSV/JSON ; chaque raison précise le champ et éventuellement le forfait. Référence |
| 429 | ingest_rate_limited | 30 nouvelles importations de l’organisation dans l’heure. |
| 422 | Liste de validation | Champ absent ou mal formé, par exemple Idempotency-Key absent, mauvaise extension ou source non autorisée. |
| 422 | unknown_release_status | status ne fait pas partie des cinq valeurs permises. |
Un fichier dépassant la limite de l’organisation produit 422 avec la raison dans errors. Une requête entière trop grande produit 413 et le corps { "detail": "request_body_too_large" }.
L’appel de proposition possède ses propres erreurs, décrites sous Proposer une correspondance. Il renvoie 403 org_admin_required ou vendor_data_not_on_plan sans autorisation d’importation, et 429 lorsque la limite horaire ou les crédits IA sont épuisés.
Fonctions non disponibles actuellement
- Mises à jour incrémentales. Pas d’upsert, de suppression par enregistrement ni d’appel « changements depuis ». Une release remplace toute la précédente, et peut être dépubliée ou supprimée globalement.
- Republier une ancienne release. Une version superseded ou dépubliée ne peut pas redevenir active ; réimportez le fichier.
- Correspondances enregistrées. Chaque importation doit inclure le mapping ; il ne peut pas être enregistré puis référencé par identifiant.
- Connecteurs. Kaleidr n’extrait pas les données de bases, systèmes de réservation ou services de tableur.
- Importation multipart ou binaire. Le fichier est une chaîne dans le corps JSON.
Pages associées
- Réponses à partir de vos données : parcours, forfaits, limites, vérification et fonction distincte de jeux de données sur carte accessible à tous les forfaits.
- Authentification et portées : création d’une clé autorisée à lire vos données.
- Erreurs : catalogue d’erreurs de la plateforme.