Visites virtuelles

API de visites virtuelles

Transformez des photos 360° en une visite virtuelle hébergée et partageable en un seul appel. L'IA nomme les pièces et place les points de navigation entre elles ; vous recevez une URL publique et un iframe d'intégration.

Envoyez vos photos 360° et récupérez une visite virtuelle hébergée, à partager ou à intégrer. Pedra importe les photos équirectangulaires, l'IA nomme chaque pièce et place les points de navigation de porte à porte, et la réponse vous donne un tourUrl public et un iframe embedCode prêt à coller. Aucun lecteur à héberger, aucun point de navigation à placer à la main.

Ce que vous obtenez en un seul appel :

  • Une page de visite hébergée — un tourUrl public et un iframe embedCode pour n'importe quelle page d'annonce, CRM ou portail. Fonctionne sur mobile (avec le gyroscope) et sur ordinateur.
  • Noms de pièces par IA — les pièces que vous ne nommez pas sont nommées pour vous (Entrée, Cuisine, Chambre 1…) dans la langue de la visite, gratuitement. Les noms que vous envoyez ne sont jamais modifiés.
  • Navigation par IA — Pedra repère chaque passage dans la photo et place les points de navigation entre les pièces, dans les deux sens.
  • Contrôle total ensuite — renommez, réordonnez, retirez ou ajoutez des pièces, et remplacez les points de navigation par les vôtres, le tout via l'API.
  • Fonctionne depuis le chat — les mêmes endpoints sont des outils du serveur MCP de Pedra, donc ChatGPT et Claude peuvent créer une visite depuis une conversation.

Comment ça marche

La création d'une visite est asynchrone : l'appel de création renvoie un tourId immédiatement et la visite se construit en arrière-plan (environ 10 secondes par pièce reliée).

  1. Créez — POST /api/create_virtual_tour avec vos photos 360° dans l'ordre de visite. Vous recevez immédiatement le tourId, le tourUrl et l'embedCode, avec status: "processing".
  2. Interrogez — appelez POST /api/get_virtual_tour toutes les quelques secondes jusqu'à ce que status soit "ready" (ou "failed", avec la raison dans error).
  3. Partagez — envoyez le tourUrl ou collez l'embedCode dans votre page d'annonce. L'URL ne change pas quand vous modifiez la visite ensuite.
# 1. Create the tour (returns immediately with "status": "processing")
curl -X POST https://app.pedra.ai/api/create_virtual_tour \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY",
    "name": "Calle Mayor 12",
    "scenes": [
      { "imageUrl": "https://example.com/360/entrance.jpg", "name": "Entrance" },
      { "imageUrl": "https://example.com/360/living-room.jpg" },
      { "imageUrl": "https://example.com/360/kitchen.jpg" },
      { "imageUrl": "https://example.com/360/bedroom.jpg" }
    ]
  }'

# 2. Poll until "status" is "ready" (or "failed")
curl -X POST https://app.pedra.ai/api/get_virtual_tour \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY", "tourId": "TOUR_ID" }'

Modes de liaison et crédits

Le paramètre linking détermine comment les points de navigation sont placés. Le nommage des pièces est toujours gratuit. Les crédits ne sont débités qu'au début de la liaison, et une construction qui échoue n'est jamais facturée.

Mode
Ce qu'il fait
Coût
sequential
Par défaut. Envoyez les pièces dans l'ordre de visite ; chaque pièce est reliée à la suivante, dans les deux sens.
max(3, ⌈pièces ÷ 3⌉) crédits — 3 jusqu'à 9 pièces, 4 pour 12, 10 pour 30
smart
L'IA compare chaque paire de pièces et relie celles qui communiquent visiblement — quand vous ne connaissez pas l'ordre de visite. Plus lent ; jusqu'à 40 pièces.
5–160 crédits selon le nombre de pièces (tableau ci-dessous)
none
Aucun point de navigation. Placez les vôtres ensuite avec update_virtual_tour.
Gratuit

Liaison smart selon le nombre de pièces

Pièces
Crédits
1–6
5 crédits
7–10
12 crédits
11–15
25 crédits
16–20
50 crédits
21–25
70 crédits
26–30
100 crédits
31–35
130 crédits
36–40
160 crédits

