{"openapi":"3.1.0","info":{"title":"EZSender API","version":"1.0.0","description":"EZSender 이메일 캠페인, 주소록, 구독자, 자동화 REST API"},"servers":[{"url":"https://localhost:3000/api/v1"}],"components":{"securitySchemes":{"ezsenderId":{"type":"apiKey","in":"header","name":"X-EZSENDER-ID"},"ezsenderSecret":{"type":"apiKey","in":"header","name":"X-EZSENDER-SECRET"}}},"paths":{"/auth-check":{"get":{"tags":["인증"],"summary":"인증 확인","description":"발급된 API ID와 secret key 조합이 유효한지 확인합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[],"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"authenticated":true,"apiKeyId":"ez_xxx","userIdx":1}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/campaigns":{"get":{"tags":["이메일 캠페인"],"summary":"이메일 캠페인 목록조회","description":"캠페인을 최신 생성순으로 조회합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"campaigns":[{"id":10,"title":"7월 뉴스레터","status":"draft"}],"pagination":{"page":1,"limit":20,"total":1,"totalPages":1}}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}},"post":{"tags":["이메일 캠페인"],"summary":"이메일 캠페인 생성","description":"작성중 상태의 이메일 캠페인을 생성합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"example":{"title":"7월 뉴스레터","subject":"새 소식입니다","html":"<h1>Hello</h1>","recipients":{"groups":[1],"segments":[]}}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"campaign":{"id":10,"title":"7월 뉴스레터","status":"draft"}}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/campaigns/{id}":{"get":{"tags":["이메일 캠페인"],"summary":"이메일 캠페인 상세내용 조회","description":"캠페인 본문과 수신 대상 설정을 함께 조회합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"campaign":{"id":10,"subject":"새 소식입니다","html":"<h1>Hello</h1>","recipients":{"groups":[1]}}}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}},"patch":{"tags":["이메일 캠페인"],"summary":"이메일 캠페인 수정","description":"제목, 본문, 발신자, 수신 대상 등을 수정합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"example":{"subject":"수정된 제목","html":"<p>Updated</p>"}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"campaign":{"id":10,"subject":"수정된 제목"}}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}},"delete":{"tags":["이메일 캠페인"],"summary":"이메일 캠페인 삭제","description":"캠페인을 삭제합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"deletedId":10}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/campaigns/{id}/copy":{"post":{"tags":["이메일 캠페인"],"summary":"이메일 캠페인 복사","description":"기존 캠페인과 수신 대상 설정을 복사해 새 작성중 캠페인을 만듭니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"campaign":{"id":11,"title":"7월 뉴스레터 복사본","status":"draft"}}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/campaigns/{id}/test-send":{"post":{"tags":["이메일 캠페인"],"summary":"이메일 캠페인 메일 테스트 발송","description":"캠페인 본문을 지정한 이메일 주소로 테스트 발송합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"example":{"to":["test@example.com"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"recipients":["test@example.com"],"server":"primary-mail"}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/campaigns/{id}/send":{"post":{"tags":["이메일 캠페인"],"summary":"이메일 캠페인 메일 발송 실행","description":"즉시 발송 또는 예약 발송을 실행합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"example":{"mode":"immediate"}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"id":10,"status":"scheduled","recipientCount":120}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/address-books/groups":{"get":{"tags":["주소록 그룹"],"summary":"주소록 그룹 목록조회","description":"주소록 그룹과 그룹별 구독자 수를 조회합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[],"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"groups":[{"id":1,"name":"기본 그룹","active":100,"total":102}]}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}},"post":{"tags":["주소록 그룹"],"summary":"주소록 그룹 생성","description":"새 주소록 그룹을 생성합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"example":{"name":"VIP 고객","description":"고가치 고객 그룹"}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"group":{"id":2,"name":"VIP 고객"}}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/address-books/groups/{id}":{"patch":{"tags":["주소록 그룹"],"summary":"주소록 그룹명 수정","description":"그룹 이름 또는 설명을 수정합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"example":{"name":"VIP 고객 2026"}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"group":{"id":2,"name":"VIP 고객 2026"}}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}},"delete":{"tags":["주소록 그룹"],"summary":"주소록 그룹 삭제","description":"주소록 그룹을 삭제합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"example":{"deleteSubscribers":false}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"deletedId":2}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/subscribers":{"get":{"tags":["구독자"],"summary":"구독자 목록 조회","description":"구독자 목록을 이메일 기준으로 조회합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"string"}},{"name":"groupId","in":"query","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"subscribers":[{"id":100,"email":"user@example.com","status":"active","groups":["기본 그룹"]}]}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}},"post":{"tags":["구독자"],"summary":"구독자 추가","description":"지정한 그룹에 구독자를 추가하거나 기존 정보를 갱신합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"example":{"groupName":"기본 그룹","subscribers":[{"email":"user@example.com","name":"홍길동"}]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"inserted":1,"updated":0,"failed":0}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}},"patch":{"tags":["구독자"],"summary":"구독자 상태 변경","description":"구독자 상태를 active 또는 unsubscribed로 변경합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"example":{"emails":["user@example.com"],"status":"unsubscribed"}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"updated":1,"status":"unsubscribed"}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}},"delete":{"tags":["구독자"],"summary":"구독자 삭제","description":"구독자를 ID 또는 이메일 기준으로 삭제합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"example":{"emails":["user@example.com"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"deleted":1}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/automations":{"get":{"tags":["자동화"],"summary":"자동화 목록조회","description":"자동화 목록을 조회합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"automations":[{"id":3,"name":"웰컴 자동화","status":"active"}]}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/automations/{id}":{"get":{"tags":["자동화"],"summary":"자동화 상세내역","description":"자동화 시작 조건과 단계 구성을 조회합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"automation":{"id":3,"name":"웰컴 자동화","steps":[]}}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/automations/{id}/emails":{"post":{"tags":["자동화"],"summary":"자동화 메일 추가","description":"자동화 흐름에 이메일 단계를 추가합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"example":{"title":"첫 인사 메일","subject":"가입을 환영합니다","html":"<p>Welcome</p>"}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"step":{"type":"email","title":"첫 인사 메일"}}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}},"/automations/{id}/run":{"post":{"tags":["자동화"],"summary":"자동화 발송 실행","description":"활성 상태의 대상 선택 후 실행 자동화를, 활성 구독자에게 실행합니다.","security":[{"ezsenderId":[],"ezsenderSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"example":{"subscriberIds":[12]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"example":{"success":true,"id":3,"status":"active","executionCount":1}}}},"400":{"description":"잘못된 요청"},"401":{"description":"인증 실패"},"404":{"description":"리소스 없음"},"500":{"description":"서버 오류"}}}}}}