Saltar al contenido
← Volver a las guías

Referencia de la API

12 min de lectura

La API de Prewalk forma parte del plan Corporativo. Con una clave de API, tu propio software puede crear recorridos, subir escenas, publicar, leer proyectos y estadísticas, y recibir un webhook firmado en cada etapa del procesamiento. Esta página es la referencia; el estudio y el reproductor público siguen funcionando como siempre.

URL base y convenciones

  • URL base: https://prewalk.co. No uses app.prewalk.co: redirige (308) y la mayoría de los clientes HTTP descartan el encabezado Authorization al redirigir a otro host.
  • Formato: JSON de entrada y de salida (Content-Type: application/json), salvo en la subida de escenas, que envía la imagen como cuerpo en bruto de la solicitud.
  • Los ID tienen 12 caracteres entre letras minúsculas y dígitos, por ejemplo teeg8crtm0u0. Las fechas van en ISO 8601 y en UTC.
  • Los errores siempre tienen la misma forma: un estado HTTP y {"error": {"code": "…", "message": "…"}}; los errores de validación añaden field. Los códigos aparecen al final de esta página.
  • Límite de frecuencia: 600 solicitudes por minuto por clave. Si lo superas, recibes un 429 con un encabezado Retry-After (en segundos).

Autenticación

Crea una clave en Configuración → API (propietario de la cuenta o administrador, plan Corporativo). Una clave pertenece a la cuenta, puede limitarse a un perfil de marca y tiene hasta tres permisos: read, write y stats. La clave completa se muestra una sola vez; en la lista solo aparece su prefijo. Hasta 20 claves por cuenta; una clave revocada deja de funcionar al instante.

Authorization: Bearer pw_…

Una clave actúa en nombre de una cuenta. GET /api/me describe lo que la clave puede ver: la cuenta y los límites de su plan, los perfiles de esa cuenta, el perfil con el que actúa la clave (actor) y la propia clave con sus permisos. Nunca devuelve el correo del propietario de la clave ni sus otras cuentas.

Endpoints

Método y rutaPermisoQué hace
GET /api/mereadLa cuenta, los perfiles y los permisos de la clave
GET /api/toursreadLista los recorridos de la cuenta (limit ≤ 50, cursor, profileId)
GET /api/tours/{id}readUn recorrido con sus escenas, hotspots y configuración
GET /api/tours/{id}/eventsreadEl progreso del procesamiento como flujo de eventos enviados por el servidor
POST /api/tourswriteCrea un recorrido ({"title": "…"})
PATCH /api/tours/{id}writeCambia el título, la descripción, la categoría, la ubicación, las etiquetas, el slug (la dirección legible), el orden de las escenas, la escena de inicio y los nombres de las escenas
POST /api/tours/{id}/sceneswriteSube una imagen 360° como cuerpo en bruto
POST /api/content/{id}/visibilitywritePublica un recorrido o proyecto, lo deja solo con enlace o lo protege con contraseña
GET /api/projectsreadLista los proyectos de la cuenta (limit, cursor, profileId)
GET /api/projects/{id}readUn proyecto con sus recorridos, imágenes, videos y planos
GET /api/stats/{contentId}statsVisualizaciones de un recorrido o proyecto (range en días)
GET /api/stats/{contentId}/export.csvstatsLo mismo en CSV (table = daily, scenes o referrers)

Cualquier otro endpoint responde 403 api_key_forbidden si se llama con una clave. La cuenta, el equipo, la facturación, las claves de API y los webhooks se gestionan en el navegador.

Recorridos

Listar. GET /api/tours?limit=50 devuelve {"items": […], "next": "…", "usage": {…}}. Envía next como cursor para obtener la página siguiente; usage contiene el número de escenas de la cuenta y sus límites. Cada elemento incluye id, title, visibility, publishedAt, createdAt, updatedAt, el perfil y los recuentos de escenas.

Leer. GET /api/tours/{id} devuelve el recorrido completo: title, description, category, location, tags, slug, visibility (public, link o password), hasPassword, publishedAt, profile, projectId, startScene, coverScene, revision, scenes en orden, hotspots, settings, audio y links (player es la dirección para compartir; post, la página pública cuando está publicado).

Una escena tiene id, name, status (queued, processing, ready o error), createdAt y, opcionalmente, view (la dirección de la vista inicial: yaw, pitch y fov en radianes), north (en radianes; 0 es el centro de la imagen y aumenta hacia la derecha) y, mientras se procesa, stage y pct. Cuando está lista, la escena incluye meta con sus niveles de teselas y la raíz de los archivos multimedia.

Crear. POST /api/tours con {"title": "Harbor View — Unit 4"} devuelve el nuevo recorrido. Si no tiene título, se llama «Untitled tour».

