Build · Shopify
Crie um app de try-on para Shopify
Em uma frase
Um app de try-on para Shopify lê a imagem do produto da Admin API, faz um POST para o Photta, monitora o job via polling em um worker em segundo plano e, em seguida, entrega a URL finalizada à Shopify via productCreateMedia.
- Credits: 5 credits em 2K · 6 credits em 4K
- Tempo típico: 1.5–4 min
- Processamento: assíncrono, polling
Todos os números nesta página vêm de a documentação da API da Photta · verificado
Leia a foto do produto da Admin API, processe o try-on com o Photta e envie o resultado de volta como mídia do produto. Quatro chamadas, sem necessidade de manipular imagens por conta própria.
RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/apparel \
-H "Authorization: Bearer $PHOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": true,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')const res = await fetch("https://api.photta.app/api/v1/tryon/apparel", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": true,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
}),
});
const { data } = await res.json(); // data.id, data.statusimport os, requests
res = requests.post(
"https://api.photta.app/api/v1/tryon/apparel",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": True,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
},
)
data = res.json()["data"] # data["id"], data["status"]Como funciona
De uma página de produto a uma imagem de try-on
Defina os escopos do app, leia a foto, envie a requisição, faça polling fora do fluxo principal e anexe a mídia.
Passo 1
Defina os escopos do app
Um app de try-on precisa ler produtos e gravar mídias. Solicite apenas os escopos de produto que seu app realmente utiliza — os lojistas prestam atenção na tela de consentimento.
Passo 2
Obtenha uma chave de API do Photta
Uma chave por ambiente, mantida nas configurações do servidor do seu app. Ela nunca deve trafegar para a storefront nem para o navegador do lojista.
Passo 3
Leia a imagem do produto
Consulte o produto para obter sua primeira imagem. Essa URL é pública, exatamente o que o endpoint do Photta espera — sem novo upload, sem URLs assinadas para gerenciar.
Passo 4
Envie a requisição de try-on
Envie a imagem via POST especificando um manequim e uma pose. A resposta é imediata e retorna o ID da geração; nada foi renderizado ainda.
Passo 5
Faça polling em um job de segundo plano
A Shopify espera que um webhook handler responda em segundos, e uma geração leva mais tempo do que isso. Confirme o recebimento (ACK), enfileire a tarefa e faça polling a cada 3 segundos a partir do worker.
Passo 6
Anexe a mídia
Entregue a URL finalizada à Shopify e ela mesma baixa o arquivo. Persista a imagem no seu lado também, garantindo que a galeria permaneça acessível de forma independente.
As quatro chamadas, de ponta a ponta
A requisição e o polling do Photta são gerados a partir da documentação da API; as chamadas da Shopify são da própria Admin API.
// Shopify Admin GraphQL — the product's first image is your source photo
const query = `query($id: ID!) {
product(id: $id) { title images(first: 1) { nodes { url } } }
}`;
const res = await admin.graphql(query, { variables: { id: productGid } });
const { data } = await res.json();
const productImage = data.product.images.nodes[0].url;const res = await fetch("https://api.photta.app/api/v1/tryon/apparel", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": true,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
}),
});
const { data } = await res.json(); // data.id, data.statusasync function waitFor(id) {
for (let attempt = 0; attempt < 120; attempt++) {
const res = await fetch(`https://api.photta.app/api/v1/tryon/apparel/${id}`, { headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}` } });
const { data } = await res.json();
if (data.status === "completed") return data.output_url;
if (data.status === "failed") throw new Error(data.error_message ?? "generation failed");
await new Promise((r) => setTimeout(r, 3000));
}
throw new Error("timed out after 6 minutes");
}// Shopify downloads the URL itself, so hand it the Photta output_url
const mutation = `mutation($id: ID!, $media: [CreateMediaInput!]!) {
productCreateMedia(productId: $id, media: $media) {
mediaUserErrors { field message }
}
}`;
await admin.graphql(mutation, {
variables: {
id: productGid,
media: [{ originalSource: outputUrl, mediaContentType: "IMAGE", alt: "Virtual try-on" }],
},
});Dúvidas frequentes de desenvolvedores
Perguntas frequentes de desenvolvedores Shopify
Onde a chave do Photta deve ficar em um app da Shopify?
Nas variáveis de ambiente do servidor da sua aplicação, nunca no tema, em um app block ou na resposta de um app proxy. Qualquer informação acessível pela storefront pode ser lida por um cliente.
Quais escopos da Shopify são necessários?
Leitura da imagem do produto e gravação de mídias de produto. O Photta não precisa de nenhum acesso à Shopify — seu app é o único intermediário entre os dois lados.
Como mantenho o webhook rápido?
Responda imediatamente confirmando o recebimento, enfileire a tarefa e faça polling a partir do worker. A geração leva mais tempo do que o tempo limite aceitável de um webhook handler, logo, nenhuma operação que aguarde o resultado deve rodar dentro dele.
Posso cobrar os lojistas por imagem?
Essa é uma decisão do seu modelo de preços. O Photta debita da sua conta em credits por chamada, de modo que o custo por imagem é previsível antes da renderização; a margem cobrada a mais fica a seu critério.
E se um produto não tiver foto?
Ignore-o em vez de enviar uma imagem de placeholder. O endpoint precisa da foto real de uma peça de roupa, e usar um placeholder consumirá credits em uma imagem que ninguém vai publicar.
Páginas relacionadas
Leituras relacionadas
Recursos
API de try-on virtual para roupas
API REST que veste roupas em manequins de IA. Assíncrona, geração em 1.5–4 minutos, 5 credits em 2K, 6 em 4K. Exemplos em cURL, Node.js e Python.
LerInício rápido
Primeira imagem no Photta em menos de cinco minutos.
Cadastre-se, gere uma chave de API, execute sua primeira chamada cURL, faça polling até a conclusão, persista o resultado. Cinco etapas, documentadas de ponta a ponta.
LerLinguagens
Node.js walkthrough
LerRate limits
Ler
Todos os números nesta página vêm de a documentação da API da Photta · verificado
Entregue o app, não a infraestrutura básica
As chamadas ao Photta nesta página vêm diretamente da documentação da API. Obtenha uma chave e a primeira renderização estará pronta em poucos minutos.