Documentação pública

Documentação da API GTIN

Contrato tecnico das APIs V3 e V4, exemplos de integracao em varias linguagens e o mapeamento das rotas antigas. Crie uma conta gratuita para gerar seu token e comecar a consumir.

Documentação da API GTIN

Contrato de integração

Endereco base: https://gtin.rscsistemas.com.br. Todas as respostas JSON usam Content-Type: application/json, exceto os endpoints de imagem. O token deve ser enviado em Authorization: Bearer SEU_TOKEN. As versoes V3 e V4 coexistem por design: V3 e um schema simples e estavel, V4 e o schema rico (fabricante, NCM/CEST, imagens em 3 tamanhos) e a fonte de verdade efetiva hoje - use V4 para integracoes novas e V3 quando so precisar dos campos basicos.

Formato GTIN

Use apenas numeros. A GS1 trabalha com estruturas GTIN-8, GTIN-12, GTIN-13 e GTIN-14.

Autenticação

Gere o token com Basic Auth (V3 ou V4, e o mesmo mecanismo) e reaproveite o Bearer token nas chamadas protegidas.

Permissão

Consulta e imagem exigem token valido. Escrita (cadastro, atualizacao, automacao) tambem exige permissao de alteracao na conta.

Termos e uso dos dados

O uso da API e dos dados segue os Termos de Uso e Licença de Dados e a Política de Privacidade. As versões vigentes vêm no cabeçalho X-Termos-Versao de toda resposta da API. Em resumo, em todos os planos, inclusive o gratuito:

  • Em todos os planos, inclusive o gratuito: consultar os dados pela API (dentro dos limites do plano), armazená-los de forma temporária ou permanente, usá-los nas suas aplicações, exibi-los aos seus usuários e clientes, combiná-los com outras fontes e usá-los comercialmente.
  • Não é permitido revender, alugar, sublicenciar ou repassar os dados a terceiros como produto (base, arquivo, API ou serviço de consulta).
  • No momento não é exigida atribuição; a exigência futura terá aviso prévio de 30 dias.
  • Classificação fiscal (NCM/CEST) é referência e não substitui a classificação do contribuinte.

Este resumo não substitui os documentos.

O resumo não substitui os documentos. O aceite é feito no cadastro ou no próximo acesso à área do cliente.

Autenticação e erros comuns

Valem igualmente para V3 e V4 - o mecanismo de token e de validacao de permissao e compartilhado entre as duas versoes.

