문서로 건너뛰기
CLI

연락처, 오디언스, 브로드캐스트

주소록, 오디언스, 브로드캐스트, 발송 차단 목록을 위한 모든 명령과 실제 예제.

서로 어떻게 맞물리는지

네 네임스페이스가 메일을 보내는 사람들을 다룹니다. 연락처는 워크스페이스 주소록이고, 오디언스는 이름이 붙은 연락처 목록이며, 브로드캐스트는 몇몇 오디언스의 모두에게 메시지 하나를 보내고, 발송 차단 목록에는 워크스페이스가 보내지 않을 주소가 있습니다. 각 명령은 SDK 메서드 하나를 호출하므로, SDK 페이지에서 같은 호출을 더 깊이 설명합니다.

  • 연락처에는 ID가 없습니다. 모든 contacts 명령이 받는 키는 주소이며, 앞뒤 공백을 없애고 소문자로 바꾸므로 [email protected]과 [email protected]은 같은 연락처입니다. 오디언스에는 aud_ ID, 브로드캐스트에는 brd_ ID가 있고, 발송 차단 항목에는 suppressions list가 출력하는 ID가 있습니다.
  • 모든 연락처는 존재하는 동안 기본 오디언스에 속합니다. 이 오디언스는 삭제하거나 비우거나 줄일 수 없으며, builtin이 default입니다.
  • 주소록은 워크스페이스에 속하므로, 모든 멤버와 모든 키가 같은 주소록을 읽고 씁니다.
  • 각 네임스페이스는 openemail contact get처럼 단수형으로도 응답하며, 흔히 쓰는 별칭 ls, show, new, edit, rm도 됩니다. 동사가 add와 remove인 suppressions에서는 new가 add로, rm이 remove로 이어집니다.

openemail <namespace> <verb> --help는 모든 플래그의 타입, 범위, 엔드포인트, 명령의 반환값을 보여 줍니다. --json을 붙이면 같은 페이지를 데이터로 받습니다.

연락처

워크스페이스 주소록입니다. 멤버가 앱의 작성기에서 메일을 보낸 사람들과 직접 저장한 사람들이 들어 있습니다. 도착하는 메일은 아무도 추가하지 않으며, API나 CLI를 통한 보내기도 마찬가지입니다.

명령하는 일
openemail contacts list저장된 연락처 한 페이지, 최근에 메일을 주고받은 순. --source는 manual 또는 auto 연락처만 남기고, --q는 이름과 주소를 검색합니다
openemail contacts get <email>연락처 하나와 그 연락처가 속한 모든 오디언스
openemail contacts create --email <value>--name, --notes, --audience-ids와 함께 새 연락처를 저장합니다. 이미 주소록에 있는 주소는 409 contact_exists로 거부됩니다
openemail contacts update <email>--name이나 --notes를 바꾸며, null은 값을 지웁니다. 주소 자체는 바꿀 수 없습니다
openemail contacts delete <email>연락처를 메모, 사진, 소속과 함께 삭제하고, 작성기가 다시 기록하지 않도록 주소를 숨깁니다
openemail contacts set-audiences <email> --audience-ids <a,b>연락처가 속한 오디언스를 정확히 이 목록으로 맞춥니다. 기본 오디언스는 항상 유지됩니다
openemail contacts list-people연락처 페이지의 모든 사람: 저장된 연락처와, threads:read가 있으면 메일에서 본 모든 주소를 스레드 수와 함께 보여 줍니다. --sort, --q, --email, --blocked로 좁힙니다
openemail contacts save <email>주소를 저장하거나, 보내기에서 기록된 주소를 유지하거나, 삭제된 주소를 되살립니다. 주소가 어떤 상태든 오류가 나지 않습니다
openemail contacts delete-many <emails...>호출 한 번으로 주소 1개에서 200개까지 삭제하고 숨깁니다
openemail contacts set-photo <email> <data>파일에서, 또는 -로 stdin에서 사진을 업로드합니다. 최대 5 MB의 PNG, JPEG, WebP, GIF입니다
openemail contacts remove-photo <email>사진을 떼고 저장된 이미지를 삭제합니다
openemail contacts block <email>주소를 워크스페이스 차단 목록에 올려 그 주소에서 오는 메일을 거부합니다. 플러스 태그는 버립니다
openemail contacts unblock <email>주소를 차단하는 차단 목록 규칙을 도메인 전체 규칙까지 포함해 모두 뺍니다
openemail contacts list-threads <email>모든 폴더에서 그 주소가 작성했거나 그 주소로 작성된 스레드. --q로 그 안을 검색합니다
openemail contacts activity <email>기간 동안 그 주소에서 받고 그 주소로 보낸 메일. --minutes로 달리 정하지 않으면 90일이며, 답장을 기다리는 스레드와 양방향 답장 시간의 중앙값이 함께 나옵니다

