API Admin › Recursos

Provador virtual

O provador virtual mostra a armação no rosto do comprador, pela câmera ou numa foto, tudo no aparelho dele. Cada armação precisa de um arquivo: 2d, a foto da frente (e, se tiver, a do lado, com as hastes), em PNG com o fundo transparente, ou 3d, um modelo GLB. O arquivo é do produto e vale para todas as variantes; uma variante (a cor) pode ter o dela, que vale por cima.

É por aqui que uma agência ou um ERP carrega centenas de armações: os arquivos vão por endereço, e a API baixa e processa cada um, com as mesmas regras do painel (Produtos › o produto › Provador virtual).

EscopoO que abre
read_productsler os arquivos do provador
write_productsgravar e tirar os arquivos

A vitrine só mostra o provador com ele ligado na loja, no painel (Configurações › Provador virtual). Os arquivos podem ser carregados antes: ligar depois não pede nada de novo.

O objeto provador

{
  "type": "2d",
  "width_mm": 140,
  "adjustments": {
    "vertical_offset_mm": -2,
    "tilt_degrees": 8,
    "size_factor": 1
  },
  "front": {
    "src": "https://fotos.denaryx.com/.../frente-7f3a....webp",
    "width": 1600,
    "height": 571
  },
  "side": {
    "src": "https://fotos.denaryx.com/.../lado-1c9e....webp",
    "width": 1600,
    "height": 402
  },
  "model": null,
  "updated_at": "2026-10-16T12:00:00.000Z"
}
  • type: 2d (as fotos) ou 3d (o GLB). O 2d convence de frente e nos giros moderados (até uns 30°); o GLB acompanha os giros grandes.
  • width_mm: a largura total da frente, de ponta a ponta, em mm, de 80 a 200. É ela que dá a escala da armação no rosto: confira na ficha do fabricante.
  • adjustments: o acerto fino que a foto não diz. vertical_offset_mm sobe (positivo) ou desce a armação em relação à linha dos olhos, de -10 a 10; tilt_degrees é a inclinação pantoscópica (a parte de baixo vai na direção do rosto), de -5 a 20; size_factor multiplica a escala, de 0.8 a 1.2. Os padrões (-2, 8 e 1) servem na maioria das armações.
  • front e side: no 2d, as fotos como a vitrine as recebe, em WebP com transparência, aparadas pelas margens transparentes e com até 1600 px de largura. side é null sem a foto do lado: o provador desenha uma haste genérica, da cor do aro.
  • model: no 3d, o GLB normalizado (em mm, com a origem no centro da frente) e o número de triângulos. As fotos ficam null.

Os endereços mudam a cada envio: guarde o que a resposta trouxer, e não o que você mandou.

O arquivo do produto

GET /products/{id}/try_on

O arquivo do produto e as variantes que têm um próprio:

{
  "product_id": "0b6f2c1e-...",
  "try_on": { "type": "2d", "width_mm": 140, "...": "..." },
  "variants": [
    {
      "variant_id": "5e2a...",
      "try_on": { "type": "3d", "width_mm": 140, "...": "..." }
    }
  ]
}

try_on é null quando o produto não tem arquivo próprio. A variante fora de variants usa o do produto (ou fica sem provador, se o produto também não tem).

PUT /products/{id}/try_on

Grava o arquivo do produto. Responde 200 com o mesmo objeto do GET.

curl -X PUT https://api.denaryx.com/admin/2026-10/products/<id>/try_on \
  -H "Authorization: Bearer dnxa_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f6c..." \
  -d '{
    "type": "2d",
    "width_mm": 140,
    "front_url": "https://cdn.fornecedor.com.br/armacoes/AR-1020-frente.png",
    "side_url": "https://cdn.fornecedor.com.br/armacoes/AR-1020-lado.png"
  }'