Status Quando ocorre Exemplo
400Cabecalho Basic ausente ou JSON invalido.{"mensagem":"Cabecalho de autorizacao invalido"}
400GTIN invalido na consulta: fora do formato (somente digitos, com 8, 12, 13 ou 14 posicoes) ou com digito verificador que nao confere e sem cadastro na base. O campo motivo traz formato ou digito_verificador, e o campo ajuda o link da pagina GTIN valido (regra, calculo do digito e verificador de codigos).{"mensagem":"GTIN invalido: digito verificador nao confere.","motivo":"digito_verificador","ajuda":"https://gtin.rscsistemas.com.br/gtin-valido"}
401Token ausente, invalido ou credenciais incorretas.{"mensagem":"Token nao fornecido"}
403Limite do plano atingido.{"mensagem":"..."}
403Versao da API nao liberada no seu plano: cada plano libera a consulta pela V3, pela V4 ou pelas duas. O token e o mesmo nas duas versoes; o que o plano define e qual delas pode ser consultada. Pedir o token em /api/v4/oauth/token sem a V4 no plano tambem responde 403 - use /api/v3/oauth/token.{"erro":"Seu plano não permite acesso à API V4. Entre em contato para revisar seu plano."}
403Termos de Uso e Politica de Privacidade nao aceitos, depois do prazo avisado por e-mail: o pedido e a renovacao do token respondem com o motivo termos_pendentes e o link da area do cliente, onde o aceite aparece ao entrar. Depois do aceite, o token volta a ser emitido na hora.{"mensagem":"Aceite os Termos de Uso e a Politica de Privacidade...","motivo":"termos_pendentes","aceite_url":"https://gtin.rscsistemas.com.br/login"}
404GTIN nao encontrado na base.{"mensagem":"Produto nao encontrado"}
404GTIN valido que nao identifica um produto global e nao tem cadastro: circulacao restrita (codigos internos de loja e de peso/preco variavel, prefixo 200 a 299, UPC iniciado em 2 ou 4, GTIN-8 iniciado em 0 ou 2), cupons e comprovantes, ou publicacao periodica (ISSN, prefixo 977). Nao e pesquisado nem entra na fila de cadastro. O campo motivo traz circulacao_restrita, cupom ou issn, e o campo ajuda o link da pagina GTIN valido.{"mensagem":"Codigo de circulacao restrita ...","motivo":"circulacao_restrita","ajuda":"https://gtin.rscsistemas.com.br/gtin-valido"}
429Consultas suspensas por envio repetido de GTIN invalido: 10 GTINs invalidos (formato ou digito verificador) em 20 minutos suspendem a consulta de produtos e imagens por 1 hora; novas ocorrencias em 7 dias suspendem por 6 horas e depois por 24 horas. Token e gravacao continuam funcionando. Responde com o header Retry-After e os campos motivo (suspenso_gtin_invalido), liberado_em, retry_after (segundos) gtins_recusados e ajuda. Valide o GTIN (formato e digito verificador GS1) antes de consultar: veja a pagina GTIN valido.{"mensagem":"Consultas suspensas ate ...","motivo":"suspenso_gtin_invalido","nivel":1,"retry_after":3540,"ajuda":"https://gtin.rscsistemas.com.br/gtin-valido"}
500Erro interno de banco, email, arquivo ou configuracao.{"mensagem":"Erro ao buscar detalhes do produto"}

Erro 406 Not Acceptable (firewall da hospedagem)

O firewall do servidor (ModSecurity) recusa algumas requisicoes antes de elas chegarem a API. A resposta e uma pagina HTML com "Not Acceptable! ... generated by Mod_Security", sem JSON, e a chamada nao aparece no historico da sua conta. Acontece em dois casos:

  • POST sem o cabecalho Content-Length - por exemplo o pedido de token, que nao tem corpo. Envie Content-Length: 0 (ou um corpo vazio, que faz a biblioteca mandar o cabecalho). Vale para qualquer POST; GET, PUT e DELETE nao sao afetados.
  • User-Agent padrao de algumas bibliotecas: o do Delphi/Indy (Mozilla/3.0 (compatible; Indy Library)) e recusado em POST; python-requests, Python-urllib e Go-http-client sao recusados em qualquer chamada. Defina um User-Agent proprio, como NomeDoSeuSistema/1.0. Acrescentar texto ao User-Agent do Indy nao basta: troque-o inteiro.
var
  Corpo: TStringStream;
  Resposta: string;
begin
  // O User-Agent padrao do Indy e recusado em POST: troque-o inteiro.
  IdHTTP1.Request.UserAgent := 'NomeDoSeuSistema/1.0';
  IdHTTP1.Request.Accept := 'application/json';
  IdHTTP1.Request.BasicAuthentication := True;
  IdHTTP1.Request.Username := 'seu_usuario';
  IdHTTP1.Request.Password := 'sua_senha';
  Corpo := TStringStream.Create(''); // corpo vazio: o Indy envia Content-Length: 0
  try
    Resposta := IdHTTP1.Post('https://gtin.rscsistemas.com.br/api/v3/oauth/token', Corpo);
  finally
    Corpo.Free;
  end;
end;
import requests