오디언스

이름이 붙은 연락처 목록이며, 워크스페이스에 최대 100개까지 둘 수 있습니다. 주소가 오디언스에 들어가려면 먼저 연락처여야 합니다. 예외는 import-contacts로, 새 주소를 저장하면서 넣습니다.

명령하는 일
openemail audiences list오디언스 한 페이지. 기본 오디언스가 먼저, 나머지는 최신순이며 각각 contactCount가 함께 나옵니다
openemail audiences growth기간 동안 오디언스가 어떻게 늘었는지. --days나 --minutes로 달리 정하지 않으면 30일이며, 구간별 가입과 구독 해지, 그리고 합계입니다
openemail audiences get <id>오디언스 하나와 새로 센 contactCount
openemail audiences create --name <value>빈 오디언스를 만들며, --description은 선택 사항입니다. 이름은 고유하지 않아도 됩니다
openemail audiences update <id>--name이나 --description을 바꿉니다. 소속은 건드리지 않습니다
openemail audiences delete <id>오디언스를 삭제하고 연락처는 유지합니다. 기본 오디언스는 삭제할 수 없습니다
openemail audiences empty <id>모든 연락처를 빼고 오디언스는 ID, 이름, 설명과 함께 유지합니다
openemail audiences list-contacts <id>오디언스의 연락처 한 페이지. 각 연락처가 언제 들어왔는지와 구독을 해지했는지가 함께 나옵니다. --sort, --q, --source, --statuses로 좁힙니다
openemail audiences add-contact <id> --email <value>기존 연락처 하나를 오디언스에 넣습니다. 이미 있는 사람을 넣으면 아무것도 바뀌지 않습니다
openemail audiences remove-contact <id> <email>연락처 하나를 뺍니다. 오디언스에 없는 연락처는 404입니다
openemail audiences add-contacts <id> --emails <a,b>기존 연락처를 최대 200개까지 넣고, 연락처가 아닌 주소는 missing에 보고합니다
openemail audiences remove-contacts <id> --emails <a,b>연락처를 최대 200개까지 빼고, 오디언스에 없던 것을 보고합니다
openemail audiences import-contacts <id> --contacts <json|@file|->{ email, name } 행을 최대 500개까지 가져오며, 아직 연락처가 아닌 주소는 저장합니다

브로드캐스트

최대 10개 오디언스의 모두에게 보내는 메시지 하나로, 사람마다 별도 사본으로 보내며 병합 필드를 채우고 수신 거부 링크를 붙입니다. 각 사본은 자체 msg_ ID, 이벤트, 웹훅이 있는 일반 이메일입니다.

명령하는 일
openemail broadcasts preview --audience-ids <a,b>이 오디언스로 보내는 브로드캐스트가 누구에게 닿고, 구독 해지나 발송 차단으로 누구를 건너뛸지 셉니다. 아무것도 보내지 않습니다
openemail broadcasts send --audience-ids <a,b> --from <value>--subject와 --html 또는 --text, 또는 저장된 --template으로 지금이나 --scheduled-at에 보냅니다
openemail broadcasts list브로드캐스트 한 페이지, 최신순이며 실시간 수치가 함께 나옵니다. --audience-id는 그 오디언스로 보낸 것만 남깁니다
openemail broadcasts get <id>브로드캐스트 하나와 그 상태, 실시간 수치. 보내는 동안 폴링할 명령입니다
openemail broadcasts stats <id>배달, 반송, 열람, 클릭, 구독 해지의 합계와 --grain 구간별 시계열. 지정하지 않으면 한 시간 단위입니다
openemail broadcasts list-recipients <id>각 사본이 누구에게 갔고 어떻게 되었는지. --filter는 bounced나 not_opened 같은 한 그룹만 남깁니다
openemail broadcasts get-recipient <id> <email-id>한 사람의 사본. 그 사람이 받은 그대로의 제목, HTML, 텍스트가 나옵니다
openemail broadcasts cancel <id>예약되었거나 대기 중이거나 아직 보내는 중인 브로드캐스트를 멈춥니다. 이미 나간 사본은 회수할 수 없습니다