add_virtual_tour_scenes coûte comme la liaison sequential, en ne comptant que les nouvelles pièces. get_virtual_tour, list_virtual_tours, update_virtual_tour, delete_virtual_tour et create_upload_link sont gratuits. Vérifiez votre solde avec credits.

Créer une visite virtuelle

POST/api/create_virtual_tour

Importe les photos 360°, puis nomme et relie les pièces en arrière-plan. Envoyez scenes dans l'ordre de visite — la première est celle où la visite s'ouvre. Sans propertyId, une nouvelle propriété est créée, nommée d'après name. Pour créer une visite à partir de photos déjà dans une propriété (par exemple celles envoyées via un lien de téléversement), envoyez seulement le propertyId sans scenes : toutes les photos 360° de la propriété sont utilisées, dans l'ordre de téléversement. Une propriété a une seule visite ; si elle en a déjà une, vous recevez 409 tour_exists avec son tourId.

apiKeystringobligatoire
Votre clé API.
scenesarray
Les photos 360°, dans l'ordre de visite (max 50). Obligatoire sauf si vous envoyez un propertyId dont les photos 360° formeront la visite.
imageUrlsarray
Raccourci pour scenes : une simple liste d'URL de photos 360°.
propertyIdstring
Crée la visite dans cette propriété. Nécessaire si les scènes utilisent imageId. Sans scenes, toutes les photos 360° de la propriété sont utilisées dans l'ordre de téléversement. Omettez-le pour créer une nouvelle propriété.
namestring
Titre de la visite, par ex. l'adresse de l'annonce. C'est aussi le nom de la nouvelle propriété si elle est créée.
linkingstring
Comment les points de navigation sont placés — voir Modes de liaison et crédits.
Values: sequential smart none
Default: sequential
languagestring
Langue de la page de visite et des noms de pièces de l'IA. Les visites non anglaises ont une URL du type /fr/virtual-tour/….
Values: en es fr de it pt
Default: en

Objet scene

Chaque scène est { imageUrl } ou { imageId }, avec un name optionnel. Une simple chaîne est traitée comme un imageUrl. Jusqu'à 50 scènes par visite.

imageUrlstring
URL publique (ou URI data:) d'une photo 360° équirectangulaire — 2:1, jusqu'à 80 Mo. Les liens de partage Dropbox et Google Drive fonctionnent.
imageIdstring
Une photo 360° déjà dans la propriété (de list_property_images avec type "360"). À utiliser à la place d'imageUrl.
namestring
Nom de la pièce. Omettez-le et l'IA nomme la pièce.
curl -X POST https://app.pedra.ai/api/create_virtual_tour \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY",
    "name": "Calle Mayor 12",
    "linking": "sequential",
    "language": "en",
    "scenes": [
      { "imageUrl": "https://example.com/360/entrance.jpg", "name": "Entrance" },
      { "imageUrl": "https://example.com/360/living-room.jpg" },
      { "imageUrl": "https://example.com/360/kitchen.jpg" },
      { "imageUrl": "https://example.com/360/bedroom.jpg" }
    ]
  }'

Réponse

JSON
{
  "tourId": "1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
  "propertyId": "196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
  "name": "Calle Mayor 12",
  "status": "processing",
  "tourUrl": "https://app.pedra.ai/virtual-tour/1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
  "embedCode": "<iframe src=\"https://app.pedra.ai/virtual-tour/1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19\" title=\"Calle Mayor 12\" width=\"100%\" height=\"600\" style=\"border:0\" allow=\"fullscreen; gyroscope; accelerometer\" allowfullscreen loading=\"lazy\"></iframe>",
  "appUrl": "https://app.pedra.ai/?projectId=196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
  "shareable": true,
  "sceneCount": 4,
  "linkCount": 0,
  "coverImageUrl": null,
  "createdAt": "2026-09-30T15:22:52.028Z",
  "updatedAt": "2026-09-30T15:22:52.028Z",
  "progress": { "stage": "queued" },
  "scenes": [
    { "sceneId": "f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21", "name": "Entrance", "source": "https://example.com/360/entrance.jpg" },
    { "sceneId": "cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68", "name": null, "source": "https://example.com/360/living-room.jpg" },
    { "sceneId": "5b2e9c71-0d3a-4a8f-b6e4-9c1f7d2a5e30", "name": null, "source": "https://example.com/360/kitchen.jpg" },
    { "sceneId": "a8d4f0b2-6e1c-4d97-8f3a-2b5c9e7d1a46", "name": null, "source": "https://example.com/360/bedroom.jpg" }
  ],
  "linking": "sequential",
  "creditsCost": 3,
  "estimatedSeconds": 47,
  "message": "Building the tour. Poll get_virtual_tour with this tourId until status is \"ready\" (or \"failed\")."
}

