Voltar para o blog
KalshiComplianceBunRegulação

Kalshi em Utah: quando o seu código vira acusação criminal

05 de novembro de 2026·7 min de leitura·Diego Horvatti

Os dois fundadores da Kalshi foram acusados de crime grave em Utah. O motivo é um app de previsões que funcionava normalmente no resto dos Estados Unidos. A Kalshi é a plataforma onde você compra contratos de "sim" ou "não" sobre eventos reais: eleição, juros, resultado de jogo. Utah olhou para isso e viu aposta. E Utah proíbe toda forma de aposta, inclusive loteria. Aí a história ficou estranha: o governo Trump processou o estado de Utah para proteger a Kalshi, segundo a Ars Technica.

Parece papo de advogado. Não é. Tem uma lição bem prática aqui para quem escreve software que atende gente em mais de um lugar.

O que aconteceu com a Kalshi em Utah?

O resumo cabe em quatro frases.

A Kalshi é regulada em nível federal pela CFTC, a agência americana que cuida de derivativos e mercados futuros. Para a empresa, um contrato sobre "o time X vence no domingo?" é um instrumento financeiro, não uma aposta. Vários estados discordam, principalmente quando o contrato é sobre esporte. Utah foi o mais longe: em vez de mandar carta ou abrir processo civil, apresentou acusação criminal contra a empresa e contra os fundadores, Tarek Mansour e Luana Lopes Lara.

O governo federal respondeu processando o estado. O argumento é de preempção: se a lei federal regula esses mercados, um estado não pode criminalizar o mesmo produto por conta própria.

Quem ganha essa briga vai ser decidido no tribunal, provavelmente em mais de uma instância. Eu não vou fingir que sei o resultado. Só que, para quem programa, o resultado importa menos do que a pergunta que o caso levanta.

Por que um dev deveria ligar para isso?

Porque quase todo produto digital hoje roda em várias jurisdições ao mesmo tempo, e ninguém no time pensa nisso até ser tarde.

Você faz deploy uma vez e o app aparece no mundo inteiro. A lei não funciona assim. Cada estado, cada país, às vezes cada cidade tem uma regra. O que é legal em Nova York pode ser crime em Salt Lake City. O que é ok no Brasil pode precisar de licença em Portugal.

A gente trata isso como problema do jurídico. Mas quem decide se um usuário de Utah vê ou não vê o botão de comprar é um if no seu código. Esse if existe? Ele está certo? Quem testou?

A lei tem fronteira. O deploy não tem. O meio do caminho é responsabilidade do seu código.

E tem um detalhe que assusta: a acusação foi contra pessoas, não só contra o CNPJ deles. Fundador geralmente entende o risco quando assina. O dev que implementou a feature, em geral, nem ficou sabendo que existia risco.

O que "regulado federalmente" não te garante

Esse é o ponto que eu acho mais útil para quem está começando um produto.

A Kalshi não é uma startup que ignorou a lei. Ela passou anos brigando para ter aprovação da CFTC. Ela tem a licença. Mesmo assim, um estado decidiu que a licença não vale no território dele.

Traduzindo para o nosso mundo:

  • Ter conta aprovada na Stripe não significa que o seu produto é legal em todo país que a Stripe atende.
  • Estar na App Store não significa que o app cumpre a lei de todo lugar onde ele pode ser baixado.
  • Seguir a LGPD não te cobre na Califórnia, e o contrário também vale.

Licença é necessária. Só que ela não basta. Ela é o começo da conversa. Se o seu produto mexe com dinheiro, saúde, aposta, conteúdo adulto, criptomoeda ou dados sensíveis, parta do princípio de que alguém, em algum lugar, vai discordar de você.

Como isso aparece no código: geobloqueio de verdade

Na prática, empresas como a Kalshi bloqueiam ou limitam funcionalidades por região. Se você um dia precisar fazer algo parecido, o jeito preguiçoso e errado é esconder o botão no frontend. Isso não bloqueia nada. Qualquer pessoa com DevTools aberto chama a API direto.

O bloqueio tem que estar no servidor, no ponto onde a ação acontece. Um exemplo mínimo com Bun:

