메인 콘텐츠로 건너뛰기
API 호출에 영향을 주는 /api/preview/*의 변경 사항을 최신순으로 정리합니다. 날짜는 UTC 기준입니다. 이 API는 프리뷰 단계라 호환성을 보장하지 않습니다. 호환성 변경은 기존 연동이 실패할 수 있는 변경을 뜻하며, 각 항목에 무엇을 바꿔야 하는지 적혀 있습니다.
그룹 인원 수 계산은 10초 뒤에 중단됩니다
동작 변경: 그룹 규칙에 맞는 연락처 수를 세는 작업이 이제 약 10초 뒤에 중단됩니다. POST /api/preview/segments, POST /api/preview/segments/preview, GET /api/preview/segments/{id}에 적용됩니다. 매우 무거운 규칙은 이제 retryable: true가 포함된 503 SERVICE_UNAVAILABLE을 반환합니다. 규칙을 단순하게 (조건을 줄이거나 가벼운 조건으로) 바꾸거나 다시 시도하세요. 만들기 요청이 시간 초과되면 아무것도 만들어지지 않으며 같은 Idempotency-Key를 다시 보낼 수 있습니다.
그룹 만들기와 조회
신규: 이제 API로 그룹을 만들고 조회할 수 있습니다. POST /api/preview/segments는 규칙으로 그룹을 만들며, Idempotency-Key와 새 segments:write 범위가 필요합니다. POST /api/preview/segments/preview는 아무것도 저장하지 않고 규칙에 맞는 연락처 수를 세고, GET /api/preview/segments/{id}는 그룹 하나를 규칙과 멤버 수와 함께 반환합니다. 두 엔드포인트는 automations:read만 있으면 됩니다. 수치만 반환하며 연락처 정보는 반환하지 않습니다. 이전에 만든 키에는 segments:write가 없으니 Settings → Developers의 Edit scopes에서 추가하세요. GET /api/preview/segments는 바뀌지 않았습니다. 그룹 만들기와 그룹 조건을 참고하세요.
태그 만들기
신규: POST /api/preview/tags로 이름만으로 태그를 만들 수 있습니다. contacts:tag 범위가 필요하고 Idempotency-Key는 필요 없습니다. 같은 이름으로 다시 호출하면 기존 태그를 (created: false) 돌려주고, 대소문자나 앞뒤 공백만 다른 이름은 409 TAG_ALREADY_EXISTS로 거부됩니다. 태그 만들기를 참고하세요.
요청 제한
동작 변경: 이제 /api/preview/*의 제한은 계정당 분당 60회이며, 기존 30회에서 늘었습니다. 또한 계정은 동시에 실행 중인 요청을 최대 10개까지 가질 수 있습니다. 11번째 요청은 429 TOO_MANY_CONCURRENT_REQUESTS와 Retry-After: 1로 거절되며 그대로 재시도해도 됩니다. 자세한 내용은 에러를 참고하세요.
상품에 가격 방식 필드 추가
새 필드: GET /api/preview/products의 각 항목에 이제 pricingModel(fixed 또는 phased)이 포함됩니다. phased 상품은 일정에 따라 가격이 바뀌므로 하나의 가격으로 나타낼 수 없습니다. 이때 priceMinor는 기본 가격일 뿐이며 설정되지 않았다면 0입니다. priceMinor를 쓰기 전에 pricingModel을 먼저 확인하세요. 기존 필드는 모두 그대로입니다.
입력 검사 강화
호환성 변경: 아래 요청은 그동안 받아들여지거나, 무시되거나, 500으로 응답했지만 이제 문제가 된 필드를 알려주는 400 VALIDATION_ERROR입니다.
  • POST /documents, POST /instagram/rules 요청 본문의 속성 이름에 NUL 문자(\u0000)가 있는 경우.
  • kind: form인 POST /documents에서 leadFormQuestions 항목 안에 알 수 없는 키가 있는 경우.
  • GET /tags와 GET /segments에서 반복된 쿼리 파라미터, 그리고 GET /instagram/rules에서 status가 아닌 반복된 파라미터.
  • 목록 엔드포인트의 q 검색 파라미터에 NUL 문자가 있는 경우.
동작 변경:
  • q는 앞뒤 공백이 제거되고 일반 텍스트로 비교됩니다. %와 _는 더 이상 와일드카드가 아닙니다.
  • GET /instagram/rules: 100을 넘는 limit은 400 대신 100으로 처리됩니다. 다른 목록과 같습니다.
  • PATCH /documents/{id}: GET이 반환한 ETag 헤더 값을 revision으로 그대로 보낼 수 있습니다.
문서 revision을 요청 본문으로 이동
호환성 변경: PATCH /api/preview/documents/{id}는 이제 문서의 revision을 If-Match 헤더가 아니라 JSON 본문의 revision 필드로 받습니다. GET /api/preview/documents/{id}(또는 직전 PATCH 응답)의 revision을 보내세요. If-Match나 If-Unmodified-Since 헤더가 있는 요청은 400 VALIDATION_ERROR로 거절됩니다. 헤더를 빼세요.동작 변경: kind: post와 status: live(기본값)로 보내는 POST /api/preview/documents는 이제 초안을 게시할 때와 같은 내용 검사를 거칩니다. 내용이 없는 포스트는 422 EMPTY_BODY, {recipient_name} 같은 이메일 변수가 포함된 포스트는 422 UNSUPPORTED_VARIABLE입니다. 검사를 건너뛰려면 status: draft로 생성하세요.
일시정지 상태로 Instagram 규칙 생성
POST /api/preview/instagram/rules가 status: active | paused(기본값 active)를 받습니다. status: paused와 schedule.batchSendAt을 함께 보내면 422 BATCH_RULE_NOT_PAUSABLE입니다.
엔드포인트 정리: 문서 리소스 통합, 상태는 PATCH로
호환성 변경. 작업(operation)이 28개에서 22개로 줄었습니다.
  • 제거: POST /posts, POST /forms. kind: notion | post | form과 함께 POST /documents를 사용하세요.
  • 제거: GET, PATCH /documents/{id}/settings. 이제 GET /documents/{id}가 만료, 보호 설정, revision을 반환하고, PATCH /documents/{id}가 기존 설정 필드를 받아 GET과 같은 형태로 응답합니다.
  • 대체: 생성 시 isDraft 대신 status(draft | live, 기본값 live. Notion 문서는 live)를 사용합니다. 생성 시점의 status: inactive는 422 STATUS_NOT_SUPPORTED입니다. 다른 kind에 같은 Idempotency-Key를 쓰면 409 IDEMPOTENCY_KEY_CONFLICT입니다.
  • 제거: POST /instagram/rules/{id}/pause, .../resume. 대신 status: paused 또는 status: active만 담아 PATCH /instagram/rules/{id}를 보내세요. 다른 필드와 함께 보낸 status는 422 STATUS_CHANGE_MUST_BE_ALONE입니다.
  • 제거: DELETE /instagram/rules/{id}(이제 405).
응답 필드 정리와 Instagram 소문자 값
호환성 변경.
  • GET /documents, GET /documents/{id}: viewCount와 leadCount가 제거되었습니다. 애널리틱스 엔드포인트를 사용하세요.
  • 403 DOCUMENT_LIMIT_REACHED에 더 이상 details가 없습니다.
  • 422 PROTECTION_RULE_CONFLICT는 변경을 거절한 규칙을 details.rule로 반환합니다.
  • GET /products: sales, usageCount, archived 쿼리 파라미터가 제거되었습니다(archived는 이제 400입니다. status로 필터링하세요).
  • GET /automations: triggerType은 문서화된 목록이며, 목록에 없는 트리거는 other입니다.
  • GET /documents/{id}/analytics/channels: 문서화된 채널에 속하지 않는 유입은 other로 묶이므로, 채널별 조회수의 합이 전체 조회수와 같습니다.
  • Instagram 규칙은 소문자 값을 사용합니다: status는 waiting_for_post, active, scheduled, expired, paused 중 하나, type은 standard, target.type은 next_post입니다(둘 다 이제 선택 사항). 기존 대문자 값은 400입니다.
  • Instagram 에러 코드 이름 변경: PRESET_RULE_EXISTS는 NEXT_POST_RULE_EXISTS로, RULE_PARKED는 BATCH_SEND_MISSED로, PLAN_UPGRADE_REQUIRED는 PLAN_REQUIRED로 바뀌었습니다.
초안 게시, 보호 설정, 애널리틱스 추가
  • 초안 포스트나 폼은 PATCH /documents/{id}에서 status: live로 게시합니다.
  • 같은 엔드포인트에 이메일 보호 필드가 추가되었습니다: requireEmail, requireEmailVerification, allowedEmails, allowedDomains. 문서 구성과 충돌하는 변경은 422 PROTECTION_RULE_CONFLICT입니다.
  • 애널리틱스: 문서 애널리틱스의 compare=previous, 그리고 GET /documents/{id}/analytics/channels, GET /documents/{id}/analytics/funnel(폼), GET /analytics/documents(조회수, 고유 방문자, 리드 기준 문서 순위).
  • 호환성 변경: GET /whoami는 { "scopes": [...] }만 반환합니다.
  • 폼의 날짜 질문은 항상 허용되며, 403 LEAD_FORM_DATE_QUESTION_DISABLED는 더 이상 반환되지 않습니다.
조회 엔드포인트와 연락처 태그
  • 조회 엔드포인트 10개: 문서(목록과 상세), 문서 애널리틱스, 폴더와 코스, 상품, 태그, 그룹, 이메일 1회성 발송과 인사이트, 자동화. 목록은 커서 페이지네이션을 사용합니다(limit 기본값 20, 최대 100).
  • PUT, DELETE /contacts/{contactId}/tags/{tagName}로 연락처 1명에 기존 태그 하나를 추가하거나 제거합니다(새 범위 contacts:tag).
범위, whoami, Instagram 규칙
  • 새 범위 documents:read, email:read, automations:read, products:read, contacts:tag. 기존 키에는 Settings → Developers의 Edit scopes로 범위를 추가할 수 있습니다.
  • GET /whoami는 호출에 사용한 키의 범위를 보여 줍니다.
  • 결제가 연체된 계정은 결제 수단을 업데이트할 때까지 모든 라우트에서 403 PAST_DUE_RESTRICTED를 받습니다.
  • Instagram DM 규칙: 계정의 다음 게시물 규칙을 생성, 목록 조회, 조회, 수정합니다(범위 instagram:write, instagram:read).
더 엄격한 요청 본문, 키 교체 후에도 유지되는 멱등성
  • 호환성 변경: 생성 요청은 알 수 없는 본문 필드를 무시하지 않고 400 VALIDATION_ERROR로 거절합니다.
  • Idempotency-Key는 API 키 하나가 아니라 계정에 속하므로, 새로 교체한 키로 보낸 재시도도 원래 응답을 재생합니다.
프리뷰 출시
POST /api/preview/documents로 공개된 Notion 페이지에서 문서를 생성합니다. Idempotency-Key가 필수이며 계정별 속도 제한이 적용됩니다. API 키는 Settings → Developers에서 관리합니다.