개발자
메일함은 누가 다루든
신경 쓰지 않습니다.
앱이 하는 모든 일을 당신의 코드도 합니다. 68개 경로에 걸친 104개의 문서화된 작업, 그리고 키 없이 읽을 수 있는 OpenAPI 3.1 문서. TypeScript 클라이언트는 빌드마다 그 문서에 맞춰 검증됩니다.
MCP는 붙여넣을 키가 필요 없습니다. 클라이언트가 엔드포인트에서 인증 서버를 찾아 스스로 등록하고, 로그인하도록 여기로 보냅니다.
104
문서화된 작업
68
한 호스트 아래의 경로
116
SDK 메서드, 그 전부를 덮습니다
20
웹훅 이벤트, 세 계열로
OpenAPI 3.1 문서는 GET /openapi.json에 있고, 읽는 데 키가 필요 없습니다.
접점
문은 셋,
메일함은 하나.
워크스페이스 키가 호출이 할 수 있는 일과 발신 가능한 주소를 정합니다. 폐기는 삭제가 아니라 갱신이라, 이후의 호출은 키가 폐기되었다는 응답을 받습니다.
키 하나로 도메인 전체 25개, 개별 주소 50개까지 발신합니다. GET /ping은 키가 가진 스코프와 역할이 남긴 스코프를 돌려줍니다.
클라이언트를 엔드포인트로 향하게 하고 로그인하세요. 붙여넣을 키는 없습니다. 클라이언트가 스스로 등록하고 여기로 보내니까요.
도구는 호출자가 할 수 있는 일에서 만들어집니다. 읽기만 허용된 클라이언트에는 발신 도구가 아예 없습니다. 다만 토큰은 여전히 메일함 전체에 닿습니다.
https 엔드포인트를 등록하면 메일함이 그곳으로 보냅니다. 전송은 API 호출이 아니라 메일함 자체가 일으키므로, 앱에서 작성하든 API로 보내든 같은 이벤트가 납니다.
세 계열의 20개 이벤트, 메일함당 엔드포인트 10개.
일치
클라이언트는 API보다
뒤처질 수 없습니다.
일치 검사는 빌드마다 OpenAPI 문서를 읽고 어긋나면 실패합니다. 스펙에 없는 작업을 가리키는 메서드, 메서드가 없는 문서화된 작업, 작업이 요구하는 것과 다른 스코프 목록이 대상입니다. 검사는 무엇을 확인했는지 출력하며, 오늘 기준으로 문서화된 104개 작업 전부에 대한 116개의 SDK 메서드입니다.
설정, 요청, 호출은 같은 작업을 세 가지 방식으로 쓴 것입니다.
에이전트, API 및 MCP
OpenEmail은 사람뿐 아니라 소프트웨어도 다루도록 만들어졌습니다. 어느 쪽이든 메일함은 같습니다.
MCP 서버
Claude를, 또는 어떤 MCP 클라이언트든 당신의 메일함으로 연결하세요.
서드파티 클라이언트용 OAuth
곧PKCE 기반 셀프서비스 클라이언트 등록으로, 앱이 제대로 접근을 요청할 수 있습니다.
동의와 취소는 있지만 범위 지정은 없어, 토큰이 앱이 요청한 부분이 아니라 사서함 전체에 닿습니다.
REST API
발급하고, 범위를 정하고, 폐기할 수 있는 키를 갖춘 문서화된 HTTP API.
퀵스타트
빈손에서 보낸 메일까지.
세 단계.
- 1
키 발급
본인 소유 메일함의 설정, API 키에서. 스코프를 고르고, 발신할 수 있는 대상을 도메인 전체나 개별 주소로 좁히세요. 비밀값은 한 번만 표시되고 저장되는 것은 단방향 해시입니다.
GET /ping은 키가 가진 스코프와 역할이 남긴 스코프를 답으로 줍니다. export OPENEMAIL_API_KEY=oe_live_9f2c1a4b7e05d3862c1f0a44_kX7… curl https://api.openemail.uk/ping \ -H "Authorization: Bearer $OPENEMAIL_API_KEY" - 2
클라이언트 설치
의존성 없는 TypeScript 클라이언트. ESM과 CommonJS로 배포되고 키는 OPENEMAIL_API_KEY에서 읽습니다. 직접 JSON을 보내고 싶다면 건너뛰어도 됩니다. 모든 엔드포인트가 평범한 HTTP니까요.
Node 18 이상, Workers, Deno, Bun, 그리고 브라우저. bun add @openemail/sdk - 3
발송
응답에 id가 담깁니다. GET /emails/{id}로 조회하고, /events에는 수신자별 기록이, /tracking에는 열람과 클릭이 있습니다.
같은 Idempotency-Key로 재시도하면 Idempotency-Replayed: true와 함께 첫 결과를 돌려받습니다. import { init, openemail } from '@openemail/sdk' init({ apiKey: process.env.OPENEMAIL_API_KEY }) const email = await openemail.emails.send({ from: 'Acme Billing <[email protected]>', to: '[email protected]', subject: 'Your September invoice', html: '<p>Invoice attached.</p>',}) console.log(email.id, email.status)
없는 것
이것이 해주지 않는 일,
아직은.
이 위에 무언가 만든 뒤가 아니라, 만들기 전에 알아둘 만한 다섯 가지.
- 업로드 엔드포인트 없음
- 인라인 첨부는 총 5MB 한도 안에서 base64로 나갑니다. 더 큰 파일은 워크스페이스에 이미 있는 파일을 id로 지정해 보내며, 다운로드 링크로 전달됩니다.
- 반송은 메일함에서 멈춥니다
- 반송 보고서는 파싱되어 Message-ID로 매칭되고, 스레드에 표시된 뒤 email.bounced 웹훅으로 전송됩니다. 발신 레코드에는 아무것도 기록되지 않아, GET /emails에서는 반송된 메시지도 여전히 보낸 것으로 보입니다.
- 작성기 메일은 GET /emails에 없습니다
- 앱 작성기에서 보낸 메일은 그 목록에 나오지 않습니다. 작성기는 같은 발신 경로를 거치지 않기 때문입니다.
- OAuth에는 동의만 있고 범위는 없습니다
- 요청은 승인되기 전에 표시되고 연결된 앱에서 회수할 수 있지만, 토큰은 앱이 요청한 부분이 아니라 메일함 전체에 닿습니다.
- 릴리스 워크플로 없음
- 클라이언트 배포는 프리플라이트, 빌드, bun publish를 수동으로 실행하는 일입니다. 그래서 버전은 변경이 반영될 때가 아니라 누군가 실행할 때 npm에 올라갑니다.
전송 검증하기
모든 전송에는 서명이 있고,
모든 재시도에는 그 id가 실립니다.
서명은 타임스탬프, 점, 원본 본문에 대한 HMAC-SHA-256입니다. 도착한 바이트 그대로 검증하세요. 파싱한 뒤 다시 직렬화하면 키 순서가 바뀌어 서명이 깨집니다.
X-OpenEmail-Signature: t=1758240000,v1=9f0c4b2e7d1a86c3X-OpenEmail-Event: email.deliveredX-OpenEmail-Delivery: evt_4b7e05d3862c1f0a- 재전송 허용 시간
- 300초이며, 적용은 수신자의 몫입니다. SDK의 검증기는 이 값을 기본으로 씁니다.
- Idempotency-Key
- 키와 당신의 API 키를 함께 묶은 고유 인덱스로 확보되므로, 타임아웃 뒤의 재시도는 두 번 보내는 대신 Idempotency-Replayed: true와 함께 첫 결과를 돌려줍니다.
- 재시도
- 다섯 번 시도합니다. 이벤트가 나는 즉시, 그리고 1분, 5분, 25분, 2시간 뒤. 타임아웃, 연결 거부, 408, 425, 429, 5xx만 다시 보냅니다.
- X-OpenEmail-Delivery
- 이벤트 id는 한 번만 발급되어 모든 시도에 함께 실립니다. 같은 id를 두 번 본 수신자는 두 번째를 다시 처리하지 않고 버리면 됩니다.
누구를 위한 것인가
하나의 메일함.
들어오는 세 가지 길.
키를 발급하세요.
무언가 보내세요.
Full API, MCP and SDK access는 모든 요금제에 있습니다. Free에는 50 AI actions a day가 함께 옵니다.