Usando o token
Toda chamada leva o token no cabeçalho Authorization. Não há login, sessão nem renovação automática.
O cabeçalho
Authorization: Bearer otl_prod_SEU_TOKEN
curl "https://api.otlshoes.com.br/v1/eu" \
-H "Authorization: Bearer otl_prod_SEU_TOKEN"curl "https://api-sandbox.otlshoes.com.br/v1/eu" \
-H "Authorization: Bearer otl_sbx_SEU_TOKEN"const resposta = await fetch('https://api.otlshoes.com.br/v1/eu', {
headers: {
Authorization: 'Bearer otl_prod_SEU_TOKEN',
},
});
if (!resposta.ok) {
const { erro } = await resposta.json();
throw new Error(`${erro.codigo}: ${erro.mensagem} (${erro.requestId})`);
}
const dados = await resposta.json();const resposta = await fetch('https://api-sandbox.otlshoes.com.br/v1/eu', {
headers: {
Authorization: 'Bearer otl_sbx_SEU_TOKEN',
},
});
if (!resposta.ok) {
const { erro } = await resposta.json();
throw new Error(`${erro.codigo}: ${erro.mensagem} (${erro.requestId})`);
}
const dados = await resposta.json();<?php
$ch = curl_init('https://api.otlshoes.com.br/v1/eu');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer otl_prod_SEU_TOKEN',
]);
$corpo = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new Exception($corpo['erro']['codigo'] . ': ' . $corpo['erro']['mensagem']);
}<?php
$ch = curl_init('https://api-sandbox.otlshoes.com.br/v1/eu');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer otl_sbx_SEU_TOKEN',
]);
$corpo = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new Exception($corpo['erro']['codigo'] . ': ' . $corpo['erro']['mensagem']);
}import requests
resposta = requests.get(
"https://api.otlshoes.com.br/v1/eu",
headers={
"Authorization": "Bearer otl_prod_SEU_TOKEN",
},
timeout=30,
)
if not resposta.ok:
erro = resposta.json()["erro"]
raise RuntimeError(f'{erro["codigo"]}: {erro["mensagem"]} ({erro["requestId"]})')
dados = resposta.json()import requests
resposta = requests.get(
"https://api-sandbox.otlshoes.com.br/v1/eu",
headers={
"Authorization": "Bearer otl_sbx_SEU_TOKEN",
},
timeout=30,
)
if not resposta.ok:
erro = resposta.json()["erro"]
raise RuntimeError(f'{erro["codigo"]}: {erro["mensagem"]} ({erro["requestId"]})')
dados = resposta.json()Testar agora no ambiente de testes
A chamada é feita de verdade, do seu navegador para a API de testes (https://api-sandbox.otlshoes.com.br/v1). Use um token otl_sbx_…: ele fica só nesta aba, e some ao fechá-la. Token de produção não é aceito aqui.
Não existe rota de login nem de “refresh”: o token é criado no painel e usado como está até vencer ou ser revogado.
Erros de autenticação
| HTTP | codigo |
O que significa | O que fazer |
|---|---|---|---|
| 401 | TOKEN_INVALIDO |
Token ausente, digitado errado ou revogado | Confira o cabeçalho. Se estava funcionando e parou, o parceiro revogou ou gerou outro |
| 401 | TOKEN_EXPIRADO |
A validade acabou | O parceiro gera um novo token na mesma integração |
| 401 | TOKEN_DE_OUTRO_AMBIENTE |
Token de sandbox na URL de produção, ou o contrário | Troque a URL base ou o token |
| 401 | CONTA_DESATIVADA |
A conta do parceiro foi desativada | O parceiro fala com a OTL |
| 403 | API_NAO_LIBERADA |
A OTL suspendeu (ou ainda não liberou) a API do parceiro | O parceiro fala com a OTL. Os tokens voltam a funcionar sem troca |
| 403 | TERMS_PENDING |
O parceiro precisa aceitar os Termos de Uso no painel | Só ele resolve, no painel. A API volta na hora |
| 403 | ESCOPO_INSUFICIENTE |
A integração não tem a permissão da rota | Veja escopoNecessario na resposta e peça ao parceiro para incluir |
De propósito: a API não confirma se um token já foi válido algum dia.
Cabeçalhos de resposta úteis
| Cabeçalho | Quando vem | Para que serve |
|---|---|---|
X-Request-Id |
Sempre | Identifica a chamada. Guarde no seu log e informe ao suporte |
X-RateLimit-Limit · -Remaining · -Reset |
Em toda chamada autenticada | Seu limite, quanto resta e quando a janela reinicia |
Retry-After |
Com 429 |
Quantos segundos esperar |
Aviso-Expiracao-Token |
Nos últimos 7 dias do token | A data em que ele vence |
Aviso-Termos-Api |
Quando o parceiro tem uma versão nova dos Termos da API para aceitar | A data em que a integração para se ele não aceitar |
Quando o Aviso-Termos-Api aparecer
A OTL publicou uma versão nova dos Termos de Uso da API, e o parceiro tem um prazo (7 dias, a contar
da publicação) para aceitá-la no painel. Durante o prazo tudo funciona; o cabeçalho traz a data
limite. Passado o prazo sem o aceite, toda chamada responde
403 TERMOS_API_PENDENTES, com prazoEncerradoEm no corpo, e os
webhooks do parceiro ficam pausados.
O aceite é do parceiro, no painel — o seu sistema não tem como fazer por ele. O que ele pode
fazer é avisar: ao ver o cabeçalho, mande um alerta para quem cuida da conta. Depois do aceite a API
volta na chamada seguinte, sem trocar token. O que aconteceu enquanto esteve parada não é reenviado
por webhook: ressincronize com atualizadoDesde.
Tentativas com token inválido são limitadas
Muitas chamadas seguidas com token inválido, a partir do mesmo endereço, bloqueiam aquele endereço
por alguns minutos — inclusive para tokens bons. Se o seu sistema recebeu 401, não fique
repetindo a chamada: o token não vai passar a valer sozinho.