발송 차단

이 워크스페이스가 보내지 않을 주소입니다. 하드 바운스와 스팸 신고가 일어날 때 기록되며, 직접 추가한 주소도 있습니다. 이런 주소로 보내면 무엇이든 나가기 전에 그 받는 사람에 대해 거부됩니다.

명령하는 일
openemail suppressions list목록 한 페이지, 최신순. --reason은 bounce, complaint, manual만 남기고, --q는 검색합니다
openemail suppressions get <id>행 하나: 주소, 사유, 반송이나 신고에 담긴 세부 내용, 그리고 제거할 수 있는지 여부
openemail suppressions add --email <value>주소로 보내기를 멈춥니다. 이미 있는 주소를 추가하면 그 주소의 행을 반환합니다
openemail suppressions remove <id>주소로 메일을 다시 허용합니다. 하드 바운스는 제거할 수 없습니다

발송 차단 목록과 차단 목록은 서로 다른 목록입니다. suppressions add는 주소로 나가는 메일을 멈추고, contacts block은 그 주소에서 들어오는 메일을 거부합니다.

범위

대부분의 명령에는 자기 네임스페이스의 읽기 또는 쓰기 범위가 필요합니다. 다른 것을 읽거나 바꾸기 때문에 다른 범위가 필요한 명령도 몇 개 있습니다:

범위명령
contacts:readcontacts list, get, list-people
contacts:writecontacts create, update, delete, save, delete-many, set-photo, remove-photo, 그리고 audiences:write와 함께 audiences import-contacts
audiences:readaudiences list, growth, get, list-contacts, 그리고 broadcasts preview. 그래서 보낼 수 없는 키도 인원수는 보여 줄 수 있습니다
audiences:write나머지 모든 audiences 명령과 contacts set-audiences. contacts create --audience-ids에는 contacts:write와 함께 필요합니다
threads:readcontacts list-threads, activity, 그리고 list-people의 메일에서 본 주소
settings:readsuppressions list, get
settings:writesuppressions add, remove, 그리고 contacts block, unblock
emails:readbroadcasts list, get, stats, list-recipients, get-recipient
emails:sendaudiences:read도 필요한 broadcasts send, 그리고 broadcasts cancel
  • 특정 주소나 도메인으로 제한된 키도 다른 모든 키와 같은 주소록을 읽고 씁니다. 그런 키는 자신이 가진 주소나 도메인에서 보낸 브로드캐스트만 보고, list-people에서는 저장된 연락처만 받으며, contacts list-threads, activity, block, unblock과 suppressions add, remove에서는 422 capability_unsupported로 거부됩니다.
  • 일부 주소에만 닿는 멤버의 브라우저 로그인은 모든 contacts, audiences, broadcasts 명령에서 422 capability_unsupported로 거부됩니다. suppressions add는 워크스페이스 소유자가 아닌 사람의 브라우저 로그인을 거부합니다.

실제 예제

파일로 오디언스를 만든 뒤, 그 오디언스로 보내는 브로드캐스트가 누구에게 닿을지 셉니다. import-contacts는 아직 연락처가 아닌 주소를 저장하며, 다시 실행해도 아무것도 두 번 만들거나 넣지 않습니다.

contacts.json
[  { "email": "[email protected]", "name": "Ada Lovelace" },  { "email": "[email protected]", "name": "Grace Hopper" },  { "email": "[email protected]" }]
오디언스를 만들고 인원 세기
AUDIENCE=$(openemail audiences create --name 'Product updates' --json | jq -r .id)openemail audiences import-contacts "$AUDIENCE" --contacts @contacts.jsonopenemail broadcasts preview --audience-ids "$AUDIENCE"

요청을 출력하고 아무것도 보내지 않는 --dry-run으로 브로드캐스트를 확인한 뒤 보냅니다. 브로드캐스트는 즉시 만들어지고 백그라운드에서 보내지므로, get을 폴링해 진행을 따라가세요. 이 본문에는 {{unsubscribeUrl}}이 없으므로 모든 사본에 한 줄짜리 수신 거부 푸터가 붙습니다.

