Skip to navigation

이메일 발송

View as Markdown

이메일 한 통을 발송합니다. from 은 이 계정에 등록되고 검증(verified)된 도메인의 주소여야 합니다 — 도메인 등록·검증은 「이메일 발신 도메인」 API 로 먼저 마치십시오.

기본 사용법

{
"from": "no-reply@example.com",
"to": ["customer@gmail.com"],
"subject": "주문이 접수되었습니다",
"body": "주문번호 1024 접수되었습니다."
}

첨부

첨부는 URL 로 전달합니다. 파일 바이트를 요청 본문에 실을 수 없습니다.

{
"from": "no-reply@example.com",
"to": ["customer@gmail.com"],
"subject": "영수증",
"body": "영수증을 첨부합니다.",
"attachmentUrl": ["https://files.example.com/receipt-1024.pdf"]
}

우리가 그 URL 을 서버에서 내려받아 메일에 붙입니다. 그래서 URL 은 인증 없이 접근 가능한 공개 주소여야 하고, 사설 대역(10.*·192.168.*·127.*)이나 클라우드 메타데이터 주소를 가리키면 400 attachment_url_not_allowed 로 거절합니다.

수신자와 크기 상한

  • 수신자는 to·cc·bcc 를 합쳐 최대 50명입니다(공급자 제약, 조정 불가). 넘으면 400 too_many_recipients.

  • 메시지 전체는 5MB 입니다. ⚠️ 이 값은 첨부를 base64 로 인코딩한 뒤 기준이라 원본 파일 크기의 약 1.37배로 계산됩니다 — 즉 원본 파일 기준 약 3.6MB 까지입니다. 넘으면 400 message_too_large.

    대부분의 거래 메일(영수증·주문확인·계약서 PDF)은 이 안에 들어갑니다. 더 큰 파일은 첨부 대신 링크로 보내 주세요 — 받는 사람의 메일 서버가 큰 첨부를 거부하는 경우가 많아(Gmail 25MB · Outlook 20MB 대) 반송으로 돌아올 가능성이 높습니다.

과금 단위는 “통”이 아니라 “수신자”입니다

⚠️ 한 통을 3명에게 보내면 3건으로 과금됩니다. to·cc·bcc 를 가리지 않습니다. 첨부가 있으면 전송 데이터량도 함께 과금됩니다.

발송 결과

이 API 의 201 은 공급자가 접수했다는 뜻이지 수신함에 도착했다는 뜻이 아닙니다. 실제 전달·반송·수신거부는 비동기로 확인되며, 그 결과를 보는 API 는 아직 제공하지 않습니다.

Authentication

AuthorizationBearer

API Key를 Bearer 토큰으로 전달

Path parameters

accountIdstringRequired

계정 ID

Request

This endpoint expects an object.
fromstringRequiredformat: "email"

발신 주소. 이 계정에서 검증된 도메인의 주소여야 합니다.

검증되지 않았거나 남의 계정 도메인이면 403 email_domain_not_verified 입니다. 도메인이 pending 인 동안에도 발신할 수 없습니다 — DNS 레코드를 심고 검증 API 로 verified 를 만든 뒤에 쓰십시오.

tolist of stringsRequired

수신 주소. cc·bcc 와 합쳐 50명을 넘을 수 없습니다.

subjectstringRequired<=998 characters

제목. 한글 등 비ASCII 문자를 그대로 쓸 수 있습니다.

cclist of stringsOptional

참조. 수신자 수에 포함됩니다.

bcclist of stringsOptional

숨은 참조. 수신자 수에 포함되며 과금됩니다.

다른 수신자에게는 보이지 않지만 발송 이력에는 남습니다.

bodystringOptional

본문(평문). html 과 둘 중 하나 이상은 있어야 합니다 — 둘 다 없으면 400 body_required 입니다.

둘 다 주면 수신자의 메일 클라이언트가 표시 가능한 쪽을 고릅니다. HTML 만 보내는 것보다 평문을 함께 주는 편이 스팸 판정에 유리합니다.

htmlstringOptional

본문(HTML). body 와 둘 중 하나 이상 필요합니다.

attachmentUrllist of stringsOptional

