> ## Documentation Index
> Fetch the complete documentation index at: https://docurise.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 그룹 조건

> 그룹 규칙에 쓸 수 있는 모든 조건: 무엇과 일치하는지, 키와 값, 필요한 id를 어디서 찾는지

그룹은 규칙으로 정의됩니다. 이 페이지는 그 규칙의 레퍼런스입니다. 규칙의 각 부분이 어떻게 합쳐지는지, 쓸 수 있는 모든 조건 타입, 조건에 필요한 id를 설명합니다. 규칙은 `POST /segments`(그룹 만들기)와 `POST /segments/preview`(저장하지 않고 규칙에 맞는 연락처 수만 세기)에 보내는 `filter` 객체입니다.

## 규칙의 구조

```json theme={null}
{
  "operator": "AND",
  "conditions": [{ "field": "tag", "operator": "has", "value": "newsletter" }],
  "requiredConditions": [{ "field": "consent", "operator": "active" }],
  "excludeConditions": [{ "field": "tag", "operator": "has", "value": "do-not-contact" }]
}
```

| 키 | 필수 | 의미 |
| - | - | - |
| `operator` | 예 | `AND` 또는 `OR`: `conditions`의 조건들을 어떻게 이을지 정합니다. |
| `conditions` | 예 | 기본 목록입니다. 모두 만족하면(`AND`) 또는 하나라도 만족하면(`OR`) 이 목록에 일치합니다. |
| `requiredConditions` | 아니요 | 멤버가 추가로 모두 만족해야 하는 조건입니다. `operator`와 상관없이 항상 `AND`로 이어집니다. |
| `excludeConditions` | 아니요 | 연락처를 빼는 조건입니다. 이 중 하나라도 만족하는 연락처는 제외됩니다. |

세 목록은 다음과 같이 합쳐집니다. 연락처가 `conditions`(`operator`로 이어짐)에 일치하고, **그리고** `requiredConditions`의 모든 조건에 일치하고, **그리고** `excludeConditions`의 어떤 조건에도 일치하지 않으면 그룹에 속합니다. 비어 있거나 생략된 목록은 건너뜁니다. `excludeConditions`만 있으면, 그 조건에 일치하는 연락처를 뺀 모든 연락처가 그룹이 됩니다.

* 목록 하나에는 조건을 최대 20개까지 넣을 수 있습니다. 더 길면 `400 VALIDATION_ERROR`입니다.
* 규칙에는 세 목록을 통틀어 조건이 하나 이상 있어야 합니다. 하나도 없으면 `422 EMPTY_FILTER`로 거부됩니다.
* 알 수 없는 키는 규칙과 모든 조건에서 거부됩니다(`400 VALIDATION_ERROR`, `message`에 잘못된 키의 경로가 표시됩니다). 조건 타입별로 이 페이지에 나온 키만 보내세요.
* 조건은 `field`로 타입을 지정하는 객체입니다. 가능한 타입은 모두 아래에 있으며, 타입마다 쓰는 키가 다릅니다.
* 일부 조건은 특정 목록에서 거부됩니다(아래 "일부 목록에서 거부되는 조건" 참고). 이런 조건은 `422 CONDITION_NOT_SUPPORTED`를 받습니다.
* 수신 거부한 연락처는 규칙과 상관없이 어떤 그룹의 멤버도 되지 않습니다.
* 기간(`withinDays`, 일 수를 뜻하는 `value` 등)은 규칙을 평가하는 시점부터 거슬러 셉니다. 그래서 같은 규칙도 시간이 지나면 다른 연락처와 일치합니다.
* "한 적 없음" 형태의 연산자(`not_viewed`, `not_clicked`, `not_enrolled`)는 기록이 전혀 없는 연락처도 포함합니다. 중요한 경우에는 아래 각 항목에 따로 적어 두었습니다.

## 조건에 쓰는 id

일부 조건은 내 문서, 상품, 폴더, 1회성 발송, 그룹을 id로 가리킵니다. 모든 id는 내 계정에 있는지 확인합니다. 내 계정에 없는 id는 `422 REFERENCE_NOT_FOUND`이며, `details.path`(규칙 안의 위치)와 `details.kind`(`document`, `product`, `tier`, `cta`, `folder`, `broadcast`, `step` 중 하나)가 함께 옵니다. 내 계정에 없는 태그를 지정한 `tag` 조건은 `422 TAG_NOT_FOUND`(`details.tag`)를 받습니다. 내 계정에 없는 그룹을 지정한 `group_membership` 조건은 `422 GROUP_REFERENCE_NOT_FOUND`(`details.groupIds`)를 받습니다. UUID가 아닌 id는 `400 VALIDATION_ERROR`입니다.

