Autenticação na API
Como autenticar chamadas à API da Axuz - sessão, token pessoal axp_, chaves de equipe e tokens de integração - e qual credencial cada rota aceita.
A API da Axuz aceita quatro tipos de credencial. Cada rota declara quais aceita (campo x-axuz-access na referência), e usar a credencial errada resulta em 401 ou 403. Esta página mostra como obter e enviar cada uma e quando escolher qual.
Visão geral
| Credencial | Formato | Quem usa | Situação |
|---|---|---|---|
| Sessão (cookie) | cookie access_token | navegador, após o login | disponível |
| Sessão (bearer) | Authorization: Bearer <JWT> | clientes que já fizeram login | disponível |
| Token pessoal | axp_ + 60 caracteres | scripts e CLIs do próprio usuário | disponível |
| Chave de equipe | axt_ + 60 caracteres | integrações da equipe | emissão pronta, uso em construção |
| Token de integração | axz_bot_ + 48 caracteres | bots externos | emitido na Central de Integrações; rotas de tarefas do workspace ainda não o aceitam |
Hosts: a API principal fica em https://api.axuz.net (staging; produção é axuz.club). O login fica em https://auth-api.axuz.net. Os segredos abaixo aparecem como $AXUZ_TOKEN: guarde-os em variável de ambiente ou em um cofre, nunca no código nem em URL.
Sessão: cookie e bearer
Quem faz login em POST /auth/login (host auth-api) recebe cookies HttpOnly de sessão, entre eles access_token e refresh_token, válidos para os subdomínios da Axuz (SSO). O navegador os reenvia sozinho. O login exige o segundo fator: a resposta de /auth/login abre um desafio de MFA e só depois dele a sessão é plena. Veja postAuthLogin e postAuthRefresh.
O mesmo JWT do cookie access_token também é aceito no header:
curl
curl -sS https://api.axuz.net/me/notes \
-H "Authorization: Bearer $AXUZ_SESSION_JWT"
Node
const res = await fetch('https://api.axuz.net/me/notes', {
headers: { authorization: `Bearer ${process.env.AXUZ_SESSION_JWT}` },
});
console.log(res.status, await res.json());
A ordem de resolução no servidor é: cookie access_token, depois Authorization: Bearer. A sessão expira; renove com POST /auth/refresh em vez de guardar a senha.
O header X-User-ID não autentica: ele só existe como atalho de teste, desligado por padrão e ignorado em produção.
Token pessoal (axp_)
É a forma recomendada para automação própria. Ele pertence a um usuário (sem equipe), carrega escopos e tem limite de requisições próprio.
POST/me/api-tokens
Só uma sessão cria, lista ou revoga tokens pessoais. Um token axp_ nunca consegue gerenciar tokens (nem criar outro), para que um token vazado não se multiplique. Crie pelas configurações da conta ou com a sessão:
curl
curl -sS -X POST https://api.axuz.net/me/api-tokens \
-H "Authorization: Bearer $AXUZ_SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{"name":"backup noturno","scopes":["me:read"],"expires_in_days":90,"rate_limit_per_min":120}'
Node
const res = await fetch('https://api.axuz.net/me/api-tokens', {
method: 'POST',
headers: {
authorization: `Bearer ${process.env.AXUZ_SESSION_JWT}`,
'content-type': 'application/json',
},
body: JSON.stringify({ name: 'backup noturno', scopes: ['me:read'], expires_in_days: 90 }),
});
const created = await res.json(); // created.token só aparece nesta resposta
| Campo | Regra |
|---|---|
name | obrigatório, até 100 caracteres |
scopes | pelo menos um; veja a tabela abaixo |
expires_in_days | opcional, de 1 a 1825 (5 anos); omitido = não expira |
rate_limit_per_min | opcional, de 1 a 1000; padrão 60 |
A resposta é 201 com id, name, prefix (por exemplo axp_AbCd, só para você reconhecer o token na lista), scopes, rate_limit_per_min, expires_at e o campo token, o segredo completo. O segredo aparece uma única vez; no servidor fica só o hash SHA-256. Se perder, revogue e crie outro: não há edição de escopo nem de limite.
Usando o token
curl -sS https://api.axuz.net/me/tasks -H "Authorization: Bearer $AXUZ_TOKEN"
O token só vale em header Authorization: Bearer (nunca em query string, para não vazar em logs e histórico) e só nas rotas /me/* marcadas na referência como “sessão ou PAT”, como /me/notes, /me/tasks, /me/files, /me/time e /me/notifications. Perfil, avatar, LGPD e gestão de tokens ficam só com a sessão.
Escopos
| Escopo | Libera |
|---|---|
me:read | métodos GET, HEAD e OPTIONS nas rotas acima |
me:write | POST, PATCH, PUT e DELETE nas rotas acima |
me:profile | reservado para dados sensíveis do perfil; hoje nenhuma rota por token o usa |
Para ler e escrever, peça os dois escopos: me:write não implica me:read. A criação aceita escopos desconhecidos (compatibilidade futura), mas eles não autorizam nada. Sem o escopo, a resposta é 403 com {"error":"scope required: me:read"}.
Limite de requisições
Cada token tem um balde por minuto. Toda resposta traz X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset (epoch em segundos do próximo minuto). Ao estourar, a resposta é 429 com Retry-After e o corpo {"error":"rate_limited","limit":60,"count":61,"retry_after":23}. Espere o Retry-After antes de repetir. Se o contador (Redis) estiver fora, a API deixa passar em vez de derrubar sua integração; em ambientes configurados como fail-closed, devolve 503 rate_limiter_unavailable.
Expiração e revogação
Token expirado ou revogado responde 401. Revogue com DELETE /me/api-tokens/{tokenID} (204; 404 se não existe ou já foi revogado, sem distinguir os casos). A revogação é publicada para todas as instâncias; se essa publicação falhar, um token revogado pode continuar válido por até 30 segundos em outra instância. A listagem (GET /me/api-tokens) mostra last_used_at, que pode atrasar até 30 segundos.
Chaves de equipe (axt_)
POST/teams/{teamId}/api-keys
Uma chave de equipe pertence à equipe, não a uma pessoa. Quem tem a permissão team:api_keys:manage (administradores) cria, lista, edita (nome, escopos, expiração) e revoga em /teams/{teamId}/api-keys, sempre com sessão. O corpo de criação é o mesmo do token pessoal, com limite padrão de 120 por minuto. O segredo (axt_ e 60 caracteres) também aparece uma só vez. Os escopos vêm do catálogo público em GET /v1/scopes: forms:read, forms:write, forms:submissions:read, tasks:read, tasks:write, files:read, files:write, webhooks:manage, mail:send, me:read, me:write, me:profile (comparação exata, sem curinga).
Token de integração (axz_bot_)
Os bots externos (Telegram, Discord, Slack e similares) usarão um token axz_bot_ mais 48 caracteres, emitido na Central de Integrações da equipe (/teams/{teamId}/integrations). Pelo contrato, ele alcança só GET /v1/integration/self e as rotas de tarefas, quadros e comentários do mapa de integração; qualquer outra rota responde 403 antes do handler. Os escopos de integração são tasks:read, tasks:write, boards:read, boards:write, comments:write e integrations:read, e nunca incluem exclusão. A emissão já está no ar na homologação; para o estado do uso nas rotas, veja a página de bots e a referência de integrações.
Qual rota aceita qual credencial
A referência mostra em cada operação o campo x-axuz-access (classe) e o detalhe da guarda. Resumo dos detalhes mais comuns:
| Guarda (detalhe) | Aceita |
|---|---|
public | nenhuma credencial |
sessão JWT (authenticated) | cookie ou bearer de sessão |
sessão ou PAT | sessão ou token pessoal axp_ (com escopo me:read / me:write) |
sessão JWT; membership do {teamId} (team-member) | sessão de quem é membro da equipe |
membership do {teamId}; ... admin (team-admin) | sessão de administrador da equipe |
membership do {teamId}; rbac <permissão> (permission) | sessão de membro com a permissão RBAC citada |
sessão JWT; platform_roles (platform-admin) | sessão de operador da plataforma |
bearer OAuth | access token de um app OAuth (/oauth/userinfo) |
api-key do team | chave de API de e-mail (/v1/send, /v1/usage) do serviço de e-mail |
public-signed | assinatura HMAC ou URL com token no caminho (webhooks de entrada) |
internal | chave entre serviços; não é para integradores |
Os escopos de um token nunca ampliam o que a pessoa já pode: o teto é sempre a permissão dela (RBAC e participação em canal ou projeto).
Erros
| Status | Quando | Corpo típico |
|---|---|---|
401 | credencial ausente, malformada, expirada ou revogada | {"error":"unauthorized"} |
403 | credencial válida sem o escopo, sem permissão na equipe ou sessão restrita | {"error":"scope required: me:write"} ou {"error":"enrollment_required",...} |
404 | recurso de outro usuário (a API não confirma que existe) | {"error":"token not found"} |
429 | limite do token estourado | {"error":"rate_limited",...} com Retry-After |
O que não fazer
- Colocar o token em URL, em código-fonte, em log ou em bundle de front-end: segredo só no servidor.
- Usar um token
axp_para outra pessoa: ele age como o dono. Para agir em nome de terceiros, use Login com Axuz. - Tentar enviar
X-User-IDou ouser_idno corpo para “escolher” a identidade: o servidor ignora e identifica o usuário pela credencial verificada. - Repetir sem pausa após
429: respeiteRetry-After.