Obtenir une visite virtuelle

POST/api/get_virtual_tour

Renvoie le statut de la visite et, une fois prête, ses scènes, liens de navigation et réglages d'affichage. C'est l'endpoint à interroger après create_virtual_tour et add_virtual_tour_scenes.

apiKeystringobligatoire
Votre clé API.
tourIdstringobligatoire
L'id de la visite (de create_virtual_tour ou list_virtual_tours).
curl -X POST https://app.pedra.ai/api/get_virtual_tour \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY", "tourId": "TOUR_ID" }'

Statut

  • processing — en construction. progress.stage vaut queued, importing, naming ou linking, avec done / total le cas échéant.
  • ready — en ligne sur tourUrl. Inclut scenes, links et settings.
  • failed — rien n'a été facturé. error indique pourquoi et failedScenes liste chaque photo inutilisable (par exemple une photo qui n'est pas en 2:1). Les photos importées restent dans la propriété : remplacez la mauvaise et recréez la visite par imageId.

Si un appel à add_virtual_tour_scenes échoue, la visite reste ready et contient lastError et failedScenes. Sur un compte du plan gratuit, la visite se construit, mais son lien public affiche une page de mise à niveau : les réponses indiquent alors shareable: false, avec un shareableNote.

Réponse

JSON
{
  "tourId": "1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
  "propertyId": "196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
  "name": "Calle Mayor 12",
  "status": "ready",
  "tourUrl": "https://app.pedra.ai/virtual-tour/1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
  "embedCode": "<iframe src=\"https://app.pedra.ai/virtual-tour/1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19\" title=\"Calle Mayor 12\" width=\"100%\" height=\"600\" style=\"border:0\" allow=\"fullscreen; gyroscope; accelerometer\" allowfullscreen loading=\"lazy\"></iframe>",
  "appUrl": "https://app.pedra.ai/?projectId=196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
  "shareable": true,
  "sceneCount": 4,
  "linkCount": 6,
  "coverImageUrl": "https://img.pedra.ai/f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21",
  "createdAt": "2026-09-30T15:22:52.028Z",
  "updatedAt": "2026-09-30T15:23:41.310Z",
  "scenes": [
    { "sceneId": "f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21", "name": "Entrance", "imageUrl": "https://img.pedra.ai/f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21" },
    { "sceneId": "cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68", "name": "Living room", "imageUrl": "https://img.pedra.ai/cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68" },
    { "sceneId": "5b2e9c71-0d3a-4a8f-b6e4-9c1f7d2a5e30", "name": "Kitchen", "imageUrl": "https://img.pedra.ai/5b2e9c71-0d3a-4a8f-b6e4-9c1f7d2a5e30" },
    { "sceneId": "a8d4f0b2-6e1c-4d97-8f3a-2b5c9e7d1a46", "name": "Bedroom", "imageUrl": "https://img.pedra.ai/a8d4f0b2-6e1c-4d97-8f3a-2b5c9e7d1a46" }
  ],
  "links": [
    { "linkId": "ai-7c21", "fromSceneId": "f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21", "toSceneId": "cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68", "yaw": -18, "pitch": 0, "aiGenerated": true },
    { "linkId": "ai-7c22", "fromSceneId": "cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68", "toSceneId": "f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21", "yaw": 164, "pitch": 0, "aiGenerated": true }
  ],
  "settings": {
    "navigationStyle": "white",
    "navigationSize": "medium",
    "showLabels": false,
    "language": "en"
  }
}

Lister les visites virtuelles

POST/api/list_virtual_tours