| id | 어디서 얻나 |
| - | - |
| 태그(id가 아니라 이름) | `GET /tags`: 태그의 `name`을 철자 그대로 쓰세요(대소문자를 구분합니다). |
| `groupId` | `GET /segments`. |
| `documentId` | `GET /documents`. |
| `productId` | `GET /products`. 보관된 상품은 `status=archived` 또는 `status=all`을 넘겨야 보입니다. |
| `folderId` | `GET /folders`. 코스도 폴더입니다. 그 `id`를 쓰세요. |
| `broadcastId` | `GET /email/broadcasts`. |
| `tierId`, `ctaId`, `stepId`(이메일 단계) | 이 id를 알려 주는 공개 엔드포인트는 아직 없습니다. 값을 받아 확인은 하지만, 이미 가지고 있는 id만 쓸 수 있습니다. |

id가 선택이면 생략할 때 조건이 "계정 어디서든"으로 넓어집니다(예: `documentId` 없는 `document_view`는 내 모든 문서를 뜻합니다). id를 생략한 형태의 의미는 각 항목에 적어 두었습니다.

## 조건 타입

### `tag`

내 태그를 가진(또는 가지지 않은) 연락처입니다. 태그는 정확한 이름으로 찾습니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `tag` | 조건 타입. |
| `operator` | string | 필수 | `has`, `not_has` | 연락처가 태그를 가지고 있는지. |
| `value` | string | 필수 | 1-50자 | 태그 이름. 철자 그대로 써야 합니다(대소문자 구분). `GET /tags`에서 얻으세요. 내 태그가 아니면 `TAG_NOT_FOUND`로 거부됩니다. |

| 연산자 | 일치하는 대상 |
| - | - |
| `has` | 지금 그 태그를 가진 연락처. |
| `not_has` | 그 태그가 없는 연락처. 태그가 하나도 없는 연락처도 포함합니다. |

```json theme={null}
{ "field": "tag", "operator": "has", "value": "newsletter" }
```

### `document_view`

내 문서를 본(또는 본 적 없는) 연락처입니다. 어떤 문서인지, 얼마나 최근인지, 몇 번인지, 어디까지 읽었는지로 범위를 좁힐 수 있습니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `document_view` | 조건 타입. |
| `operator` | string | 필수 | `viewed`, `not_viewed` | 연락처가 봤는지. |
| `documentId` | string (uuid) | 선택 | 문서 id | 내 문서 하나(`GET /documents`). 생략하면 내 모든 문서. |
| `withinDays` | integer | 선택 | 1-365 | 최근 이 일수 안의 조회만. `viewedFrom` / `viewedTo`와 함께 쓸 수 없습니다. |
| `minCount` | integer | 선택 | 1-1000 | 같은 문서를 이 횟수 이상 봤을 때. `viewed`에 쓰는 옵션입니다. |
| `minScrollPct` | integer | 선택 | 1-100 | 한 번이라도 이 비율(퍼센트) 이상 읽었을 때. `viewed`에 쓰는 옵션입니다. |
| `viewedFrom` | string (date) | 선택 | `YYYY-MM-DD` | 고정 기간의 시작일(한국 표준시, KST). `viewedTo`가 함께 필요합니다. |
| `viewedTo` | string (date) | 선택 | `YYYY-MM-DD` | 기간의 끝일(KST, 이 날 포함). `viewedFrom`이 함께 필요하며 그보다 빠를 수 없습니다. |

| 연산자 | 일치하는 대상 |
| - | - |
| `viewed` | 설정한 범위에 맞는 조회가 한 번이라도 있는 연락처. |
| `not_viewed` | 설정한 범위에 맞는 조회가 없는 연락처. 범위를 두지 않으면 전체 기록을 통틀어 한 번도 본 적 없다는 뜻입니다. `withinDays`나 기간을 지정하면 그 기간에 본 적이 없다는 뜻이며, 그 전에는 봤을 수 있습니다. |

