이메일
이메일 카테고리의 API 작업 7개를 다룹니다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /v1/hooks/ses | SES 반송, 불만, 전송 웹훅 (SNS가 호출, docs/email.md §6.2) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/email | 이메일 상태 (runlot email) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/email | 이메일을 켭니다 (배포가 "email": true를 읽은 뒤 이를 호출합니다) |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/email | 이메일을 끕니다 (runlot email delete) |
| 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이고 토픽이 서버의 RUNLOT_SES_SNS_TOPIC_ARN과 일치할 때만 요청을 수락합니다 (그렇지 않으면 403). SubscriptionConfirmation은 SubscribeURL로 GET을 보내 자동으로 완료됩니다. 서버에 토픽 ARN이 없으면 501을 반환합니다. 클라이언트 라이브러리는 이를 호출하지 않습니다.
operationId sesHook
요청 본문: text/plain · string
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 수신됨(알 수 없는 이벤트 유형과 알 수 없는 id도 200을 반환합니다) | — |
| 400 | — | — |
| 403 | SNS 서명이 일치하지 않습니다 | — |
| 501 | 웹훅이 꺼져 있습니다 | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/email
부여 여부, 주소, 발신자, 시간당 한도, 최근 발신/수신 건수 (docs/email.md §5). 부여되지 않은 경우에도 address와 from은 채워져서 옵니다 — "이 기능을 켜면 주소가 이렇게 됩니다"를 보여주기 위한 자료입니다. 실제 상태는 granted입니다.
뷰어 이상.
operationId getEmail
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 이메일 상태 | EmailStatus |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core | Error |
POST /v1/orgs/{orgSlug}/projects/{projectName}/email
멱등적입니다. 요청 본문이 없습니다 — 주소는 서버가 결정하고 (<project>.<org>.<mail-domain>), 한도는 플랜이 결정합니다. 주소는 부여 시점의 이름으로 고정됩니다.
활성화되면 다음 수렴 시 노드가 env.email을 연결하고, 해당 주소로 보낸 메일이 워커의 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/log
발신 및 수신 메시지마다 한 줄씩, 최신순으로 표시됩니다 (docs/email.md §6.1). 봉투, 결과, 크기, 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로 다른 프로젝트의 로그를 조회할 수 없습니다. 뷰어 이상.
operationId getMailLog
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 이메일 하나 | MailLogEntry |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/email/log/{mailId}/raw
헤더를 포함한 원본 메시지를 그대로 반환합니다. 수신 메일의 경우 저희가 추가한 Received와 Authentication-Results 헤더가 포함됩니다. 발신 메일의 경우 릴레이에 전달된 내용으로 조립됩니다. .eml로 다운로드됩니다. 원본 메시지가 없는 행(hasRaw: false)은 404를 반환합니다. 뷰어 이상.
operationId getMailLogRaw
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 원본 텍스트 | string |
| 403 | — | — |
| 404 | — | — |