SysCatálogo

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.

Nesta página
  1. A primeira chamada
  2. Delphi e C#
  3. Os campos da resposta
  4. Sincronização incremental
  5. Licença da foto (obrigatório)
  6. Códigos de erro
  7. Como a cota funciona
  8. Estabilidade do contrato

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;
Delphi mais antigo · o chamado número um

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"
    }
  }
}
CampoO que é
gtinO código normalizado para 14 dígitos. Use este como chave.
encontradofalse quando não temos o produto. O campo produto vem nulo.
confianca0 a 100. Quanto maior, mais confiável a fonte do dado — útil se você já tem cadastro próprio e precisa decidir qual prevalece.
imagemNulo 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.licencaQuando 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:

CampoSignifica
itensOs produtos, com dados e fotos.
nao_encontradosNão temos este produto. Significa isto e só isto, nos dois modos.
recusadosTemos, mas o seu plano acabou. Não apague estes do seu catálogo — eles voltam quando você subir de faixa.
codigos_internosCódigo que a própria loja inventou. Não existe em base nenhuma do mundo; marque e pare de mandar.
resumo.sem_alteracaoSó contagem: o produto existe e não mudou desde o desde.
Cuidado ao limpar catálogo local

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

Obrigatório

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

HTTPO que houve, e o que fazer
401Token errado, ausente ou licença desativada. Os três respondem igual de propósito.
404Não temos o produto. O corpo traz motivo: "nao_encontrado".
422Có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.
402Teto de produtos do plano atingido. Esperar não resolve: é preciso mudar de faixa. O corpo traz motivo: "limite_do_plano".
429Limite diário atingido (motivo: "limite_diario") ou excesso de requisições. Amanhã libera.
400Corpo 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:

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.