* 기간(`withinDays`, 또는 `viewedFrom`과 `viewedTo`)을 지정하면, 가장 최근 조회가 그 기간 안에 있을 때 본 것으로 칩니다. `minCount`와 `minScrollPct`는 전체 기간 기준 값입니다. 기간은 최근 여부만 정하므로, "30일 안에 3번 조회"는 전체 조회가 3번 이상이고 마지막 조회가 최근 30일 안이라는 뜻입니다.
* 그 문서가 들어 있는 폴더나 코스를 방문한 것도 문서를 본 것으로 칩니다. `minScrollPct`는 문서를 직접 본 경우만 세고 폴더 방문은 세지 않습니다.
* `withinDays`는 `viewedFrom` / `viewedTo`와 함께 쓸 수 없습니다. `viewedFrom`과 `viewedTo`는 함께 써야 하고, `viewedFrom`은 `viewedTo`와 같거나 이전이어야 합니다.
* `minCount`와 `minScrollPct`는 `viewed`에 쓰는 옵션입니다. `not_viewed`와 쓰면 받아들여지며 뜻이 뒤집힙니다. 그 횟수나 깊이에 이른 조회가 없는 연락처가 됩니다.

```json theme={null}
{
  "field": "document_view",
  "operator": "viewed",
  "documentId": "3f2b8c1a-9d4e-4a7b-8c3d-5e6f7a8b9c0d",
  "withinDays": 14,
  "minScrollPct": 75
}
```

### `consent`

마케팅 메시지 수신에 동의했는지로 나눕니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `consent` | 조건 타입. |
| `operator` | string | 필수 | `active`, `withdrawn` | 마케팅 동의가 유효한지. |

| 연산자 | 일치하는 대상 |
| - | - |
| `active` | 마케팅 동의를 했고 수신 거부하지 않은 연락처. |
| `withdrawn` | 그 외 모두: 동의 기록이 없거나, 동의를 철회했거나, 수신 거부한 연락처. |

```json theme={null}
{ "field": "consent", "operator": "active" }
```

### `cta_click`

내 문서의 CTA(행동 유도) 버튼을 누른(또는 누른 적 없는) 연락처입니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `cta_click` | 조건 타입. |
| `operator` | string | 필수 | `clicked`, `not_clicked` | 연락처가 눌렀는지. |
| `ctaId` | string (uuid) | 선택 | CTA id | 특정 버튼 하나. CTA id를 알려 주는 공개 엔드포인트는 아직 없습니다. `documentId`와 함께 쓸 수 없습니다. |
| `documentId` | string (uuid) | 선택 | 문서 id | 이 문서의 아무 버튼(`GET /documents`). `ctaId`와 함께 쓸 수 없습니다. |
| `withinDays` | integer | 선택 | 1-365 | 최근 이 일수 안의 클릭만. |

| 연산자 | 일치하는 대상 |
| - | - |
| `clicked` | 범위 안에서 한 번이라도 누른 연락처. |
| `not_clicked` | 범위 안에서 누른 적이 없는 연락처. 단독으로 쓰면 한 번도 누른 적 없다는 뜻입니다. `withinDays`를 지정하면 그 기간에 누른 적이 없다는 뜻이며, 그 전에는 눌렀을 수 있습니다. |

* 범위는 지정한 id가 정합니다. `ctaId`는 그 버튼, `documentId`는 그 문서의 아무 버튼, 둘 다 없으면 내 모든 문서의 아무 버튼입니다.
* `ctaId`와 `documentId`는 둘 중 하나만 보내세요.

```json theme={null}
{
  "field": "cta_click",
  "operator": "clicked",
  "documentId": "3f2b8c1a-9d4e-4a7b-8c3d-5e6f7a8b9c0d",
  "withinDays": 7
}
```

### `email_open`

