Resend란? 이메일 API 사용법 — Cloudflare Pages · Astro 문의하기 연동 · 무료 한도 · 요금 · 장단점

Astro·Hugo·Cloudflare Pages로 정적 홈페이지를 올리면 「문의하기」가 막히는 경우가 많습니다. HTML만으로는 메일을 보낼 수 없고, API 키를 브라우저에 넣으면 바로 유출됩니다.
Resend는 개발자용 이메일 API입니다. 서버리스 함수(Workers · Pages Functions · Vercel Functions 등) 뒤에서 호출하면, 정적 사이트에도 안정적인 문의 폼을 붙일 수 있습니다. 이번 글에서는 Resend가 무엇인지, 무료 계정 한도·요금·장단점, 정적 사이트 「문의하기」 구현 흐름을 공식 문서 기준으로 정리합니다.
· 정의 — 개발자용 이메일 API (Transactional · Marketing Broadcasts)
· 준비물 — 본인 도메인 인증 + API 키 (
RESEND_API_KEY)· Free(Transactional) — 월 3,000통 · 일 100통 · 도메인 1개 · 초과 과금 없음
· Pro — 월 $20부터 (50,000통) · 일일 한도 없음 · 초과 시 1,000통당 $0.90
· 정적 사이트 핵심 — API 키는 서버/엣지 함수에만 · 프론트는 폼 POST만
· 문서 — resend.com/docs/introduction · resend.com/pricing
Resend란?
Resend는 애플리케이션에서 이메일을 보내기 위한 이메일 API입니다. 공식 소개(Introduction) 기준으로, 시작에 필요한 것은 본인 도메인 인증과 API 키입니다.
보낼 수 있는 메일은 크게 두 가지입니다.
- Transactional — 가입 확인, 비밀번호 재설정, 문의 폼 알림처럼 이벤트 단위로 보내는 메일
- Marketing (Broadcasts) — 연락처 목록에 대량으로 보내는 캠페인
Node.js · Next.js · Python · Go · PHP · Laravel 등 공식 SDK가 있고, REST API · SMTP 릴레이도 지원합니다. React Email로 HTML 템플릿을 컴포넌트처럼 작성할 수도 있습니다.
정적 HTML/CSS/JS만으로는 메일을 「안전하게」 보낼 수 없습니다. Resend는 서버(또는 서버리스)에서 호출하는 API입니다. Cloudflare Pages · Astro 정적 사이트라면 Pages Functions / Workers 같은 얇은 백엔드를 한 겹 두는 구성이 정석입니다.
왜 정적 사이트에 「문의하기」가 어려운가
| 방식 | 문제 | 권장 여부 |
|---|---|---|
| 브라우저에서 Resend 직접 호출 | API 키 노출 · 스팸 남용 | 금지 |
mailto:만 사용 |
메일 앱 의존 · UX 불편 · 추적 어려움 | 임시용 |
| 서드파티 폼(외부 SaaS) | 브랜드·데이터 위치·한도 제각각 | 상황에 따라 |
| 폼 → 서버리스 → Resend | 함수·환경변수 설정 필요 | 권장 |

re_xxxx API 키를 넣으면 누구나 키를 복사해 메일 쿼터를 소진할 수 있습니다. 키는 환경 변수(RESEND_API_KEY)로만 보관하세요.정적 홈페이지 「문의하기」 구현 흐름
실무에서 많이 쓰는 구조는 아래와 같습니다.
/api/contact (Cloudflare Pages Functions · Workers · Vercel Serverless)fetch('/api/contact', { method: 'POST', ... })from은 인증 도메인 · to는 본인 수신 주소 · replyTo에 방문자 이메일방문자 브라우저 → 정적 폼 → Pages Function / Worker(API 키 보관) → Resend API → 내 메일함
배포 면은 Cloudflare Pages · 콘텐츠 면은 Astro와 잘 맞습니다. Vercel이라면 Vercel 배포 가이드의 Functions를 같은 역할로 쓰면 됩니다.
무료 계정 시작 — 사용법 위주
1) 가입과 API 키
Dashboard에서 API Key를 만들고, 로컬·배포 환경에 RESEND_API_KEY로 넣습니다. 코드에 하드코딩하지 마세요.
RESEND_API_KEY=re_xxxxxxxxx
2) 도메인 인증
프로덕션 from 주소는 인증된 도메인이어야 합니다. 테스트 전용 주소 onboarding@resend.dev는 개발·샘플용이며, 실제 서비스 from으로 쓰지 않는 것이 공식 가이드입니다.
3) Node.js SDK로 전송 (서버 측)
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
const { data, error } = await resend.emails.send({
from: '문의 알림 <hello@yourdomain.com>',
to: ['you@yourdomain.com'],
replyTo: visitorEmail,
subject: `[문의] ${subject}`,
html: `<p><b>이름</b>: ${name}</p><p>${message}</p>`,
});
if (error) { /* 429·검증 실패 등 처리 */ }
// data.id 로 전송 로그 추적
SDK는 { data, error }를 반환합니다. 네트워크 예외만 try/catch로 잡고, API 오류는 error 객체를 확인하는 패턴이 공식 권장입니다. 파라미터는 camelCase(replyTo)를 씁니다.
4) Cloudflare Pages Functions 스케치
functions/api/contact.ts(경로는 프로젝트 규칙에 맞게)에서 POST만 받고, 본문을 검증한 뒤 위 SDK(또는 fetch로 REST)를 호출합니다. Pages 대시보드 Environment Variables에 RESEND_API_KEY를 등록합니다.
await fetch('/api/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, email, message }),
});
delivered@resend.dev · bounced@resend.dev 등)를 쓰면 도메인 평판을 해치지 않고 이벤트를 확인할 수 있습니다.비용·한도 (공식 Pricing 기준)
요금은 변동될 수 있으니 발행 직전 resend.com/pricing을 다시 확인하세요. 아래는 문서·요금표에 공개된 Transactional 기준 요약입니다.
| 플랜 | 월 요금 | 포함 발송 | 비고 |
|---|---|---|---|
| Free | $0 | 3,000 / 월 | 일 100통 · 초과 과금 없음 · 한도 초과 시 전송 제한(429) |
| Pro | $20 | 50,000 / 월 | 일일 한도 없음 · 초과 1,000통당 $0.90 |
| Pro | $35 | 100,000 / 월 | 동일 overage |
| Scale | $90~ | 100,000~ | 대량 · Dedicated IP 애드온 가능 |
· Transactional: 일 100 / 월 3,000 (발신·수신이 쿼터에 포함되는 안내)
· To / CC / BCC 수신자마다 통수로 집계
· Marketing Free: 연락처 최대 1,000/월 기준(캠페인 메일 수 제한이 아닌 연락처 기준)
· Automation Runs: 월 10,000 (Free는 overage 없음)
· 데이터 보관: 30일 · AI credits: 5/월
· 기본 rate limit: 팀당 초당 10 요청(초과 시 429)
하루 문의가 수십 건을 넘지 않는 개인 사이트·랜딩이면 Free(일 100)로 시작하는 경우가 많습니다. 런칭·캠페인으로 스파이크가 예상되면 Pro로 올려 일일 한도를 없애는 편이 안전합니다.
장단점
| 구분 | 장점 | 단점·주의 |
|---|---|---|
| 개발 DX | SDK·문서·React Email · 테스트 주소 체계가 명확 | 정적만으로는 불가 · 서버리스 한 겹 필수 |
| 비용 | Free 3,000통으로 MVP·포트폴리오에 여유 | Free는 일 100 · 초과 과금 없음(막힘) · 유료는 overage 관리 필요 |
| 전달성 | 도메인 인증 · DKIM/SPF/DMARC · 웹훅 | 도메인·DNS 설정이 초보에게 허들 |
| 운영 | 트랜잭션·마케팅 분리 · 대시보드 활동 확인 | 문의 DB 저장은 Resend 역할 밖(필요 시 Supabase 등) |