# requests ja envia Content-Length: 0 no POST sem corpo; falta so o User-Agent
response = requests.post(
    'https://gtin.rscsistemas.com.br/api/v3/oauth/token',
    auth=('seu_usuario', 'sua_senha'),
    headers={'Accept': 'application/json', 'User-Agent': 'NomeDoSeuSistema/1.0'}
)
req, _ := http.NewRequest(http.MethodPost, "https://gtin.rscsistemas.com.br/api/v3/oauth/token", http.NoBody)
req.SetBasicAuth("seu_usuario", "sua_senha")
req.Header.Set("Accept", "application/json")
req.Header.Set("User-Agent", "NomeDoSeuSistema/1.0") // o padrao Go-http-client e recusado
resp, err := http.DefaultClient.Do(req)
# curl -X POST sem corpo nao envia Content-Length: informe-o
curl -X POST "https://gtin.rscsistemas.com.br/api/v3/oauth/token" \
  -H "Content-Length: 0" \
  -H "Authorization: Basic BASE64_USUARIO_SENHA" \
  -H "Accept: application/json"
<?php
// CURLOPT_POST sem CURLOPT_POSTFIELDS nao envia Content-Length
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '');

Funcionam sem ajuste, entre outros: navegadores e fetch, Node, axios, PHP Guzzle, Java, okhttp, .NET (HttpClient, RestSharp), PowerShell, Postman, python-httpx e o TNetHTTPClient do Delphi.

Autenticação

POST /api/v3/oauth/token

Gerar token de acesso (V3)

Autentica usuario e senha via Basic Auth e retorna um JWT para uso nas demais chamadas V3.

200 OK
Autorização

Authorization: Basic base64(username:senha)

curl -X POST "https://gtin.rscsistemas.com.br/api/v3/oauth/token" \
  -H "Content-Length: 0" \
  -H "Authorization: Basic BASE64_USUARIO_SENHA" \
  -H "Accept: application/json"
const credentials = btoa('seu_usuario:sua_senha');

const response = await fetch('https://gtin.rscsistemas.com.br/api/v3/oauth/token', {
  method: 'POST',
  headers: {
    Authorization: `Basic ${credentials}`,
    Accept: 'application/json'
  }
});

const data = await response.json();
console.log(data.token);
<?php
$credentials = base64_encode('seu_usuario:sua_senha');

$ch = curl_init('https://gtin.rscsistemas.com.br/api/v3/oauth/token');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => '', // POST sem corpo precisa de Content-Length (erro 406)
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Basic ' . $credentials,
        'Accept: application/json',
    ],
]);

$response = curl_exec($ch);
echo $response;
import requests

# User-Agent proprio: o padrao python-requests e recusado pela hospedagem (erro 406)

response = requests.post(
    'https://gtin.rscsistemas.com.br/api/v3/oauth/token',
    auth=('seu_usuario', 'sua_senha'),
    headers={'Accept': 'application/json', 'User-Agent': 'SeuSistema/1.0'}
)

print(response.json()['token'])
Resposta esperada
{"token":"ACCESS_TOKEN","access_token":"ACCESS_TOKEN","token_type":"Bearer","expires_in":3600,"expires_at":"ISO_8601_UTC","refresh_token":"REFRESH_TOKEN","refresh_expires_in":604800,"refresh_expires_at":"ISO_8601_UTC"}
POST /api/v4/oauth/token

Gerar token de acesso (V4)

Mesmo mecanismo do token V3 (Basic Auth com usuario e senha da conta). O JWT retornado vale para as chamadas V3 e V4 - a versao da API e definida pelo prefixo da URL, nao pelo token.

200 OK
Autorização

Authorization: Basic base64(username:senha)

curl -X POST "https://gtin.rscsistemas.com.br/api/v4/oauth/token" \
  -H "Content-Length: 0" \
  -H "Authorization: Basic BASE64_USUARIO_SENHA" \
  -H "Accept: application/json"
const credentials = btoa('seu_usuario:sua_senha');

const response = await fetch('https://gtin.rscsistemas.com.br/api/v4/oauth/token', {
  method: 'POST',
  headers: {
    Authorization: `Basic ${credentials}`,
    Accept: 'application/json'
  }
});

