Documentação do app v1.0

URLs e grupos de chaves

O cliente do Load Balance não escolhe a chave: ele chama uma URL, e essa URL decide quais chaves servem aquele tráfego. Aqui você monta a cadeia inteira — a URL config, o grupo de chaves e a credencial sk-lb- — e confere quem vê cada peça.

A cadeia tem três peças

Uma URL só atende quando o endereço existe, o roteamento aponta para um grupo ou para uma chave fixa, e o cliente apresenta uma chave sk-lb- com acesso àquela URL. Sem a credencial, a resposta é 401 — o mesmo código para chave ausente, chave inválida e URL que você não vê, para não permitir enumerar URLs.

Pré-requisitos#

Antes de montar a primeira URL, tenha estes quatro itens resolvidos.

  • Sessão no painel. Criar e editar URL exige ADMIN; a única mutação aberta ao MEMBER é criar e revogar a própria chave pessoal.
  • Ao menos uma chave de provedor cadastrada em Chaves de API — o roteamento precisa de onde tirar a credencial upstream.
  • O orgSlug da sua organização: a rota pública do proxy é /{orgSlug}/{customUrl}/v1/messages.
  • A URL base pública do proxy, vinda de PROXY_PUBLIC_URL. É ela que o painel mostra e copia, não o host do SPA.
  • As três peças#

    Três modelos respondem por todo o caminho do cliente até a credencial do provedor.

    PeçaModeloO que ela decideOnde você configura
    URL configRequestConfigO endereço customUrl, quem o vê e para onde o tráfego é roteadoConfigurações de URL (/app/configs)
    Grupo de chavesApiKeyGroupQuais chaves entram no rodízio e com qual strategyGrupos de chaves (/app/groups)
    Chave sk-lb-UserApiKey (pessoal) ou ClientApiKey (de serviço)Quem está autorizado a chamar a URLChaves de URL (/app/client-keys)

    A URL config é o ponto onde as três se encontram: ela guarda o endereço público, aponta para o roteamento e é nela que a credencial do cliente é conferida. O resto desta página percorre essas peças em ordem.

    A URL config#

    A URL config é uma RequestConfig. Ela define o segmento público, quem o vê e para onde o tráfego vai.

    O customUrl

    O customUrl é o segmento de caminho que o cliente chama, e ele é único entre os valores não-nulos do banco.

  • A rota nova carrega o orgSlug antes dele: /{orgSlug}/{customUrl}/v1/messages e /{orgSlug}/{customUrl}/v1/messages/count_tokens.
  • A rota legada /{customUrl}/v1/messages ainda responde, com remoção declarada para 2026-12-31. Quando o mesmo customUrl existe em mais de uma organização, ela responde 409 pedindo a migração para a rota com orgSlug.
  • Config inexistente responde 404 com Custom URL config not found. Organização inexistente responde igual — a URL pública não enumera organizações.
  • Criar uma config com um customUrl já usado devolve 400: A config with this custom URL already exists.
  • O customUrl ainda é global

    Enquanto a rota legada resolve só pelo customUrl, a unique global de valores não-nulos continua no banco: duas organizações não usam o mesmo segmento. A única composta organizationId + customUrl já existe e é a que rege a rota nova; a global sai junto com a rota legada.

    A visibilidade

    A visibilidade decide quem enxerga a URL e o tráfego dela, no painel e no monitoramento. O enum é ConfigVisibility, com dois valores.

    ValorQuem vê a URL e o tráfego dela
    ORGANIZATIONTodo membro da organização. É o valor default da coluna visibility.
    RESTRICTEDSó OWNER/ADMIN e os usuários listados em assignments (RequestConfigAssignment).

    Em RESTRICTED, a lista de pessoas é gravada em RequestConfigAssignment e vale para ver e usar a URL no monitoramento. Voltar a ORGANIZATION zera a lista de atribuídos no formulário.

    O grupo padrão da organização

    A organização guarda um grupo de chaves padrão, o defaultKeyGroupId, que entra na cena quando um membro é convidado.

  • Quem entra como MEMBER ganha, no aceite do convite, uma URL própria gerada a partir da primeira parte do e-mail, apontando para esse grupo padrão.
  • Nome ocupado recebe sufixo -2, -3… — o aceite nunca falha pelo nome da URL. Nome que colide com rota do app ganha o sufixo -user.
  • Organização sem grupo padrão: a URL do membro nasce desativada e sem grupo. O convite não é bloqueado — o admin liga a URL depois.
  • Só ADMIN/OWNER enxergam e alteram o defaultKeyGroupId, por PUT /api/organizations/:id. Nome e slug da empresa não mudam por lá: vêm da Conta.
  • Os ajustes da própria URL

    A mesma config ainda carrega três ajustes de corpo e de vida útil.

  • systemPrompt com appendSystemPrompt: o LB aplica a config ao corpo antes de escolher a chave — anexar depois do system prompt do usuário ou substituí-lo.
  • isActive: a resolução da URL só encontra configs ativas — desligar a config faz a URL responder 404 na hora, sem apagar o histórico de requisições.
  • Excluir a config: as requisições para aquela URL personalizada começam a falhar na hora. O painel avisa antes de confirmar.
  • O grupo de chaves#

    Quem escolhe a chave que atende cada requisição é o roteamento gravado na URL config. O formulário chama esse bloco de Roteamento de chaves, e cada modo deixa um campo diferente preenchido.

    Modo em Roteamento de chavesCampo gravadoQuem atende o tráfego
    Padrão (rodízio)nenhumO pool unlocked da organização: chaves ativas, sem grupo e sem trava numa URL ativa.
    Grupo específico de chavesapiKeyGroupIdAs chaves do ApiKeyGroup, escolhidas pela strategy dele.
    Chave específicaapiKeyIdSempre a mesma chave, sem rodízio.
    Grupo liberado pela NomadsharedKeyGroupIdUm grupo da organização da Nomad (PLAT-12). O uso conta para a sua organização; as chaves não ficam visíveis.

    URL com grupo x URL travada numa chave

    A distinção mais importante do roteamento é esta — e ela muda o comportamento do motor e o destino da própria chave.

  • URL com grupo (apiKeyGroupId): a cada requisição o motor abre o snapshot do grupo — cache no Redis com TTL de 15 s —, tira da frente as chaves em cooldown e as contas fora da janela de uso, e escolhe pela strategy do grupo. Quando a chave escolhida falha, o failover caminha pelas demais do grupo.
  • URL travada numa chave (apiKeyId): a seleção carrega só aquela chave, sem rodízio. Se ela falhar, o failover usa o pool unlocked da organização como lista de reserva — o próprio snapshot de retry cai nesse pool quando não há grupo.
  • Travar tem efeito colateral: a chave sai do pool unlocked, porque ele só reúne chaves ativas sem grupo e sem trava numa URL ativa. Ela deixa de servir o rodízio das outras URLs.
  • Sem grupo e sem chave fixa, a URL já nasce no pool unlocked da organização, ordenado por lastUsed — a chave menos usada recentemente é a primeira.
  • Travar uma URL numa chave trava a seleção

    O rodízio, o rating e o failover ordeiro ficam no grupo. Numa URL travada, a seleção é sempre a mesma chave — mesmo quando ela está lenta — e a lista de reserva é o pool unlocked, não um grupo escolhido por você. Se o controle importa, aponte a URL para um grupo.

    A estratégia do grupo

    Dentro do grupo, a strategy é o que decide o roteamento. A coluna é String no schema e o valor é validado na borda. Os valores aceitos são estes.

  • round_robin — o default; rotaciona entre as chaves saudáveis do grupo.
  • priority — sempre a chave de maior prioridade saudável, cascateando para a próxima quando ela falha e voltando sozinha quando ela se recupera.
  • rated — a de menor score de rating, calculado sobre TTFT, latência total e taxa de erro.
  • hedge — a primária sai pelo rated e uma reserva é disparada depois do atraso configurado no grupo.
  • race — duas ou mais chaves correm juntas e o cliente recebe a resposta da primeira; as perdedoras são abortadas.
  • Cada grupo guarda também o hedgeConfig dele. Nulo significa os defaults do servidor. Os detalhes de portão, atraso e abort estão no guia do motor de seleção.

    Três coisas chamadas de grupo

    ApiKeyGroup é o grupo que decide o roteamento. RequestConfigGroup só agrupa URLs para consulta e estatística. SharedKeyGroup é o grupo da organização da Nomad, liberado para a sua organização — quando a liberação cai, a URL que o usa responde erro na hora.

    Quem vê o quê#

    O acesso tem duas frentes: o que cada papel enxerga no painel e o que cada credencial sk-lb- consegue chamar no proxy. A tabela resume o painel.

    O queADMIN / OWNERMEMBER
    Ver URLsTodas as da organizaçãoAs ORGANIZATION e as em que ele está em assignments
    URL invisível a ele—Responde 404, não 403: não revela que a URL existe
    Criar, editar ou excluir URLSimNão
    Grupos de chaves e de configSimNem em leitura
    Emitir chave sk-lb-De serviço, e vê as pessoais da organizaçãoSó as próprias, por POST /api/account/keys
    Ver o grupo padrão da organizaçãoSimNão
    MonitoramentoTodo o tráfegoSó o tráfego das URLs que ele vê

    O piso vem do método HTTP: GET/HEAD nascem MEMBER e POST/PUT/PATCH/DELETE nascem ADMIN. As duas exceções declaradas são criar e revogar a própria chave pessoal. Quem nega de verdade é o backend — o menu e a guarda de rota do front só escondem e bloqueiam o acesso direto.

    Quem consegue chamar a URL

    No proxy, a mesma credencial sk-lb- é conferida contra a URL antes de qualquer processamento.

  • Chave pessoal: ADMIN sempre passa; o MEMBER passa se vê a URL — a mesma regra de visibilidade do painel.
  • Chave de serviço: passa somente nas URLs marcadas na própria chave, em ClientApiKeyConfig.
  • A credencial precisa ser da mesma organização da URL, estar válida e não revogada. Contrato encerrado na Conta responde 403 com ORG_SUSPENDED, mesmo com a chave ainda boa: ela volta a valer quando a empresa contratar de novo.
  • A chave sk-lb- sai dos headers antes de a requisição seguir para o provedor — ela nunca chega ao upstream.
  • Liberar uma URL#

    Estas são as ações de tela, na ordem em que você faz a primeira URL e a coloca para rodar.

    1. Abra Configurações de URL

      Entre em Configurações de URL (/app/configs) e use o botão New Config. A tela é aberta a qualquer autenticado; criar e editar continuam sendo ação de ADMIN.

    2. Preencha o nome e o customUrl

      O customUrl é o segmento que entra na URL do cliente, e precisa estar livre entre as URLs não-nulas. O painel monta o endereço completo a partir de PROXY_PUBLIC_URL e mostra pronto para copiar.

    3. Escolha quem pode usar

      Em Quem pode usar, selecione Toda a organização (ORGANIZATION) ou Somente usuários específicos (RESTRICTED) e, neste caso, liste as pessoas. Voltar para ORGANIZATION limpa a lista de atribuídos.

    4. Escolha o roteamento de chaves

      Em Roteamento de chaves, defina o modo — Padrão (rodízio), Grupo específico de chaves, Chave específica ou Grupo liberado pela Nomad — e aponte para o grupo ou para a chave. O painel grava só o campo do modo escolhido e limpa os outros.

    5. Emita a chave sk-lb-

      Em Chaves de URL (/app/client-keys, ADMIN) você cria a credencial que o cliente envia. O valor aparece uma única vez — guarde-o. A chave de serviço recebe também a lista de URLs que ela pode chamar. O MEMBER emite as próprias chaves pessoais pela API, em POST /api/account/keys, e as revoga em DELETE /api/account/keys/:id.

    6. Aponte o cliente e confira o preflight

      O cliente trabalha com duas variáveis: o endereço base da URL e a credencial. O painel monta o endereço a partir de PROXY_PUBLIC_URL e do caminho da config, pronto para copiar.

      bash
      ANTHROPIC_BASE_URL=<URL copiada na config>
      ANTHROPIC_API_KEY=<sua chave sk-lb-...>

      O caminho que o cliente chama por baixo é este — a rota nova carrega o orgSlug antes do customUrl:

      • POST /{orgSlug}/{customUrl}/v1/messages
      • POST /{orgSlug}/{customUrl}/v1/messages/count_tokens

      Antes da primeira chamada real, o cliente dispara um preflight contra a base. O handler responde 200 com corpo vazio, sem headers próprios:

      bash
      curl -s -o /dev/null -w '%{http_code}\n' -I "$ANTHROPIC_BASE_URL"
      text
      200

    Próximos passos#

    Com a URL no ar e a credencial na mão, o próximo passo é ver como cada requisição chega a uma chave concreta.

    Depois de dominar o básico, explore além:

    Documentação gerada com a skill docs-padrao.