Renvoie les visites du compte, des plus récentes aux plus anciennes (jusqu'à 100), avec les mêmes champs de résumé que get_virtual_tour mais sans scenes, links ni settings. Les visites supprimées sont exclues.

apiKeystringobligatoire
Votre clé API.
propertyIdstring
Ne renvoie que la visite de cette propriété.
curl -X POST https://app.pedra.ai/api/list_virtual_tours \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY" }'

Réponse

JSON
{
  "tours": [
    {
      "tourId": "1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
      "propertyId": "196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
      "name": "Calle Mayor 12",
      "status": "ready",
      "tourUrl": "https://app.pedra.ai/virtual-tour/1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
      "embedCode": "<iframe …></iframe>",
      "appUrl": "https://app.pedra.ai/?projectId=196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
      "shareable": true,
      "sceneCount": 4,
      "linkCount": 6,
      "coverImageUrl": "https://img.pedra.ai/f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21",
      "createdAt": "2026-09-30T15:22:52.028Z",
      "updatedAt": "2026-09-30T15:23:41.310Z"
    }
  ]
}

Modifier une visite virtuelle

POST/api/update_virtual_tour

Renommez la visite ou ses pièces, réordonnez ou retirez des pièces, remplacez les points de navigation et changez leur apparence. Gratuit et instantané. La validation est tout ou rien : si un champ est invalide, rien ne change. Renvoie la visite complète, comme get_virtual_tour, ou 409 tour_processing tant que la visite est en construction.

apiKeystringobligatoire
Votre clé API.
tourIdstringobligatoire
L'id de la visite (de create_virtual_tour ou list_virtual_tours).
namestring
Nouveau titre de la visite.
sceneNamesobject
Noms de pièces par sceneId, par ex. { "<sceneId>": "Cuisine" }.
sceneOrderarray
Chaque sceneId exactement une fois, dans le nouvel ordre. La première est celle où la visite s'ouvre.
removeScenesarray
sceneIds à retirer de la visite. Les photos restent dans la propriété et les liens qui les concernent sont supprimés. Au moins une scène doit rester.
linksarray
Remplace TOUS les liens de navigation. Chaque lien va dans un seul sens : { fromSceneId, toSceneId, yaw, pitch? }.
navigationStylestring
Couleur des points de navigation.
Values: white blue
navigationSizestring
Taille des points de navigation.
Values: small medium large
showLabelsboolean
Toujours afficher le nom de la pièce de destination à côté de chaque point de navigation.
languagestring
Langue de la page de visite.
Values: en es fr de it pt

Objet link

fromSceneIdstringobligatoire
La scène dans laquelle le point de navigation s'affiche.
toSceneIdstringobligatoire
La scène vers laquelle il mène.
yawnumberobligatoire
Angle horizontal dans la photo de fromScene, de −180 à 180. 0 est le centre de la photo ; négatif vers la gauche.
pitchnumber
Angle vertical, de −90 à 90. 0 est l'horizon.
Default: 0

Pour ajuster les liens de l'IA plutôt que repartir de zéro, lisez links depuis get_virtual_tour, modifiez la liste et renvoyez-la.

curl -X POST https://app.pedra.ai/api/update_virtual_tour \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY",
    "tourId": "TOUR_ID",
    "sceneNames": { "a8d4f0b2-6e1c-4d97-8f3a-2b5c9e7d1a46": "Main bedroom" },
    "sceneOrder": [
      "f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21",
      "5b2e9c71-0d3a-4a8f-b6e4-9c1f7d2a5e30",
      "cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68",
      "a8d4f0b2-6e1c-4d97-8f3a-2b5c9e7d1a46"
    ],
    "navigationSize": "large",
    "showLabels": true
  }'

Réponse

