Riferimento API
L’API di Prewalk fa parte del piano Enterprise. Con una chiave API il tuo software può creare tour, caricare scene, pubblicare, leggere progetti e statistiche e ricevere un webhook firmato a ogni fase di elaborazione. Questa pagina è il riferimento; lo studio e il player pubblico continuano a funzionare come prima.
URL di base e convenzioni
- URL di base:
https://prewalk.co. Non usareapp.prewalk.co: reindirizza (308) e la maggior parte dei client HTTP scarta l’headerAuthorizationin caso di reindirizzamento verso un altro host. - Formato: JSON in ingresso e in uscita (
Content-Type: application/json), tranne il caricamento delle scene, che invia l’immagine come corpo grezzo della richiesta. - Gli ID sono composti da 12 lettere minuscole e cifre, ad es.
teeg8crtm0u0. Le date sono in formato ISO 8601 in UTC. - Gli errori hanno sempre la stessa forma: uno stato HTTP e
{"error": {"code": "…", "message": "…"}}; gli errori di validazione aggiungonofield. I codici sono elencati alla fine di questa pagina. - Limite di richieste: 600 richieste al minuto per chiave. Oltre questo limite ricevi
429con un headerRetry-After(in secondi).
Autenticazione
Crea una chiave in Impostazioni → API (proprietario o amministratore dell’account, Enterprise). Una chiave appartiene all’account, può essere limitata a un solo profilo del brand e ha fino a tre autorizzazioni: read, write e stats. La chiave completa viene mostrata una sola volta; l’elenco ne mostra solo il prefisso. Fino a 20 chiavi per account; una chiave revocata smette subito di funzionare.
Authorization: Bearer pw_…
Una chiave agisce per un solo account. GET /api/me descrive ciò che la chiave può vedere: l’account e i limiti del suo piano, i profili di quell’account, il profilo con cui agisce la chiave (actor) e la chiave stessa con le sue autorizzazioni. Non restituisce mai l’email del proprietario della chiave né i suoi altri account.
Endpoint
| Metodo e percorso | Autorizzazione | Cosa fa |
|---|---|---|
GET /api/me | read | L’account, i profili e le autorizzazioni della chiave |
GET /api/tours | read | Elenca i tour dell’account (limit ≤ 50, cursor, profileId) |
GET /api/tours/{id} | read | Un tour con le sue scene, gli hotspot e le impostazioni |
GET /api/tours/{id}/events | read | L’avanzamento dell’elaborazione come flusso di server-sent event |
POST /api/tours | write | Crea un tour ({"title": "…"}) |
PATCH /api/tours/{id} | write | Modifica titolo, descrizione, categoria, luogo, tag, slug (l’indirizzo leggibile), ordine delle scene, scena iniziale, nomi delle scene |
POST /api/tours/{id}/scenes | write | Carica un’immagine 360° come corpo grezzo |
POST /api/content/{id}/visibility | write | Pubblica un tour o un progetto, rendilo visibile solo con link o proteggilo con una password |
GET /api/projects | read | Elenca i progetti dell’account (limit, cursor, profileId) |
GET /api/projects/{id} | read | Un progetto con i suoi tour, immagini, video e planimetrie |
GET /api/stats/{contentId} | stats | Visualizzazioni di un tour o di un progetto (range in giorni) |
GET /api/stats/{contentId}/export.csv | stats | Gli stessi dati in CSV (table = daily, scenes o referrers) |
Ogni altro endpoint risponde 403 api_key_forbidden a una richiesta con chiave. Account, team, fatturazione, chiavi API e webhook si gestiscono nel browser.
Tour
Elenco. GET /api/tours?limit=50 restituisce {"items": […], "next": "…", "usage": {…}}. Passa di nuovo next come cursor per ottenere la pagina successiva; usage contiene il numero di scene dell’account e i limiti. Ogni elemento ha id, title, visibility, publishedAt, createdAt, updatedAt, il profilo e il numero di scene.
Lettura. GET /api/tours/{id} restituisce il tour completo: title, description, category, location, tags, slug, visibility (public, link o password), hasPassword, publishedAt, profile, projectId, startScene, coverScene, revision, scenes in ordine, hotspots, settings, audio e links (player è l’indirizzo condivisibile, post la pagina pubblica quando il tour è pubblicato).
Una scena ha id, name, status (queued, processing, ready o error), createdAt, facoltativamente view (la direzione iniziale: yaw, pitch e fov in radianti), north (in radianti; 0 è il centro dell’immagine e il valore cresce verso destra) e, durante l’elaborazione, stage e pct. Una scena pronta contiene meta con i suoi livelli di tile e la radice dei media.
Creazione. POST /api/tours con {"title": "Harbor View — Unit 4"} restituisce il nuovo tour. Senza titolo si chiama «Tour senza titolo».
Aggiornamento. PATCH /api/tours/{id} accetta uno qualsiasi di questi campi e restituisce il tour:
title,description,category,location,tags(array di stringhe),slug(l’indirizzo pubblico: lettere minuscole, cifre e trattini),commentsEnabled;order: un array di id di scena nell’ordine che vuoi; le scene che ometti mantengono la loro posizione dopo quelle elencate;startScene: un id di scena; la scena viene spostata in testa (la prima scena è la scena iniziale);coverScene: un id di scena oppurenullper usare la scena iniziale;scenes: un oggetto con gli id di scena come chiavi, conname,view({"yaw", "pitch", "fov"}) enorth(in gradi).
Invia If-Match: "<revision>" con l’ultima revision che hai letto per far rifiutare una scrittura che sovrascriverebbe la modifica di qualcun altro: in quel caso la risposta è 409 revision_conflict con il tour attuale in error.tour. Senza If-Match vince l’ultima scrittura.
Caricare le scene
POST /api/tours/{id}/scenes con il file dell’immagine come corpo grezzo. Header:
Content-Type:image/jpeg,image/png,image/tiffoimage/webp;x-file-name: il nome del file, codificato per URL (encodeURIComponent); la scena prende il nome dal file, quindi01-living-room.jpgdiventa «01 living room»;x-pw-upload-batchex-pw-upload-index(facoltativi): quando carichi in parallelo più file della stessa selezione, assegna a tutti lo stesso id di batch (lettere, cifre,-e_, fino a 32 caratteri) e a ciascuno il suo indice nella selezione; il server mantiene così quell’ordine, indipendentemente da quale file finisca per primo. Senza questi header le scene vengono aggiunte in ordine di arrivo.
Immagini accettate: panorami equirettangolari 2:1 fino alla larghezza prevista dal piano (8K con Gratuito, 16K da Pro in su), oppure panorami stereo top-bottom 1:1 da Pro in su (occhio sinistro in alto), fino a 1 GiB. La risposta è la scena (status: "queued"). L’elaborazione avviene per fasi: prima la scena diventa visibile (tile di anteprima), poi arrivano i tile a piena risoluzione («affinamento») e, da Pro in su, le texture VR; le due fasi procedono in parallelo e l’una o l’altra può terminare per prima. Il campo meta.pending della scena, il flusso di eventi e i webhook ti dicono quali fasi sono ancora in corso.
Errori: 400 unsupported_format (non è un JPG, PNG, TIFF o WebP), 400 unsupported_ratio (non è 2:1 né 1:1 top-bottom), 400 unreadable_image (un file danneggiato), 402 plan_required (16K o stereo con un piano che non li include), 402 quota_exceeded (il limite di scene dell’account), 413 file_too_large.
Avanzamento dell’elaborazione
GET /api/tours/{id}/events è un flusso di server-sent event (text/event-stream). Eventi: hello alla connessione, queue (la posizione in coda delle scene in attesa e un riepilogo del tour, ogni pochi secondi mentre c’è qualcosa in corso), scene (status, stage, pct o error) e tour (il tour è cambiato; rileggilo). Per un’integrazione da server a server preferisci i webhook descritti più sotto.
Pubblicazione e visibilità
POST /api/content/{id}/visibility funziona per tour e progetti e restituisce il contenuto:
{"visibility": "link"}– raggiungibile solo tramite il suo indirizzo (l’impostazione predefinita di ogni nuovo tour);{"visibility": "public", "rightsAccepted": true}– sul profilo, in Esplora e indicizzabile; serve unacategory(impostala prima conPATCH) e confermi di avere il diritto di pubblicare le immagini. Per un progetto aggiungi"tourIds": [...]per pubblicare dei tour insieme al progetto;{"visibility": "password", "password": "…"}– da Pro in su; omettipasswordper mantenere quella attuale.
Un tour all’interno di un progetto protetto da password non può diventare pubblico né avere una password propria (409 in_password_project); l’accesso è regolato dalla password del progetto.
Progetti
Per ora i progetti sono in sola lettura tramite l’API. GET /api/projects li elenca con id, title, slug, visibility, category, coverUrl, tourCount, imageCount, videoCount e le date; GET /api/projects/{id} aggiunge description, location, tags, urls (public e il link privato), i tours con le loro scene e, della galleria, le images, i videos e le floorplans con i loro pin. Crea i progetti e aggiungi i media nello studio.
Statistiche
GET /api/stats/{contentId}?range=30 restituisce le visualizzazioni di un tour o di un progetto. Cosa ottieni dipende dal piano: il total complessivo con il piano Gratuito; una serie daily con i giorni vuoti a zero (from, to, fino a 90 giorni) con il piano Pro; fino a 365 giorni, più sources (pagina, incorporamento, accesso diretto), devices (telefono, desktop, visore VR), scenes e i referrers che incorporano il contenuto, con Office ed Enterprise. …/export.csv?range=30&table=daily fornisce la tabella giornaliera, table=scenes le visualizzazioni per scena e table=referrers i siti che incorporano il contenuto. Le visualizzazioni vengono contate per indirizzo del visitatore e contenuto, una volta ogni 30 minuti; non viene memorizzato nulla di personale.
Webhook
Aggiungi fino a cinque webhook in Impostazioni → API. Inviamo una richiesta POST firmata con un corpo JSON:
{"eventId": "evt_…", "eventType": "scene.ready", "occurredAt": "2026-10-22T09:12:03.000Z",
"data": {"tourId": "…", "sceneId": "…", "status": "ready", "pending": ["refine", "vr"]}}
| Evento | Quando | Dati |
|---|---|---|
scene.ready | La scena è visibile (tile di anteprima) | pending: fasi ancora in corso – refine (tile a piena risoluzione) e vr (texture per il visore); [] quando l’anteprima è definitiva |
scene.sharpened | I tile a piena risoluzione sono pronti | stage: "refine", ok (false quando la fase è stata abbandonata e la scena resta in qualità di anteprima), pending |
scene.vr_ready | Le texture VR sono pronte | stage: "vr", ok, pending |
scene.failed | L’elaborazione non è riuscita in modo definitivo | error con il motivo |
ping | Il pulsante «Invia test» | vuoto |
Header: Prewalk-Signature: ts=<unix seconds>;h1=<hex>, dove h1 è l’HMAC-SHA256 di ts + ":" + body calcolato con il segreto del tuo webhook (sugli esatti byte che hai ricevuto), più Prewalk-Event-Id e Prewalk-Event-Type. Durante la rotazione di un segreto l’header contiene due valori h1 (ts=…;h1=<new>;h1=<old>) finché il segreto precedente non scade: accetta la consegna se uno qualsiasi dei due risulta valido. Verifica la firma, rifiuta un timestamp più vecchio di qualche minuto ed elimina i duplicati in base a eventId: una consegna viene ritentata finché il tuo endpoint non risponde con 2xx (dieci tentativi, dopo 30 s e poi a intervalli che raddoppiano, circa quattro ore in tutto) e il corpo ritentato è identico byte per byte. Dopo 20 consegne fallite di fila il webhook viene disattivato e il proprietario dell’account riceve un’email. Gli endpoint devono usare https su un indirizzo pubblico; i reindirizzamenti non vengono seguiti. Il segreto può essere ruotato; quello precedente resta valido per 24 ore.
Un esempio completo
# 1. create a tour
curl -s https://prewalk.co/api/tours -H "Authorization: Bearer $PW_KEY" \
-H "Content-Type: application/json" -d '{"title":"Harbor View — Unit 4"}'
# 2. upload two scenes in order
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. set a category and publish
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. views of the last 30 days
curl -s "https://prewalk.co/api/stats/$TOUR?range=30" -H "Authorization: Bearer $PW_KEY"
Incorporamento
L’incorporamento non richiede una chiave: ogni tour ha https://prewalk.co/embed/{id}, e embed.js dimensiona il riquadro e lo apre a schermo intero nella tua pagina. Quali siti web possono mostrare i tuoi incorporamenti si imposta in Impostazioni → Identità visiva. La guida all’incorporamento spiega tutti i dettagli.
Codici di errore
| Stato | Codice | Significato |
|---|---|---|
| 400 | invalid_request | Un campo manca o non è valido; field indica quale |
| 400 | unsupported_format, unsupported_ratio, unreadable_image, rights_required, category_required, project_needs_content | Requisiti per il caricamento o la pubblicazione (un progetto ha bisogno di un tour pubblico, un’immagine o un video) |
| 401 | unauthorized, invalid_api_key | Nessuna chiave, oppure una chiave non valida o revocata |
| 402 | plan_required, quota_exceeded | Il piano non include la funzionalità, oppure è stato raggiunto un limite (feature o limit indica quale) |
| 403 | api_key_forbidden, api_scope_missing | L’endpoint non è accessibile con una chiave, oppure alla chiave manca l’autorizzazione |
| 404 | not_found | Non è tuo, è stato eliminato o l’id non esiste |
| 409 | revision_conflict, slug_taken, in_password_project | Modifica simultanea (il tour attuale è incluso), indirizzo già in uso, regola della password del progetto |
| 413 | file_too_large | Supera il limite di dimensione |
| 429 | rate_limited | Troppe richieste; attendi Retry-After secondi |
| 503 | maintenance | Prewalk è in aggiornamento; riprova tra un minuto |
Modifiche
- 10 novembre 2026: un progetto può essere pubblicato o protetto da password anche solo con immagini o video. Un progetto senza nulla da mostrare risponde
400 project_needs_content, sia pubblico sia con password; il codice sostituisceproject_needs_public_toureproject_needs_tour, che non vengono più inviati.GET /api/projectsaggiungevideoCount. - 22 ottobre 2026:
scene.readycontienepending; nuovi eventiscene.sharpenedescene.vr_ready; header per l’ordine di caricamentox-pw-upload-batchex-pw-upload-index;GET /api/mecon una chiave descrive solo l’account della chiave.
Hai domande o manca un endpoint? Scrivi a hello@prewalk.co.