내 1회성 발송과 자동화 이메일을 연(또는 열지 않은) 연락처입니다. 영수증 같은 거래 이메일은 포함되지 않습니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `email_open` | 조건 타입. |
| `operator` | string | 필수 | `opened`, `not_opened`, `sent_not_opened` | 연락처가 열었는지. |
| `broadcastId` | string (uuid) | 선택 | 1회성 발송 id | 1회성 발송 하나(`GET /email/broadcasts`). `stepId`, `minCount`와 함께 쓸 수 없습니다. |
| `stepId` | string (uuid) | 선택 | 자동화 단계 id | 자동화의 단계 하나. 단계 id를 알려 주는 공개 엔드포인트는 아직 없습니다. `broadcastId`, `minCount`와 함께 쓸 수 없습니다. |
| `minCount` | integer | 선택 | 1-1000 | 계정 전체에서 이 개수 이상의 이메일을 열었을 때. `broadcastId`, `stepId`와 함께 쓸 수 없습니다. |
| `sinceSentDays` | integer | 선택 | 1-365 | `sent_not_opened`에서만: 이메일을 보낸 지 이 일수 이상 지났을 때. |

| 연산자 | 일치하는 대상 |
| - | - |
| `opened` | 범위 안에서 한 번이라도 연 연락처(또는 전체에서 `minCount`개 이상 연 연락처). |
| `not_opened` | 범위 안에서 연 기록이 없는 연락처. 그 이메일을 아예 받지 않은 연락처도 포함합니다. |
| `sent_not_opened` | 이메일을 받았지만 열지 않은 연락처. `not_opened`와 달리 받은 적 없는 연락처는 빠집니다. `broadcastId` 또는 `stepId`가 필요합니다. |

* 범위는 지정한 id가 정합니다. 1회성 발송, 자동화 단계, 또는 둘 다 없으면 모든 1회성 발송과 자동화 이메일입니다.
* `sent_not_opened`에는 `broadcastId` 또는 `stepId`가 필요합니다. `sinceSentDays`는 `sent_not_opened`에서만 쓸 수 있습니다. 쓰지 않으면 아직 발송 대기 중인 이메일도 보낸 것으로 치고, 쓰면 그 일수 이전에 이미 발송된 이메일만 셉니다.
* `minCount`는 `broadcastId`, `stepId`와 함께 쓸 수 없습니다.

```json theme={null}
{
  "field": "email_open",
  "operator": "sent_not_opened",
  "broadcastId": "7c1d9e24-6a3b-4f58-9e0a-2b4c6d8e0f13",
  "sinceSentDays": 3
}
```

### `email_link_click`

내 1회성 발송과 자동화 이메일의 링크를 누른(또는 누르지 않은) 연락처입니다. 내 콘텐츠로 가는 링크만 셉니다. 수신 거부 링크는 세지 않습니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `email_link_click` | 조건 타입. |
| `operator` | string | 필수 | `clicked`, `not_clicked`, `within_days`, `inactive_for_days` | 눌렀는지, 또는 얼마나 최근에 눌렀는지. |
| `broadcastId` | string (uuid) | 선택 | 1회성 발송 id | 1회성 발송 하나(`GET /email/broadcasts`). `stepId`와 함께 쓸 수 없습니다. |
| `stepId` | string (uuid) | 선택 | 자동화 단계 id | 자동화의 단계 하나. 단계 id를 알려 주는 공개 엔드포인트는 아직 없습니다. `broadcastId`와 함께 쓸 수 없습니다. |
| `value` | integer | 선택 | 1-365 | 일 수. `within_days`, `inactive_for_days`에서는 필수이고 `clicked`, `not_clicked`에서는 쓸 수 없습니다. |

| 연산자 | 일치하는 대상 |
| - | - |
| `clicked` | 범위 안의 링크를 언제든 한 번이라도 누른 연락처. |
| `not_clicked` | 범위 안에서 누른 기록이 없는 연락처. 범위 안의 이메일을 받은 적 없는 연락처도 포함합니다. |
| `within_days` | 최근 `value`일 안에 범위 안의 링크를 누른 연락처. |
| `inactive_for_days` | 최근 `value`일 안에 범위 안의 링크를 누른 기록이 없는 연락처. 한 번도 누르지 않았거나 받은 적 없는 연락처도 포함합니다. |

* 범위는 지정한 id가 정합니다. 1회성 발송, 자동화 단계, 또는 둘 다 없으면 모든 1회성 발송과 자동화 이메일입니다.
* `broadcastId`와 `stepId`는 둘 중 하나만 보내세요.

```json theme={null}
{ "field": "email_link_click", "operator": "within_days", "value": 30 }
```

### `has_phone`

