Tour virtuali

API per tour virtuali

Trasforma foto 360° in un tour virtuale ospitato e condivisibile con una sola chiamata. L'IA dà un nome alle stanze e posiziona i punti di navigazione tra di esse; ricevi un URL pubblico del tour e un iframe da incorporare.

Invia le tue foto 360° e ricevi un tour virtuale ospitato da condividere o incorporare. Pedra importa le foto equirettangolari, l'IA dà un nome a ogni stanza e posiziona i punti di navigazione da porta a porta, e la risposta ti restituisce un tourUrl pubblico e un iframe embedCode pronto da incollare. Nessun visualizzatore da ospitare e nessun punto di navigazione da posizionare a mano.

Cosa ottieni con una sola chiamata:

  • Una pagina del tour ospitata — un tourUrl pubblico e un iframe embedCode per qualsiasi pagina annuncio, CRM o portale. Funziona su smartphone (con il giroscopio) e su desktop.
  • Nomi delle stanze con IA — le stanze senza nome vengono nominate per te (Ingresso, Cucina, Camera 1…) nella lingua del tour, gratis. I nomi che invii non vengono mai modificati.
  • Navigazione con IA — Pedra individua ogni porta nella foto e posiziona i punti di navigazione tra le stanze, in entrambe le direzioni.
  • Controllo totale dopo — rinomina, riordina, rimuovi o aggiungi stanze e sostituisci i punti di navigazione con i tuoi, tutto tramite l'API.
  • Funziona dalla chat — gli stessi endpoint sono strumenti del server MCP di Pedra, quindi ChatGPT e Claude possono creare un tour da una conversazione.

Come funziona

La creazione di un tour è asincrona: la chiamata di creazione restituisce subito un tourId e il tour viene costruito in background (circa 10 secondi per stanza collegata).

  1. Crea — POST /api/create_virtual_tour con le tue foto 360° nell'ordine del percorso. Ricevi subito tourId, tourUrl ed embedCode, con status: "processing".
  2. Controlla — chiama POST /api/get_virtual_tour ogni pochi secondi finché status non è "ready" (o "failed", con il motivo in error).
  3. Condividi — invia il tourUrl o incolla l'embedCode nella pagina dell'annuncio. L'URL resta lo stesso quando modifichi il tour in seguito.
# 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" }'

Modalità di collegamento e crediti

Il parametro linking decide come vengono posizionati i punti di navigazione. Dare un nome alle stanze è sempre gratis. I crediti vengono addebitati solo quando inizia il collegamento, e una costruzione fallita non viene mai addebitata.

Modalità
Cosa fa
Costo
sequential
Predefinita. Invia le stanze nell'ordine del percorso; ogni stanza viene collegata alla successiva, in entrambe le direzioni.
max(3, ⌈stanze ÷ 3⌉) crediti — 3 fino a 9 stanze, 4 per 12, 10 per 30
smart
L'IA confronta ogni coppia di stanze e collega quelle visibilmente comunicanti — per quando non conosci l'ordine del percorso. Più lenta; fino a 40 stanze.
5–160 crediti in base al numero di stanze (tabella sotto)
none
Nessun punto di navigazione. Posiziona i tuoi in seguito con update_virtual_tour.
Gratis

Collegamento smart in base al numero di stanze

Stanze
Crediti
1–6
5 crediti
7–10
12 crediti
11–15
25 crediti
16–20
50 crediti
21–25
70 crediti
26–30
100 crediti
31–35
130 crediti
36–40
160 crediti

add_virtual_tour_scenes costa come il collegamento sequential, contando solo le nuove stanze. get_virtual_tour, list_virtual_tours, update_virtual_tour, delete_virtual_tour e create_upload_link sono gratuiti. Controlla il saldo con credits.

Creare un tour virtuale

POST/api/create_virtual_tour

Importa le foto 360°, poi dà un nome alle stanze e le collega in background. Invia scenes nell'ordine del percorso — la prima è quella da cui si apre il tour. Senza propertyId viene creata una nuova proprietà con il nome indicato in name. Per creare un tour da foto già presenti in una proprietà (ad esempio caricate tramite un link di caricamento), invia solo il propertyId e ometti scenes: vengono usate tutte le foto 360° della proprietà, in ordine di caricamento. Una proprietà ha un solo tour; se ne ha già uno ricevi 409 tour_exists con il suo tourId.

