요약
Brevo API를 사용하면 마케팅 이메일, 트랜잭션 이메일, SMS 메시지를 프로그램으로 보낼 수 있습니다. API 키로 인증하고 api.brevo.com으로 요청을 보내며, 웹훅을 사용하여 전송 및 참여를 추적합니다. 테스트를 위해서는 Apidog를 사용하여 페이로드를 검증하고, 웹훅 핸들러를 테스트하며, 통합이 반송 및 구독 취소를 올바르게 처리하는지 확인하세요.
소개
Brevo (이전 Sendinblue)는 50만 개 이상의 기업을 위해 매일 수백만 개의 이메일을 처리합니다. 마케팅 캠페인, 트랜잭션 이메일, SMS 마케팅 및 자동화 워크플로우를 처리합니다.
이메일 API는 메시지를 보내는 간단한 것처럼 보입니다. 그러나 실제 운영 환경의 이메일 시스템은 반송, 스팸 불만, 구독 취소 및 전송 시간을 처리해야 합니다. Brevo는 이러한 복잡성을 관리하므로 사용자가 직접 처리할 필요가 없습니다.
API는 세 가지 주요 사용 사례를 다룹니다:
- 마케팅 캠페인 - 연락처 목록에 대량 이메일 발송
- 트랜잭션 이메일 - 비밀번호 재설정, 주문 확인, 알림
- SMS 메시지 - 인증 코드, 알림, 마케팅 문자 메시지
인증 및 설정
API 키 받기
- Brevo에 로그인
- SMTP & API → API 키로 이동
- 적절한 권한으로 새 키 생성
- 안전하게 보관
API 키는 api-key 헤더에 포함됩니다:
curl -X GET "https://api.brevo.com/v3/account" \
-H "accept: application/json" \
-H "api-key: your-api-key-here"
API 기본 URL
모든 요청은 다음으로 전송됩니다:
https://api.brevo.com/v3/
전송량 제한
Brevo는 요금제에 따라 요청을 제한합니다:
- 무료: 분당 300 요청
- 스타터: 분당 600 요청
- 비즈니스: 분당 1200 요청
X-RateLimit-Remaining 헤더를 확인하여 사용량을 추적하세요.
트랜잭션 이메일 전송
트랜잭션 이메일은 사용자 행동에 의해 트리거되는 개별 메시지입니다. 비밀번호 재설정, 주문 확인, 환영 이메일 등을 생각해보세요.
간단한 이메일 보내기
curl -X POST "https://api.brevo.com/v3/smtp/email" \
-H "accept: application/json" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"sender": {
"name": "Your App",
"email": "noreply@yourapp.com"
},
"to": [
{
"email": "user@example.com",
"name": "John Doe"
}
],
"subject": "Welcome to Our Platform",
"htmlContent": "<html><body><h1>Welcome!</h1><p>Thanks for signing up.</p></body></html>",
"textContent": "Welcome! Thanks for signing up."
}'
응답:
{
"messageId": "<20260324123456.123456@relay.brevo.com>"
}
템플릿 사용
Brevo의 시각 편집기에서 템플릿을 생성한 다음 ID로 전송합니다:
curl -X POST "https://api.brevo.com/v3/smtp/email" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"templateId": 15,
"to": [
{
"email": "user@example.com",
"name": "John Doe"
}
],
"params": {
"name": "John",
"order_number": "ORD-12345",
"tracking_url": "https://tracking.example.com/ORD-12345"
}
}'
템플릿 변수는 이중 중괄호를 사용합니다:
<p>Hi {{params.name}},</p>
<p>Your order {{params.order_number}} has shipped.</p>
<p><a href="{{params.tracking_url}}">Track your package</a></p>
첨부 파일과 함께 보내기
const response = await fetch('https://api.brevo.com/v3/smtp/email', {
method: 'POST',
headers: {
'api-key': process.env.BREVO_API_KEY,
'content-type': 'application/json'
},
body: JSON.stringify({
sender: { name: 'Your App', email: 'noreply@yourapp.com' },
to: [{ email: 'user@example.com' }],
subject: 'Your Invoice',
htmlContent: '<p>Please find your invoice attached.</p>',
attachment: [
{
name: 'invoice.pdf',
content: base64EncodedPdfContent
}
]
})
})
마케팅 캠페인
마케팅 이메일은 연락처 목록으로 전송됩니다. Brevo는 구독 취소 링크, 예약 및 분석을 처리합니다.
캠페인 생성
curl -X POST "https://api.brevo.com/v3/emailCampaigns" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"name": "March Newsletter",
"subject": "What'\''s New in March",
"sender": {
"name": "Your Brand",
"email": "newsletter@yourbrand.com"
},
"type": "classic",
"htmlContent": "<html><body>Newsletter content here...</body></html>",
"recipients": {
"listIds": [12, 15]
},
"scheduledAt": "2026-03-25T09:00:00+00:00"
}'
즉시 보내기
curl -X POST "https://api.brevo.com/v3/emailCampaigns/{campaignId}/sendNow" \
-H "api-key: your-api-key"
캠페인 통계 가져오기
curl -X GET "https://api.brevo.com/v3/emailCampaigns/{campaignId}" \
-H "api-key: your-api-key"
응답 포함:
{
"statistics": {
"delivered": 4850,
"opened": 1455,
"clicked": 291,
"unsubscribed": 12,
"bounces": 150
}
}
연락처 관리
연락처는 이메일을 보내는 대상입니다. 연락처를 목록으로 구성하고 사용자 지정 속성을 추가합니다.
연락처 생성
curl -X POST "https://api.brevo.com/v3/contacts" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"email": "new.user@example.com",
"attributes": {
"FIRSTNAME": "Jane",
"LASTNAME": "Smith",
"PLAN": "premium"
},
"listIds": [12, 15],
"updateEnabled": true
}'
updateEnabled: true 플래그는 기존 연락처를 업데이트하며 실패하지 않습니다.
연락처 세부 정보 가져오기
curl -X GET "https://api.brevo.com/v3/contacts/user@example.com" \
-H "api-key: your-api-key"
목록에 추가
curl -X POST "https://api.brevo.com/v3/contacts/lists/12/contacts/add" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"emails": ["user1@example.com", "user2@example.com"]
}'
목록에서 제거
curl -X DELETE "https://api.brevo.com/v3/contacts/lists/12/contacts/remove" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"emails": ["user@example.com"]
}'
연락처 구독 취소
curl -X PUT "https://api.brevo.com/v3/contacts/user@example.com" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"emailBlacklisted": true
}'
SMS 마케팅
Brevo는 SMS API를 통해 전 세계적으로 SMS 메시지를 보냅니다.
SMS 보내기
curl -X POST "https://api.brevo.com/v3/transactionalSMS/sms" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"sender": "YourApp",
"recipient": "+15551234567",
"content": "Your verification code is: 123456",
"type": "transactional"
}'
마케팅 SMS 보내기
curl -X POST "https://api.brevo.com/v3/transactionalSMS/sms" \
-H "api-key: your-api-key" \
-H "content-type: application/json" \
-d '{
"sender": "YourBrand",
"recipient": "+15551234567",
"content": "Flash sale! 50% off today only. Reply STOP to unsubscribe.",
"type": "marketing"
}'
SMS 통계 가져오기
curl -X GET "https://api.brevo.com/v3/transactionalSMS/statistics?startDate=2026-03-01&endDate=2026-03-31" \
-H "api-key: your-api-key"
추적을 위한 웹훅
웹훅은 이메일 이벤트(전송됨, 열림, 클릭됨, 반송됨, 구독 취소됨)에 대해 앱에 알립니다.
웹훅 구성
Brevo 대시보드에서: 설정 → 웹훅 → 웹훅 추가
추적할 이벤트:
delivered- 이메일이 받은 편지함에 도달함opened- 수신자가 이메일을 열었음clicked- 수신자가 링크를 클릭했음bounced- 이메일이 반송됨 (하드 또는 소프트 반송)spam- 스팸으로 표시됨unsubscribed- 수신자가 구독을 취소했음
웹훅 페이로드 처리
app.post('/webhooks/brevo', (req, res) => {
const event = req.body
switch (event.event) {
case 'delivered':
console.log(`Email ${event.messageId} delivered to ${event.email}`)
break
case 'opened':
console.log(`Email opened by ${event.email} at ${event.date}`)
break
case 'bounced':
console.log(`Bounce: ${event.email} - ${event.reason}`)
// Mark contact as invalid
markContactBounced(event.email)
break
case 'spam':
console.log(`Spam complaint from ${event.email}`)
// Remove from all lists
removeFromAllLists(event.email)
break
case 'unsubscribed':
console.log(`Unsubscribed: ${event.email}`)
break
}
res.status(200).send('OK')
})
Apidog로 테스트하기
이메일 API에는 복잡한 실패 모드가 있습니다. 템플릿, 반송 및 웹훅을 테스트해야 합니다. Apidog가 도움이 됩니다.