const data = await response.json();
console.log(data.token);
<?php
$credentials = base64_encode('seu_usuario:sua_senha');

$ch = curl_init('https://gtin.rscsistemas.com.br/api/v4/oauth/token');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => '', // POST sem corpo precisa de Content-Length (erro 406)
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Basic ' . $credentials,
        'Accept: application/json',
    ],
]);

echo curl_exec($ch);
import requests

# User-Agent proprio: o padrao python-requests e recusado pela hospedagem (erro 406)

response = requests.post(
    'https://gtin.rscsistemas.com.br/api/v4/oauth/token',
    auth=('seu_usuario', 'sua_senha'),
    headers={'Accept': 'application/json', 'User-Agent': 'SeuSistema/1.0'}
)

print(response.json()['token'])
Resposta esperada
{"token":"ACCESS_TOKEN","access_token":"ACCESS_TOKEN","token_type":"Bearer","expires_in":3600,"expires_at":"ISO_8601_UTC","refresh_token":"REFRESH_TOKEN","refresh_expires_in":604800,"refresh_expires_at":"ISO_8601_UTC"}
POST /api/auth/refresh

Renovar token de acesso

Envie o refresh_token recebido no login. A resposta traz novo token/access_token, expires_in, expires_at e novo refresh_token. Substitua ambos e serialize renovacoes. Reutilizar refresh consumido revoga a sessao; nesse caso faca novo login. Refresh nao altera planos/cotas. Aliases: /api/v3/refresh e /api/v4/refresh.

200 OK
Autorização

JSON com refresh_token; nao precisa de access token valido

curl -X POST "https://gtin.rscsistemas.com.br/api/auth/refresh" -H "Content-Type: application/json" -d '{"refresh_token":"SEU_REFRESH_TOKEN"}'
Resposta esperada
{"token":"NOVO_ACCESS_TOKEN","access_token":"NOVO_ACCESS_TOKEN","token_type":"Bearer","expires_in":3600,"expires_at":"ISO_8601_UTC","refresh_token":"NOVO_REFRESH_TOKEN","refresh_expires_in":604800,"refresh_expires_at":"ISO_8601_UTC"}
POST /api/auth/logout

Encerrar sessao da API

Revoga a familia de access/refresh tokens. Envie o refresh_token no JSON, mesmo se o access expirou.

200 OK
Autorização

JSON com refresh_token

curl -X POST "https://gtin.rscsistemas.com.br/api/auth/logout" -H "Content-Type: application/json" -d '{"refresh_token":"SEU_REFRESH_TOKEN"}'
Resposta esperada
{"mensagem":"Sessao encerrada."}

Produtos V3

Schema flat: principais campos retornados nas consultas de produto.

CampoTipoUso
eanstring numericaGTIN/EAN do produto. Obrigatorio para criar.
ean_tipostringTipo do codigo, por exemplo GTIN-13.
ceststringCEST do produto (Codigo Especificador da Substituicao Tributaria), quando aplicavel. A plataforma informa so a classificacao do produto (NCM/CEST); aliquotas, CFOP, CST e demais regras tributarias nao sao guardadas nem retornadas.
ncmstringNomenclatura Comum do Mercosul, com 8 digitos e sem pontos (formato da NF-e), ex.: 22021000. Vazio quando o produto nao tem NCM.
nomestringNome normalizado do produto.
nome_acentostringNome com acentuacao para exibicao.
unid_abrstringUnidade abreviada, por exemplo UN, CX, KG.
unid_descstringDescricao da unidade.
marcastringMarca comercial.
paisstringPais associado ao cadastro.
categoriastringCategoria interna do produto.
GET /api/v3/gtin/{ean}

Consultar produto

Consulta o cadastro do produto pelo GTIN/EAN. Quando nao encontrado, o GTIN e registrado para triagem.

200 OK
Autorização

Authorization: Bearer SEU_TOKEN

