이메일
email 카테고리의 API 작업 11개를 다룹니다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /v1/hooks/ses | SES 반송, 불만 신고, 전달 웹훅 |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/email | 이메일 상태 (runlot email) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/email | 끈 이메일을 다시 켭니다 |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/email | 이메일을 끕니다 (runlot email delete) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/email/domains | 맞춤 발신 도메인 (runlot email domain list) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/email/domains | 맞춤 발신 도메인을 추가합니다 (runlot email domain add) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/email/domains/{domain}/verify | 발신 도메인을 지금 다시 확인합니다 (runlot email domain verify) |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/email/domains/{domain} | 발신 도메인을 삭제합니다 (runlot email domain rm) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/email/log | 이메일 로그 (runlot email log) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId} | 이메일 하나의 메타데이터 |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}/raw | 원본 이메일 메시지 (message/rfc822) |
POST /v1/hooks/ses
이 경로는 여러분이 직접 호출하는 것이 아닙니다. Amazon SNS가 HTTPS 구독을 통해 이곳으로 SES 이벤트를 전달합니다. 인증은 토큰이 아니라 SNS 서명으로 이루어지며 — 인증서 URL이 sns.<region>.amazonaws.com에서 https이고, topic이 서버의 RUNLOT_SES_SNS_TOPIC_ARN과 일치하는 경우에만 요청이 수락됩니다(그렇지 않으면 403). SubscriptionConfirmation은 SubscribeURL로 GET을 보내 자동으로 완료됩니다. 서버에 topic ARN이 없으면 501을 반환합니다. 클라이언트 라이브러리는 이를 호출하지 않습니다.
operationId sesHook
요청 본문: text/plain · string
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 수신됨(알 수 없는 이벤트 유형과 알 수 없는 id도 200을 반환합니다) | — |
| 400 | — | — |
| 403 | SNS 서명이 일치하지 않습니다 | — |
| 501 | 웹훅이 꺼져 있습니다 | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/email
email이 허용되었는지 여부와 함께 주소, 발신자, 시간당 한도, 최근 발신 및 수신 개수를 보여줍니다. 허용되지 않은 경우에도 address와 from은 값이 채워져 있어 켰을 때 주소가 어떻게 될지 미리 볼 수 있으며, 실제 상태는 granted입니다.
viewer 이상이 필요합니다.
operationId getEmail
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 이메일 상태 | EmailStatus |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core — 서비스를 일시적으로 사용할 수 없습니다 | Error |
POST /v1/orgs/{orgSlug}/projects/{projectName}/email
이 작업은 멱등적입니다. 요청 본문이 없으며 — 주소는 (<project>.<org>.<mail-domain>) 형식으로 자동 생성되고, 한도는 요금제에 따라 결정됩니다. 주소는 허용이 이루어진 시점의 프로젝트 이름으로 고정됩니다.
활성화되면 잠시 후 env.email이 worker에 연결되며, 해당 주소로 보낸 메일은 worker의 email() 핸들러로 전달됩니다. 발신과 수신은 함께 켜지며 — 하나의 도메인이 양방향을 모두 처리합니다.
멤버 이상 권한이 필요합니다. email.grant로 감사 기록됩니다.
operationId grantEmail
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 부여 상태(이미 있었다면 기존 값) | EmailStatus |
| 403 | — | — |
| 404 | — | — |
| 409 | email_unavailable — 이 배포에 메일 도메인이 없습니다. email_address_taken — 다른 프로젝트가 이미 같은 주소를 사용 중입니다 | Error |
| 503 | no_core — 서비스를 일시적으로 사용할 수 없습니다 | Error |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/email
해당 주소로 보낸 메일은 이제 550을 받습니다 — 발신 MTA는 반송을 받고 재시도하지 않습니다. 이는 멱등적입니다.
관리자 이상 권한이 필요합니다. 감사 이벤트 email.revoke.
operationId revokeEmail
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 꺼짐 | — |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core — 서비스를 일시적으로 사용할 수 없습니다 | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/email/domains
프로젝트 자체의 발신 도메인과 그 검증 상태입니다. 각 행에는 게시해야 할 정확한 DNS 레코드가 포함되어 있습니다.
viewer 이상이 필요합니다.
operationId listEmailDomains
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 발신 도메인 | object |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core — 서비스를 일시적으로 사용할 수 없습니다 | Error |
POST /v1/orgs/{orgSlug}/projects/{projectName}/email/domains
도메인을 DKIM으로 발신용으로 등록하고 게시해야 할 레코드를 응답합니다: 세 개의 <token>._domainkey.<domain> CNAME(필수), SPF TXT와 DMARC TXT(둘 다 권장 사항). 도메인은 verified 상태가 되어야만 env.email.send({ from })에서 사용할 수 있습니다.
publish: true를 지정하면 Runlot이 해당 도메인을 포함하는 zone을 호스팅하고 있고 동일한 조직에 속해 있는 경우 레코드를 zone에 바로 기록합니다. 직접 작성한 레코드는 절대 덮어쓰지 않습니다.
반복 호출은 오류가 아니며 토큰을 변경하지 않습니다 — 이미 게시된 레코드는 그대로 올바르게 유지됩니다. member 이상의 권한이 필요합니다. email.domain.add로 감사 기록됩니다.
operationId addEmailDomain
요청 본문: application/json · object
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 도메인과 게시할 레코드 | EmailDomain |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | email_not_granted — 이 프로젝트에는 email이 허용되어 있지 않습니다. email_domains_unavailable — 이 설치본은 맞춤 발신 도메인을 제공하지 않습니다. email_domain_taken — 다른 프로젝트가 이미 이 도메인을 증명했습니다. email_domain_provider — 제공업체가 거부했습니다 | Error |
| 503 | no_core — 서비스를 일시적으로 사용할 수 없습니다 | Error |
POST /v1/orgs/{orgSlug}/projects/{projectName}/email/domains/{domain}/verify
지금 도메인의 DKIM 상태를 다시 확인하고 해당 행을 업데이트합니다. 도메인이 pending 상태인 동안에는 백그라운드 검사가 1분마다 동일한 작업을 수행하며, 이 버튼은 레코드를 방금 게시하고 기다리고 싶지 않을 때 사용합니다.
검사를 완료할 수 없는 경우 상태는 그대로 유지되며 이유는 lastError에 표시됩니다.
member 이상의 권한이 필요합니다.
operationId verifyEmailDomain
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 검사 후의 도메인 | EmailDomain |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core — 서비스를 일시적으로 사용할 수 없습니다 | Error |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/email/domains/{domain}
발신 identity와 해당 행을 삭제하고, Runlot이 호스팅하는 zone에 기록한 레코드가 있다면 제거합니다. 이후 잠시 뒤부터는 이 도메인을 지정한 모든 env.email.send({ from }) 호출이 from_not_verified로 거부됩니다.
존재하지 않는 것을 삭제하려는 경우에도 204가 반환됩니다. admin 이상의 권한이 필요합니다. email.domain.remove로 감사 기록됩니다.
operationId removeEmailDomain
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 제거됨 | — |
| 403 | — | — |
| 404 | — | — |
| 409 | email_domain_provider — 발신 아이덴티티를 삭제할 수 없어 행이 유지되며, 호출을 다시 시도할 수 있습니다. | Error |
| 503 | no_core — 서비스를 일시적으로 사용할 수 없습니다 | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/email/log
발신 및 수신 메시지마다 한 줄로, 최신순으로 envelope, 결과, 크기, SPF 결과를 표시합니다. 원본 메시지는 …/log/{mailId}/raw에 있습니다.
보관 기간은 플랜을 따릅니다 — Free는 30일, Pro는 365일(keepDays)입니다.
viewer 이상이 필요합니다.
operationId listMailLog
| 매개변수 | 위치 | 필수 | 타입 | 설명 |
|---|---|---|---|---|
direction | query | 아니오 | 문자열 | 비어 있으면 둘 다 |
cursor | query | 아니오 | 문자열 | 이전 페이지의 cursor |
limit | query | 아니오 | 정수 | — |
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 한 페이지 | MailLogPage |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}
프로젝트 외부의 id는 404를 반환합니다 — id로 다른 프로젝트의 로그를 조회할 수 없습니다. viewer 이상의 권한이 필요합니다.
operationId getMailLog
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 이메일 하나 | MailLogEntry |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}/raw
헤더를 포함한 원본 메시지 그대로입니다. 수신 메일의 경우 runlot이 추가한 Received 및 Authentication-Results 헤더가 포함되며, 발신 메일의 경우 제출된 내용을 기반으로 구성됩니다. .eml로 다운로드됩니다. 원본 메시지가 없는 행(hasRaw: false)은 404를 반환합니다. viewer 이상의 권한이 필요합니다.
operationId getMailLogRaw
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 원본 텍스트 | string |
| 403 | — | — |
| 404 | — | — |