Autenticação
Você recebe duas credenciais. Uma identifica sua conta e viaja em toda requisição; a outra nunca sai do seu servidor e serve para derivar uma assinatura HMAC-SHA256, que você envia como prova de posse.
Se você ainda não gerou as credenciais, comece por Introdução e Primeiros Passos — lá o passo a passo vai do painel até o primeiro 200 em sandbox.
As duas credenciais
| Credencial | O que é | Onde aparece |
|---|---|---|
ACCESS_TOKEN | Identificador de acesso | No header Authorization, em texto aberto |
SECRET_KEY | Chave usada para calcular a assinatura | Em lugar nenhum da requisição — só no cálculo |
Ambas são geradas no painel, em Configurações → Usuários, na edição do seu próprio usuário.
Headers obrigatórios
Toda requisição à API deve incluir estes três headers:
| Header | Valor | O que faz |
|---|---|---|
Authorization | Basic {ACCESS_TOKEN} | Identifica quem está chamando |
Key | {HMAC_SIGNATURE} | Prova que quem chama tem a chave secreta |
cache-control | no-cache | Impede que um proxy no caminho devolva resposta em cache sem chegar na API |
Authorization: Basic {ACCESS_TOKEN}
Key: {HMAC_SIGNATURE}
cache-control: no-cache
Como calcular a assinatura
A assinatura é um hash HMAC-SHA256 do ACCESS_TOKEN usando a SECRET_KEY como chave:
HMAC_SIGNATURE = HMAC-SHA256(ACCESS_TOKEN, SECRET_KEY)
Ou seja: a chave do HMAC é a SECRET_KEY e a mensagem é o ACCESS_TOKEN. Inverter os dois é o erro nº 1 da integração, e o sintoma é um fbk_001 constante.
O resultado deve ser uma string hexadecimal. Não use base64 ou qualquer outra codificação — a API espera e valida o hash em hexadecimal (hex digest).
Ela prova que você possui a SECRET_KEY. Ela não assina o conteúdo da requisição — corpo, URL e horário não entram no cálculo. Por isso o valor é constante enquanto o par de credenciais existir: na prática é uma segunda credencial derivada, e merece o mesmo cuidado de armazenamento que a primeira.
Do lado prático, isso significa que você calcula a assinatura uma vez e reutiliza em todas as chamadas — não precisa recalcular a cada requisição.
Exemplos de código
- Node.js
- PHP
- Python
- cURL
const crypto = require('crypto');
function calcularHmac(accessToken, secretKey) {
// chave = SECRET · mensagem = TOKEN · saída = hex
return crypto
.createHmac('sha256', secretKey)
.update(accessToken)
.digest('hex');
}
const accessToken = process.env.FROTA_ACCESS_TOKEN;
const secretKey = process.env.FROTA_SECRET_KEY;
const hmacKey = calcularHmac(accessToken, secretKey);
const headers = {
Authorization: `Basic ${accessToken}`,
Key: hmacKey,
'cache-control': 'no-cache',
};
$accessToken = getenv('FROTA_ACCESS_TOKEN');
$secretKey = getenv('FROTA_SECRET_KEY');
// ordem: algoritmo, mensagem, chave · saída = hex por padrão
$hmacKey = hash_hmac('sha256', $accessToken, $secretKey);
$headers = [
'Authorization: Basic ' . $accessToken,
'Key: ' . $hmacKey,
'cache-control: no-cache',
];
import hmac
import hashlib
import os
access_token = os.environ['FROTA_ACCESS_TOKEN']
secret_key = os.environ['FROTA_SECRET_KEY'].encode()
# ordem: chave, mensagem, algoritmo · saída = hex
hmac_key = hmac.new(secret_key, access_token.encode(), hashlib.sha256).hexdigest()
headers = {
'Authorization': f'Basic {access_token}',
'Key': hmac_key,
'cache-control': 'no-cache',
}
ACCESS_TOKEN="meu_token_aqui"
SECRET_KEY="minha_chave_secreta"
# Calcular assinatura — chave = SECRET · mensagem = TOKEN · saída = hex
HMAC_KEY=$(printf '%s' "$ACCESS_TOKEN" \
| openssl dgst -sha256 -hmac "$SECRET_KEY" \
| awk '{print $2}')
# Fazer a chamada
curl -X GET \
'https://apidev.v1.frota162.com.br/key/list-cars?pagination[page]=1&pagination[perpage]=10' \
-H "Authorization: Basic $ACCESS_TOKEN" \
-H "Key: $HMAC_KEY" \
-H 'cache-control: no-cache'
Use printf, não echo -n. O -n não é portável entre shells e, onde não funciona, o newline entra no cálculo e a assinatura sai errada sem nenhum aviso.
Erros de autenticação
API v1 (formato fbk_xxx)
| Código | Mensagem | O que aconteceu |
|---|---|---|
fbk_001 | Não autorizado | Token não encontrado, inválido ou assinatura HMAC incorreta |
fbk_002 | Sem permissão | A conta não tem permissão para acessar a empresa |
{
"message": "Não autorizado",
"error": true,
"code": "fbk_001"
}
O fbk_001 não distingue a causa — todos os casos abaixo devolvem exatamente essa resposta:
| Sintoma | Causa provável | Como resolver |
|---|---|---|
fbk_001 constante | Chave e mensagem invertidas no HMAC | A chave é a SECRET_KEY, a mensagem é o ACCESS_TOKEN |
fbk_001 constante | Assinatura em base64 | A API só aceita hexadecimal (digest('hex')) |
fbk_001 constante | Algoritmo errado | Precisa ser sha256 — não sha1, não md5 |
fbk_001 constante | Credencial de outro ambiente | Chave de produção em sandbox devolve fbk_001 |
fbk_001 intermitente | Newline ou espaço no valor lido do ambiente | Aplique trim() no token e na chave |
fbk_002 | Conta sem permissão para a empresa | Não é problema de assinatura. Fale com o suporte |
API v2 (formato RFC 7807)
A API v2 usa o mesmo mecanismo HMAC, mas retorna erros em um formato padronizado (RFC 7807):
type | Status | O que aconteceu |
|---|---|---|
urn:frota162-api-v2:error:unauthorized | 401 | Header Authorization ou Key ausente, ou esquema inválido |
urn:frota162-api-v2:error:authentication-failed | 401 | Assinatura HMAC incorreta ou token não reconhecido |
{
"type": "urn:frota162-api-v2:error:authentication-failed",
"title": "Authentication Failed",
"status": 401,
"detail": "Invalid Key header",
"instance": "/v2/driver-indications",
"traceId": "abc123"
}
Para a lista completa de códigos, consulte Tratamento de Erros.
Segurança
- Guarde
ACCESS_TOKENeSECRET_KEYem variável de ambiente ou gerenciador de segredos — nunca no código-fonte - Todas as chamadas via HTTPS (os endpoints da API já exigem)
- A
SECRET_KEYnunca deve chegar ao navegador do usuário nem aparecer em log de requisição - Em caso de comprometimento, gere novas credenciais imediatamente no painel
Lidar com rate limiting
Se a API retornar status 429 (muitas requisições), espere o tempo indicado no header Retry-After antes de tentar novamente:
async function fetchWithRetry(url: string): Promise<Response> {
const response = await fetch(url, {
headers: {
Authorization: `Basic ${credentials}`,
Key: hmacSignature,
},
});
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
console.log(`Rate limited. Aguardando ${retryAfter}s...`);
await sleep(retryAfter * 1000);
return fetchWithRetry(url);
}
return response;
}
Login automático (POST /key/generator)
Esta rota não gera credenciais de API. Ela cria um token de sessão temporário que permite autenticar um usuário no sistema Frota162 sem que ele precise digitar email e senha.
Cenários de uso:
- Iframe — embutir o sistema Frota162 dentro de outro sistema
- SSO simplificado — redirecionar o usuário para o Frota162 já autenticado após login no sistema do cliente
- Deep link autenticado — abrir uma tela específica do Frota162 sem exigir novo login
Como funciona:
- Seu backend faz um
POST /key/generatorcom as credenciais HMAC normais - A API retorna um token de sessão temporário (
accessKey) - Você redireciona o usuário (ou carrega o iframe) usando a URL:
https://app.frota162.com.br/login?accessKey={TOKEN_GERADO} - O Frota162 autentica o usuário automaticamente
Requisição:
curl -X POST \
https://apidev.v1.frota162.com.br/key/generator \
-H 'Authorization: Basic {ACCESS_TOKEN}' \
-H 'Key: {HMAC_SIGNATURE}' \
-H 'Content-Type: application/json' \
-d '{"email": "usuario@empresa.com", "password": "senha_do_usuario"}'
Resposta:
{
"accessKey": "7a12ad20-136f-4c06-9f40-532a6e952127",
"error": false,
"code": "fbk_200"
}
O accessKey retornado é de uso único e expira após o login. Não confunda com o ACCESS_TOKEN usado para autenticar chamadas da API.
Próximos passos
O passo a passo do painel até o primeiro 200 em sandbox, com ambientes e URLs.
Os formatos de erro da API v1 (fbk_xxx) e v2 (RFC 7807) e como tratá-los no seu código.
Endpoints por módulo, com exemplos de payload.
Respostas para as dúvidas mais comuns sobre integração com a API Frota162.