전화번호가 있는지로 나눕니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `has_phone` | 조건 타입. |
| `operator` | string | 필수 | `has`, `not_has` | 전화번호가 기록되어 있는지. |

| 연산자 | 일치하는 대상 |
| - | - |
| `has` | 전화번호가 기록된 연락처. |
| `not_has` | 전화번호가 없는(없거나 빈) 연락처. |

```json theme={null}
{ "field": "has_phone", "operator": "has" }
```

### `form_submission`

내 폼을 제출한(또는 제출한 적 없는) 연락처입니다. 폼 하나를 고르는 방법은 없고, 모든 폼이 대상입니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `form_submission` | 조건 타입. |
| `operator` | string | 필수 | `submitted`, `not_submitted`, `inactive_for_days` | 제출했는지, 또는 얼마나 최근에 제출했는지. |
| `value` | integer | 선택 | 1-365 | 일 수. `inactive_for_days`에서는 필수이고 `submitted`, `not_submitted`에서는 쓸 수 없습니다. |

| 연산자 | 일치하는 대상 |
| - | - |
| `submitted` | 내 폼을 언제든 한 번이라도 제출한 연락처. |
| `not_submitted` | 내 폼을 한 번도 제출한 적 없는 연락처. |
| `inactive_for_days` | 최근 `value`일 동안 폼을 제출하지 않은 연락처. 폼을 제출한 적이 한 번도 없는 연락처도 포함합니다. |

```json theme={null}
{ "field": "form_submission", "operator": "inactive_for_days", "value": 60 }
```

### `payment_status`

결제가 완료되거나 실패하거나 환불될 때 연락처에 기록되는 결제 상태로 나눕니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `payment_status` | 조건 타입. |
| `operator` | string | 필수 | `is`, `is_not` | 그 상태인지. |
| `value` | string | 필수 | `paid`, `failed`, `refunded` | 결제 상태. |

| 연산자 | 일치하는 대상 |
| - | - |
| `is` | 지금 이 상태로 표시된 연락처. |
| `is_not` | 이 상태로 표시되지 않은 연락처. 결제한 적이 없는 연락처도 포함합니다. |

```json theme={null}
{ "field": "payment_status", "operator": "is", "value": "paid" }
```

### `first_seen`

연락처가 처음 나타난 시점(첫 조회, 방문, 제출)이 얼마나 오래되었는지로 나눕니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `first_seen` | 조건 타입. |
| `operator` | string | 필수 | `within_days`, `more_than_days_ago` | 일 수보다 최근인지 오래됐는지. |
| `value` | integer | 필수 | 1-365 | 일 수. |

| 연산자 | 일치하는 대상 |
| - | - |
| `within_days` | 최근 `value`일 안에 처음 나타난 연락처(새 연락처). |
| `more_than_days_ago` | `value`일보다 더 전에 처음 나타난 연락처. |

```json theme={null}
{ "field": "first_seen", "operator": "within_days", "value": 7 }
```

### `last_active`

연락처가 내 콘텐츠를 마지막으로 보거나 방문한 시점으로 나눕니다. 문서와 폴더 방문만 셉니다. 이메일을 열거나 링크를 누른 것은 세지 않습니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `last_active` | 조건 타입. |
| `operator` | string | 필수 | `within_days`, `inactive_for_days` | 최근에 활동했는지, 활동이 없었는지. |
| `value` | integer | 필수 | 1-365 | 일 수. |

| 연산자 | 일치하는 대상 |
| - | - |
| `within_days` | 마지막 활동이 최근 `value`일 안인 연락처. |
| `inactive_for_days` | 마지막 활동이 `value`일보다 더 전인 연락처. |

```json theme={null}
{ "field": "last_active", "operator": "inactive_for_days", "value": 90 }
```

### `group_membership`

내 다른 그룹에 속한(또는 속하지 않은) 연락처입니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `group_membership` | 조건 타입. |
| `operator` | string | 필수 | `in`, `not_in` | 연락처가 그 그룹에 속하는지. |
| `groupId` | string (uuid) | 필수 | 그룹 id | 다른 그룹(`GET /segments`). 내 그룹이어야 하며, 아니면 `GROUP_REFERENCE_NOT_FOUND`로 거부됩니다. |