JSON
{
  "tourId": "1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
  "propertyId": "196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
  "name": "Calle Mayor 12",
  "status": "ready",
  "tourUrl": "https://app.pedra.ai/virtual-tour/1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
  "embedCode": "<iframe src=\"https://app.pedra.ai/virtual-tour/1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19\" title=\"Calle Mayor 12\" width=\"100%\" height=\"600\" style=\"border:0\" allow=\"fullscreen; gyroscope; accelerometer\" allowfullscreen loading=\"lazy\"></iframe>",
  "appUrl": "https://app.pedra.ai/?projectId=196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
  "shareable": true,
  "sceneCount": 4,
  "linkCount": 6,
  "coverImageUrl": "https://img.pedra.ai/f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21",
  "createdAt": "2026-09-30T15:22:52.028Z",
  "updatedAt": "2026-09-30T15:23:41.310Z",
  "scenes": [
    { "sceneId": "f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21", "name": "Entrance", "imageUrl": "https://img.pedra.ai/f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21" },
    { "sceneId": "cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68", "name": "Living room", "imageUrl": "https://img.pedra.ai/cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68" },
    { "sceneId": "5b2e9c71-0d3a-4a8f-b6e4-9c1f7d2a5e30", "name": "Kitchen", "imageUrl": "https://img.pedra.ai/5b2e9c71-0d3a-4a8f-b6e4-9c1f7d2a5e30" },
    { "sceneId": "a8d4f0b2-6e1c-4d97-8f3a-2b5c9e7d1a46", "name": "Bedroom", "imageUrl": "https://img.pedra.ai/a8d4f0b2-6e1c-4d97-8f3a-2b5c9e7d1a46" }
  ],
  "links": [
    { "linkId": "ai-7c21", "fromSceneId": "f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21", "toSceneId": "cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68", "yaw": -18, "pitch": 0, "aiGenerated": true },
    { "linkId": "ai-7c22", "fromSceneId": "cf0a13ee-8b4d-4f62-a0c7-3e9d5b1f2a68", "toSceneId": "f1815046-2a7c-4e3b-9d15-6b8e0c4a7f21", "yaw": 164, "pitch": 0, "aiGenerated": true }
  ],
  "settings": {
    "navigationStyle": "white",
    "navigationSize": "medium",
    "showLabels": false,
    "language": "en"
  }
}

Ajouter des pièces à une visite

POST/api/add_virtual_tour_scenes

Ajoute des photos 360° à une visite existante. Avec la liaison sequential, seul le nouveau tronçon est relié : la dernière pièce existante à la première nouvelle, puis chaque nouvelle pièce à la suivante. Les liens existants, y compris ceux que vous avez placés, sont conservés. Coûte max(3, ⌈nouvelles pièces ÷ 3⌉) crédits. Asynchrone comme la création, et la visite reste en ligne pendant ce temps — interrogez get_virtual_tour jusqu'à ce que status redevienne "ready".

apiKeystringobligatoire
Votre clé API.
tourIdstringobligatoire
L'id de la visite (de create_virtual_tour ou list_virtual_tours).
scenesarrayobligatoire
Les photos 360° à ajouter, même format que dans create_virtual_tour. Les scènes par imageId doivent être des photos 360° de la propriété de la visite.
linkingstring
sequential relie le nouveau tronçon ; none ajoute les pièces sans points de navigation.
Values: sequential none
Default: sequential
curl -X POST https://app.pedra.ai/api/add_virtual_tour_scenes \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY",
    "tourId": "TOUR_ID",
    "scenes": [
      { "imageUrl": "https://example.com/360/bathroom.jpg", "name": "Bathroom" },
      { "imageUrl": "https://example.com/360/terrace.jpg" }
    ]
  }'

Réponse

JSON
{
  "tourId": "1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
  "propertyId": "196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
  "name": "Calle Mayor 12",
  "status": "processing",
  "tourUrl": "https://app.pedra.ai/virtual-tour/1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19",
  "sceneCount": 6,
  "linkCount": 6,
  "progress": { "stage": "queued" },
  "addedScenes": [
    { "sceneId": "3e7b1a95-4c0f-4b2d-9e68-1a5d8c3f7b02", "name": "Bathroom", "source": "https://example.com/360/bathroom.jpg" },
    { "sceneId": "9f6c2d48-7a1e-4e5b-8c3d-0b4a6f9e2d17", "name": null, "source": "https://example.com/360/terrace.jpg" }
  ],
  "creditsCost": 3,
  "estimatedSeconds": 31,
  "message": "Adding the scenes. The tour stays live while this runs. Poll get_virtual_tour until status is \"ready\"."
}

Supprimer une visite virtuelle

POST/api/delete_virtual_tour