broadcast.json
{  "audienceIds": ["aud_4c1b8e2a7d9f05c36b4e8a71"],  "from": "Acme <[email protected]>",  "subject": "{{firstName|Hello}}, the September release is out",  "html": "<p>Hi {{firstName|there}},</p><p>Here is what changed this month.</p>",  "scheduledAt": "2026-10-01T09:00:00Z"}
브로드캐스트를 확인한 뒤 보내기
openemail broadcasts send --data @broadcast.json --dry-runBROADCAST=$(openemail broadcasts send --data @broadcast.json --yes --json | jq -r .id)openemail broadcasts get "$BROADCAST"openemail broadcasts stats "$BROADCAST" --grain day

브로드캐스트가 누구에게 닿지 않았는지 봅니다. --ndjson은 한 줄에 받는 사람 하나를, --all --json은 모든 페이지를 담은 문서 하나를 출력합니다.

닿지 않은 사람
openemail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b --filter bounced --ndjson | jq -r .emailopenemail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b --filter not_opened --all --json | jq ".items | length"openemail suppressions list --reason bounce --all --max 50

한 오디언스의 구독 중인 멤버를 다른 오디언스로 복사합니다. jq가 스트림을 add-contacts가 받는 본문으로 바꾸고, --data -가 stdin에서 읽습니다. --max 200은 호출 한 번이 받는 주소 200개로 맞춥니다.

구독 중인 멤버 복사
openemail audiences list-contacts aud_9f2c4b7e1a0d63d84c5f2e7b --statuses subscribed --max 200 --ndjson \  | jq -s '{ emails: map(.email) }' \  | openemail audiences add-contacts aud_1c4e7a9b2d0f36e85a7c1b4d --data -

작성기가 한 도메인에서 기록한 연락처를 모두 삭제합니다. delete-many는 호출마다 주소를 최대 200개 받으므로, 더 긴 목록은 xargs -n 200으로 나눕니다. 되돌릴 수 없으니 먼저 --dry-run으로 묶음을 확인하세요.

도메인별 삭제
openemail contacts list --source auto --all --ndjson \  | jq -r 'select(.email | endswith("@old-vendor.example")) | .email' > leaving.txtxargs -n 200 openemail contacts delete-many --dry-run < leaving.txtxargs -n 200 openemail contacts delete-many --yes < leaving.txt

주소로 보내기를 멈추고, 주소를 다시 허용하고, 보낸 사람을 차단합니다. removable은 suppressions remove가 어떤 행을 받을지 알려 줍니다.

발송 차단, 허용, 차단
openemail suppressions add --email [email protected]openemail suppressions list --q [email protected] --json | jq -r '.items[] | select(.removable) | .id'openemail suppressions remove 7b1e2c3d-4f5a-4b6c-8d7e-9f0a1b2c3d4e --yesopenemail contacts block [email protected]

확인과 인증 코드

다음 명령은 실행하기 전에 터미널에서 확인을 요청합니다:

네임스페이스확인 요청
contactsdelete, delete-many, remove-photo, unblock
audiencesdelete, empty, remove-contact, remove-contacts
broadcastssend, cancel
suppressionsremove
  • --yes가 대신 확인합니다. --json이나 --no-input을 주었거나, CI이거나, 터미널이 없는 무인 실행에서는 확인을 물었을 명령이 Refusing to run unattended. Pass --yes to confirm.와 종료 코드 2로 멈춥니다.
  • --dry-run은 명령이 보낼 요청을 출력하고, 묻지도 바꾸지도 않고 코드 0으로 종료합니다.
  • 브라우저 로그인에서는 audiences delete가 웹 앱처럼 먼저 인증 코드를 요구합니다. --yes는 이를 절대 건너뛰지 않으며, 무인 실행에서는 명령이 종료 코드 4로 멈춥니다. 미리 openemail verify를 실행하거나, 코드를 요구받지 않는 API 키를 쓰세요.
  • audiences empty는 인증 코드를 요구하지 않으므로, --yes를 넘기기 전에 ID를 확인하세요.

페이지 넘기기

목록을 보여 주는 명령은 모두 한 페이지를 읽습니다. 더 남아 있으면 출력된 커서를 같은 필터와 함께 --cursor에 넘기거나, 전부 읽으세요:

  • --all은 모든 페이지를 읽어 항목을 스트리밍합니다. 터미널에서는 표로, 파이프로 보내거나 --ndjson을 주면 한 줄에 JSON 객체 하나로 출력합니다.
  • --max <n>은 그 개수만큼 읽고 멈추며, --all을 포함합니다.
  • --json은 --all일 때도 { items, hasMore, nextCursor } 문서 하나를 출력합니다.
  • 형식이 잘못되었거나 오래된 커서는 400 invalid_cursor입니다. 커서 없이 다시 시작하세요.