| 연산자 | 일치하는 대상 |
| - | - |
| `in` | 지금 그 그룹에 속한 연락처. |
| `not_in` | 지금 그 그룹에 속하지 않은 연락처. 한 번도 속한 적 없는 연락처도 포함합니다. |

```json theme={null}
{
  "field": "group_membership",
  "operator": "not_in",
  "groupId": "5a9e4b70-2c1d-4e83-b6f9-0d7c8a1b2e34"
}
```

### `tier_access`

내 상품을 구매해 지금 이용 권한이 있는(또는 없는) 연락처입니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `tier_access` | 조건 타입. |
| `operator` | string | 필수 | `enrolled`, `not_enrolled`, `expiring_within_days` | 이용 권한이 있는지, 또는 곧 끝나는지. |
| `productId` | string (uuid) | 선택 | 상품 id | 상품 하나(`GET /products`). |
| `tierId` | string (uuid) | 선택 | 이용 등급 id | 이용 등급 하나. 등급 id를 알려 주는 공개 엔드포인트는 아직 없습니다. |
| `documentId` | string (uuid) | 선택 | 문서 id | 이 문서의 결제 폼에서 판매하는 모든 상품(`GET /documents`). |
| `saleStatus` | string | 선택 | `active`, `archived` | 판매 중인 모든 상품(`active`) 또는 판매가 끝난 모든 상품(`archived`). 나중에 판매가 시작될 예정인 상품은 어느 쪽에도 속하지 않습니다. |
| `expiringWithinDays` | integer | 선택 | 1-365 | 일 수. `expiring_within_days`에서는 필수이고 다른 연산자에서는 쓸 수 없습니다. |

| 연산자 | 일치하는 대상 |
| - | - |
| `enrolled` | 지금 이용 권한이 있는 연락처. 나중에 시작되는 권한(드립 일정)도 포함합니다. 만료, 환불, 회수된 권한은 포함하지 않습니다. |
| `not_enrolled` | `enrolled`에 일치하지 않는 모든 연락처. 범위가 넓습니다. 구매한 적 없는 연락처뿐 아니라 권한이 만료, 환불, 회수된 연락처도 포함합니다. `productId`나 `documentId`와 함께는 아직 지원하지 않습니다("일부 목록에서 거부되는 조건" 참고). |
| `expiring_within_days` | 앞으로 `expiringWithinDays`일 안에 이용 권한이 끝나는 연락처. 이미 끝난 권한과 종료일이 없는 권한은 일치하지 않습니다. |

* 범위는 지정한 id 하나가 정합니다. `productId`, `tierId`, `documentId`, `saleStatus`를 모두 생략하면 내 모든 상품이 대상입니다.
* `productId`, `tierId`, `documentId`, `saleStatus`는 최대 하나만 보내세요.
* `expiringWithinDays`는 `expiring_within_days`에서 필수이며, 다른 연산자에서는 생략해야 합니다.

```json theme={null}
{
  "field": "tier_access",
  "operator": "expiring_within_days",
  "productId": "9b2e6d14-8f30-4c5a-a1e7-3d4f5a6b7c80",
  "expiringWithinDays": 14
}
```

### `days_since_purchase`

상품을 결제한 지 얼마나 되었는지로 나눕니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `days_since_purchase` | 조건 타입. |
| `operator` | string | 필수 | `within_days`, `more_than_days_ago` | 일 수보다 최근에 결제했는지, 더 전에 결제했는지. |
| `value` | integer | 필수 | 1-365 | 일 수. |
| `productId` | string (uuid) | 선택 | 상품 id | 상품 하나(`GET /products`). |
| `tierId` | string (uuid) | 선택 | 이용 등급 id | 이 이용 등급을 부여하는 상품. 등급 id를 알려 주는 공개 엔드포인트는 아직 없습니다. |
| `documentId` | string (uuid) | 선택 | 문서 id | 이 문서의 결제 폼에서 판매하는 모든 상품(`GET /documents`). |
| `saleStatus` | string | 선택 | `active`, `archived` | 판매 중인 모든 상품(`active`) 또는 판매가 끝난 모든 상품(`archived`). |

| 연산자 | 일치하는 대상 |
| - | - |
| `within_days` | 범위 안에서 최근 `value`일 안에 결제한 주문이 있는 연락처. |
| `more_than_days_ago` | 범위 안에서 `value`일보다 오래된 결제 주문이 있는 연락처. 최근에 또 구매한 연락처도 오래된 주문이 있으면 일치합니다. |

