Référence de l’API
L’API Prewalk fait partie de l’offre Entreprise. Avec une clé d’API, votre propre logiciel peut créer des visites, importer des scènes, publier, lire les projets et les statistiques, et recevoir un webhook signé à chaque étape du traitement. Cette page sert de référence ; le studio et le lecteur public continuent de fonctionner comme avant.
URL de base et conventions
- URL de base :
https://prewalk.co. N’utilisez pasapp.prewalk.co: elle redirige (308) et la plupart des clients HTTP abandonnent l’en-têteAuthorizationlors d’une redirection vers un autre hôte. - Format : JSON en entrée et en sortie (
Content-Type: application/json), sauf pour l’import de scènes, qui envoie l’image comme corps brut de la requête. - Les identifiants se composent de 12 lettres minuscules et chiffres, par exemple
teeg8crtm0u0. Les dates sont au format ISO 8601, en UTC. - Les erreurs ont toujours la même forme : un statut HTTP et
{"error": {"code": "…", "message": "…"}}; les erreurs de validation ajoutentfield. Les codes sont listés à la fin de cette page. - Limite de débit : 600 requêtes par minute et par clé. Au-delà, vous recevez
429avec un en-têteRetry-After(en secondes).
Authentification
Créez une clé dans Paramètres → API (propriétaire ou administrateur du compte, Entreprise). Une clé appartient au compte, peut être limitée à un seul profil de marque et dispose de trois portées au maximum : read, write et stats. La clé complète n’est affichée qu’une seule fois ; la liste n’en montre que le préfixe. Jusqu’à 20 clés par compte ; une clé révoquée cesse de fonctionner immédiatement.
Authorization: Bearer pw_…
Une clé agit pour un seul compte. GET /api/me décrit ce que la clé peut voir : le compte et les limites de son offre, les profils de ce compte, le profil au nom duquel la clé agit (actor) et la clé elle-même avec ses portées. Il ne renvoie jamais l’adresse e-mail du propriétaire de la clé ni ses autres comptes.
Points de terminaison
| Méthode et chemin | Portée | Fonction |
|---|---|---|
GET /api/me | read | Le compte, les profils et les portées de la clé |
GET /api/tours | read | Liste les visites du compte (limit ≤ 50, cursor, profileId) |
GET /api/tours/{id} | read | Une visite avec ses scènes, ses hotspots et ses réglages |
GET /api/tours/{id}/events | read | La progression du traitement sous forme de flux d’événements envoyés par le serveur (SSE) |
POST /api/tours | write | Crée une visite ({"title": "…"}) |
PATCH /api/tours/{id} | write | Modifie le titre, la description, la catégorie, le lieu, les tags, slug (l’adresse lisible), l’ordre des scènes, la scène de départ, les noms des scènes |
POST /api/tours/{id}/scenes | write | Importe une image 360° envoyée comme corps brut |
POST /api/content/{id}/visibility | write | Publie une visite ou un projet, le rend accessible par lien uniquement ou le protège par mot de passe |
GET /api/projects | read | Liste les projets du compte (limit, cursor, profileId) |
GET /api/projects/{id} | read | Un projet avec ses visites, ses images, ses vidéos et ses plans |
GET /api/stats/{contentId} | stats | Les vues d’une visite ou d’un projet (range en jours) |
GET /api/stats/{contentId}/export.csv | stats | Les mêmes données en CSV (table = daily, scenes ou referrers) |
Avec une clé, tout autre point de terminaison répond 403 api_key_forbidden. Le compte, l’équipe, la facturation, les clés d’API et les webhooks se gèrent dans le navigateur.
Visites
Lister. GET /api/tours?limit=50 renvoie {"items": […], "next": "…", "usage": {…}}. Renvoyez next comme cursor pour obtenir la page suivante ; usage contient le nombre de scènes du compte et ses limites. Chaque élément comporte id, title, visibility, publishedAt, createdAt, updatedAt, le profil et le nombre de scènes.
Lire. GET /api/tours/{id} renvoie la visite complète : title, description, category, location, tags, slug, visibility (public, link ou password), hasPassword, publishedAt, profile, projectId, startScene, coverScene, revision, scenes dans l’ordre, hotspots, settings, audio et links (player est l’adresse à partager, post la page publique une fois la visite publiée).
Une scène comporte id, name, status (queued, processing, ready ou error), createdAt, éventuellement view (la direction d’ouverture : yaw, pitch et fov en radians), north (en radians ; 0 correspond au centre de l’image, la valeur augmente vers la droite) et, pendant le traitement, stage et pct. Une scène prête porte meta avec ses niveaux de tuiles et la racine des médias.
Créer. POST /api/tours avec {"title": "Harbor View — Unit 4"} renvoie la nouvelle visite. Sans titre, elle s’appelle « Visite sans titre ».
Modifier. PATCH /api/tours/{id} accepte n’importe lequel de ces champs et renvoie la visite :
title,description,category,location,tags(tableau de chaînes),slug(l’adresse publique : lettres minuscules, chiffres et tirets),commentsEnabled;order: un tableau d’identifiants de scènes dans l’ordre voulu ; les scènes que vous omettez gardent leur place après celles que vous avez listées ;startScene: un identifiant de scène ; elle passe en tête (la première scène est la scène de départ) ;coverScene: un identifiant de scène, ounullpour la scène de départ ;scenes: un objet indexé par identifiant de scène, avecname,view({"yaw", "pitch", "fov"}) etnorth(en degrés).
Envoyez If-Match: "<revision>" avec la revision que vous avez lue en dernier pour refuser une écriture par-dessus la modification de quelqu’un d’autre : la réponse est alors 409 revision_conflict, avec la visite actuelle dans error.tour. Sans If-Match, la dernière écriture l’emporte.
Importer des scènes
POST /api/tours/{id}/scenes avec le fichier image comme corps brut. En-têtes :
Content-Type:image/jpeg,image/png,image/tiffouimage/webp;x-file-name: le nom du fichier, encodé pour URL (encodeURIComponent) ; la scène prend ce nom, ainsi01-living-room.jpgdevient « 01 living room » ;x-pw-upload-batchetx-pw-upload-index(facultatifs) : lorsque vous importez en parallèle plusieurs fichiers d’une même sélection, donnez-leur le même identifiant de lot (lettres, chiffres,-et_, jusqu’à 32 caractères) et leur rang dans la sélection ; le serveur conserve alors cet ordre, quel que soit le fichier qui se termine en premier. Sans eux, les scènes sont ajoutées dans l’ordre d’arrivée.
Images acceptées : panoramas équirectangulaires 2:1 jusqu’à la largeur permise par l’offre (8K avec Gratuit, 16K à partir de Pro), ou panoramas stéréo haut-bas 1:1 à partir de Pro (œil gauche en haut), jusqu’à 1 Gio. La réponse est la scène (status: "queued"). Le traitement se fait par étapes : la scène devient d’abord visible (tuiles d’aperçu), puis arrivent les tuiles en pleine résolution (« affinage ») et, à partir de Pro, les textures VR ; ces deux étapes se déroulent en parallèle et l’une ou l’autre peut se terminer en premier. Le champ meta.pending de la scène, le flux d’événements et les webhooks indiquent les étapes encore en cours.
Erreurs : 400 unsupported_format (ni JPG, ni PNG, ni TIFF, ni WebP), 400 unsupported_ratio (ni 2:1, ni 1:1 haut-bas), 400 unreadable_image (fichier endommagé), 402 plan_required (16K ou stéréo sur une offre qui ne les inclut pas), 402 quota_exceeded (limite de scènes du compte), 413 file_too_large.
Progression du traitement
GET /api/tours/{id}/events est un flux d’événements envoyés par le serveur (text/event-stream). Événements : hello à la connexion, queue (la position dans la file des scènes en attente et un résumé de la visite, toutes les quelques secondes tant qu’un traitement est en cours), scene (status, stage, pct ou error) et tour (la visite a changé ; relisez-la). Pour une intégration de serveur à serveur, préférez les webhooks décrits ci-dessous.
Publication et visibilité
POST /api/content/{id}/visibility fonctionne pour les visites et les projets, et renvoie le contenu :
{"visibility": "link"}— accessible uniquement par son adresse (le réglage par défaut de toute nouvelle visite) ;{"visibility": "public", "rightsAccepted": true}— sur le profil, dans Explorer et indexable ; unecategoryest requise (définissez-la d’abord avecPATCH) et vous confirmez avoir le droit de publier les images. Pour un projet, ajoutez"tourIds": [...]afin de publier des visites en même temps que lui ;{"visibility": "password", "password": "…"}— à partir de Pro ; omettezpasswordpour conserver le mot de passe actuel.
Une visite placée dans un projet protégé par mot de passe ne peut pas devenir publique ni avoir son propre mot de passe (409 in_password_project) ; c’est le mot de passe du projet qui en contrôle l’accès.
Projets
Pour l’instant, les projets sont en lecture seule via l’API. GET /api/projects les liste avec id, title, slug, visibility, category, coverUrl, tourCount, imageCount, videoCount et les dates ; GET /api/projects/{id} ajoute description, location, tags, urls (public et le lien privé), les tours avec leurs scènes, ainsi que la galerie : images, videos et floorplans avec leurs repères. Créez vos projets et ajoutez vos médias dans le studio.
Statistiques
GET /api/stats/{contentId}?range=30 renvoie les vues d’une visite ou d’un projet. Ce que vous obtenez dépend de l’offre : le total depuis le début en Gratuit ; une série daily complétée par des zéros (from, to, jusqu’à 90 jours) en Pro ; jusqu’à 365 jours, plus sources (page, intégration, accès direct), devices (téléphone, ordinateur, casque VR), scenes et les referrers qui intègrent le contenu, en Office et Entreprise. …/export.csv?range=30&table=daily fournit le tableau quotidien, table=scenes les vues par scène et table=referrers les sites qui intègrent le contenu. Les vues sont comptées par adresse de visiteur et par contenu, une fois toutes les 30 minutes ; aucune donnée personnelle n’est stockée.
Webhooks
Ajoutez jusqu’à cinq webhooks dans Paramètres → API. Nous envoyons un POST signé avec un corps JSON :
{"eventId": "evt_…", "eventType": "scene.ready", "occurredAt": "2026-10-22T09:12:03.000Z",
"data": {"tourId": "…", "sceneId": "…", "status": "ready", "pending": ["refine", "vr"]}}
| Événement | Moment | Données |
|---|---|---|
scene.ready | La scène est visible (tuiles d’aperçu) | pending : étapes encore en cours — refine (tuiles en pleine résolution) et vr (textures pour casque) ; [] quand l’aperçu est définitif |
scene.sharpened | Les tuiles en pleine résolution sont en place | stage: "refine", ok (false si l’étape a été abandonnée et que la scène reste en qualité d’aperçu), pending |
scene.vr_ready | Les textures VR sont en place | stage: "vr", ok, pending |
scene.failed | Le traitement a définitivement échoué | error avec la raison |
ping | Le bouton « Envoyer un test » | vide |
En-têtes : Prewalk-Signature: ts=<unix seconds>;h1=<hex>, où h1 est le HMAC-SHA256 de ts + ":" + body avec le secret de votre webhook (calculé sur les octets exacts que vous avez reçus), plus Prewalk-Event-Id et Prewalk-Event-Type. Pendant une rotation de secret, l’en-tête porte deux valeurs h1 (ts=…;h1=<new>;h1=<old>) jusqu’à l’expiration du secret précédent : acceptez la livraison si l’une d’elles est vérifiée. Vérifiez la signature, rejetez un horodatage de plus de quelques minutes et dédupliquez par eventId : une livraison est retentée jusqu’à ce que votre point de terminaison réponde 2xx (dix tentatives, 30 s puis un délai qui double, environ quatre heures au total), et le corps renvoyé est identique à l’octet près. Après 20 échecs de livraison consécutifs, le webhook est désactivé et le propriétaire du compte reçoit un e-mail. Les points de terminaison doivent être en https sur une adresse publique ; les redirections ne sont pas suivies. Le secret peut être renouvelé ; le précédent reste valide pendant 24 heures.
Exemple pas à pas
# 1. créer une visite
curl -s https://prewalk.co/api/tours -H "Authorization: Bearer $PW_KEY" \
-H "Content-Type: application/json" -d '{"title":"Harbor View — Unit 4"}'
# 2. importer deux scènes dans l’ordre
curl -s https://prewalk.co/api/tours/$TOUR/scenes -H "Authorization: Bearer $PW_KEY" \
-H "Content-Type: image/jpeg" -H "x-file-name: 01-living-room.jpg" \
-H "x-pw-upload-batch: sel-1" -H "x-pw-upload-index: 0" --data-binary @01-living-room.jpg
curl -s https://prewalk.co/api/tours/$TOUR/scenes -H "Authorization: Bearer $PW_KEY" \
-H "Content-Type: image/jpeg" -H "x-file-name: 02-kitchen.jpg" \
-H "x-pw-upload-batch: sel-1" -H "x-pw-upload-index: 1" --data-binary @02-kitchen.jpg
# 3. définir une catégorie et publier
curl -s -X PATCH https://prewalk.co/api/tours/$TOUR -H "Authorization: Bearer $PW_KEY" \
-H "Content-Type: application/json" -d '{"category":"real-estate","location":"Istanbul"}'
curl -s https://prewalk.co/api/content/$TOUR/visibility -H "Authorization: Bearer $PW_KEY" \
-H "Content-Type: application/json" -d '{"visibility":"public","rightsAccepted":true}'
# 4. vues des 30 derniers jours
curl -s "https://prewalk.co/api/stats/$TOUR?range=30" -H "Authorization: Bearer $PW_KEY"
Intégration
L’intégration ne nécessite aucune clé : chaque visite dispose de https://prewalk.co/embed/{id}, et embed.js dimensionne le cadre et l’ouvre en plein écran sur votre page. Les sites autorisés à afficher vos intégrations se règlent dans Paramètres → Image de marque. Le guide d’intégration donne tous les détails.
Codes d’erreur
| Statut | Code | Signification |
|---|---|---|
| 400 | invalid_request | Un champ est manquant ou invalide ; field l’indique |
| 400 | unsupported_format, unsupported_ratio, unreadable_image, rights_required, category_required, project_needs_content | Conditions préalables à l’import ou à la publication (un projet doit contenir une visite publique, une image ou une vidéo) |
| 401 | unauthorized, invalid_api_key | Aucune clé, ou une clé mal formée ou révoquée |
| 402 | plan_required, quota_exceeded | L’offre n’inclut pas la fonctionnalité, ou une limite est atteinte (feature ou limit précise laquelle) |
| 403 | api_key_forbidden, api_scope_missing | Le point de terminaison n’est pas ouvert aux clés, ou la clé n’a pas la portée requise |
| 404 | not_found | Ne vous appartient pas, a été supprimé, ou cet identifiant n’existe pas |
| 409 | revision_conflict, slug_taken, in_password_project | Modification concurrente (la visite actuelle est incluse), adresse déjà utilisée, règle du mot de passe de projet |
| 413 | file_too_large | Au-delà de la taille maximale |
| 429 | rate_limited | Trop de requêtes ; attendez Retry-After secondes |
| 503 | maintenance | Prewalk est en cours de mise à jour ; réessayez dans une minute |
Historique des modifications
- 10 nov. 2026 : un projet peut être publié ou protégé par mot de passe avec seulement des images ou des vidéos. Un projet qui n’a rien à montrer renvoie
400 project_needs_content, qu’il soit public ou protégé par mot de passe ; ce code remplaceproject_needs_public_touretproject_needs_tour, qui ne sont plus envoyés.GET /api/projectsajoutevideoCount. - 22 oct. 2026 :
scene.readyinclutpending; nouveaux événementsscene.sharpenedetscene.vr_ready; en-têtes d’ordre d’importx-pw-upload-batchetx-pw-upload-index; avec une clé,GET /api/mene décrit que le compte de la clé.
Une question, ou un point de terminaison manquant ? Écrivez à hello@prewalk.co.



