Guia
Começar
1. O que o FINAUTON entrega ao seu time
| Item | Para quê |
|---|---|
| clientId + clientSecret | credencial do seu backend (o segredo aparece uma vez — guarde em secret manager) |
| tenantId | o contrato onde seus clientes ficam: corretoras, estratégias, limites de risco, preço |
| Origens de retorno | endereços https do seu app para o botão "Voltar ao app" da página hospedada |
| Webhook + segredo | URL https do seu backend que recebe os eventos, e o segredo para validar a assinatura |
| Ambiente | API | Página hospedada |
|---|---|---|
| Produção | https://api.finauton.com/v1 | https://app.finauton.com |
| Homologação | informada pelo FINAUTON com a credencial de QA | idem |
2. Autenticação
Toda chamada leva a credencial do parceiro — somente servidor → servidor. Teste com GET /v1/health: 200 = ok; 401 B2B_CREDENTIAL_INVALID = errada ou revogada.
Authorization: Basic base64(clientId:clientSecret)3. Cliente REST no seu backend
Os exemplos "Node.js" da referência usam esta função. Timeout, sem retry automático em escrita, erro com code e requestId.
// src/lib/finauton.ts — SERVIDOR apenas, nunca no navegador
const BASE = process.env.FIN_API_BASE!; // https://api.finauton.com
const AUTH = 'Basic ' + Buffer.from(
`${process.env.FIN_CLIENT_ID}:${process.env.FIN_CLIENT_SECRET}`
).toString('base64');
export async function fin(method: string, path: string, body?: unknown, idempotencyKey?: string) {
const res = await fetch(BASE + path, {
method,
headers: {
authorization: AUTH,
...(body !== undefined ? { 'content-type': 'application/json' } : {}),
...(idempotencyKey ? { 'idempotency-key': idempotencyKey } : {})
},
body: body !== undefined ? JSON.stringify(body) : undefined,
signal: AbortSignal.timeout(15_000)
});
const data = await res.json().catch(() => null);
if (!res.ok && res.status !== 202) {
// mostre data.error.message ao usuário; trate por data.error.code; logue o requestId
throw Object.assign(new Error(data?.error?.message ?? `HTTP ${res.status}`), {
status: res.status, code: data?.error?.code, requestId: data?.error?.requestId
});
}
return { status: res.status, data };
}4. Autorização: responsabilidade do SEU backend
A credencial alcança todos os seus clientes
A FINAUTON não sabe qual usuário está logado no seu app. Seu backend precisa garantir que cada usuário só acesse o próprioexternalUserId, e que telas de backoffice sejam só da sua equipe.// Toda rota do SEU backend que recebe um externalUserId:
const usuario = await sessaoDoSeuApp(req); // seu login
if (!usuario) return res.status(401).end();
if (!usuario.ehBackoffice && params.externalUserId !== usuario.externalUserId) {
return res.status(403).json({ error: 'NOT_YOUR_ACCOUNT' }); // cliente A nunca vê o cliente B
}
const { data } = await fin('GET', `/v1/users/${params.externalUserId}/status`);5. Identidade do cliente: externalUserId
- É o id que você escolhe (1–120 caracteres) — por exemplo, o id do usuário no seu banco.
- Não use o e-mail nem dado pessoal. A FINAUTON não precisa saber quem é a pessoa.
- Cliente que não é seu responde
404, igual a inexistente.
6. Formato, erros e requestId
JSON UTF-8; valores em USD (até 6 casas; cobranças em 2); datas ISO-8601 UTC. Campos novos podem aparecer — ignore o que não conhece. Todo erro vem no mesmo envelope; a message já vem em português, pronta para a tela. Guarde o requestId nos logs para suporte.
{
"error": {
"code": "RISK_ENVELOPE_EXCEEDED",
"message": "Alavancagem acima do limite do parceiro (50 > 5).",
"requestId": "req_muyn0wrj_s4sspdq0"
}
}7. Idempotency-Key
Escritas que criam ou mudam estado exigem o cabeçalho Idempotency-Key (8–128 caracteres A-Z a-z 0-9 . _ : -). Gere uma chave por ação do usuário e reenvie a mesma se a rede falhar.
| Situação | Resultado |
|---|---|
| mesma chave + mesmo corpo | mesma resposta, sem duplicar |
| mesma chave + corpo diferente | 409 IDEMPOTENCY_CONFLICT |
| sem a chave | 400 IDEMPOTENCY_KEY_REQUIRED |
Exigem a chave: criar cliente, gravar setup, risco, automação, instrução e confirmação de pagamento, ordens manuais. Na referência, esses endpoints têm a etiqueta "Idempotency-Key obrigatório".
8. Limites
Por parceiro (requestsPerMinute, ordersPerMinute) → 429 RATE_LIMITED. Espere a próxima janela de 1 minuto, com backoff. Consumo em GET /v1/usage.
9. Campos que você nunca envia
Receita e escopo são definidos pelo FINAUTON: performanceFeePercent, subscriptionMonthlyUsd, carryPolicy, performancePeriod, builder*, paymentRecipient, principalId, riskEnvelope… Enviados no corpo → 403 SCOPE_FIELD_REJECTED.