apiKeystringobbligatorio
La tua chiave API.
scenesarray
Le foto 360°, nell'ordine del percorso (max 50). Obbligatorio a meno che non invii un propertyId le cui foto 360° formeranno il tour.
imageUrlsarray
Scorciatoia per scenes: un semplice elenco di URL di foto 360°.
propertyIdstring
Crea il tour in questa proprietà. Necessario se le scene usano imageId. Senza scenes, vengono usate tutte le foto 360° della proprietà in ordine di caricamento. Omettilo per creare una nuova proprietà.
namestring
Titolo del tour, ad es. l'indirizzo dell'annuncio. È anche il nome della nuova proprietà se ne viene creata una.
linkingstring
Come vengono posizionati i punti di navigazione — vedi Modalità di collegamento e crediti.
Values: sequential smart none
Default: sequential
languagestring
Lingua della pagina del tour e dei nomi delle stanze dell'IA. I tour non in inglese hanno un URL del tipo /it/virtual-tour/….
Values: en es fr de it pt
Default: en

Oggetto scene

Ogni scena è { imageUrl } o { imageId }, con un name opzionale. Una stringa semplice viene trattata come imageUrl. Fino a 50 scene per tour.

imageUrlstring
URL pubblico (o URI data:) di una foto 360° equirettangolare — 2:1, fino a 80 MB. Funzionano i link di condivisione di Dropbox e Google Drive.
imageIdstring
Una foto 360° già nella proprietà (da list_property_images con type "360"). Da usare al posto di imageUrl.
namestring
Nome della stanza. Se lo ometti, l'IA dà un nome alla stanza.
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" }
    ]
  }'

Risposta

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\")."
}

Ottenere un tour virtuale

POST/api/get_virtual_tour

Restituisce lo stato del tour e, quando è pronto, le sue scene, i link di navigazione e le impostazioni di visualizzazione. È l'endpoint da interrogare dopo create_virtual_tour e add_virtual_tour_scenes.

apiKeystringobbligatorio
La tua chiave API.
tourIdstringobbligatorio
L'id del tour (da create_virtual_tour o 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" }'

Stato

  • processing — in costruzione. progress.stage è queued, importing, naming o linking, con done / total quando applicabile.
  • ready — online su tourUrl. Include scenes, links e settings.
  • failed — non è stato addebitato nulla. error spiega il motivo e failedScenes elenca ogni foto che non è stato possibile usare (ad esempio una che non è 2:1). Le foto importate restano nella proprietà, quindi puoi sostituire quella errata e ricreare il tour tramite imageId.

Se una chiamata a add_virtual_tour_scenes fallisce, il tour resta ready e riporta lastError e failedScenes. Con un account del piano gratuito il tour viene creato, ma il link pubblico mostra una pagina di upgrade: le risposte indicano shareable: false, con uno shareableNote.

Risposta

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"
  }
}

Elencare i tour virtuali

POST/api/list_virtual_tours

Restituisce i tour dell'account, dal più recente (fino a 100), con gli stessi campi di riepilogo di get_virtual_tour ma senza scenes, links e settings. I tour eliminati sono esclusi.

apiKeystringobbligatorio
La tua chiave API.
propertyIdstring
Restituisce solo il tour di questa proprietà.
curl -X POST https://app.pedra.ai/api/list_virtual_tours \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY" }'

Risposta

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"
    }
  ]
}

Aggiornare un tour virtuale

POST/api/update_virtual_tour

Rinomina il tour o le sue stanze, riordina o rimuovi stanze, sostituisci i punti di navigazione e cambiane l'aspetto. Gratis e immediato. La validazione è tutto o niente: se un campo non è valido, non cambia nulla. Restituisce il tour completo, come get_virtual_tour, oppure 409 tour_processing mentre il tour è ancora in costruzione.

