뉴스레터 가입 폼4분 분량
내 뉴스레터 폼의 가입을 beehiiv로 보내기
내 가입 폼을 beehiiv에 연결합니다. 릴레이가 더블 옵트인을 켜고, 위치를 UTM source로, 페이지를 referrer로 해서 각 구독을 만듭니다.
내 폼을 Ikiform으로 POST하고, beehiiv의 구독 생성 엔드포인트를 호출하는 릴레이로 웹훅을 보내세요. beehiiv가 확인 이메일을 보내도록 double_opt_override: "on"을 보내고, 폼의 위치는 utm_source로, 페이지는 referring_site로 넘기고, 가입이 수신 거부를 조용히 되돌리지 않도록 reactivate_existing은 false로 두세요. 가입마다 API 호출 한 번이며, 키는 릴레이에 둡니다.
beehiiv에서 다른 점
beehiiv의 API는 퍼블리케이션을 중심으로 구성됩니다. 구독은 한 퍼블리케이션을 구독한 이메일 주소이며, /v2/publications/{publicationId}/subscriptions로 POST 한 번이면 만들어집니다. 가입에 관한 모든 것이 그 요청 하나에 담깁니다. 확인할지, 환영 이메일을 보낼지, 독자가 어디서 왔는지, 커스텀 필드입니다. Kit처럼 별도의 태그나 폼 단계가 없습니다.
beehiiv는 유입도 UTM 용어로 보고합니다. 구독 레코드에는 utm_source, utm_medium, utm_campaign, referring_site가 있습니다. 폼의 필드를 여기에 매핑하면 beehiiv의 각 구독자에게 어느 위치와 어느 글에서 왔는지 표시됩니다.
- fields.email은 email이 됩니다.
- fields.source는 utm_source가 됩니다.
- meta.referrer는 referring_site가 됩니다.
- fields.first_name은 custom_fields: First Name이 됩니다.
- double_opt_override: "on"은 릴레이가 추가합니다.
- reactivate_existing: false는 릴레이가 추가합니다.
beehiiv 설정하기
- beehiiv에서 Settings를 열고, Workspace Settings 아래의 API에서 Create New API Key를 고르세요. 바로 복사하세요. beehiiv는 다시 보여 주지 않습니다.
- 유료 플랜이라면 키를 폼이 연결되는 퍼블리케이션 하나로 제한하세요. 퍼블리케이션 범위의 키는 다른 퍼블리케이션에 대해
404를 받으므로, 유출되었을 때 피해가 제한됩니다. - 퍼블리케이션 ID를 찾으세요. beehiiv API가 경로에 쓰는 접두사가 붙은 ID입니다. API의 퍼블리케이션 목록 엔드포인트가 반환합니다.
- 이름을 저장하고 싶다면
First Name이라는 커스텀 필드를 만드세요. beehiiv는 아직 존재하지 않는 커스텀 필드를 버립니다. - 퍼블리케이션 설정에서 더블 옵트인 이메일과 환영 이메일을 설정하세요. 릴레이는 요청마다 이를 켜고, 내용은 beehiiv에 있습니다.
릴레이
이것은 Netlify Function이며, 이미 Netlify에 있는 사이트에 잘 맞습니다. 별도 서비스 없이 정적 사이트 옆, 내 도메인에서 실행됩니다. 타입을 위해 @netlify/functions를 설치하고, 사이트의 환경 설정에 변수 세 개를 설정하세요.
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"은 퍼블리케이션 기본값과 관계없이 확인 이메일을 보냅니다. 퍼블리케이션 설정을 따르려면"not_set"을 쓰고, 공개 폼에는 절대"off"를 쓰지 마세요.- API에서
send_welcome_email의 기본값은false입니다. 임베드 가입자가 받는 환영 이메일을 API 가입자도 받게 하려면true로 설정하세요. reactivate_existing: false도 기본값입니다. 나중에 누가 생각 없이 바꾸지 않도록 명시하세요. 수신 거부한 사람을 다시 활성화합니다.- beehiiv는 구독과 함께
200으로 응답하며,status는 beehiiv가 주소를 확인하는 동안validating으로 시작해 독자가 확인할 때까지pending입니다. 429가 오면 릴레이가 Unix 시간인 beehiiv의RateLimit-Reset을 읽어 Ikiform용Retry-After지연으로 바꿉니다.
함수의 URL은 https://your-site.com/hooks/beehiiv입니다. Ikiform의 Webhooks에 추가하고 whsec_ 시크릿을 IKIFORM_WEBHOOK_SECRET에 복사하세요. URL 규칙은 웹훅 문서에 있고, 자체 서버에서 이미 처리한 전달을 건너뛰는 방법을 보여 줍니다.
UTM 값 정하기
beehiiv의 UTM 필드는 자유 텍스트이므로 값을 한 번 정하고 일관되게 유지하세요. 그러지 않으면 footer와 Footer처럼 거의 같은 기록으로 갈라집니다. 폼의 hidden source 입력이 자연스러운 utm_source입니다. utm_medium은 고정해 두면 내 폼에서 온 가입을 beehiiv 호스팅 페이지나 가져오기와 구분할 수 있습니다.
| 위치 | source 입력 | utm_source | utm_medium |
|---|---|---|---|
| 사이트 푸터 | footer | footer | signup_form |
| 글의 끝 | post | post | signup_form |
| 뉴스레터 페이지 | newsletter-page | newsletter-page | signup_form |
폼이 있는 페이지로 링크하는 캠페인을 운영한다면, 릴레이에서 페이지 URL로부터 캠페인을 읽으세요. meta.referrer에는 브라우저가 보낸 경우 쿼리 문자열까지 포함한 페이지의 전체 URL이 담기므로, 릴레이가 그 안의 utm_campaign 파라미터를 요청에 복사할 수 있습니다.
플랜별 레이트 리밋
beehiiv는 API 키별로 고정된 60초 구간에서 한도를 측정하며, 한도는 플랜에 따라 다릅니다. 가입마다 요청 하나입니다.
| beehiiv 플랜 | 분당 요청 수 |
|---|---|
| Free | 30 |
| Lite | 180 |
| Pro | 500 |
| Enterprise | 800, 요청 시 상향 가능 |
분당 30건이면 대부분의 푸터 폼에 충분하지만, 무료 퍼블리케이션의 출시 글이 이를 넘을 수 있습니다. 릴레이의 503 덕분에 Ikiform은 가입을 버리지 않고 기다렸다가 재시도합니다. 플랜 이름과 한도는 바뀌므로, 내 플랜이 목록에 없다면 beehiiv의 레이트 리밋 페이지를 확인하세요.
주의할 점
- 커스텀 필드 이름은 정확해야 합니다. beehiiv는 이름으로 커스텀 필드를 맞추고, 모르는 필드는 오류가 아니라 응답의 경고와 함께 버립니다. 오타가 있으면 이름이 조용히 사라집니다.
referring_site는 비어 있을 수 있습니다. 브라우저가 referrer를 보내지 않으면meta.referrer는null이고, 릴레이는 그 필드를 뺍니다.- 기존 구독자. beehiiv 문서에 따르면 이 호출은 구독을 만들거나 업데이트하지만, 활성 구독자에게 무엇이 바뀌는지는 나와 있지 않습니다. 폼을 모든 페이지에 두기 전에 확인된 내 주소로 테스트하세요.
- 키는 기본적으로 워크스페이스 전체에 적용됩니다. 퍼블리케이션 제한이 없는 키는 워크스페이스의 모든 퍼블리케이션에 접근할 수 있습니다. 범위를 제한하세요.
- 유료 등급은 beehiiv에 남습니다. 가입이 유료 구독 없이 이루어지도록
tier는 빼세요. 업그레이드는 beehiiv 자체 결제에서 이루어집니다.
작동 확인하기
- Ikiform의 엔드포인트에서 Send test를 누르세요. 전달에
204가 표시되고 beehiiv에는 요청이 가지 않습니다. - 내 주소로 페이지에서 구독하세요. 전달에
204가 표시됩니다. - beehiiv에서 구독자가 pending으로 나타나며, 위치는 UTM source로, 글은 referring site로 표시됩니다.
- 더블 옵트인 이메일이 도착합니다. 확인하면 환영 이메일이 이어집니다.
- beehiiv에서 그 주소를 수신 거부하고 다시 가입하세요.
reactivate_existing이 false이므로 구독자는 비활성 상태로 남습니다.
질문
네. 폼을 Ikiform으로 POST하고, 릴레이가 가입마다 beehiiv의 구독 생성 엔드포인트를 호출하게 하세요. 폼은 내 디자인을 유지하고, 확인, 환영, 이메일 발송은 여전히 beehiiv가 합니다.
beehiiv 요금 페이지에는 모든 플랜에 API 접근이 있다고 나와 있고, 레이트 리밋 페이지는 가장 낮은 플랜에 분당 30개 요청을 줍니다. Send API는 상위 플랜으로 제한되지만, 구독 생성에는 쓰이지 않습니다.
구독 생성 요청에서 double_opt_override를 "on"으로 보내거나, 퍼블리케이션 자체 설정을 쓰려면 "not_set"을 보내세요. "off"는 이메일 없이 구독자를 바로 활성화합니다.
네. beehiiv는 Zapier, Make와 함께 동작하며, 이 도구들이 레이트 리밋을 대신 지켜 줍니다. Ikiform 웹훅을 자동화로 보내고 구독자를 추가하는 beehiiv 액션을 쓰세요.
막히는 단계가 있거나 내 상황에 맞는 가이드가 필요하다면 이메일을 보내세요: hello@ikiform.com.