첨부 파일 URL. 우리가 서버에서 내려받아 메일에 붙입니다.

  • https 만 받습니다. 인증 없이 접근 가능해야 합니다.
  • 사설 대역·루프백·클라우드 메타데이터 주소는 400 attachment_url_not_allowed.
  • 내려받지 못하면(404·타임아웃 등) 400 attachment_fetch_failed 이고 메일은 발송되지 않습니다.
  • 파일명은 URL 경로에서 가져옵니다.

⚠️ 공급자가 거부하는 확장자가 있습니다(실행 파일 등). 그 거부는 발송 시점에 일어나므로 502 로 돌아옵니다 — 요청 검증 단계에서는 걸러지지 않습니다.

replyTolist of stringsOptional

답장 주소(Reply-To). 받는 사람이 답장하면 from 이 아니라 이 주소로 갑니다. no-reply@ 로 보내고 support@ 로 받는 구성에 씁니다.

⚠️ 스레드와는 무관합니다. 대화를 잇는 것은 아래 두 필드입니다.

inReplyTostringOptional<=200 characters

답장하는 원본 메일의 Message-ID. 조회 응답이나 email.received webhook 의 messageId 를 그대로 넣으십시오. 꺾쇠(< >)는 있어도 없어도 됩니다.

⚠️ 이것만으로는 부족합니다 — 2회차 이후의 답장은 references 도 함께 채워야 여러 클라이언트에서 한 대화로 묶입니다.

⛔ 헤더가 완벽해도 제목이 다르면 Gmail·Outlook 은 새 대화로 엽니다. 두 클라이언트는 정규화한 제목을 함께 봅니다. 원본 제목에 Re: 를 붙인 형태를 그대로 쓰시고, 이미 Re: 로 시작하면 덧붙이지 마십시오.

referenceslist of stringsOptional

대화의 조상 사슬. 오래된 것이 앞입니다. 원본 메일 m 에 답장한다면 [...m.references, m.messageId] 입니다.

⚠️ 긴 대화는 공급자 헤더 길이 상한(986자) 때문에 RFC 5537 §3.4.4 에 따라 줄여서 보냅니다 — 첫 항목과 최근 항목은 남고 가운데가 빠집니다. 발송은 실패하지 않으며, 응답의 references 가 실제로 나간 목록입니다.

idempotencyKeystringOptional1-255 characters

발송 멱등키. 같은 계정에서 같은 키로 다시 요청하면 발송하지 않고 1회차 결과를 그대로 돌려줍니다. 재시도 경로가 있는 호출자만 채우십시오.

미지정이면 매번 발송합니다. 빈 문자열은 400 입니다 — 템플릿에서 빈 값이 들어가 멱등이 조용히 꺼진 채 중복 발송되는 걸 막습니다.

⚠️ 순차 재시도를 막는 용도입니다. 같은 키로 동시에 두 요청이 들어오면 둘 다 발송될 수 있습니다.

⚠️ 본문이 달라도 검사하지 않습니다. 같은 키로 다른 내용을 보내면 새 메일은 나가지 않고 1회차 결과가 돌아옵니다. 키는 메일 한 통 단위로 만드십시오 (order-1024-접수 처럼). 만료도 없습니다.

Response

발송 접수 성공. 공급자가 받았다는 뜻이며 수신함 도착을 보장하지 않습니다.

emailIdstring

ClawOps 이메일 리소스 ID.

directionenum

outbound 는 이 계정이 보낸 메일, inbound 는 이 계정의 수신 도메인으로 들어온 메일입니다.

Allowed values:
statusenum

보낸 메일은 sent(공급자 접수) 또는 failed 입니다 — sent 는 접수됐다는 뜻이지 수신함 도착이 아닙니다. 받은 메일은 항상 received 입니다.

Allowed values:
fromstringformat: "email"
tolist of strings
recipientCountinteger

보낸 메일에서는 과금 단위입니다 — 실제로 발송한 To+Cc+Bcc 의 합계이며 한 통을 3명에게 보내면 3입니다. 수신거부로 빠진 주소는 세지 않습니다(suppressed 참고). 받은 메일에서는 이 계정에 실제로 배달된 주소 수(recipients 의 길이)입니다.

createdAtdatetime
cclist of stringsOptional
bcclist of stringsOptional
suppressedlist of stringsOptional

수신거부 명단에 있어 이 발송에서 빠진 주소들. 요청한 표기 그대로 돌려줍니다.

