Formulário de inscrição em newsletter6 min de leitura
Envie as inscrições do seu próprio formulário de newsletter para o beehiiv
Conecte seu próprio formulário de inscrição ao beehiiv: um relay cria cada subscription com double opt-in ligado, a posição como UTM source e a página como referrer.
Envie seu próprio formulário ao Ikiform e aponte o webhook para um relay que chama o endpoint de criar subscription do beehiiv. Envie double_opt_override: "on" para o beehiiv enviar a confirmação por e-mail, passe a posição do formulário como utm_source e a página como referring_site, e mantenha reactivate_existing como false para que uma inscrição nunca desfaça um descadastro sem ninguém perceber. Uma chamada de API por inscrição, com a chave guardada no relay.
O que muda com o beehiiv
A API do beehiiv é organizada em torno de publicações. Uma subscription é um endereço de e-mail inscrito numa publicação, e você a cria com um POST em /v2/publications/{publicationId}/subscriptions. Tudo sobre a inscrição vai nessa única requisição: se deve confirmar, se deve enviar o e-mail de boas-vindas, de onde o leitor veio e os campos personalizados. Não há etapa separada de tag ou formulário como no Kit.
O beehiiv também reporta a aquisição em termos de UTM. Os registros de subscription dele trazem utm_source, utm_medium, utm_campaign e referring_site. Mapeie os campos do seu formulário para esses, e cada assinante no beehiiv mostra qual posição e qual artigo o trouxeram:
- fields.email vira email.
- fields.source vira utm_source.
- meta.referrer vira referring_site.
- fields.first_name vira custom_fields: First Name.
- double_opt_override: "on" é adicionado pelo relay.
- reactivate_existing: false é adicionado pelo relay.
Configure o beehiiv
- No beehiiv, abra Settings, depois API em Workspace Settings, e escolha Create New API Key. Copie na hora; o beehiiv não vai mostrá-la de novo.
- Num plano pago, restrinja a chave à única publicação que o formulário alimenta. Uma chave restrita a uma publicação recebe
404para qualquer outra publicação, o que limita o estrago se ela vazar. - Encontre o id da publicação, o id com prefixo que a API do beehiiv usa no caminho. O endpoint da API que lista publicações o retorna.
- Crie um campo personalizado chamado
First Namese quiser guardar primeiros nomes. O beehiiv descarta campos personalizados que ainda não existem. - Configure os e-mails de double opt-in e de boas-vindas nas configurações da publicação. O relay os ativa a cada requisição; o conteúdo deles fica no beehiiv.
O relay
Esta é uma Netlify Function, que combina com um site que já está na Netlify: roda no seu próprio domínio, ao lado do site estático, sem um serviço separado. Instale @netlify/functions para os tipos e defina as três variáveis nas configurações de ambiente do site.
import type { Config } from "@netlify/functions";
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
export default async (request: Request) => {
const payload = await request.text();
let event;
try {
event = await verifyWebhook({
payload,
headers: request.headers,
secret: Netlify.env.get("IKIFORM_WEBHOOK_SECRET")!,
});
} catch (error) {
if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
throw error;
}
if (event.type !== "submission.created") return new Response(null, { status: 204 });
const { email, first_name, consent, source } = event.data.fields;
if (consent !== true || typeof email !== "string") return new Response("Skipped", { status: 200 });
const publication = Netlify.env.get("BEEHIIV_PUBLICATION_ID");
const answer = await fetch(`https://api.beehiiv.com/v2/publications/${publication}/subscriptions`, {
method: "POST",
headers: {
Authorization: `Bearer ${Netlify.env.get("BEEHIIV_API_KEY")}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
double_opt_override: "on",
send_welcome_email: true,
reactivate_existing: false,
utm_source: typeof source === "string" ? source : "website",
utm_medium: "signup_form",
referring_site: event.data.meta.referrer ?? undefined,
custom_fields: typeof first_name === "string" && first_name ? [{ name: "First Name", value: first_name }] : [],
}),
});
if (answer.status === 429) {
const reset = Number(answer.headers.get("ratelimit-reset"));
const wait = reset ? Math.max(1, reset - Math.floor(Date.now() / 1000)) : 60;
return new Response("beehiiv rate limit", { status: 503, headers: { "retry-after": String(wait) } });
}
if (!answer.ok) return new Response(`beehiiv answered ${answer.status}: ${await answer.text()}`, { status: 502 });
return new Response(null, { status: 204 });
};
export const config: Config = {
path: "/hooks/beehiiv",
};double_opt_override: "on"envia o e-mail de confirmação seja qual for o padrão da publicação. Use"not_set"para seguir a configuração da publicação e nunca"off"num formulário público.send_welcome_emailtemfalsecomo padrão na API. Defina comotruese quiser que as inscrições via API recebam o e-mail de boas-vindas que as inscrições pelo embed recebem.reactivate_existing: falsetambém é o padrão. Deixe explícito para ninguém trocar depois sem pensar; ele reativa pessoas que cancelaram a assinatura.- O beehiiv responde
200com a assinatura, e ostatusdela começa comovalidatingenquanto o beehiiv confere o endereço, e depois ficapendingaté o leitor confirmar. - Em caso de
429, o relay lê oRateLimit-Resetdo beehiiv, um horário Unix, e o transforma num atrasoRetry-Afterpara o Ikiform.
A URL da função é https://your-site.com/hooks/beehiiv. Adicione-a em Webhooks no Ikiform e copie o segredo whsec_ para IKIFORM_WEBHOOK_SECRET. A documentação de webhooks lista as regras de URL, e seu próprio servidor mostra como pular uma entrega que você já processou.
Escolhendo os valores de UTM
Os campos de UTM do beehiiv são texto livre, então decida os valores uma vez e mantenha-os consistentes, ou os registros se dividem em quase duplicados como footer e Footer. O input oculto source do formulário é o utm_source natural. Mantenha utm_medium fixo, para que toda inscrição vinda dos seus formulários possa ser distinguida das páginas hospedadas do beehiiv e das importações:
| Posição | Input source | utm_source | utm_medium |
|---|---|---|---|
| Rodapé do site | footer | footer | signup_form |
| Fim de um post | post | post | signup_form |
| Página da newsletter | newsletter-page | newsletter-page | signup_form |
Se você roda uma campanha com link para uma página com o formulário, leia a campanha da URL da página no relay. meta.referrer guarda a URL completa da página, com a query string quando o navegador a envia, então o relay pode copiar um parâmetro utm_campaign dela para a requisição.
Limites de taxa por plano
O beehiiv mede o limite por chave de API em janelas fixas de 60 segundos, e o limite depende do plano. Cada inscrição é uma requisição:
| Plano do beehiiv | Requisições por minuto |
|---|---|
| Free | 30 |
| Lite | 180 |
| Pro | 500 |
| Enterprise | 800, mais sob pedido |
Trinta por minuto bastam para a maioria dos formulários de rodapé, mas um post de lançamento numa publicação gratuita pode passar disso. O 503 do relay faz o Ikiform esperar e tentar de novo em vez de perder a inscrição. Nomes de planos e limites mudam, então confira a página de rate limiting do beehiiv se o seu não estiver na lista.
Pegadinhas
- Nomes de campos personalizados são exatos. O beehiiv associa campos personalizados pelo nome e descarta os desconhecidos com um aviso na resposta, não um erro. Um erro de digitação faz os primeiros nomes sumirem sem alarde.
referring_sitepode vir vazio.meta.referrerénullquando o navegador não enviou um referrer, e o relay deixa o campo de fora.- Assinantes existentes. A documentação do beehiiv diz que a chamada cria ou atualiza a assinatura, mas não o que muda para um assinante ativo. Teste com o seu próprio endereço confirmado antes de colocar o formulário em todas as páginas.
- Chaves valem para o workspace inteiro por padrão. Uma chave sem restrição de publicação alcança todas as publicações do workspace. Restrinja o escopo.
- Planos pagos ficam no beehiiv. Deixe
tierde fora para que as inscrições entrem sem assinatura paga. Upgrades acontecem no checkout do próprio beehiiv.
Confira se funciona
- Escolha Send test no endpoint no Ikiform. A entrega mostra
204e o beehiiv não recebe nenhuma requisição. - Inscreva-se pela sua página com um endereço seu. A entrega mostra
204. - No beehiiv, o assinante aparece como pendente, com a sua posição como UTM source e o artigo como referring site.
- O e-mail de double opt-in chega. Confirme, e o e-mail de boas-vindas vem em seguida.
- Cancele a assinatura desse endereço no beehiiv e inscreva-se de novo. O assinante continua inativo, porque
reactivate_existingé false.
Perguntas
Sim. Envie seu formulário ao Ikiform e deixe um relay chamar o endpoint de criar assinatura do beehiiv para cada inscrição. Seu formulário mantém o seu design, e o beehiiv continua confirmando, dando boas-vindas e enviando e-mails ao leitor.
A página de preços do beehiiv lista acesso à API em todos os planos, e a página de rate limiting dá ao plano mais baixo 30 requisições por minuto. A Send API fica restrita aos planos mais altos, mas criar assinaturas não a usa.
Envie double_opt_override com "on" na requisição de criar assinatura, ou "not_set" para usar a configuração da própria publicação. "off" deixa o assinante ativo na hora, sem nenhum e-mail.
Sim. O beehiiv funciona com Zapier e Make, que respeitam os limites de taxa dele por você. Aponte o webhook do Ikiform para a automação e use a ação do beehiiv para adicionar um assinante.
Travou em algum passo ou quer um guia para o seu caso? Envie um e-mail para hello@ikiform.com.