curl -X GET "https://gtin.rscsistemas.com.br/api/v3/gtin/7896116900029" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Accept: application/json"
const response = await fetch('https://gtin.rscsistemas.com.br/api/v3/gtin/7896116900029', {
  headers: {
    Authorization: 'Bearer SEU_TOKEN',
    Accept: 'application/json'
  }
});

console.log(await response.json());
<?php
$ch = curl_init('https://gtin.rscsistemas.com.br/api/v3/gtin/7896116900029');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer SEU_TOKEN',
        'Accept: application/json',
    ],
]);

echo curl_exec($ch);
import requests

# User-Agent proprio: o padrao python-requests e recusado pela hospedagem (erro 406)

response = requests.get(
    'https://gtin.rscsistemas.com.br/api/v3/gtin/7896116900029',
    headers={
        'Authorization': 'Bearer SEU_TOKEN',
        'Accept': 'application/json',
        'User-Agent': 'SeuSistema/1.0'
    }
)

print(response.json())
Resposta esperada
{
  "ean": "7896116900029",
  "ean_tipo": "GTIN-13",
  "nome": "Produto exemplo",
  "marca": "Marca exemplo",
  "categoria": "Bebidas",
  "link_foto": "https://gtin.rscsistemas.com.br/api/v3/gtin/7896116900029/image"
}
GET /api/v3/gtin/{ean}/image

Baixar imagem do produto

Retorna a imagem PNG cadastrada. Se a imagem especifica nao existir, a API pode retornar a imagem padrao de produto sem foto.

200 OK com image/png
Autorização

Authorization: Bearer SEU_TOKEN

curl -L "https://gtin.rscsistemas.com.br/api/v3/gtin/7896116900029/image" \
  -H "Authorization: Bearer SEU_TOKEN" \
  --output "7896116900029.png"
const response = await fetch('https://gtin.rscsistemas.com.br/api/v3/gtin/7896116900029/image', {
  headers: { Authorization: 'Bearer SEU_TOKEN' }
});

const blob = await response.blob();
const imageUrl = URL.createObjectURL(blob);
document.querySelector('img').src = imageUrl;
<?php
$ch = curl_init('https://gtin.rscsistemas.com.br/api/v3/gtin/7896116900029/image');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer SEU_TOKEN'],
]);

file_put_contents('7896116900029.png', curl_exec($ch));
import requests

# User-Agent proprio: o padrao python-requests e recusado pela hospedagem (erro 406)

response = requests.get(
    'https://gtin.rscsistemas.com.br/api/v3/gtin/7896116900029/image',
    headers={'Authorization': 'Bearer SEU_TOKEN', 'User-Agent': 'SeuSistema/1.0'}
)

open('7896116900029.png', 'wb').write(response.content)
Resposta esperada
Corpo binario da imagem.

Produtos V4

Schema aninhado, mais rico que a V3. Os grupos de campos abaixo aparecem dentro de produto na resposta:

GrupoContem
fabricantenome e CNPJ do fabricante.
conteudoquantidade, unidade e quantidade de unidades por embalagem.
embalagemtipo e material da embalagem.
unidade_comercialcodigo, descricao e fator de conversao da unidade de venda.
classificacao_fiscalNCM, descricao do NCM e CEST.
atributos_adicionaisatributos livres especificos do produto, incluindo URLs de imagem na importacao.
imagenslista de imagens com principal, ordem e tamanhos (100/250/500px).
validacao_gtin / qualidade_dadosmetadados no nivel raiz (fora de produto) sobre o check-digit do GTIN e a confianca dos dados.
GET /api/v4/gtin/{ean}

Consultar produto detalhado

Consulta o cadastro rico do produto: fabricante, classificacao fiscal (NCM/CEST), conteudo/embalagem, atributos adicionais e imagens em 3 tamanhos. Quando nao encontrado, o GTIN e registrado para triagem, igual a V3.

200 OK
Autorização

Authorization: Bearer SEU_TOKEN