Actualizar. PATCH /api/tours/{id} acepta cualquiera de estos campos y devuelve el recorrido:

  • title, description, category, location, tags (array de cadenas), slug (la dirección pública: letras minúsculas, dígitos y guiones), commentsEnabled;
  • order: un array de ID de escena en el orden que quieras; las escenas que no incluyas conservan su lugar detrás de las que hayas indicado;
  • startScene: un ID de escena; esa escena pasa al principio (la primera escena es la escena de inicio);
  • coverScene: un ID de escena, o null para usar la escena de inicio;
  • scenes: un objeto indexado por ID de escena, con name, view ({"yaw", "pitch", "fov"}) y north (en grados).

Envía If-Match: "<revision>" con la revision que leíste por última vez para rechazar una escritura sobre el cambio de otra persona: la respuesta es entonces 409 revision_conflict, con el recorrido actual en error.tour. Sin If-Match, gana la última escritura.

Subida de escenas

POST /api/tours/{id}/scenes con el archivo de imagen como cuerpo en bruto. Encabezados:

  • Content-Type: image/jpeg, image/png, image/tiff o image/webp;
  • x-file-name: el nombre del archivo, codificado para URL (encodeURIComponent); la escena toma ese nombre, así que 01-living-room.jpg pasa a llamarse «01 living room»;
  • x-pw-upload-batch y x-pw-upload-index (opcionales): cuando subas en paralelo varios archivos de una misma selección, dales el mismo ID de lote (letras, dígitos, - y _, hasta 32 caracteres) y su índice en la selección; así el servidor mantiene ese orden sin importar qué archivo termine primero. Sin ellos, las escenas se añaden por orden de llegada.

Imágenes aceptadas: panorámicas equirrectangulares 2:1 hasta el ancho máximo del plan (8K en el plan Gratis y 16K a partir de Pro), o panorámicas estereoscópicas 1:1 arriba-abajo a partir de Pro (ojo izquierdo arriba), de hasta 1 GiB. La respuesta es la escena (status: "queued"). El procesamiento va por etapas: primero la escena se vuelve visible (teselas de vista previa); después llegan las teselas a resolución completa («mejora de nitidez») y, a partir de Pro, las texturas para VR; las dos etapas avanzan en paralelo y cualquiera de ellas puede terminar primero. El meta.pending de la escena, el flujo de eventos y los webhooks te indican qué etapas siguen en curso.

Errores: 400 unsupported_format (no es JPG, PNG, TIFF ni WebP), 400 unsupported_ratio (no es 2:1 ni 1:1 arriba-abajo), 400 unreadable_image (un archivo dañado), 402 plan_required (16K o estéreo en un plan que no los incluye), 402 quota_exceeded (el límite de escenas de la cuenta), 413 file_too_large.

Progreso del procesamiento

GET /api/tours/{id}/events es un flujo de eventos enviados por el servidor (text/event-stream). Eventos: hello al conectarse, queue (la posición en la cola de las escenas en espera y un resumen del recorrido, cada pocos segundos mientras haya algo en marcha), scene (status, stage, pct o error) y tour (el recorrido cambió; vuelve a leerlo). Para integraciones entre servidores, es preferible usar los webhooks que se describen más abajo.

Publicación y visibilidad

POST /api/content/{id}/visibility sirve para recorridos y proyectos, y devuelve el contenido:

  • {"visibility": "link"}: accesible solo a través de su dirección (el valor predeterminado de todo recorrido nuevo);
  • {"visibility": "public", "rightsAccepted": true}: en el perfil, en Explorar e indexable; hace falta una category (configúrala antes con PATCH) y confirmas que tienes derecho a publicar las imágenes. Para un proyecto, añade "tourIds": [...] para publicar recorridos junto con él;
  • {"visibility": "password", "password": "…"}: a partir de Pro; omite password para mantener la contraseña actual.

Un recorrido dentro de un proyecto protegido con contraseña no puede hacerse público ni tener su propia contraseña (409 in_password_project); el acceso lo controla la contraseña del proyecto.

Proyectos

Por ahora, los proyectos son de solo lectura en la API. GET /api/projects los lista con id, title, slug, visibility, category, coverUrl, tourCount, imageCount, videoCount y las fechas; GET /api/projects/{id} añade description, location, tags, urls (public y el enlace privado), los tours con sus escenas y, de la galería, las images, los videos y los floorplans con sus marcadores. Crea proyectos y añade archivos multimedia en el estudio.

Estadísticas

GET /api/stats/{contentId}?range=30 devuelve las visualizaciones de un recorrido o proyecto. Lo que recibes depende del plan: el total histórico en el plan Gratis; una serie daily rellenada con ceros (from, to, hasta 90 días) en Pro; y en Office y Corporativo, hasta 365 días más sources (página, inserción, directo), devices (teléfono, escritorio, visor de realidad virtual), scenes y los referrers de las inserciones. …/export.csv?range=30&table=daily da la tabla diaria; table=scenes, las visualizaciones por escena, y table=referrers, los sitios donde está insertado. Las visualizaciones se cuentan por dirección del visitante y contenido, una vez cada 30 minutos; no se guarda ningún dato personal.