실무 팁 — 스팸·보안·UX
- Turnstile / CAPTCHA — 봇이 폼을 두드리면 Free 일일 100이 금방 소진됩니다.
- 서버에서 검증 — 이메일 형식 · 메시지 최대 길이 · 빈 필드 거부
- replyTo — 방문자 이메일을
replyTo에 두면 수신 한 번으로 회신 가능 - idempotencyKey — 네트워크 재시도 시 중복 발송을 줄일 때 유용(키 유효 24시간)
- 로그 — 응답의
data.id를 남겨 전달 실패를 추적
자주 묻는 질문 (FAQ)
Q1. API 키를 GitHub에 올려도 되나요?
A. 안 됩니다. Secrets·Environment Variables만 쓰고, 유출 시 즉시 키를 폐기·재발급하세요.
Q2. 정적 HTML만 있는 사이트에도 가능한가요?
A. 가능합니다. 프론트는 정적 그대로 두고, Cloudflare Pages Functions 또는 별도 Worker URL로 POST만 넘기면 됩니다.
Q3. Free로 하루 100통을 넘기면?
A. Free는 일·월 한도 초과 시 전송이 막히고(429 등), Free에는 overage 과금이 없습니다. 유료로 올리거나 다음 일/월 쿼터를 기다려야 합니다.
Q4. SendGrid·Amazon SES와 뭐가 다른가요?
A. 모두 이메일 인프라이지만, Resend는 개발자 API·DX·React Email 쪽에 초점이 맞춰진 제품입니다. 팀 규모·기존 AWS 스택·단가에 따라 선택하면 됩니다.
Q5. 마케팅 메일과 문의 알림을 같은 플랜으로 쓰나요?
A. Transactional과 Marketing은 요금표가 나뉩니다. 문의 폼은 보통 Transactional 쿼터를 씁니다. 뉴스레터는 Marketing(연락처 수 기준)을 별도로 확인하세요.
체크포인트
- resend.com에서 도메인 Verified · API 키를 Secrets에만 등록했는가
- 프론트 번들·공개 repo에
re_키가 없는가 from이 인증 도메인이고, 테스트용onboarding@resend.dev를 프로덕션에 쓰지 않는가- 폼 → 서버리스 → Resend 경로에 Turnstile·길이 제한·레이트 리밋이 있는가
- Free 일 100 / 월 3,000을 넘길 트래픽인지 미리 봤는가
- 요금·한도는 발행 전 resend.com/pricing · Knowledge Base를 재확인했는가
Resend는 「정적 사이트에 메일을 붙여 주는 마법」이 아니라, 서버에서 호출하는 이메일 API입니다. Astro·Pages로 올린 홈페이지라면 Functions 한 겹만 추가하면 「문의하기」를 무료 한도 안에서 충분히 굴릴 수 있습니다.
오늘은 계정 생성 → 도메인 인증 → /api/contact 스케치까지 가 보세요. 배포는 444 — Cloudflare Pages, 사이트 뼈대는 445 — Astro와 이어서 보면 흐름이 이어집니다.
폼은 정적에,
메일은 Resend로.
#Resend #이메일API #문의하기 #정적사이트 #CloudflarePages #Astro #서버리스 #무료플랜 #트랜잭션메일 #브랜드홈페이지