curl -X GET "https://gtin.rscsistemas.com.br/api/v4/gtin/7896116900029" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Accept: application/json"
const response = await fetch('https://gtin.rscsistemas.com.br/api/v4/gtin/7896116900029', {
  headers: {
    Authorization: 'Bearer SEU_TOKEN',
    Accept: 'application/json'
  }
});

console.log(await response.json());
<?php
$ch = curl_init('https://gtin.rscsistemas.com.br/api/v4/gtin/7896116900029');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer SEU_TOKEN',
        'Accept: application/json',
    ],
]);

echo curl_exec($ch);
import requests

# User-Agent proprio: o padrao python-requests e recusado pela hospedagem (erro 406)

response = requests.get(
    'https://gtin.rscsistemas.com.br/api/v4/gtin/7896116900029',
    headers={
        'Authorization': 'Bearer SEU_TOKEN',
        'Accept': 'application/json',
        'User-Agent': 'SeuSistema/1.0'
    }
)

print(response.json())
Resposta esperada
{
  "schema_versao": "1.0.0",
  "status": "encontrado",
  "gtin_consultado": "7896116900029",
  "produto": {
    "gtin": "7896116900029",
    "nome": "Produto exemplo 2L",
    "marca": "Marca exemplo",
    "fabricante": { "nome": "Fabricante Exemplo LTDA", "cnpj": "11222333000181" },
    "conteudo": { "quantidade": 2, "unidade": "L", "quantidade_unidades": 1 },
    "classificacao_fiscal": { "ncm": "22021000", "cest": "0300100" },
    "link_foto": "https://gtin.rscsistemas.com.br/api/v4/gtin/7896116900029/image?size=500",
    "imagens": [
      { "principal": true, "ordem": 1, "tamanhos": { "100": "...", "250": "...", "500": "..." } }
    ]
  },
  "validacao_gtin": { "formato": "GTIN-13" },
  "qualidade_dados": { "confianca": "alta" }
}
GET /api/v4/gtin/{ean}/image

Baixar imagem por tamanho

Retorna a imagem principal do produto no tamanho pedido via query string ?size=. Aceita 100, 250 ou 500 (qualquer outro valor cai no padrao 500). Sem imagem cadastrada, pode retornar a imagem padrao de produto sem foto.

200 OK com image/png ou image/jpeg
Autorização

Authorization: Bearer SEU_TOKEN

curl -L "https://gtin.rscsistemas.com.br/api/v4/gtin/7896116900029/image?size=250" \
  -H "Authorization: Bearer SEU_TOKEN" \
  --output "7896116900029-250.jpg"
const response = await fetch('https://gtin.rscsistemas.com.br/api/v4/gtin/7896116900029/image?size=250', {
  headers: { Authorization: 'Bearer SEU_TOKEN' }
});

const blob = await response.blob();
const imageUrl = URL.createObjectURL(blob);
document.querySelector('img').src = imageUrl;
<?php
$ch = curl_init('https://gtin.rscsistemas.com.br/api/v4/gtin/7896116900029/image?size=250');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer SEU_TOKEN'],
]);

file_put_contents('7896116900029-250.jpg', curl_exec($ch));
import requests

# User-Agent proprio: o padrao python-requests e recusado pela hospedagem (erro 406)

response = requests.get(
    'https://gtin.rscsistemas.com.br/api/v4/gtin/7896116900029/image',
    params={'size': 250},
    headers={'Authorization': 'Bearer SEU_TOKEN', 'User-Agent': 'SeuSistema/1.0'}
)

open('7896116900029-250.jpg', 'wb').write(response.content)
Resposta esperada
Corpo binario da imagem no tamanho solicitado.
Esta documentação exibe apenas os endpoints disponíveis para o seu perfil atual. Operações de cadastro, atualização, importação e automação ficam visíveis somente para contas com permissão de gravação.

Referencias oficiais usadas para enriquecer o conteudo: GS1 - GTIN, GS1 - EAN/UPC e GS1 - Check Digit Calculator.