CampoO que é
type2d ou 3d. Obrigatório.
width_mmA largura total da frente, em mm. Obrigatório.
adjustmentsvertical_offset_mm, tilt_degrees e size_factor, cada um opcional.
front_urlNo 2d: o endereço da frente, PNG com o fundo transparente, até 10 MB.
side_urlNo 2d, opcional: o endereço do lado (a armação de lado, com a haste aberta), PNG, até 10 MB. null tira o lado.
model_urlNo 3d: o endereço do GLB (glTF 2.0), até 8 MB.

O que fica: sem arquivo novo, fica o gravado do mesmo tipo, como no painel. Assim, trocar a largura ou um ajuste não pede reenviar nada: { "type": "2d", "width_mm": 142 } basta. Os ajustes que não vierem ficam como estavam (no arquivo novo, os padrões). Trocar o tipo pede o arquivo do tipo novo, e os do outro tipo saem. No 3d, trocar a largura normaliza de novo o GLB gravado.

Os endereços são baixados como as fotos por URL: https://, na porta padrão, públicos na internet (a API não busca endereços de redes internas e confere cada redirecionamento, até 3). A foto tem 15 segundos para chegar; o GLB, 30.

O processamento: a foto precisa ser PNG com fundo transparente de verdade (a foto com fundo branco é recusada, mesmo salva em PNG com canal alfa), ter pelo menos 300 px de largura sem as margens transparentes, e a frente, ser mais larga que alta. O GLB não pode usar compressão Draco nem Meshopt nem arquivos de fora do GLB, e tem até 150 mil triângulos e texturas de até 2048 px. A recusa diz o motivo e como preparar o arquivo (422 try_on_rejected).

DELETE /products/{id}/try_on

Tira o arquivo do produto (204). As variantes com arquivo próprio continuam com ele. Sem arquivo, 404.

O arquivo de uma variante

GET /products/{id}/variants/{variant_id}/try_on

O arquivo próprio da variante:

{
  "product_id": "0b6f2c1e-...",
  "variant_id": "5e2a...",
  "try_on": null
}

try_on é null quando a variante usa o arquivo do produto. A variante de outro produto dá 404.

PUT /products/{id}/variants/{variant_id}/try_on

Grava o arquivo da variante, com os mesmos campos e as mesmas regras do produto. O arquivo da variante não herda nada do produto: a primeira gravação pede o arquivo (front_url ou model_url). Responde 200 com o mesmo objeto do GET.

DELETE /products/{id}/variants/{variant_id}/try_on

Tira o arquivo próprio da variante (204): ela volta a usar o do produto. Sem arquivo próprio, 404.

Na leitura do produto

O produto traz o resumo em try_on:

{ "available": true, "type": "2d" }
  • available: o produto ou alguma variante tem arquivo.
  • type: o tipo do arquivo do produto; null sem arquivo do produto (só nas variantes, ou nenhum).

Gravar ou tirar um arquivo gera o evento product.updated, como as fotos.

Códigos

codeStatusQuando
try_on_rejected422O arquivo não serve: a foto sem transparência ou pequena demais, a frente mais alta que larga, o GLB recusado.
invalid_image_url400O endereço da foto não é https:// na porta 443, ou tem usuário e senha.
image_url_not_allowed400O endereço da foto (ou um redirecionamento) leva a uma rede interna.
image_too_large413A foto passou de 10 MB.
image_download_failed422O endereço da foto não respondeu, respondeu com erro ou redirecionou demais.
invalid_model_url400O endereço do GLB não é https:// na porta 443, ou tem usuário e senha.
model_url_not_allowed400O endereço do GLB (ou um redirecionamento) leva a uma rede interna.
model_too_large413O GLB passou de 8 MB.
model_download_failed422O endereço do GLB não respondeu, respondeu com erro ou redirecionou demais.
invalid_request400Um campo fora do formato: a largura fora da faixa, o GLB no 2d, a foto no 3d, ou o arquivo que falta.

Nos erros de um endereço, fields diz qual foi (front_url, side_url ou model_url).