* 결제한 적 없는 연락처는 어느 연산자에도 일치하지 않습니다.
* 범위는 지정한 id 하나가 정합니다. `productId`, `tierId`, `documentId`, `saleStatus`를 모두 생략하면 내 모든 상품이 대상입니다. 넷 중 최대 하나만 보내세요.
* 전액 환불된 주문은 결제된 것으로 치지 않습니다.

```json theme={null}
{
  "field": "days_since_purchase",
  "operator": "within_days",
  "value": 30,
  "productId": "9b2e6d14-8f30-4c5a-a1e7-3d4f5a6b7c80"
}
```

### `repeat_bounce`

이메일 주소가 계속 실패하는 연락처입니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `repeat_bounce` | 조건 타입. |
| `operator` | string | 필수 | `is`, `is_not` | 주소에 반송 문제가 있는지. |

| 연산자 | 일치하는 대상 |
| - | - |
| `is` | 주소가 차단된 연락처. |
| `is_not` | 그 외 모든 연락처. |

```json theme={null}
{ "field": "repeat_bounce", "operator": "is" }
```

### `course_last_access`

폴더나 코스 하나를 얼마나 최근에 방문했는지로 나눕니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `course_last_access` | 조건 타입. |
| `operator` | string | 필수 | `within_days`, `inactive_for_days` | 그 기간 안에 방문했는지, 방문하지 않았는지. |
| `folderId` | string (uuid) | 필수 | 폴더 id | 폴더 또는 코스(`GET /folders`). |
| `value` | integer | 필수 | 1-365 | 일 수. |

| 연산자 | 일치하는 대상 |
| - | - |
| `within_days` | 최근 `value`일 안에 그 폴더를 방문한 연락처. |
| `inactive_for_days` | 그 폴더를 전에 방문한 적은 있지만 최근 `value`일 안에는 방문하지 않은 연락처. 한 번도 방문하지 않은 연락처는 일치하지 않습니다. |

```json theme={null}
{
  "field": "course_last_access",
  "operator": "inactive_for_days",
  "folderId": "e4a1c7b3-5d92-4f06-8a3b-6c7d8e9f0a12",
  "value": 14
}
```

### `kakao_reachable`

카카오 메시지를 보낼 수 있는 연락처입니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `kakao_reachable` | 조건 타입. |
| `operator` | string | 필수 | `reachable`, `not_reachable` | 메시지를 보낼 수 있는지. |

| 연산자 | 일치하는 대상 |
| - | - |
| `reachable` | 전화번호가 있고 카카오 메시지 수신을 거부하지 않은 연락처. |
| `not_reachable` | 그 외 모두: 전화번호가 없거나 수신을 거부한 연락처. |

```json theme={null}
{ "field": "kakao_reachable", "operator": "reachable" }
```

### `course_progress`

폴더나 코스 하나를 얼마나 완료했는지로 나눕니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `course_progress` | 조건 타입. |
| `operator` | string | 필수 | `at_least`, `below` | 완료율이 값 이상인지, 미만인지. |
| `folderId` | string (uuid) | 필수 | 폴더 id | 폴더 또는 코스(`GET /folders`). |
| `value` | integer | 필수 | 0-100 | 완료율(퍼센트). |

| 연산자 | 일치하는 대상 |
| - | - |
| `at_least` | 기록된 완료율이 `value`퍼센트 이상인 연락처. |
| `below` | 기록된 완료율이 `value`퍼센트 미만인 연락처. 기록된 진도가 없는 연락처(예: 한 번도 열지 않은 연락처)는 일치하지 않습니다. |

```json theme={null}
{
  "field": "course_progress",
  "operator": "at_least",
  "folderId": "e4a1c7b3-5d92-4f06-8a3b-6c7d8e9f0a12",
  "value": 80
}
```

### `location`

방문 기록에서 얻은 국가, 그리고 선택적으로 도시로 나눕니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `location` | 조건 타입. |
| `operator` | string | 필수 | `is`, `is_not` | 그 지역에 있는지. |
| `country` | string | 필수 | 대문자 2자 | 대문자 두 글자 ISO 3166-1 alpha-2 국가 코드, 예: `KR`. 값을 검사하므로, 소문자이거나 길이가 맞지 않으면 `400 VALIDATION_ERROR`로 거부됩니다(`message`가 `filter.conditions.N.country`로 시작합니다). |
| `city` | string | 선택 | 1-120자 | 기록된 도시 이름. 정확히, 대소문자를 구분해 비교합니다. `country`가 필요하며, `is`에서는 둘 다 일치해야 합니다. |