Webhooks

Añade hasta cinco webhooks en Configuración → API. Enviamos un POST firmado con un cuerpo JSON:

{"eventId": "evt_…", "eventType": "scene.ready", "occurredAt": "2026-10-22T09:12:03.000Z",
 "data": {"tourId": "…", "sceneId": "…", "status": "ready", "pending": ["refine", "vr"]}}
EventoCuándoDatos
scene.readyLa escena es visible (teselas de vista previa)pending: etapas que siguen en curso — refine (teselas a resolución completa) y vr (texturas para visores de realidad virtual); [] cuando la vista previa es la versión final
scene.sharpenedLas teselas a resolución completa están listasstage: "refine", ok (false si la etapa se descartó y la escena se queda con la calidad de vista previa), pending
scene.vr_readyLas texturas para VR están listasstage: "vr", ok, pending
scene.failedEl procesamiento falló de forma definitivaerror con el motivo
pingEl botón «Enviar prueba»vacío

Encabezados: Prewalk-Signature: ts=<unix seconds>;h1=<hex>, donde h1 es el HMAC-SHA256 de ts + ":" + body con el secreto de tu webhook (calculado sobre los bytes exactos que recibiste), además de Prewalk-Event-Id y Prewalk-Event-Type. Mientras hay una rotación del secreto en curso, el encabezado lleva dos valores h1 (ts=…;h1=<new>;h1=<old>) hasta que caduca el secreto anterior: acepta la entrega si cualquiera de ellos se verifica. Verifica la firma, rechaza las marcas de tiempo de hace más de unos minutos y elimina los duplicados por eventId: una entrega se reintenta hasta que tu endpoint responde con un 2xx (diez intentos, a los 30 s y luego con el doble de espera cada vez, unas cuatro horas en total) y el cuerpo reintentado es idéntico byte a byte. Tras 20 entregas fallidas seguidas, el webhook se desactiva y el propietario de la cuenta recibe un correo. Los endpoints deben usar https en una dirección pública; las redirecciones no se siguen. El secreto se puede rotar; el anterior sigue siendo válido durante 24 horas.

Ejemplo paso a paso

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

Inserción

Para insertar no hace falta ninguna clave: cada recorrido tiene https://prewalk.co/embed/{id}, y embed.js ajusta el tamaño del marco y lo abre a pantalla completa en tu página. Los sitios web que pueden mostrar tus inserciones se configuran en Configuración → Imagen de marca. Encontrarás los detalles en la guía de inserción.

Códigos de error

EstadoCódigoSignificado
400invalid_requestFalta un campo o no es válido; field indica cuál
400unsupported_format, unsupported_ratio, unreadable_image, rights_required, category_required, project_needs_contentCondiciones previas para subir o publicar (un proyecto necesita un recorrido público, una imagen o un video)
401unauthorized, invalid_api_keyNo se envió ninguna clave, o la clave está mal formada o revocada
402plan_required, quota_exceededEl plan no incluye la función, o se alcanzó un límite (feature o limit indica cuál)
403api_key_forbidden, api_scope_missingEl endpoint no admite claves, o a la clave le falta el permiso
404not_foundNo es tuyo, se eliminó o el ID no existe
409revision_conflict, slug_taken, in_password_projectEdición simultánea (se incluye el recorrido actual), dirección en uso, regla de contraseña del proyecto
413file_too_largeSupera el límite de tamaño
429rate_limitedDemasiadas solicitudes; espera los segundos indicados en Retry-After
503maintenancePrewalk se está actualizando; vuelve a intentarlo en un minuto

Cambios

  • 10 de noviembre de 2026: un proyecto se puede publicar o proteger con contraseña solo con imágenes o videos. Un proyecto sin nada que mostrar responde 400 project_needs_content, tanto si es público como si tiene contraseña; este código sustituye a project_needs_public_tour y project_needs_tour, que ya no se envían. GET /api/projects añade videoCount.
  • 22 de octubre de 2026: scene.ready incluye pending; nuevos eventos scene.sharpened y scene.vr_ready; encabezados de orden de subida x-pw-upload-batch y x-pw-upload-index; con una clave, GET /api/me solo describe la cuenta de la clave.

¿Tienes preguntas o te falta algún endpoint? Escribe a hello@prewalk.co.

Compartir: 𝕏 LinkedIn WhatsApp

  • Cómo hacer un recorrido virtual 360°

    Cómo hacer un recorrido virtual 360°, paso a paso: haz una foto o un render 360° de cada habitación, sube los archivos 2:1, conecta las habitaciones y comparte un enlace.

  • Crea tu primer recorrido virtual en 10 minutos

    Crea un proyecto, sube tus imágenes 360°, conecta las habitaciones, publica y comparte un solo enlace. Cada paso con el botón exacto, en unos diez minutos.