apiKeystringobbligatorio
La tua chiave API.
tourIdstringobbligatorio
L'id del tour (da create_virtual_tour o list_virtual_tours).
namestring
Nuovo titolo del tour.
sceneNamesobject
Nomi delle stanze per sceneId, ad es. { "<sceneId>": "Cucina" }.
sceneOrderarray
Ogni sceneId esattamente una volta, nel nuovo ordine. La prima è quella da cui si apre il tour.
removeScenesarray
sceneId da togliere dal tour. Le foto restano nella proprietà e i link che le riguardano vengono rimossi. Deve restare almeno una scena.
linksarray
Sostituisce TUTTI i link di navigazione. Ogni link va in una sola direzione: { fromSceneId, toSceneId, yaw, pitch? }.
navigationStylestring
Colore dei punti di navigazione.
Values: white blue
navigationSizestring
Dimensione dei punti di navigazione.
Values: small medium large
showLabelsboolean
Mostra sempre il nome della stanza di destinazione accanto a ogni punto di navigazione.
languagestring
Lingua della pagina del tour.
Values: en es fr de it pt

Oggetto link

fromSceneIdstringobbligatorio
La scena in cui compare il punto di navigazione.
toSceneIdstringobbligatorio
La scena a cui porta.
yawnumberobbligatorio
Angolo orizzontale nella foto di fromScene, da −180 a 180. 0 è il centro della foto; negativo è a sinistra.
pitchnumber
Angolo verticale, da −90 a 90. 0 è l'orizzonte.
Default: 0

Per ritoccare i link dell'IA invece di ripartire da zero, leggi links da get_virtual_tour, modifica l'elenco e rimandalo.

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
  }'

Risposta

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"
  }
}

Aggiungere stanze a un tour

POST/api/add_virtual_tour_scenes

Aggiunge foto 360° a un tour esistente. Con il collegamento sequential viene collegato solo il nuovo tratto: l'ultima stanza esistente con la prima nuova, poi ogni nuova stanza con la successiva. I link esistenti, compresi quelli posizionati da te, vengono mantenuti. Costa max(3, ⌈nuove stanze ÷ 3⌉) crediti. Asincrono come la creazione, e il tour resta online nel frattempo — interroga get_virtual_tour finché status non torna "ready".

apiKeystringobbligatorio
La tua chiave API.
tourIdstringobbligatorio
L'id del tour (da create_virtual_tour o list_virtual_tours).
scenesarrayobbligatorio
Le foto 360° da aggiungere, nello stesso formato di create_virtual_tour. Le scene per imageId devono essere foto 360° della proprietà del tour.
linkingstring
sequential collega il nuovo tratto; none aggiunge le stanze senza punti di navigazione.
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" }
    ]
  }'

Risposta

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\"."
}

Eliminare un tour virtuale

POST/api/delete_virtual_tour

Elimina il tour. Da quel momento il link pubblico restituisce 404; le foto 360° restano nella proprietà, quindi puoi creare un nuovo tour con esse. L'eliminazione è disponibile solo via API — non è esposta come strumento MCP.

apiKeystringobbligatorio
La tua chiave API.
tourIdstringobbligatorio
L'id del tour (da create_virtual_tour o 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" }'

Risposta

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

Restituisce una pagina di caricamento senza login per una proprietà, valida 24 ore. Inviala a chi ha le foto — il fotografo, l'agente, il proprietario. La apre da smartphone o computer, trascina le foto (fino a 100 file, JPEG, PNG o WebP, fino a 80 MB ciascuno; le foto HEIC dell'iPhone funzionano se caricate dall'iPhone stesso) e vede miniature, avanzamento e un "Tutto pronto" alla fine. I file sono ordinati per nome, che sulle fotocamere 360° corrisponde all'ordine di scatto — di solito anche all'ordine del percorso.

type stabilisce cosa accetta la pagina:

  • "any" (predefinito) — foto normali e foto 360°. Le immagini 2:1 vengono riconosciute e salvate automaticamente come foto 360°. Usalo per foto da modificare, arredare o trasformare in video, o un misto.
  • "360" — solo foto 360°; il resto viene rifiutato con un messaggio chiaro. Usalo quando il link serve per un tour virtuale.

Le foto vengono salvate come nell'app web: quelle normali a 2048 px sul lato lungo (3072 px se il file supera 20 MB), quelle 360° a 4096 px di larghezza (6144 px oltre 20 MB).

