Transforma fotos 360° num tour virtual alojado e pronto a partilhar com uma única chamada. A IA dá nome às divisões e coloca os pontos de navegação entre elas; recebes um URL público do tour e um iframe para incorporar.
Envia as tuas fotos 360° e recebe um tour virtual alojado que podes partilhar ou incorporar. A Pedra importa as fotos equirretangulares, a IA dá nome a cada divisão e coloca os pontos de navegação de porta a porta, e a resposta devolve um tourUrl público e um iframe embedCode pronto a colar. Sem visualizador para alojar e sem pontos de navegação para colocar à mão.
O que obténs com uma única chamada:
Uma página de tour alojada — um tourUrl público e um iframe embedCode para qualquer página de anúncio, CRM ou portal. Funciona no telemóvel (com o giroscópio) e no computador.
Nomes de divisões com IA — as divisões a que não dás nome recebem nome automaticamente (Entrada, Cozinha, Quarto 1…) no idioma do tour, grátis. Os nomes que envias nunca são alterados.
Navegação com IA — a Pedra encontra cada porta na foto e coloca os pontos de navegação entre divisões, nos dois sentidos.
Controlo total depois — muda o nome, reordena, remove ou adiciona divisões e substitui os pontos de navegação pelos teus, tudo pela API.
Funciona a partir do chat — os mesmos endpoints são ferramentas do servidor MCP da Pedra, por isso o ChatGPT e o Claude podem criar um tour a partir de uma conversa.
Como funciona
Criar um tour é assíncrono: a chamada de criação devolve um tourId de imediato e o tour é construído em segundo plano (cerca de 10 segundos por divisão ligada).
Cria — POST /api/create_virtual_tour com as tuas fotos 360° pela ordem do percurso. Recebes de imediato o tourId, o tourUrl e o embedCode, com status: "processing".
Consulta — chama POST /api/get_virtual_tour a cada poucos segundos até status ser "ready" (ou "failed", com o motivo em error).
Partilha — envia o tourUrl ou cola o embedCode na página do anúncio. O URL mantém-se quando editas o tour mais tarde.
# 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" }'
Modos de ligação e créditos
O parâmetro linking decide como os pontos de navegação são colocados. Dar nome às divisões é sempre grátis. Os créditos só são cobrados quando a ligação começa, e uma construção que falha nunca é cobrada.
Modo
O que faz
Custo
sequential
Predefinido. Envia as divisões pela ordem do percurso; cada uma é ligada à seguinte, nos dois sentidos.
máx(3, ⌈divisões ÷ 3⌉) créditos — 3 até 9 divisões, 4 para 12, 10 para 30
smart
A IA compara cada par de divisões e liga as que visivelmente comunicam — para quando não sabes a ordem do percurso. Mais lento; até 40 divisões.
5–160 créditos consoante o número de divisões (tabela abaixo)
none
Sem pontos de navegação. Coloca os teus depois com update_virtual_tour.
Grátis
Ligação smart consoante o número de divisões
Divisões
Créditos
1–6
5 créditos
7–10
12 créditos
11–15
25 créditos
16–20
50 créditos
21–25
70 créditos
26–30
100 créditos
31–35
130 créditos
36–40
160 créditos
add_virtual_tour_scenes custa o mesmo que a ligação sequential, contando apenas as divisões novas. get_virtual_tour, list_virtual_tours, update_virtual_tour, delete_virtual_tour e create_upload_link são grátis. Consulta o teu saldo com credits.
Criar um tour virtual
POST/api/create_virtual_tour
Importa as fotos 360° e depois dá nome e liga as divisões em segundo plano. Envia scenes pela ordem do percurso — a primeira é onde o tour abre. Sem propertyId, é criado um novo imóvel com o nome indicado em name. Para criar um tour com fotos que já estão num imóvel (por exemplo, carregadas através de um link de carregamento), envia apenas o propertyId e omite scenes: são usadas todas as fotos 360° do imóvel, pela ordem de carregamento. Cada imóvel tem um tour; se já tiver um, recebes 409 tour_exists com o respetivo tourId.
apiKeystringobrigatório
A tua chave API.
scenesarray
As fotos 360°, pela ordem do percurso (máx. 50). Obrigatório, exceto se enviares um propertyId cujas fotos 360° vão formar o tour.
imageUrlsarray
Atalho para scenes: uma lista simples de URLs de fotos 360°.
propertyIdstring
Cria o tour neste imóvel. Necessário se as cenas usarem imageId. Sem scenes, são usadas todas as fotos 360° do imóvel pela ordem de carregamento. Omite-o para criar um novo imóvel.
namestring
Título do tour, p. ex. a morada do anúncio. É também o nome do novo imóvel, se for criado.
linkingstring
Como são colocados os pontos de navegação — vê Modos de ligação e créditos.
Values:sequentialsmartnone
Default:sequential
languagestring
Idioma da página do tour e dos nomes de divisões da IA. Os tours que não estão em inglês têm um URL do tipo /pt/virtual-tour/….
Values:enesfrdeitpt
Default:en
Objeto scene
Cada cena é { imageUrl } ou { imageId }, com um name opcional. Uma string simples é tratada como imageUrl. Até 50 cenas por tour.
imageUrlstring
URL público (ou URI data:) de uma foto 360° equirretangular — 2:1, até 80 MB. Os links de partilha do Dropbox e do Google Drive funcionam.
imageIdstring
Uma foto 360° que já está no imóvel (de list_property_images com type "360"). Usa-o em vez de imageUrl.
namestring
Nome da divisão. Se o omitires, a IA dá nome à divisão.
Devolve o estado do tour e, quando está pronto, as suas cenas, ligações de navegação e definições de apresentação. É o endpoint a consultar depois de create_virtual_tour e add_virtual_tour_scenes.
apiKeystringobrigatório
A tua chave API.
tourIdstringobrigatório
O id do tour (de create_virtual_tour ou list_virtual_tours).
processing — em construção. progress.stage é queued, importing, naming ou linking, com done / total quando se aplica.
ready — publicado em tourUrl. Inclui scenes, links e settings.
failed — não foi cobrado nada. error explica o motivo e failedScenes lista cada foto que não foi possível usar (por exemplo, uma que não é 2:1). As fotos importadas ficam no imóvel, por isso podes substituir a errada e voltar a criar o tour por imageId.
Se uma chamada a add_virtual_tour_scenes falhar, o tour continua ready e inclui lastError e failedScenes. Numa conta do plano gratuito o tour é criado, mas o link público mostra uma página de upgrade: as respostas indicam shareable: false, com um shareableNote.
Devolve os tours da conta, do mais recente para o mais antigo (até 100), com os mesmos campos de resumo que get_virtual_tour mas sem scenes, links nem settings. Os tours eliminados ficam de fora.
Muda o nome do tour ou das suas divisões, reordena ou remove divisões, substitui os pontos de navegação e muda o seu aspeto. Grátis e imediato. A validação é tudo ou nada: se algum campo for inválido, nada muda. Devolve o tour completo, como get_virtual_tour, ou 409 tour_processing enquanto o tour ainda está a ser construído.
apiKeystringobrigatório
A tua chave API.
tourIdstringobrigatório
O id do tour (de create_virtual_tour ou list_virtual_tours).
namestring
Novo título do tour.
sceneNamesobject
Nomes das divisões por sceneId, p. ex. { "<sceneId>": "Cozinha" }.
sceneOrderarray
Cada sceneId exatamente uma vez, pela nova ordem. A primeira é onde o tour abre.
removeScenesarray
sceneIds a retirar do tour. As fotos ficam no imóvel e as ligações que as envolvem são removidas. Tem de ficar pelo menos uma cena.
linksarray
Substitui TODAS as ligações de navegação. Cada ligação vai num só sentido: { fromSceneId, toSceneId, yaw, pitch? }.
navigationStylestring
Cor dos pontos de navegação.
Values:whiteblue
navigationSizestring
Tamanho dos pontos de navegação.
Values:smallmediumlarge
showLabelsboolean
Mostrar sempre o nome da divisão de destino junto a cada ponto de navegação.
languagestring
Idioma da página do tour.
Values:enesfrdeitpt
Objeto link
fromSceneIdstringobrigatório
A cena em que o ponto de navegação aparece.
toSceneIdstringobrigatório
A cena para onde leva.
yawnumberobrigatório
Ângulo horizontal na foto de fromScene, de −180 a 180. 0 é o centro da foto; negativo é à esquerda.
pitchnumber
Ângulo vertical, de −90 a 90. 0 é o horizonte.
Default:0
Para ajustar as ligações da IA em vez de começar do zero, lê links de get_virtual_tour, edita a lista e envia-a de volta.
Adiciona fotos 360° a um tour existente. Com ligação sequential só é ligado o troço novo: a última divisão existente à primeira nova, e depois cada divisão nova à seguinte. As ligações existentes, incluindo as que colocaste, mantêm-se. Custa máx(3, ⌈divisões novas ÷ 3⌉) créditos. É assíncrono como a criação, e o tour continua publicado entretanto — consulta get_virtual_tour até status voltar a ser "ready".
apiKeystringobrigatório
A tua chave API.
tourIdstringobrigatório
O id do tour (de create_virtual_tour ou list_virtual_tours).
scenesarrayobrigatório
As fotos 360° a adicionar, no mesmo formato que em create_virtual_tour. As cenas por imageId têm de ser fotos 360° do imóvel do tour.
linkingstring
sequential liga o troço novo; none adiciona as divisões sem pontos de navegação.
{
"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\"."
}
Eliminar um tour virtual
POST/api/delete_virtual_tour
Elimina o tour. O link público passa a devolver 404; as fotos 360° ficam no imóvel, por isso podes criar um novo tour com elas. Eliminar só está disponível na API — não existe como ferramenta MCP.
apiKeystringobrigatório
A tua chave API.
tourIdstringobrigatório
O id do tour (de create_virtual_tour ou list_virtual_tours).
{
"message": "Virtual tour deleted. Its 360° photos are still in the property.",
"tourId": "1d7aabf8-3c2e-4b8a-9f61-0c5d2e7a4b19"
}
Criar um link de carregamento
POST/api/create_upload_link
Devolve uma página de carregamento sem login para um imóvel, válida durante 24 horas. Envia-a a quem tem as fotos — o fotógrafo, o agente, o proprietário. Abre-a no telemóvel ou no computador, larga as fotos (até 100 ficheiros, JPEG, PNG ou WebP, até 80 MB cada; as fotos HEIC do iPhone funcionam quando carregadas a partir do próprio iPhone) e vê miniaturas, progresso e um "Tudo pronto" no fim. Os ficheiros são ordenados pelo nome, que nas câmaras 360° corresponde à ordem de captura — normalmente também a ordem do percurso.
type define o que a página aceita:
"any" (predefinição) — fotos normais e fotos 360°. As imagens 2:1 são detetadas e guardadas automaticamente como fotos 360°. Usa-o para fotos a editar, mobilar ou transformar em vídeo, ou uma mistura.
"360" — só fotos 360°; tudo o resto é rejeitado com uma mensagem clara. Usa-o quando o link é para um tour virtual.
As fotos são guardadas como na app web: as normais com 2048 px no lado maior (3072 px se o ficheiro tiver mais de 20 MB) e as 360° com 4096 px de largura (6144 px acima de 20 MB).
É também assim que um assistente de chat obtém fotos de um telemóvel: o Claude não consegue passar anexos do chat a uma ferramenta, e as fotos que ainda estão no telemóvel nem sequer estão no chat, por isso o assistente cria um link de carregamento, tu carregas as fotos e ele continua. (No ChatGPT, as fotos anexadas ao chat funcionam diretamente — vê Servidor MCP.) O link só pode adicionar fotos a esse imóvel — não dá nenhum outro acesso à conta. Quando o carregamento terminar, chama list_property_images (type"photo" ou "360") para obter URLs para editar ou transformar em vídeo, ou create_virtual_tour com o propertyId e sem scenes.
Limites: 5 links de carregamento por dia no plano gratuito, 50 nos planos pagos (429 upload_link_limit) — cada link funciona 24 horas, por isso reutiliza o de hoje em vez de criar outro. Cada ficheiro carregado através de um link conta também para o limite diário de carregamento.
apiKeystringobrigatório
A tua chave API.
propertyIdstring
O imóvel para onde vão as fotos. Omite-o para criar um novo imóvel com o nome indicado em name.
namestring
Nome do novo imóvel, p. ex. a morada do anúncio. Aparece na página de carregamento.
typestring
O que a página aceita: "any" para fotos e fotos 360° (as imagens 2:1 são guardadas como 360° automaticamente), ou "360" só para fotos 360° — usa-o para um tour virtual.
{
"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."
}
Carregar fotos 360°
Os tours são criados a partir de fotos 360° equirretangulares — os panoramas 2:1 que as câmaras 360° exportam. Cada foto é verificada (2:1, aceita-se 1,9–2,1, até 80 MB) e guardada como JPEG com 4096 px de largura (6144 px se o ficheiro tiver mais de 20 MB). Há três formas de as carregar:
URLs públicos, diretamente — passa-os como scenes a create_virtual_tour. Ideal quando as fotos já estão online (o teu CDN ou bucket de armazenamento). Os links de partilha do Dropbox e do Google Drive são convertidos automaticamente em downloads diretos.
add_images_to_property com type: "360" — guarda primeiro as fotos num imóvel (até 10 por chamada) e depois chama create_virtual_tour apenas com o propertyId. Também aceita URIs data:, por isso podes enviar ficheiros locais em base64 — um ou poucos por chamada, abaixo do limite de 50 MB por pedido.
Um link de carregamento — quando as fotos estão no telemóvel ou na câmara de alguém e não online. Vê create_upload_link com type: "360".
Enviar ficheiros 360° locais como URIs data:, dois por chamada, e depois criar o 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()
Erros
Os erros chegam como { "error": "...", "code": "..." } (code apenas onde indicado). Vê Erros e limites para o modelo geral.
400 — dados inválidos: uma foto que não é 360°, mais de 50 cenas, um valor de linking desconhecido. no_panoramas: o imóvel ainda não tem fotos 360°. no_new_scenes: todas as cenas que estás a adicionar já estão no tour.
402 insufficient_credits — com creditsRequired, creditsAvailable e upgradeUrl. Nada é criado nem cobrado.
404 — User not found (chave API errada), Virtual tour not found ou Property not found for this account.
409 — tour_exists: o imóvel já tem um tour (o respetivo tourId vem na resposta). tour_processing: o tour ainda está a ser construído — espera até estar pronto. tour_failed: a construção falhou — elimina o tour e cria-o de novo.
429 — upload_limit: as fotos enviadas por URL ultrapassariam o limite diário de carregamento da conta (30 por dia no plano gratuito, 500 nos planos pagos, reposto à meia-noite UTC); a chamada inteira é recusada e nada é guardado. upload_link_limit: a conta já criou os links de carregamento de hoje.
Seguinte
Cria tours a partir do ChatGPT ou do Claude com o servidor MCP, gere as fotos de um tour com a API de propriedades, ou transforma o mesmo anúncio num vídeo.