Supprime la visite. Son lien public renvoie ensuite une 404 ; les photos 360° restent dans la propriété, vous pouvez donc créer une nouvelle visite avec. La suppression est réservée à l'API — elle n'est pas exposée comme outil MCP.

apiKeystringobligatoire
Votre clé API.
tourIdstringobligatoire
L'id de la visite (de create_virtual_tour ou list_virtual_tours).
curl -X POST https://app.pedra.ai/api/delete_virtual_tour \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY", "tourId": "TOUR_ID" }'

Réponse

JSON
{
  "message": "Virtual tour deleted. Its 360° photos are still in the property.",
  "tourId": "1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19"
}
POST/api/create_upload_link

Renvoie une page de téléversement sans connexion pour une propriété, valable 24 heures. Envoyez-la à qui a les photos — le photographe, l'agent, le propriétaire. Il l'ouvre sur un téléphone ou un ordinateur, dépose les photos (jusqu'à 100 fichiers, JPEG, PNG ou WebP, jusqu'à 80 Mo chacun ; les photos HEIC d'iPhone fonctionnent si elles sont envoyées depuis l'iPhone lui-même) et voit les miniatures, la progression et un « C'est fait » à la fin. Les fichiers sont triés par nom de fichier, qui sur les caméras 360° suit l'ordre de prise de vue — en général aussi l'ordre de visite.

type définit ce que la page accepte :

  • "any" (par défaut) — photos classiques et photos 360°. Les images 2:1 sont détectées et stockées automatiquement comme photos 360°. À utiliser pour des photos à retoucher, à meubler ou à transformer en vidéo, ou un mélange.
  • "360" — uniquement des photos 360° ; tout le reste est refusé avec un message clair. À utiliser quand le lien sert à une visite virtuelle.

Les photos sont stockées comme dans l'app web : les photos classiques à 2048 px sur le grand côté (3072 px si le fichier dépasse 20 Mo), les photos 360° à 4096 px de large (6144 px au-delà de 20 Mo).

C'est aussi ainsi qu'un assistant de chat récupère les photos d'un téléphone : Claude ne peut pas transmettre les pièces jointes du chat à un outil, et les photos restées sur un téléphone ne sont même pas dans le chat, donc l'assistant crée un lien de téléversement, vous envoyez les photos, et il continue. (Dans ChatGPT, les photos jointes au chat fonctionnent directement — voir Serveur MCP.) Le lien ne peut qu'ajouter des photos à cette propriété — il ne donne aucun autre accès au compte. Une fois le téléversement terminé, appelez list_property_images (type "photo" ou "360") pour obtenir des URL à retoucher ou à transformer en vidéo, ou create_virtual_tour avec le propertyId et sans scenes.

Limites : 5 liens de téléversement par jour sur le plan gratuit, 50 sur les plans payants (429 upload_link_limit) — chaque lien fonctionne 24 heures, réutilisez donc celui du jour plutôt que d'en créer un autre. Chaque fichier envoyé via un lien compte aussi dans la limite quotidienne de téléversement.

apiKeystringobligatoire
Votre clé API.
propertyIdstring
La propriété qui reçoit les photos. Omettez-le pour créer une nouvelle propriété nommée d'après name.
namestring
Nom de la nouvelle propriété, par ex. l'adresse de l'annonce. Affiché sur la page de téléversement.
typestring
Ce que la page accepte : "any" pour les photos et les photos 360° (les images 2:1 sont stockées en 360° automatiquement), ou "360" pour les photos 360° uniquement — à utiliser pour une visite virtuelle.
Values: any 360
Default: any
languagestring
Langue de la page de téléversement.
Values: en es fr de it pt
Default: en
curl -X POST https://app.pedra.ai/api/create_upload_link \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY", "name": "Calle Mayor 12", "type": "360", "language": "es" }'

Réponse