명령페이지 크기
openemail contacts list1에서 200, --limit로 달리 정하지 않으면 50
openemail contacts list-people1에서 100, --limit로 달리 정하지 않으면 25
openemail contacts list-threads1에서 100, --limit로 달리 정하지 않으면 25
openemail audiences list1에서 100, --limit로 달리 정하지 않으면 25
openemail audiences list-contacts1에서 200, --limit로 달리 정하지 않으면 50
openemail broadcasts list1에서 100, --limit로 달리 정하지 않으면 25
openemail broadcasts list-recipients1에서 200, --limit로 달리 정하지 않으면 50
openemail suppressions list1에서 100, --limit로 달리 정하지 않으면 25

알아 두면 좋은 점

  • contacts create는 이미 주소록에 있는 주소를 409 contact_exists로 거부하므로, 재시도가 누군가 고친 이름을 덮어쓰는 일은 없습니다. contacts save는 절대 거부하지 않습니다. 주소가 어떤 상태든 저장하거나, 유지하거나, 되살립니다.
  • contacts delete는 메일에서만 본 주소도 받으며, 그러면 그 사람이 list-people에서 빠집니다. 메일은 남습니다. 되돌릴 수 없습니다. 주소를 다시 저장하면 이름, 메모, 기본 오디언스 외의 오디언스가 없는 연락처로 새로 시작합니다.
  • 주소는 연락처의 신원이므로 contacts update로 바꿀 수 없습니다. 연락처를 옮기려면 delete와 create를 합니다.
  • contacts set-photo는 파일에서, 또는 -로 stdin에서 이미지를 읽습니다. image/jpeg 같은 --content-type을 넘기세요. 없으면 이미지가 application/octet-stream으로 갈 수 있고, 서버는 이를 422 invalid_image로 거부합니다.
  • broadcasts send --scheduled-at은 2026-10-01T09:00:00Z 같은 ISO 8601 시각이나 PT2H, P1D 같은 ISO 8601 기간을 받으며, 365일 뒤까지 가능합니다. send --at이 받는 2h 같은 짧은 지연은 여기서 거부됩니다.
  • 병합 필드는 --subject, --html, --text에서 동작합니다. {{firstName}}, {{lastName}}, {{name}}, {{email}}, {{unsubscribeUrl}}이며, {{firstName|there}}처럼 세로 막대 뒤에 대체 값을 둘 수 있습니다. {{unsubscribeUrl}}이 없는 본문에는 한 줄짜리 수신 거부 푸터가 붙습니다. 템플릿은 그대로 보내지므로 링크는 템플릿에 넣으세요.
  • 브로드캐스트는 무엇이든 기록하기 전에 요금제의 월간 발송량과 대조되며, 사본 한 통이 발송 한 번으로 계산됩니다. 할당량이 감당할 수 없는 브로드캐스트는 429 send_quota_exceeded로 거부되고 아무것도 남지 않습니다.
  • 스크립트가 같은 단계를 다시 실행할 수 있다면 broadcasts send에 직접 정한 --idempotency-key를 넘기세요. 같은 키는 새로 보내는 대신 이미 만든 브로드캐스트로 응답합니다.
  • 브로드캐스트에서 구독을 해지한 연락처는 unsubscribedAt이 설정된 채 오디언스에 남으며, 이후 그 오디언스로 보내는 브로드캐스트는 그 연락처를 건너뜁니다. audiences list-contacts --statuses unsubscribed가 그들을 나열합니다.
  • 하드 바운스는 발송 차단 목록에 남습니다. suppressions remove는 이를 409 suppression_not_removable로 거부하며, 각 행의 removable이 이를 미리 알려 줍니다.

받은편지함을,
내 방식대로.

기업, AI, 에이전트, 개인 메일을 위한 이메일 인프라. 규모와 프라이버시, 통제권을 위해 만들었습니다. 이메일이 처음부터 갖췄어야 할 모든 것.

OpenEmail

기업, AI, 에이전트, 개인 메일을 위한 이메일 인프라. 규모와 프라이버시, 통제권을 위해 만들었습니다. 이메일이 처음부터 갖췄어야 할 모든 것.

© 2026 OpenEmail. 모든 권리 보유.