Documentação da API
Uma chamada HTTP devolve o cadastro completo de um produto pelo código de barras. Se você usa Delphi ou C#, os exemplos abaixo são coláveis.
A primeira chamada
Autenticação é um cabeçalho Authorization: Bearer com o seu token.
Não há OAuth, não há renovação de sessão, não há segredo na URL.
Cole isto num terminal:
curl -H "Authorization: Bearer sc_SEU_TOKEN_AQUI" \
https://syscatalogo.wxdev.com.br/v1/produtos/7894900011517
O código pode ir com ou sem o dígito verificador à esquerda: internamente
tudo vira GTIN-14, então 7894900011517 e 07894900011517
são o mesmo produto.
Delphi e C#
Os dois trechos são completos — cabeçalho, chamada e leitura do JSON.
uses System.Net.HttpClient, System.Net.URLClient, System.JSON;
function ConsultarProduto(const Gtin: string): TJSONObject;
var
Http: THTTPClient;
Resposta: IHTTPResponse;
begin
Http := THTTPClient.Create;
try
Http.CustomHeaders['Authorization'] := 'Bearer sc_SEU_TOKEN_AQUI';
Resposta := Http.Get('https://syscatalogo.wxdev.com.br/v1/produtos/' + Gtin);
if Resposta.StatusCode = 200 then
Result := TJSONObject.ParseJSONValue(Resposta.ContentAsString) as TJSONObject
else
Result := nil; // ver a tabela de erros mais abaixo
finally
Http.Free;
end;
end;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "sc_SEU_TOKEN_AQUI");
var resposta = await http.GetAsync("https://syscatalogo.wxdev.com.br/v1/produtos/7894900011517");
if (resposta.IsSuccessStatusCode)
{
var json = await resposta.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(json);
var produto = doc.RootElement.GetProperty("produto");
Console.WriteLine(produto.GetProperty("descricao").GetString());
}
Se você usa TIdHTTP (Indy) em vez do THTTPClient,
o HTTPS exige as DLLs do OpenSSL na pasta do executável:
libeay32.dll e ssleay32.dll (ou
libcrypto-1_1.dll e libssl-1_1.dll nas versões novas).
Sem elas o erro é "Could not load SSL library", que não diz o que fazer.
O THTTPClient usa o TLS do próprio Windows e não precisa de
DLL nenhuma — se puder escolher, escolha ele.
Os campos da resposta
{
"gtin": "07894900011517",
"origem": "cache",
"encontrado": true,
"produto": {
"descricao": "Coca-Cola Original 350ml",
"marca": "Coca-Cola",
"categoria": "Bebidas",
"ncm": "22021000",
"cest": "0300700",
"unidade": "UN",
"peso_liquido": 0.35,
"fonte": "cadastroproduto",
"confianca": 90,
"imagem": {
"thumb": "https://.../thumb.webp",
"media": "https://.../media.webp",
"grande": "https://.../grande.webp",
"licenca": "CC BY-SA 4.0",
"atribuicao": "Foto: Open Food Facts, sob licença CC BY-SA"
}
}
}
| Campo | O que é |
|---|---|
| gtin | O código normalizado para 14 dígitos. Use este como chave. |
| encontrado | false quando não temos o produto. O campo produto vem nulo. |
| confianca | 0 a 100. Quanto maior, mais confiável a fonte do dado — útil se você já tem cadastro próprio e precisa decidir qual prevalece. |
| imagem | Nulo quando o produto existe mas ainda não tem foto que possamos servir. Não é erro: descrição, marca e NCM já poupam a digitação. |
| imagem.licenca | Quando preenchido, obriga a exibir atribuicao. Ver a seção abaixo. |
Sincronização incremental
É o endpoint que serve melhor a um ERP desktop: o cliente manda a lista de códigos que tem, recebe tudo de uma vez, grava no próprio banco e passa a ler do disco. No dia a dia o caixa bipa e o ERP responde sem tocar a rede — o que também significa que continua funcionando com a internet caída.
POST https://syscatalogo.wxdev.com.br/v1/sincronizar
Authorization: Bearer sc_SEU_TOKEN_AQUI
Content-Type: application/json
{ "gtins": ["7894900011517", "7891000100103"], "desde": "2026-09-01T00:00:00Z" }
Sem desde, vem o catálogo inteiro. Com desde, só
o que mudou desde aquela data — guarde o sincronizado_em da
resposta e mande de volta na próxima vez. Até 5.000 códigos por chamada.
A resposta separa quatro situações, e a diferença entre elas importa:
| Campo | Significa |
|---|---|
| itens | Os produtos, com dados e fotos. |
| nao_encontrados | Não temos este produto. Significa isto e só isto, nos dois modos. |
| recusados | Temos, mas o seu plano acabou. Não apague estes do seu catálogo — eles voltam quando você subir de faixa. |
| codigos_internos | Código que a própria loja inventou. Não existe em base nenhuma do mundo; marque e pare de mandar. |
| resumo.sem_alteracao | Só contagem: o produto existe e não mudou desde o desde. |
Se o seu ERP apaga o que "não voltou" na sincronização, apague apenas o que
está em nao_encontrados. Produto em recusados existe
aqui, e produto em sem_alteracao nem aparece em lista nenhuma —
ele só não mudou.
Licença da foto
Quando a resposta trouxer imagem.licenca preenchido — hoje a
maioria dos casos é "CC BY-SA 4.0" —, o seu sistema
precisa exibir o texto de imagem.atribuicao junto da foto,
ou em um rodapé de créditos acessível a quem vê a imagem.
Não é burocracia nossa: é a condição da licença sob a qual essas fotos podem ser redistribuídas. Ignorar o campo coloca o seu sistema em violação.
Quando licenca vem nulo, não há exigência de crédito.
Códigos de erro
| HTTP | O que houve, e o que fazer |
|---|---|
| 401 | Token errado, ausente ou licença desativada. Os três respondem igual de propósito. |
| 404 | Não temos o produto. O corpo traz motivo: "nao_encontrado". |
| 422 | Código interno da loja — prefixo 2x, 4x ou 20x-29x. Foi a própria loja que inventou; não existe em base nenhuma. Marque no seu cadastro e pare de consultar. |
| 402 | Teto de produtos do plano atingido. Esperar não resolve: é preciso mudar de faixa. O corpo traz motivo: "limite_do_plano". |
| 429 | Limite diário atingido (motivo: "limite_diario") ou excesso de requisições. Amanhã libera. |
| 400 | Corpo malformado — lista vazia, acima do máximo, data inválida. |
Como a cota funciona
A conta é de produtos distintos, não de consultas. O caixa bipar o mesmo refrigerante mil vezes por dia não custa nada e nunca é recusado — o que consome a faixa é conhecer um produto novo.
Duas consequências práticas:
- Estourar a faixa não derruba a loja. Tudo que você já cadastrou continua respondendo normalmente; o que para é aprender produto novo.
- Código interno e produto que não temos não consomem nada. Você só paga pelo que a gente de fato entrega.
Toda resposta traz o seu consumo nos cabeçalhos:
X-Produtos-Usados: 1842
X-Produtos-Limite: 2000
X-Produtos-Restantes: 158
X-Quota-Restante: 19873 (requisições restantes hoje)
Estabilidade do contrato
ERP instalado em loja física quase nunca é atualizado. Por isso a v1 é tratada como permanente: campo novo entra sempre opcional, e campo em uso nunca é removido nem renomeado. Você pode integrar hoje e não mexer mais.
Existe também um openapi.json, se a sua ferramenta gerar cliente a partir dele.