1. 이메일 전송 모의(Mock)
개발 중에는 실제 이메일을 보내지 마세요. 응답을 모의하세요:
pm.test('Email API accepts valid payload', () => {
const response = pm.response.json()
pm.expect(response).to.have.property('messageId')
pm.expect(response.messageId).to.match(/<.*@relay\.brevo\.com>/)
})

2. 웹훅 처리 테스트
Apidog에서 모의 웹훅 페이로드를 생성하세요:
{
"event": "bounced",
"email": "invalid@example.com",
"messageId": "<12345@relay.brevo.com>",
"reason": "hard_bounce",
"date": "2026-03-24T12:00:00Z",
"subject": "Welcome to Our Platform"
}
웹훅 엔드포인트로 보내고 코드가 이를 처리하는지 확인하세요.
3. 템플릿 유효성 검사
템플릿 페이로드를 저장하고 변수가 올바르게 대체되는지 테스트하세요:
pm.test('Template variables are valid', () => {
const payload = pm.request.body.toJSON()
pm.expect(payload.params).to.have.property('name')
pm.expect(payload.params).to.have.property('order_number')
})
4. 환경 분리
# Development
BREVO_API_KEY: xkeysib-dev-xxx
BREVO_SENDER: dev@yourapp.com
# Production
BREVO_API_KEY: xkeysib-prod-xxx
BREVO_SENDER: noreply@yourapp.com
Apidog로 Brevo 이메일 API 무료 테스트
일반적인 오류 및 해결 방법
400 Bad Request - 필수 필드 누락
원인: 페이로드에 필수 필드가 누락되었습니다.
해결: 오류 메시지에서 자세한 내용을 확인하세요:
{
"code": "invalid_parameter",
"message": "sender.email is required"
}
401 Unauthorized
원인: 유효하지 않거나 누락된 API 키입니다.
해결: api-key 헤더가 올바르게 설정되었는지 확인하세요. 키가 취소되지 않았는지 확인하세요.
402 Payment Required
원인: 계정이 제한을 초과했거나 크레딧이 부족합니다.
해결:
- 이메일의 경우: 요금제 이메일 제한을 확인하세요.
- SMS의 경우: SMS 크레딧을 구매하세요.
429 Too Many Requests
원인: 전송량 제한을 초과했습니다.
해결: 지수 백오프(exponential backoff)를 구현하세요:
async function sendWithRetry(email, retries = 3) {
for (let i = 0; i < retries; i++) {
const response = await sendEmail(email)
if (response.status === 429) {
await sleep(Math.pow(2, i) * 1000)
} else {
return response
}
}
throw new Error('Rate limit exceeded')
}
404 연락처를 찾을 수 없음
원인: 존재하지 않는 연락처를 업데이트하려고 시도했습니다.
해결: 연락처를 생성할 때 updateEnabled: true를 사용하세요:
{
"email": "new@example.com",
"updateEnabled": true
}
이렇게 하면 연락처가 생성되거나 업데이트됩니다.
대안 및 비교
| 기능 | Brevo | SendGrid | Mailchimp | Postmark |
|---|---|---|---|---|
| 가격 정책 | 일일 300 이메일 무료 | 일일 100 이메일 무료 | 월 500 이메일 무료 | 월 100 이메일 무료 |
| 마케팅 이메일 | 예 | 예 | 예 | 아니요 |
| 트랜잭션 이메일 | 예 | 예 | 제한적 | 예 (전문) |
| SMS | 예 | 아니요 | 아니요 | 아니요 |
| 자동화 | 예 | 예 | 예 | 제한적 |
| 템플릿 편집기 | 시각 + 코드 | 코드 | 시각 | 코드 |
Brevo는 경쟁력 있는 가격으로 이메일과 SMS 지원을 결합하여 돋보입니다.
실제 사용 사례
전자상거래 주문 흐름. 온라인 상점은 Brevo를 다음 용도로 사용합니다: 주문 확인(트랜잭션), 배송 알림(트랜잭션), 장바구니 포기 복구(마케팅 자동화), 주간 프로모션(마케팅 캠페인). 이 모든 것을 하나의 통합으로 처리합니다.
SaaS 온보딩. 프로젝트 관리 도구는 트랜잭션 API를 통해 환영 이메일, 비밀번호 재설정 및 팀 초대를 보냅니다. 마케팅 이메일은 옵트인(opt-in) 사용자에게 새로운 기능을 알립니다.
SMS 인증. 핀테크 앱은 Brevo의 SMS API를 사용하여 2단계 인증 코드를 전송합니다. 트랜잭션 SMS 엔드포인트는 몇 초 안에 코드를 전달하며, 웹훅은 재시도 로직을 위해 전송 실패를 추적합니다.
결론
학습한 내용은 다음과 같습니다:
- Brevo API는 마케팅, 트랜잭션 이메일 및 SMS를 처리합니다.
api-key헤더로 인증합니다.- 일관되고 유지보수 가능한 이메일을 위해 템플릿을 사용합니다.
- 타겟 캠페인을 위해 연락처와 목록을 관리합니다.
- 웹훅은 전송, 열림, 클릭 및 반송을 추적합니다.
- 실제 사용자에게 보내기 전에 Apidog로 테스트합니다.
다음 단계:
- Brevo 계정을 만들고 API 키를 받으세요.
- 첫 번째 트랜잭션 이메일을 보내세요.
- 시각 편집기에서 템플릿을 만드세요.
- 반송 및 구독 취소에 대한 웹훅 핸들러를 설정하세요.
- 개발 단계에서 Apidog로 테스트하세요.
Apidog로 Brevo 이메일 API 무료 테스트
자주 묻는 질문
Brevo와 Sendinblue의 차이점은 무엇인가요? 같은 제품의 새 이름입니다. Sendinblue는 2023년에 Brevo로 리브랜딩했습니다. API는 여전히 api.brevo.com을 사용하지만, 이전 문서에서는 Sendinblue 참조를 볼 수 있습니다.
무료로 이메일을 몇 개나 보낼 수 있나요? 무료 요금제에서는 하루 300개의 이메일을 보낼 수 있습니다. 이는 한 달에 9,000개의 이메일입니다. 더 많이 보내려면 20,000개의 이메일에 대해 월 25달러부터 시작하는 유료 요금제로 업그레이드하세요.
콜드 이메일에 Brevo를 사용할 수 있나요? 기술적으로는 가능하지만 위험합니다. 콜드 이메일은 반송 및 스팸 비율이 높습니다. Brevo는 발신자 평판을 모니터링합니다. 불만율이 높으면 계정이 정지됩니다. 먼저 도메인을 워밍업하고 이메일 모범 사례를 따르세요.
이메일 반송을 어떻게 처리하나요? bounced 웹훅을 수신하세요. 하드 반송(유효하지 않은 이메일)은 연락처를 영구적으로 제거해야 합니다. 소프트 반송(사서함 가득 참, 일시적인 문제)은 재시도할 수 있습니다. 반송률을 추적하세요. 5%를 초과하면 발신자 평판이 저하됩니다.
마케팅 이메일과 트랜잭션 이메일의 차이점은 무엇인가요? 트랜잭션 이메일은 사용자 행동(구매, 가입)에 의해 트리거되며 단일 수신자에게 전송됩니다. 마케팅 이메일은 여러 수신자에게 동시에 보내는 캠페인입니다. Brevo는 전송률 및 규정 준수상의 이유로 이들을 분리합니다.
구독 취소 링크를 어떻게 추가하나요? Brevo는 마케팅 이메일에 구독 취소 링크를 자동으로 추가합니다. 트랜잭션 이메일의 경우, 다음 링크를 직접 추가하세요:
<a href="{{ unsubscribe_url }}">Unsubscribe</a>
내 도메인에서 이메일을 보낼 수 있나요? 예. SPF, DKIM 및 DMARC 레코드를 설정하세요. Brevo는 설정 → 발신자 & IP에서 해당 값을 제공합니다. 적절한 인증 없이는 이메일이 스팸으로 분류될 수 있습니다.
특정 시간대에 이메일을 예약하려면 어떻게 해야 하나요? scheduledAt 매개변수에 ISO 8601 타임스탬프를 사용하여 예약하세요:
{
"scheduledAt": "2026-03-25T09:00:00-05:00"
}
전송량 제한에 도달하면 어떻게 되나요? 429 오류가 발생합니다. 응답에는 재설정까지 남은 시간을 나타내는 X-RateLimit-Reset 헤더가 포함됩니다. 지수 백오프(exponential backoff)를 구현하거나 나중에 보낼 이메일을 대기열에 추가하세요.
