Pular para o conteúdo principal

Mapa de Endpoints da API

Catálogo dos endpoints do BFF consumidos pelo template front-web-base (direto ou via packages do core @cactus-agents/*). Para ver qual rota SSR (/api/*) chama cada um, consulte SSR Routes → BFF.

Todos os paths abaixo são relativos ao API_BASE_URL, que é var de Worker por environment (o CI resolve das bindings do Cloudflare e mascara o valor). A base já termina em /v2 — daí os paths começarem em /auth, /bff, etc. O valor de referência do workspace fica em envs/front-web-base.env; o exemplo do template, em .env.example.

:::warning Esta página descreve a trunk main-7k Trunks de marca diferentes consomem conjuntos diferentes de endpoints — features são portadas, não mergeadas. Ver Trunks de marca. :::

Auth

MetodoEndpointObservacao
POST/auth/loginLogin por email/senha (+ 2FA, captcha, icg_token)
POST/auth/logoutInvalida sessao
GET/auth/user-profile[?check_spa_again=1&icg_token=…]Perfil do usuario logado
POST/users/refresh-tokenRefresh JWT
POST/auth/registerRegistro completo (quando documento/telefone sao obrigatorios)
POST/auth/register/simplifiedRegistro simplificado legado
POST/bff/register-simplifiedRegistro single-step por email
POST/bff/social/{provider}Login social (troca token do provider por JWT Cactus)
POST/bff/social/{provider}/registerSimplifiedRegistro social (provider dinamico)
POST/auth/passwords/reset/optionsEsqueci a senha — envia opcoes de recuperacao
POST/auth/passwords/reset/by-emailEnvia codigo por email
POST/auth/passwords/reset/by-smsEnvia codigo por SMS
POST/auth/passwords/reset/validate-codeValida codigo de recuperacao
POST/auth/passwords/reset/confirmConfirma nova senha
POST/documents/validateValida CPF (BR) / CURP (MX); tambem usado no fluxo Didit (CHL)
POST/documents/confirm-birthdateConfirma data de nascimento (fluxo Didit, CHL)
POST/bff/otp/register/sendEnvia OTP de telefone no cadastro
POST/bff/otp/register/resendReenvia o OTP de telefone

O endpoint final de registro e resolvido por resolveRegisterEndpoint() no template em runtime conforme registerTypeVersion da brand + flags requestDocument/requestPhone/socialService.

:::warning Contrato do OTP de cadastro: duas fontes discordam A rota app/routes/api/auth/register.validate-phone.ts chama de fato /bff/otp/register/send e /bff/otp/register/resend — é isso que está na tabela acima. Mas app/modules/register/flow.ts e @cactus-agents/types descrevem o contrato como /bff/register/validate-phone, path pra qual não existe nenhum call site.

Antes de escrever código novo contra esse fluxo, confirme com o time de back-end qual é o contrato real — uma das duas fontes está errada, e de qual lado fica a correção depende dessa resposta. :::

:::note /auth/logout-auto não aparece nesta página O endpoint existe no BFF, mas o caminho de logout forçado está incompleto em três camadas — e o efeito prático não é um 404, é a ausência do sinal:

  1. Core, raiz: AuthService.logoutAuto() existe de verdade e tem teste (packages/accounts/src/auth-service.test.ts), acessível só via o AuthService raiz.
  2. Core, /react: packages/accounts/src/react/auth-http.ts define defaultLogoutAuto() apontando pra /api/auth/logout-auto, mas ela não é exportada pelo barrel /react e não tem nenhum call site — é código morto.
  3. Core, config: AccountsConfig (react/config.ts) expõe só logout?; não existe seam logoutAuto?, então nem um consumidor que quisesse ligar o caminho forçado conseguiria fazê-lo via initAccounts().

No template, app/routes/api/auth/ não tem logout-auto.ts, e deleteJwtCookie() chama POST /api/auth/logout fixo, sem ramificação. Ou seja: nada dispara a rota removida, e nada 404 hoje.

Consequência real: o log de auditoria do BFF não distingue logout forçado de voluntário. Ligar isso exige uma rota proxy no template e um seam novo no core — não é só recriar a rota. Detalhe completo em ../sdk/accounts.md. :::

:::caution Não confie no comentário do código aqui app/components/user/panel/UserPanelLogout.tsx documenta um opt-in via authFeaturesConfig.useAutoLogoutEndpoint. Essa flag não existe em lugar nenhum de app/ ou overrides/ — a única ocorrência é dentro do próprio comentário que a descreve. :::

Brand

MetodoEndpointObservacao
GET/appearanceConfiguracao visual da marca (logo, cores, banners)
GET/bff/featuresFeature flags ativas
POST/bookmaker-settingsConfiguracoes do bookmaker (operador)
GET/getlegaltermTermos legais / contratos da marca

User

MetodoEndpointObservacao
POST/users/update/{id}Atualiza dados do usuario
POST/users/change-password/{id}Troca senha
GET/bff/users/address-by-userEndereco cadastrado
PATCH/bff/users/self-emailAtualiza email
PATCH/bff/users/add-phoneAdiciona telefone
PATCH/bff/users/update-addressAtualiza endereco
PATCH/bff/users/self-contractsAceita contratos/termos
PATCH/bff/users/self-mktOpt-in/out marketing
PATCH/bff/users/update-user-info-metadataPreferencias genericas — campo livre, whitelist no core (ver aviso abaixo)
PATCH/bff/users/update-pending-dataAtualiza dados pendentes pos-login
POST/bff/users/check-passwordVerifica senha atual
PATCH/bff/users/self-two-factorHabilita/desabilita 2FA
GET/bff/users/account-socialLista contas sociais vinculadas
POST/bff/users/account-social/connect/{type}Vincula conta social (google, apple)
DELETE/bff/users/account-social/{id}Remove conta social
GET/bff/users/login-history?page={page}Historico de logins paginado
GET/bff/games/user-last-casino-games-dlUltimos jogos jogados pelo usuario (DL)
GET/bff/users/zendesk/create-or-update-userToken SSO do Zendesk
POST/users/list-referralsLista convidados (refer-a-friend)
POST/apicepLookup de CEP/codigo postal
PATCH/bff/users/update-limitsAtualiza limites de deposito/aposta
PATCH/bff/users/timeout-limitsDefine timeout temporario
PATCH/bff/users/self-exclusionAutoexclusao
POST/income-report/generateGera relatorio IRPF
GET/income-report/{id}Polling do relatorio (intervalo de 3s)
GET/income-report/available-yearsAnos disponiveis para relatorio
POST/documents/verify-identityDispara verificacao de identidade (CHL)

:::danger Endpoints de campo livre: o whitelist mora no CORE Alguns endpoints do BFF aceitam qualquer JSON. O caso canônico é PATCH /bff/users/update-user-info-metadata, que grava o que vier sob a chave preferencies (typo do backend — não corrigir). Como o BFF não valida a forma, o contrato do que pode ser gravado tem que morar em outro lugar — e mora no core:

OndeO quê
ALLOWED_PREFERENCES em @cactus-agents/accountsMapa chave → valores permitidos. Única fonte de verdade.
updateUserPreferences() (mesmo package)Aplica o guard e lança antes da chamada de rede pra chave desconhecida ou valor fora da lista.
app/routes/api/user/update-preferences.ts no baseSó chama createUserFromClient(client).updateUserPreferences(body).

Três consequências práticas:

  1. O base nunca conhece o path do BFF nem a lista de chaves. Nada em app/ menciona update-user-info-metadata. Não substitua a chamada do service por um client.patch() direto — isso contorna o único guard existente e devolve ao BFF a capacidade de gravar qualquer coisa.
  2. Adicionar uma preferência exige bump do core — nova entry em ALLOWED_PREFERENCES + campo em UserPreferences. Não existe caminho pelo base, e não existe feature flag que destrave isso.
  3. Ao adicionar um endpoint de campo livre novo, repita esse padrão: guard tipado no core, base chamando o service. Um endpoint de campo livre sem whitelist no core é bug de arquitetura, não conveniência. :::

Wallet

MetodoEndpointObservacao
GET/users/walletSaldo atual
POST/bff/transactionsHistorico de transacoes (filtros no body)
GET/transactions/cashback?page=...&per_page=10Historico de cashback paginado
GET/bonus/rolloverRollover ativo
GET/bonus/rollover-accomplishedRollover concluido
POST/bonus/transferTransfere saldo de bonus
POST/cashback/transferResgata cashback
GET/withdraw/{id}/generateGera comprovante de saque

/withdraw/{id}/generate é operação de saque — listado aqui por proximidade funcional.

Payments

MetodoEndpointObservacao
GET/payment-providersLista de providers de pagamento disponiveis
POST/wallet/add-creditDeposito
GET/wallet/charge/{transactionId}Status do deposito (polling)
POST/new-withdrawsSolicita saque
GET/bff/users/bank-listLista de bancos
POST/pix-keys/user-keyLe chave PIX cadastrada (BR)
POST/pix-keys/update-user-key-v2Atualiza chave PIX (BR)
GET/mex-bank-accounts/user-accountConta bancaria do usuario (MX)
POST/mex-bank-accounts/storeCadastra conta bancaria (MX)
GET/generic-bank-accounts/user-accountConta bancaria generica do usuario (CHL/NGA)
POST/generic-bank-accounts/storeCadastra conta bancaria generica (CHL/NGA)
GET/coupons/{code}Valida cupom promocional

Games

MetodoEndpointObservacao
GET/casino-games/homeLayout da homepage — rows com jogos por categoria
GET/casino-games/page/{page}Layout de pagina curada pelo BFF (alt. de /home)
GET/casino-games/list/baseCategorias (custom_categories) + providers
GET/casino-games/list/?…Lista paginada: categories[]=slug&providers[]=slug&term=texto&page=1&per_page=24
GET/casino-games?slug={slug}Detalhe de um jogo
GET/casino-games/filterLegacy — mas ainda ativo: e o endpoint que o legacy-service usa em CASSINO_MODE=legacy
GET/start-game-v2?…?slug=&platform=MOBILE|WEB&use_demo=0|1 — autenticado, abre jogo
GET/bff/games/top-wins-dlMaiores ganhos (data-lake)
GET/bff/games/game-top-wins-dl?slug={slug}Maiores ganhos por jogo (data-lake)
GET/bff/games/last-winsUltimos ganhos
GET/bff/games/game-high-payers-dlHigh-payers (data-lake) — alimenta top-games na home
GET/bff/games/statistics?slug={slug}Estatisticas por periodo (5min, 1h, 24h, 7d, 15d, 30d)
GET/bff/games/statistics-dl?slug={slug}Estatisticas data-lake (usadas por /api/games/statistics-dl)
GET/casino-game-votes?casinoGameId={id}Voto do usuario (autenticado)
GET/casino-game-votes/count/{gameId}Contagem de likes/dislikes
POST/casino-game-votes/store/Body: { casinoGameId, is_like } — autenticado
DELETE/casino-game-votes/destroy/{gameId}Remove voto — autenticado
GET/bff/favorite-gamesLista jogos favoritos do usuario
PUT/bff/favorite-games/toggleToggle de favorito (body { slug_url })

Sports

MetodoEndpointObservacao
GET/cactus-sportbook/searchBusca no sportsbook
GET/cactus-sportbook/launchLaunch autenticado
GET/cactus-sportbook/anonymous-launchLaunch anonimo
GET/cactus-sportbook/auth/anonymousToken anonimo da Rogue (exige header x-api-key)
GET/cactus-sportbook/auth/loginToken logado da Rogue (exige header x-api-key)
GET/cactus-sportbook/*Proxy transparente para qualquer subpath (/api/cactus-sportbook/*)
POST/betby/get-jwtJWT para provider Betby
GET/alternar/tokenToken para provider Altenar

Providers suportados: ["first", "altenar", "betby", "rogue"]. As duas rotas /cactus-sportbook/auth/* devolvem { access_token, api_url } e são o único ponto de contato com o BFF no fluxo Rogue — todo o resto do tráfego vai direto pra Rogue API (fssb.io) através do proxy same-origin /api/sports/rogue-proxy/*. Ver SSR Routes.

KYC

MetodoEndpointObservacao
GET/bff/users/kyc?source={source}Inicia KYC
GET/bff/users/kyc/recoveryRecovery do KYC
GET/bff/users/kyc/status?kyc_id={id}Status do KYC
GET/bff/users/kyc/status/recoveryStatus recovery do KYC

Validation

:::warning Typo no backend Os endpoints /bff/users/validade-email-code e /bff/users/validade-sms-code possuem typo no backend — "validade" ao inves de "validate". Nao corrigir no front; usar exatamente como esta. :::

MetodoEndpointObservacao
POST/bff/users/send-emailEnvia codigo de verificacao por email
POST/bff/users/validade-email-codeValida codigo de email (typo: "validade")
POST/bff/users/send-smsEnvia codigo de verificacao por SMS
POST/bff/users/validade-sms-codeValida codigo de SMS (typo: "validade")
PATCH/bff/users/self-phoneAtualiza telefone apos validacao
PATCH/bff/users/add-addressAdiciona endereco
PATCH/bff/users/add-initial-dataDados iniciais pos-registro
POST/bff/validate-confirmationConfirma link de validacao por email

Os endpoints do fluxo Didit (CHL) — /documents/validate, /documents/confirm-birthdate e /documents/verify-identity — estão listados em Auth e User.

Gamification (REST + Smartico SDK)

A gamificacao do Cactus expoe 2 endpoints REST pelo BFF (rewards / redeem). Alem disso, ha integracao client-side com Smartico (3rd party) via JS SDK, sem rotas BFF envolvidas.

MetodoEndpointObservacao
GET/bff/gamification/rewards?page=…&per_page=…&type=…Lista paginada de rewards do usuario
POST/bff/gamification/redeemResgata reward — body { reward_id }

Smartico: ver SmarticoInitializer no layout e o hook useSmartico().

Sweepstakes (Gold Coins / Sweeps Coins)

:::info Não é dependência do front-web-base em main-7k @cactus-agents/sweepstakes não está no package.json do base nesta trunk, e nenhum arquivo de app/ o importa — logo não há rota /api/* de sweepstakes aqui. A tabela abaixo documenta o contrato que o package publicado (0.6.0) implementa, pra quem for ligar o modelo sweepstakes numa brand ou trunk. Ao adotar, as rotas de proxy /api/* precisam ser criadas e listadas em SSR Routes. :::

MetodoEndpointObservacao
GET/sweepstakes/balancesSaldos por moeda (GC / SC)
GET/sweepstakes/wallet-preferenceMoeda ativa da carteira
POST/sweepstakes/wallet-preferenceDefine a moeda ativa — body { coin_type }
POST/sweepstakes/currency-switchTroca a moeda em uso — body { coin_type }
GET/sweepstakes/eligibilityElegibilidade pra resgate
GET/sweepstakes/redemptions[?page={n}]Lista de resgates (paginador Laravel)
GET/sweepstakes/redemptions/{id}Detalhe de um resgate (envelope { data })
POST/sweepstakes/redemptionsSolicita resgate
GET/store/packagesPacotes de Gold Coins à venda
POST/store/purchaseCompra de pacote — body { package_id }

:::warning Dois níveis de incerteza nesses paths O próprio service.ts do package registra o que foi e o que não foi confirmado — reproduzido aqui porque muda o risco de cada linha:

  • /store/packages é confirmado por probe ao vivo: API_BASE_URL termina em /v2, então resolve pra /v2/store/packages. É a única variante que o BFF reconhece — /api/store/..., /sweepstakes/store/... e /sweepstakes/packages devolvem 404 duro. Com a flag sweepstakes_store_enabled desligada no tenant, responde 403 "Store not available".
  • /store/purchase NÃO foi testado (criaria uma cobrança real). Foi inferido como irmão do path confirmado. Confirme com o back-end antes de subir pra produção.
  • O prefixo /sweepstakes/* das demais linhas assume montagem na raiz do host e também está marcado como "confirmar com o backend" no código. :::

Headers

Fonte de verdade: buildHeaders() em packages/api-client/src/client.ts (comuns) e getExtraHeaders() / getCfGeoHeaders() em packages/api-client/src/server.ts (server-side).

Sempre presentes

HeaderDescricao
tenantID do tenant (marca)
langIdioma normalizado pro BFF (normalizeBackendLanguage colapsa es-cles)
languageMesmo valor de lang
versionBuild version id (cache-busting)
origin-domainMesmo valor de tenant
X-LOG-INFOPayload de log estruturado

Condicionais (client e server)

HeaderQuando
AuthorizationBearer <jwt> — quando ha sessao
X-ORIGIN-ACCESSQuando o origin access e conhecido (desktop/mobile/app)
X-ORIGIN-REFERRER, X-ORIGIN-HOSTNAME, X-ORIGIN-CINFO-ID, X-ORIGIN-CINFO-ID-REFTracking de origem, quando disponivel
cactus-service: DEBUGClient em modo debug
Content-Type: application/jsonRequests com body

Só server-side (rotas /api/*)

Nenhum destes existe em request feito do browser — só saem do Worker.

HeaderDescricao
cf-worker-keySegredo (CF_WORKER_KEY). E a credencial que identifica o proxy oficial do front pro BFF. Sem ela, um caller de outra origem toma 404.
is_new_front: "true"Marca o front novo (temporario, ate a migracao terminar)
country, country_alpha3, currency, jurisdictionDerivados da brand/geo
cityCidade (sanitizada — São PauloSao Paulo)
CookieRepassa os cookies do request original
User-AgentRepassa o UA do usuario

Geo do Cloudflare (server-side)

Emitidos por getCfGeoHeaders(). O IP real do usuario vai em quatro formatos porque o backend le nomes diferentes por integracao — sem isso o BFF veria o IP do Worker:

HeaderDescricao
S-Client-AddrIP real — nome que o backend PHP le pra PGSoft e outros providers
x-cac-real-ip, X-Forwarded-For, X-Real-IPMesmo IP, nomes alternativos
x-countryPais (lowercase)
x-user-info-timezone, x-user-info-lat, x-user-info-long, x-user-info-region, x-user-info-cityGeo do request.cf

CF-Connecting-IP é deliberadamente não enviado — é header reservado do Cloudflare e setá-lo em request de saída faz o backend/WAF responder 403.

Só em dev

dev-user, dev-user-token-checksum, CF-Access-Client-Id, CF-Access-Client-Secret — presentes apenas quando as vars correspondentes estão setadas.

Headers extras por caller

Um caller server-side pode injetar headers próprios via extraHeaders no createClient(). Escopo é aquele client só — não vaza pras outras chamadas nem pro browser. Uso real hoje: x-api-key (de SPORTS_ROGUE_API_KEY) nas rotas de token da Rogue.

Comportamentos por status HTTP

StatusComportamento
401Logout automatico (tenta refresh-token antes)
440Logout automatico — sessao encerrada server-side, refresh nao recupera (ver EM0030 em Codigos de erro)
429Abre challenge/captcha
202Timeout limit (resolve, nao throw)

Rotas de proxy do template (/api/*)

O template front-web-base expõe 101 rotas internas que atuam como proxies server-side: leem o JWT do cookie HttpOnly e delegam ao BFF. O front-end só chama essas rotas — nunca o BFF diretamente.

Consulte SSR Routes → BFF para o mapa completo /api/* → BFF, agrupado por domínio (Auth, Validation, User, Wallet, Payments, Games, Search, Sports, KYC, Rewards, Income Report, FTD Cashback, Tracking, Infra).