È anche il modo in cui un assistente in chat ottiene le foto da uno smartphone: Claude non può passare gli allegati della chat a uno strumento, e le foto ancora sul telefono non sono nemmeno in chat, quindi l'assistente crea un link di caricamento, tu carichi le foto e lui prosegue. (In ChatGPT le foto allegate alla chat funzionano direttamente — vedi Server MCP.) Il link può solo aggiungere foto a quella proprietà — non dà nessun altro accesso all'account. A caricamento finito, chiama list_property_images (type "photo" o "360") per avere URL da modificare o trasformare in video, oppure create_virtual_tour con il propertyId e senza scenes.

Limiti: 5 link di caricamento al giorno sul piano gratuito, 50 sui piani a pagamento (429 upload_link_limit) — ogni link vale 24 ore, quindi riusa quello di oggi invece di crearne un altro. Ogni file caricato tramite un link conta anche nel limite giornaliero di caricamento.

apiKeystringobbligatorio
La tua chiave API.
propertyIdstring
La proprietà in cui vanno le foto. Omettilo per creare una nuova proprietà con il nome indicato in name.
namestring
Nome della nuova proprietà, ad es. l'indirizzo dell'annuncio. Mostrato nella pagina di caricamento.
typestring
Cosa accetta la pagina: "any" per foto e foto 360° (le immagini 2:1 vengono salvate come 360° automaticamente), o "360" solo per foto 360° — usalo per un tour virtuale.
Values: any 360
Default: any
languagestring
Lingua della pagina di caricamento.
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" }'

Risposta

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."
}

Caricare foto 360°

I tour si creano da foto 360° equirettangolari — i panorami 2:1 esportati dalle fotocamere 360°. Ogni foto viene verificata (2:1, si accetta 1,9–2,1, fino a 80 MB) e salvata come JPEG largo 4096 px (6144 px se il file supera 20 MB). Ci sono tre modi per caricarle:

  1. URL pubblici, direttamente — passali come scenes a create_virtual_tour. Ideale quando le foto sono già online (il tuo CDN o bucket di storage). I link di condivisione di Dropbox e Google Drive vengono convertiti automaticamente in download diretti.
  2. add_images_to_property con type: "360" — salva prima le foto in una proprietà (fino a 10 per chiamata), poi chiama create_virtual_tour solo con il propertyId. Accetta anche URI data:, quindi puoi inviare file locali codificati in base64 — uno o pochi per chiamata, sotto il limite di 50 MB per richiesta.
  3. Un link di caricamento — quando le foto sono sullo smartphone o sulla fotocamera di qualcuno e non online. Vedi create_upload_link con type: "360".

Inviare file 360° locali come URI data:, due per chiamata, e poi creare il tour:

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()

Errori

Gli errori arrivano come { "error": "...", "code": "..." } (code solo dove indicato). Vedi Errori e limiti per il modello generale.

  • 400 — input non valido: una foto che non è 360°, più di 50 scene, un valore di linking sconosciuto. no_panoramas: la proprietà non ha ancora foto 360°. no_new_scenes: tutte le scene che aggiungi sono già nel tour.
  • 402 insufficient_credits — con creditsRequired, creditsAvailable e upgradeUrl. Non viene creato né addebitato nulla.
  • 404 — User not found (chiave API errata), Virtual tour not found o Property not found for this account.
  • 409 — tour_exists: la proprietà ha già un tour (il suo tourId è nella risposta). tour_processing: il tour è ancora in costruzione — aspetta che sia pronto. tour_failed: la costruzione è fallita — elimina il tour e ricrealo.
  • 429 — upload_limit: le foto passate tramite URL supererebbero il limite giornaliero di caricamento dell'account (30 al giorno sul piano gratuito, 500 sui piani a pagamento, azzerato a mezzanotte UTC); l'intera chiamata viene rifiutata e non si salva nulla. upload_link_limit: l'account ha già creato i suoi link di caricamento di oggi.

Successivo

Crea tour da ChatGPT o Claude con il server MCP, gestisci le foto di un tour con l'API Proprietà, o trasforma lo stesso annuncio in un video.