⚠️ 이메일은 차단된 수신자가 있어도 나머지에게는 보냅니다(전화·문자가 발신 전체를 거절하는 것과 다릅니다). 그래서 201 을 받고도 일부가 안 갔을 수 있고, 이 칸이 그걸 알려주는 유일한 자리입니다. 비어 있으면 아무도 빠지지 않았다는 뜻입니다.

recipientCount 에는 포함되지 않습니다 — 요청한 수신자 수는 recipientCount + suppressed.length 입니다. 받은 메일에서는 항상 빈 배열입니다.

subjectstring or nullOptional
attachmentCountintegerOptional
failureCodestring or nullOptional

실패 사유 코드. status 가 sent 면 null 입니다.

provider_unavailable 은 공급자를 부르지 못한 경우이고, 그 밖의 값은 공급자가 거절한 경우입니다.

failureMessagestring or nullOptional

사람이 읽는 실패 설명. status 가 sent 면 null 입니다.

replyTolist of stringsOptional

답장 주소(Reply-To). 받은 메일은 발신자가 지정한 주소, 보낸 메일은 발송할 때 지정한 값입니다.

⭐ 답장은 from 이 아니라 이 주소로 보내십시오. 비어 있을 때만 from 이 답장 주소입니다(RFC 5322 §3.6.2). 뉴스레터·티켓 시스템은 대부분 이 값을 다르게 둡니다.

messageIdstring or nullOptional

이 메일 자신의 Message-ID(꺾쇠 < > 제외). 답장할 때 inReplyTo 에 그대로 넣는 값입니다.

⛔ 보낸 메일은 항상 null 입니다. 이 헤더는 공급자가 발급하며 우리가 지정한 값을 덮어쓰기 때문에 우리도 그 값을 모릅니다. ⚠️ 받은 메일도 null 일 수 있습니다 — 이 헤더는 RFC 상 필수가 아니고, 붙이지 않고 보내는 발신자가 실제로 있습니다. 그 메일에는 스레드로 답장할 수 없습니다.

inReplyTostring or nullOptional

이 메일이 답장한 원본의 Message-ID(꺾쇠 제외). 답장이 아니면 null 입니다.

referenceslist of stringsOptional

대화의 조상 사슬. 오래된 것이 앞입니다. 다음 답장에 넘길 값은 [...references, messageId] 입니다.

⚠️ 보낸 메일의 값은 요청하신 목록이 아니라 실제로 헤더에 실어 보낸 목록입니다. 긴 대화는 공급자 헤더 길이 상한 때문에 RFC 5537 §3.4.4 에 따라 첫 항목과 최근 항목만 남기고 줄여 보냅니다.

recipientslist of strings or nullOptional

실제로 이 계정에 배달된 주소. 받은 메일에만 있습니다(보낸 메일은 null).

⚠️ to 를 보고 라우팅하지 마십시오. 숨은 참조(BCC)로 온 메일은 to 에 그 주소가 없습니다 — 이 필드에만 있습니다. 한 도메인에 support@·sales@ 처럼 여러 주소를 두고 처리를 나눈다면 반드시 이 값을 쓰십시오.

receivedAtdatetime or nullOptional

공급자가 메일을 받은 시각. 받은 메일에만 있습니다.

sizeBytesinteger or nullOptional

받은 메일의 원문 크기(바이트). ⚠️ 공급자가 덧붙인 헤더(약 3.6KB)가 포함된 값이라 메일 클라이언트가 보여 주는 크기와 다를 수 있습니다. 과금은 이 값 기준입니다.

verdictsobject or nullOptional

공급자의 스팸·바이러스·인증 판정. 받은 메일에만 있습니다.

⚠️ 값은 공급자 원문 그대로입니다(PASS·FAIL·GRAY·PROCESSING_FAILED 등). 우리가 해석하지 않으므로 목록이 늘어날 수 있습니다 — 모르는 값을 만나면 안전한 쪽으로 처리하십시오.

⛔ from 만 믿고 자동 처리하지 마십시오. 발신자는 위조될 수 있고, 그걸 판별하라고 spf·dkim·dmarc 를 함께 드립니다.

parseStatusenum or nullOptional

받은 메일의 본문 해석 결과. unparsable 이면 본문을 읽지 못한 것이며, 그때도 원문은 그대로 보관되어 단건 조회의 raw 로 받을 수 있습니다.

Allowed values:

Errors

400
Bad Request Error
401
Unauthorized Error
403
Forbidden Error
422
Unprocessable Entity Error
502
Bad Gateway Error
503
Service Unavailable Error