Supabase: limite de e-mail do Auth e como resolver
Erro email rate limit exceeded no Supabase? Veja os limites do Auth, onde mudar no painel, como ligar um SMTP próprio e o checklist para produção.
Na prática9 min de leitura
Ver em MarkdownO app está pronto, você chama o primeiro amigo para testar, ele se cadastra e o e-mail de confirmação não chega. Você tenta de novo e o Supabase responde email rate limit exceeded. Na terceira tentativa, nem o seu próprio e-mail recebe mais nada.
Não é bug do seu código. O Supabase Auth tem um envio de e-mail embutido feito para testar, com um limite muito baixo, e mais alguns limites que continuam valendo mesmo depois que você liga um SMTP próprio. Este artigo mostra cada um, onde mudar, como configurar o SMTP do jeito certo e o que conferir antes de abrir o app para o público.
Por que aparece "email rate limit exceeded"?#
O erro vem com o código over_email_send_rate_limit e o status HTTP 429. Pela lista de códigos de erro do Supabase Auth, ele quer dizer que e-mails demais foram enviados e que a pessoa precisa esperar um pouco antes de tentar de novo.
Na prática, ele aparece em três situações:
- Você ainda usa o envio embutido. Ele tem um limite por hora para o projeto inteiro e esgota em poucos testes.
- Você ligou o SMTP próprio, mas não mexeu no limite. Ao salvar o SMTP, o Supabase aplica um limite inicial baixo, que você precisa subir.
- A mesma pessoa pediu o e-mail duas vezes em menos de um minuto. Há uma janela por usuário entre um pedido e outro.
Os limites do envio embutido#
A página de SMTP personalizado do Supabase é direta: o serviço padrão não é para produção. Verificado em 20/10/2026:
| O que | Como funciona no envio embutido |
|---|---|
| Para quem envia | só para endereços pré-autorizados, os membros da organização no Supabase. Os outros recebem o erro email_address_not_authorized |
| Quantos por hora | 2 mensagens por hora, e o próprio Supabase avisa que o número pode mudar sem aviso |
| Garantia | nenhuma garantia (SLA) de entrega nem de disponibilidade |
Com 2 por hora, um cadastro e uma recuperação de senha já gastam a cota. É por isso que o erro aparece tão cedo: não é o seu app que manda demais, é o limite que foi feito para testar.
Os limites que continuam com SMTP próprio#
Ligar o SMTP próprio tira a trava dos destinatários e permite subir o limite de e-mails. Mas os outros limites do Auth continuam valendo. Estes são os padrões da página de limites do Supabase Auth, verificados em 20/10/2026:
| Limite | Padrão | Por quem conta |
|---|---|---|
| E-mails enviados pelo Auth | 2 por hora no envio embutido; ao salvar o SMTP próprio, começa em 30 por hora (segundo a página de SMTP) | projeto inteiro |
Novo pedido de link mágico ou código (/otp) |
60 segundos entre um pedido e outro | por usuário |
Novo e-mail de confirmação de cadastro (/signup) |
60 segundos | por usuário |
Novo pedido de recuperação de senha (/recover) |
60 segundos | por usuário |
| Cadastros e entradas | 30 pedidos a cada 5 minutos | por IP |
Verificações (/verify) |
30 pedidos a cada 5 minutos | por IP |
Dois cuidados práticos:
- O limite de e-mails é do projeto, não da pessoa. Se 40 pessoas se cadastram na mesma hora e o limite está em 30, as 10 últimas recebem
429. - O limite por IP pega escritórios e escolas. Muita gente atrás do mesmo IP (uma empresa, uma sala de aula numa demonstração) bate no limite de cadastros por IP mais rápido do que você imagina.
Onde mudar os limites no painel#
No painel do Supabase, abra o projeto e vá em Authentication > Rate Limits. Ali ficam os campos que dá para ajustar, entre eles o de e-mails por hora. O campo de e-mails só pode ser mudado com SMTP próprio ou com o gancho de envio (Send Email Hook) ligado; com o envio embutido ele fica travado.
Também dá para mudar pela API de gerenciamento do Supabase, com a chave rate_limit_email_sent:
curl -X PATCH "https://api.supabase.com/v1/projects/$PROJECT_REF/config/auth" \
-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "rate_limit_email_sent": 120 }'O 120 é só um exemplo. Para achar o seu número, faça a conta com os seus dados:
limite por hora = cadastros na hora de pico × e-mails por cadastro (confirmação, boas-vindas, recuperação) × uma folga (por exemplo, 2)
E lembre que o limite do Supabase não pode passar do limite do seu serviço de SMTP. Se o Supabase deixa sair 500 por hora e o seu SMTP aceita menos, os que sobrarem voltam com erro no log.
Um exemplo real: o limite que aparece mesmo com o gancho#
Nem todo 429 se resolve no primeiro ajuste. A issue 45743 do repositório do Supabase, aberta em 9 de maio de 2026, relata o erro over_email_send_rate_limit no cadastro mesmo com o Auth Email Hook configurado (o gancho que manda o e-mail por uma função sua, em vez do SMTP). Quem abriu esperava que o limite não valesse nesse caso. Outras pessoas confirmaram o mesmo comportamento nos comentários, e uma delas contou que só saiu do problema ligando o SMTP próprio.
Até 20/10/2026, a issue seguia aberta e sem resposta da equipe do Supabase. A lição prática: se você usa o gancho e ainda recebe 429, confira o campo de e-mails em Authentication > Rate Limits e teste com o mesmo endereço mais de uma vez por minuto para separar o limite do projeto da janela de 60 segundos por usuário.
Como configurar um SMTP próprio no Supabase#
Qualquer serviço de SMTP autenticado funciona. O passo a passo abaixo usa o SMTP do Couryo; com outro serviço, mudam só o servidor, o usuário e a senha.
Antes de começar#
- Verifique o domínio de onde os e-mails vão sair no seu serviço de envio, com SPF, DKIM e DMARC. Sem isso, o e-mail sai, mas cai no spam. No Couryo, isso fica em Domínios, com o status de cada registro ao vivo e conexão com a Cloudflare em um clique; veja Domínios e DNS e o guia SPF, DKIM e DMARC.
- Crie uma chave de API com escopo
send. No Couryo, ela é a senha do SMTP.
No painel do Supabase#
Em Authentication > Emails > SMTP Settings, ligue Enable Custom SMTP e preencha:
| Campo | Valor |
|---|---|
| Sender email | um endereço do domínio verificado, como nao-responda@auth.exemplo.com.br |
| Sender name | o nome do seu app |
| Host | smtp.couryo.com |
| Port number | 587 (STARTTLS) ou 465 (TLS direto) |
| Username | couryo |
| Password | a chave de API (ck_live_...) |
Salve e, logo em seguida, vá em Authentication > Rate Limits e ajuste os e-mails por hora. Esse é o passo que mais gente esquece: sem ele, você troca o limite de 2 por hora pelo de 30 por hora e acha que o SMTP "não resolveu".
Pela CLI, para projetos versionados#
[auth.email.smtp]
enabled = true
host = "smtp.couryo.com"
port = 587
user = "couryo"
pass = "env(COURYO_API_KEY)"
admin_email = "nao-responda@auth.exemplo.com.br"
sender_name = "Exemplo"
[auth.rate_limit]
email_sent = 120Na referência de configuração da CLI, o email_sent vale 2 por padrão e o intervalo mínimo entre pedidos (max_frequency, em [auth.email]) é de 1m. A chave fica na variável de ambiente, nunca no arquivo.
Mais detalhes, inclusive pela API de gerenciamento, na página Supabase Auth com SMTP personalizado.
Como testar sem gastar o limite#
- Teste com uma chave de teste. No Couryo, uma chave
ck_test_funciona no mesmo campo de senha, mas não entrega nada: o e-mail de confirmação é capturado e aparece no painel com o link clicável. Dá para repetir o fluxo quantas vezes quiser sem incomodar ninguém e sem gastar envios. Veja Modo de teste. - Cadastre um usuário de teste no app, ou use Authentication > Users > Add user > Send invitation.
- Confira os dois lados. No Supabase, Logs > Auth mostra se o envio saiu e o erro SMTP, se houver. No Couryo, E-mails mostra a linha do tempo da mensagem: aceita, enviada e entregue, com a resposta do servidor de destino e a explicação em português.
- Troque para a chave
ck_live_quando o fluxo estiver certo.
Se aparecer um código no log do Supabase:
| Código | O que quer dizer |
|---|---|
535 5.7.8 |
usuário diferente de couryo ou chave inválida, revogada ou sem escopo send |
550 5.7.1 |
o Sender email não está num domínio verificado, ou a conta ainda está no nível 0 |
452 4.7.0 |
limite do nível ou do plano no Couryo; a mensagem traz o motivo e os números |
over_email_send_rate_limit |
limite do Supabase, em Authentication > Rate Limits |
Uma coisa honesta sobre o Couryo: a conta nova também começa no nível 0 (sandbox), com 25 e-mails por dia só para os endereços da própria conta. Com o domínio verificado e um sinal de que há alguém real por trás (cartão, CNPJ conferido ou domínio com mais de 30 dias), a conta sobe sozinha para o nível 1, com 100 por dia. O plano Grátis tem 3 mil e-mails por mês. Os números de cada nível estão em Limites e níveis.
Mostre o erro para a pessoa, sem susto#
Mesmo com tudo configurado, a janela de 60 segundos por usuário continua. Trate o 429 na tela, em vez de deixar a pessoa clicando em "reenviar":
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!);
export async function cadastrar(email: string, senha: string) {
const { error } = await supabase.auth.signUp({ email, password: senha });
if (!error) return { ok: true, mensagem: "Enviamos um link para o seu e-mail." };
if (error.code === "over_email_send_rate_limit" || error.status === 429) {
return {
ok: false,
mensagem: "Já enviamos um e-mail há pouco. Confira a caixa de entrada e o spam; em 1 minuto você pode pedir de novo.",
};
}
return { ok: false, mensagem: error.message };
}Mostrar um contador de 60 segundos no botão "reenviar" evita o segundo pedido e a frustração.
Checklist para produção#
- SMTP próprio ligado em Authentication > Emails > SMTP Settings.
- E-mails por hora ajustados em Authentication > Rate Limits, com a conta do pico.
- Domínio do remetente verificado, com SPF, DKIM e DMARC alinhados.
- Um subdomínio só para o Auth (por exemplo,
auth.exemplo.com.br), verificado como os outros domínios e separado do marketing. O próprio Supabase recomenda não misturar e-mails de autenticação com marketing. - Site URL e Redirect URLs certos em Authentication > URL Configuration (nada de
localhostem produção). - Modelos em Authentication > Emails > Templates curtos, sem promoção, com o nome do app no assunto e sem encurtador de link.
- Código de 6 dígitos (
{{ .Token }}) como opção no celular: alguns filtros corporativos abrem o link antes da pessoa e gastam o link de uso único. - CAPTCHA no cadastro, como o Supabase recomenda, para robôs não gastarem o seu limite.
- Um jeito de ver cada envio: no Couryo, a linha do tempo em E-mails e webhooks de devolução e reclamação.
Se o e-mail sai e mesmo assim não aparece para a pessoa, o problema já não é limite. Siga o guia E-mail de confirmação não chega e o de e-mail caindo no spam.
Perguntas frequentes#
Qual é o limite de e-mail do Supabase Auth?#
Com o envio embutido, 2 e-mails por hora para o projeto inteiro, e só para os membros da organização. Com SMTP próprio, o limite começa em 30 por hora e você ajusta em Authentication > Rate Limits. Há ainda uma janela de 60 segundos por usuário entre um pedido e outro (números verificados na documentação do Supabase em 20/10/2026).
Liguei o SMTP próprio e o erro continua. Por quê?#
Quase sempre porque o limite de e-mails por hora ficou no valor inicial. Abra Authentication > Rate Limits e suba o número. Se o erro aparece só quando a mesma pessoa pede duas vezes seguidas, é a janela de 60 segundos por usuário, e ela é proposital.
O limite do Supabase substitui o limite do serviço de SMTP?#
Não, os dois valem. O Supabase decide quantos e-mails pede por hora, e o serviço de SMTP decide quantos aceita. No Couryo, o limite do nível e do plano aparece no painel e no erro 452 4.7.0, com o motivo e os números.
Dá para testar o fluxo de cadastro sem mandar e-mail de verdade?#
Sim. No Couryo, use uma chave ck_test_ como senha do SMTP: o e-mail é capturado e aparece no painel com o link clicável, sem entregar nada. Localmente, a CLI do Supabase já captura os e-mails numa caixa de teste.
Usar o Auth Email Hook livra do limite?#
Pela documentação, o limite de e-mails fica ajustável quando você usa SMTP próprio ou o gancho. Mas a issue 45743 relata 429 mesmo com o gancho, e até 20/10/2026 ela seguia aberta. Se for o seu caso, confira o campo em Authentication > Rate Limits ou use o SMTP próprio.