JSON
{
  "uploadUrl": "https://app.pedra.ai/upload/q7Ht2vXk9LmP4wRz8NcB1sYd6FgJ3eUa0KoV5iTn?lang=es",
  "propertyId": "196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
  "propertyName": "Calle Mayor 12",
  "type": "360",
  "expiresAt": "2026-10-01T15:26:30.687Z",
  "maxFiles": 100,
  "appUrl": "https://app.pedra.ai/?projectId=196e742a-5b0d-4c9e-8a3f-7e2b1c6d9f04",
  "message": "Send this link to whoever has the 360° photos. It works on a phone or a computer with no login, for 24 hours. When they're done, list the property's photos (list_property_images; type "360" for 360° photos) and use them."
}

Téléverser des photos 360°

Les visites sont construites à partir de photos 360° équirectangulaires — les panoramas 2:1 exportés par les caméras 360°. Chaque photo est vérifiée (ratio 2:1, de 1,9 à 2,1 accepté, 80 Mo maximum) et stockée en JPEG de 4096 px de large (6144 px si le fichier dépasse 20 Mo). Trois façons de les envoyer :

  1. URL publiques, directement — passez-les en scenes à create_virtual_tour. Idéal quand les photos sont déjà en ligne (votre CDN ou bucket de stockage). Les liens de partage Dropbox et Google Drive sont convertis automatiquement en téléchargements directs.
  2. add_images_to_property avec type: "360" — stockez d'abord les photos dans une propriété (jusqu'à 10 par appel), puis appelez create_virtual_tour avec seulement le propertyId. Il accepte aussi les URI data:, vous pouvez donc envoyer des fichiers locaux encodés en base64 — un ou quelques-uns par appel, sous la limite de 50 Mo par requête.
  3. Un lien de téléversement — quand les photos sont sur le téléphone ou la caméra de quelqu'un plutôt qu'en ligne. Voir create_upload_link avec type: "360".

Envoyer des fichiers 360° locaux en URI data:, deux par appel, puis créer la visite :

import base64
import pathlib
import requests

API = "https://app.pedra.ai/api"
API_KEY = "YOUR_API_KEY"

def data_uri(path):
    return "data:image/jpeg;base64," + base64.b64encode(path.read_bytes()).decode()

# Sorted by file name = shooting order on most 360° cameras
files = sorted(pathlib.Path("./calle-mayor-12").glob("*.jpg"))

prop = requests.post(f"{API}/create_property",
                     json={"apiKey": API_KEY, "name": "Calle Mayor 12"}).json()

for i in range(0, len(files), 2):  # two per call keeps the body under 50 MB
    res = requests.post(f"{API}/add_images_to_property", json={
        "apiKey": API_KEY,
        "propertyId": prop["propertyId"],
        "type": "360",
        "imageUrls": [data_uri(p) for p in files[i:i + 2]],
    }).json()
    for f in res["failed"]:
        print("Skipped:", f["error"])

# No scenes: every 360° photo in the property, in upload order
tour = requests.post(f"{API}/create_virtual_tour",
                     json={"apiKey": API_KEY, "propertyId": prop["propertyId"]}).json()

Erreurs

Les erreurs arrivent sous la forme { "error": "...", "code": "..." } (code seulement quand indiqué). Voir Erreurs et limites pour le modèle général.

  • 400 — entrée invalide : une photo qui n'est pas en 360°, plus de 50 scènes, une valeur de linking inconnue. no_panoramas : la propriété n'a pas encore de photos 360°. no_new_scenes : toutes les scènes ajoutées sont déjà dans la visite.
  • 402 insufficient_credits — avec creditsRequired, creditsAvailable et upgradeUrl. Rien n'est créé ni facturé.
  • 404 — User not found (clé API invalide), Virtual tour not found ou Property not found for this account.
  • 409 — tour_exists : la propriété a déjà une visite (son tourId est dans la réponse). tour_processing : la visite est encore en construction — attendez qu'elle soit prête. tour_failed : la construction a échoué — supprimez la visite et recréez-la.
  • 429 — upload_limit : les photos passées par URL dépasseraient la limite quotidienne de téléversement du compte (30 par jour sur le plan gratuit, 500 sur les plans payants, remise à zéro à minuit UTC) ; l'appel entier est refusé et rien n'est stocké. upload_link_limit : le compte a déjà créé ses liens de téléversement du jour.

Suivant

Créez des visites depuis ChatGPT ou Claude avec le serveur MCP, gérez les photos d'une visite avec l'API Propriétés, ou transformez la même annonce en vidéo.