// regiões onde a funcionalidade não pode existir
const BLOCKED = new Set(["US-UT", "US-NV"]);

Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);
    // a CDN injeta a região; o nome do header muda conforme o provedor
    const region = req.headers.get("x-geo-region") ?? "UNKNOWN";

    if (url.pathname.startsWith("/api/orders")) {
      if (region === "UNKNOWN" || BLOCKED.has(region)) {
        return Response.json(
          { error: "Indisponível na sua região" },
          { status: 451 },
        );
      }
    }
    return new Response("ok");
  },
});

Três coisas para reparar nesse trecho.

Primeiro, o status 451 Unavailable For Legal Reasons. Ele existe de verdade, é do RFC 7725, e quase ninguém usa. Use. Ele deixa claro no log por que a requisição caiu, o que ajuda muito quando alguém do jurídico pergunta "quantas pessoas de Utah tentaram comprar?".

Segundo, região desconhecida é bloqueada. Esse é o padrão seguro. Se o header não veio, você não sabe onde o usuário está, e "não sei" não pode virar "pode".

Terceiro, IP sozinho é fraco. VPN resolve em dois cliques. Para produto regulado de verdade, a localização vem combinada com endereço verificado, documento e às vezes GPS do celular. O código acima é o piso, não o teto.

A lista de regiões não é configuração, é decisão de negócio

Aqui entra a minha opinião forte: essa lista de regiões bloqueadas não pode ficar enterrada em uma constante que só o dev conhece.

Já vi isso acontecer em projeto de cliente. Uma regra de "não vender para tal estado" morava num arquivo de config que ninguém abria fazia dois anos. A lei mudou, o jurídico avisou o comercial, o comercial avisou ninguém. O app continuou vendendo.

O que eu faria hoje:

  • A lista vive num lugar versionado e com dono, seja repositório, banco ou feature flag com histórico.
  • Toda mudança na lista tem um responsável que não é só o dev.
  • Existe um log de quem foi bloqueado e quando, porque esse log é a sua prova de boa-fé se alguém perguntar depois.

Nada disso é complicado. É uma tabela, um endpoint e um commit. O difícil é lembrar que precisa existir antes de alguém precisar dela.

E se o governo federal ganhar?

Pode ser que a Justiça diga que a lei federal vale mais e que Utah não pode fazer isso. A Kalshi volta a operar tranquila e a acusação cai.

Mesmo nesse cenário, a lição para o dev continua igual. O caso mostra que um produto pode estar certo no papel e ainda assim ser alvo de um processo criminal por anos. O custo de ter razão no tribunal é enorme. O custo de ter um geobloqueio decente desde o começo é uma tarde de trabalho.

Também vale lembrar que regra política muda com o governo. O que o governo federal defende hoje pode não ser o que vai defender daqui a quatro anos. Código que depende de "o governo está do nosso lado" é código com prazo de validade.

O que eu tiro disso

Eu não tenho opinião formada sobre se mercado de previsão é aposta ou derivativo. Acho que as duas leituras têm argumento, e por isso o caso está no tribunal e não no Twitter.

A parte que me interessa é mais simples. A maioria de nós nunca vai ser acusada de crime em Utah, ainda bem. Mas quase todo mundo já escreveu, ou vai escrever, um código que decide quem pode fazer o quê e de onde. Esse código é tão crítico quanto o de autenticação, e costuma receber um décimo da atenção.

Se você está construindo algo que mexe com dinheiro ou dado sensível, gaste a tarde. Faça o bloqueio no servidor, use o 451, bloqueie o que é desconhecido e dê um dono para a lista. É o tipo de cuidado que eu tento colocar nos projetos que eu construo, mesmo quando ninguém pediu.

Resumo para o LinkedIn

Os fundadores da Kalshi foram acusados de crime em Utah por causa de um app que funcionava normalmente no resto dos EUA.

A empresa tem licença federal. Mesmo assim, o estado decidiu que a licença não vale no território dele.

O deploy não tem fronteira, mas a lei tem. E quem decide se um usuário de Utah vê o botão de comprar é um if no seu código.

Esconder o botão no frontend não bloqueia nada. O bloqueio tem que estar no servidor, retornar 451 e tratar região desconhecida como bloqueada.

A lista de regiões bloqueadas é decisão de negócio, não uma constante esquecida num arquivo de config. Ela precisa de dono, de histórico e de log.

Escrevi o artigo completo com o código e o que eu faria hoje. O link está nos comentários, para quem constrói produto que mexe com dinheiro ou com dado sensível.

#DesenvolvimentoDeSoftware #Compliance #Backend #Startups #Tecnologia