| 연산자 | 일치하는 대상 |
| - | - |
| `is` | 그 국가의 연락처. `city`를 주면 그 국가의 그 도시에 있는 연락처. |
| `is_not` | 그 외 모두. 기록된 위치가 없는 연락처도 포함합니다. `city`를 주면 그 국가와 도시의 조합이 아닌 연락처이므로, 같은 국가의 다른 도시에 있는 연락처도 일치합니다. |

```json theme={null}
{ "field": "location", "operator": "is", "country": "KR", "city": "Seoul" }
```

### `checkout_abandoned`

상품 하나의 결제를 시작했지만 끝내지 않은 연락처입니다. 반대 연산자는 없습니다.

| 키 | 타입 | 필수 여부 | 허용 값 | 의미 |
| - | - | - | - | - |
| `field` | string | 필수 | `checkout_abandoned` | 조건 타입. |
| `operator` | string | 필수 | `within_days` | 유일한 연산자. |
| `value` | integer | 필수 | 1-365 | 결제를 시작한 시점이 며칠 전까지인지. |
| `productId` | string (uuid) | 필수 | 상품 id | 상품(`GET /products`). |

| 연산자 | 일치하는 대상 |
| - | - |
| `within_days` | 최근 `value`일 안에 그 상품의 결제를 시작했고 그 뒤로 결제를 완료하지 않은 연락처. |

```json theme={null}
{
  "field": "checkout_abandoned",
  "operator": "within_days",
  "value": 7,
  "productId": "9b2e6d14-8f30-4c5a-a1e7-3d4f5a6b7c80"
}
```

## 일부 목록에서 거부되는 조건

일부 조건 형태는 `422 CONDITION_NOT_SUPPORTED`로 거부됩니다. `details.path`는 그 조건의 위치, `details.operator`는 그 조건의 연산자이고, 같은 결과를 내는 연산자가 있으면 `details.invertTo`에 담기며 그 연산자를 `requiredConditions`에 넣으면 됩니다. 여기에 없는 경우는 모든 목록에서 그대로 쓸 수 있습니다.

| 조건 | 거부되는 경우 | 거부되는 목록 | 해결 방법 |
| - | - | - | - |
| `repeat_bounce` | `is` | `excludeConditions` | `requiredConditions`에 `is_not`을 넣으세요. 같은 사람이 빠지고, 반송 기록이 없는 연락처는 남습니다. |
| `location` | `is` (`city` 유무와 상관없음) | `excludeConditions` | `requiredConditions`에 같은 `country`와 `city`로 `is_not`을 넣으세요. |
| `tier_access` | `productId` 또는 `documentId`가 있는 `enrolled` | `excludeConditions` | 이 id에는 같은 결과를 내는 방법이 없습니다. 제외하려면 `tierId`로 범위를 정하거나 id를 빼세요. `conditions`, `requiredConditions`에서는 그대로 쓸 수 있습니다. |
| `tier_access` | `productId` 또는 `documentId`가 있는 `not_enrolled` | 세 목록 모두 | 이 id로는 아직 지원하지 않습니다. `tierId`로 범위를 정하거나 id를 빼세요. |
| `days_since_purchase` | `productId`, `tierId`, `documentId`가 있는 `within_days`, `more_than_days_ago` | `excludeConditions` | 이 id에는 같은 결과를 내는 방법이 없습니다. 제외하려면 id를 빼세요. `conditions`, `requiredConditions`에서는 그대로 쓸 수 있습니다. |

다른 모든 조건과, 위 조건이라도 다른 연산자나 범위로 쓰는 경우는 모든 목록에서 그대로 쓸 수 있습니다.

## 아직 지원하지 않는 조건

`custom_field` 조건은 받지 않습니다. 이 조건이 들어 있는 규칙은 `422 CONDITION_NOT_SUPPORTED`로 거부되며, `details.field`에 조건 타입이, `details.path`에 그 위치가 담깁니다.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.