> For the complete documentation index, see [llms.txt](https://sharelink-docs.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sharelink-docs.toss.im/developers/developers/open-api/api/sub-tags.md).

# subTag 관리

거래처 하위의 크리에이터·채널을 구분하는 subTag를 등록하고 관리합니다. 실적을 채널별로 나눠 보려면 먼저 여기서 등록합니다.

**subTag는 제휴사가 자기 하위 채널(크리에이터·매체·구좌)을 구분하려고 등록해 두는 식별 단위입니다.**

인증 정보는 거래처 1곳에 1벌만 발급되기 때문에, 아무것도 하지 않으면 하위 채널이 아무리 많아도 실적이 한 덩어리로만 보입니다. subTag를 등록해 두고 [쉐어링크 발급](/developers/developers/open-api/api/link.md) 요청에 `subTagId`를 함께 넘기면, 그 링크로 발생한 성과가 그 subTag에 귀속되어 [실적 조회](/developers/developers/open-api/api/performance.md)·[정산 실적 조회](/developers/developers/open-api/api/settlement.md)에서 채널별로 나뉘어 보입니다.

**`subTagId`는 토스가 발번하지 않습니다.** 제휴사가 쓰고 계신 크리에이터 ID를 그대로 넣으시면 되므로, 별도 매핑 테이블을 만드실 필요가 없습니다.

```
POST /openapi/sub-tags/create          subTag 등록
GET  /openapi/sub-tags                 subTag 목록 조회
POST /openapi/sub-tags/label/update    표시 이름 수정
POST /openapi/sub-tags/delete          subTag 삭제
```

필요 스코프: 목록 조회는 `sharelink:read`, 등록·수정·삭제는 `sharelink:write`

> subTag를 쓰지 않으셔도 됩니다. 링크 발급에서 `subTagId`를 넣지 않으시면 지금까지와 완전히 동일하게 동작합니다.

***

### 값 규칙

먼저 이 규칙부터 확인해 주세요. **등록 실패의 대부분이 형식 위반입니다.**

| 항목               | 규칙                                                     |
| ---------------- | ------------------------------------------------------ |
| `subTagId` 길이    | 1\~64자                                                 |
| `subTagId` 허용 문자 | 영문 대소문자, 숫자, `-`, `_`, `.`만                            |
| `subTagId` 금지 문자 | 공백, 한글, `/` `?` `&` `#` 등 그 밖의 모든 문자                   |
| `subTagId` 대소문자  | **구분합니다.** `Creator_A1`과 `creator_a1`은 서로 다른 subTag입니다 |
| `subTagId` 유일성   | 거래처 안에서 유일합니다. 다른 거래처가 같은 값을 쓰고 있어도 무관합니다              |
| `subTagId` 변경    | **불가능합니다.** 이미 발급된 링크의 실적이 이 값에 걸려 있기 때문입니다            |
| `label`          | 선택 항목. 100자 이하. 표시용이며 식별에는 쓰지 않습니다                     |

**앞뒤 공백은 잘라내지 않고 거절합니다.** `" creator_a1"`처럼 공백이 섞이면 등록되지 않습니다. 보내신 값과 저장된 값이 달라지면 이후 발급 요청에서 조회 키가 어긋나기 때문에, 조용히 고쳐 담지 않습니다. (`label`은 반대로 앞뒤 공백을 걷어내고, 빈 문자열은 값 없음으로 저장합니다.)

***

### subTag 등록

한 번에 **1\~100건**을 등록합니다. 4만 건 규모를 등록하실 때는 100건씩 나눠 호출해 주세요.

```
POST /openapi/sub-tags/create
```

필요 스코프: `sharelink:write`

#### 요청

```json
{
  "subTags": [
    { "subTagId": "creator_a1", "label": "A 크리에이터" },
    { "subTagId": "creator_b2", "label": "B 크리에이터" },
    { "subTagId": "creator_c3" }
  ]
}
```

| 필드                   | 필수     | 설명                         |
| -------------------- | ------ | -------------------------- |
| `subTags`            | **필수** | 등록할 항목 배열. 1\~100건         |
| `subTags[].subTagId` | **필수** | 제휴사가 정하는 식별자. 위 값 규칙을 따릅니다 |
| `subTags[].label`    | 선택     | 표시용 이름. 생략하시면 값 없음으로 저장됩니다 |

```bash
curl -X POST \
  -H "Authorization: Bearer {액세스 토큰}" \
  -H "Content-Type: application/json" \
  -d '{"subTags":[{"subTagId":"creator_a1","label":"A 크리에이터"},{"subTagId":"creator_c3"}]}' \
  "https://sharelink.toss.im/openapi/sub-tags/create"
```

#### 응답

```json
{
  "resultType": "SUCCESS",
  "success": {
    "results": [
      { "subTagId": "creator_a1", "status": "CREATED" },
      { "subTagId": "creator_c3", "status": "ALREADY_EXISTS" }
    ]
  }
}
```

`results`는 **요청에 담으신 항목과 같은 순서**로 내려갑니다. `subTagId`도 보내신 값 그대로 돌려드리므로 항목을 짝지어 처리하시면 됩니다.

| `status`         | 의미                                             | 조치                                                                    |
| ---------------- | ---------------------------------------------- | --------------------------------------------------------------------- |
| `CREATED`        | 새로 등록됐습니다                                      | 없음                                                                    |
| `RESTORED`       | 삭제돼 있던 subTag를 다시 쓸 수 있게 되살렸습니다                | 없음                                                                    |
| `ALREADY_EXISTS` | 이미 등록돼 있어 **아무것도 바꾸지 않았습니다**                   | 라벨을 바꾸시려면 표시 이름 수정 API를 쓰세요                                           |
| `INVALID_FORMAT` | `subTagId` 또는 `label` 형식이 규칙에 맞지 않아 등록하지 않았습니다 | 위 값 규칙에 맞게 고쳐 다시 보내 주세요                                               |
| `UNKNOWN`        | 위 어디에도 해당하지 않는 결과입니다                           | 등록되지 않은 것으로 보고 [토스쇼핑 고객센터](https://toss-business.channel.io)로 문의해 주세요 |

#### 부분 성공과 전체 거절

**항목 하나의 형식이 틀려도 나머지는 그대로 등록됩니다.** 100건 중 1건이 틀렸다고 99건이 되밀리지 않습니다.

다만 아래 두 가지는 **요청 전체를 거절**합니다. 응답 항목과 요청 항목을 짝지을 수 없게 만드는 오류이기 때문입니다.

| 조건                                | `errorCode`                             |
| --------------------------------- | --------------------------------------- |
| `subTags`가 비었거나 100건을 넘음          | `OPENAPI_SUB_TAG_BULK_SIZE_INVALID`     |
| 한 요청 안에 같은 `subTagId`가 두 번 이상 들어감 | `OPENAPI_SUB_TAG_DUPLICATED_IN_REQUEST` |

#### 이미 등록된 subTag를 다시 보내면

| 대상 상태               | 결과                                               |
| ------------------- | ------------------------------------------------ |
| 살아 있음               | `ALREADY_EXISTS`. **`label`을 함께 보내셔도 덮어쓰지 않습니다** |
| 삭제됨 + `label` 함께 보냄 | `RESTORED`. 보내신 `label`로 교체하고 되살립니다              |
| 삭제됨 + `label` 없음    | `RESTORED`. 기존 `label`을 유지한 채 되살립니다              |

살아 있는 subTag의 라벨을 덮어쓰지 않는 이유는, 재시도·중복 호출이 이미 쓰고 계신 라벨을 조용히 바꾸는 일을 막기 위해서입니다. 라벨 변경은 표시 이름 수정 API의 몫입니다.

**삭제한 subTag를 다시 등록하시면 되살아납니다.** 크리에이터를 이탈 처리했다가 복귀시키시는 흐름이 이 규약에 그대로 걸립니다.

***

### subTag 목록 조회

등록해 두신 subTag를 커서 페이징으로 받습니다. **삭제된 subTag는 내려가지 않습니다.**

```
GET /openapi/sub-tags
```

필요 스코프: `sharelink:read`

#### 요청

| 파라미터     | 필수 | 설명                        |
| -------- | -- | ------------------------- |
| `cursor` | 선택 | 다음 페이지 위치. 첫 요청에는 넣지 않습니다 |

한 페이지는 **100건 고정**이며 크기를 지정하는 파라미터는 없습니다.

```bash
curl -H "Authorization: Bearer {액세스 토큰}" \
  "https://sharelink.toss.im/openapi/sub-tags"
```

#### 응답

```json
{
  "resultType": "SUCCESS",
  "success": {
    "subTags": [
      { "subTagId": "creator_a1", "label": "A 크리에이터" },
      { "subTagId": "creator_c3", "label": null }
    ],
    "nextCursor": "AAAAAAAAAGQ",
    "hasNext": true
  }
}
```

| 필드                   | 타입             | 설명                         |
| -------------------- | -------------- | -------------------------- |
| `subTags[].subTagId` | string         | 등록하신 식별자                   |
| `subTags[].label`    | string \| null | 표시용 이름. 등록하지 않으셨으면 `null`  |
| `nextCursor`         | string \| null | 다음 페이지 커서. 마지막 페이지면 `null` |
| `hasNext`            | boolean        | 다음 페이지 존재 여부               |

페이징 방법은 [공통 규약](/developers/developers/open-api/convention.md)의 **커서 페이징**과 같습니다. `cursor` 값은 해석하지 마시고 직전 응답이 준 값을 그대로 전달해 주세요.

***

### 표시 이름 수정

`label`만 바꿉니다. **`subTagId` 자체는 바꿀 수 없습니다.**

```
POST /openapi/sub-tags/label/update
```

필요 스코프: `sharelink:write`

#### 요청

```json
{
  "subTagId": "creator_a1",
  "label": "A 크리에이터 (유튜브)"
}
```

| 필드         | 필수     | 설명                                        |
| ---------- | ------ | ----------------------------------------- |
| `subTagId` | **필수** | 수정할 대상                                    |
| `label`    | 선택     | 새 표시 이름. `null`이나 빈 문자열을 보내시면 값 없음으로 지웁니다 |

```bash
curl -X POST \
  -H "Authorization: Bearer {액세스 토큰}" \
  -H "Content-Type: application/json" \
  -d '{"subTagId":"creator_a1","label":"A 크리에이터 (유튜브)"}' \
  "https://sharelink.toss.im/openapi/sub-tags/label/update"
```

#### 응답

```json
{
  "resultType": "SUCCESS",
  "success": {
    "subTagId": "creator_a1",
    "label": "A 크리에이터 (유튜브)"
  }
}
```

등록되지 않았거나 이미 삭제된 `subTagId`를 주시면 `OPENAPI_SUB_TAG_NOT_FOUND`로 거절됩니다.

***

### subTag 삭제

**신규 발급에서만 제외합니다.** 이미 발급된 링크는 계속 동작하고, 그 실적도 그대로 남아 실적·정산 조회에 계속 나옵니다.

```
POST /openapi/sub-tags/delete
```

필요 스코프: `sharelink:write`

#### 요청

```json
{ "subTagId": "creator_a1" }
```

```bash
curl -X POST \
  -H "Authorization: Bearer {액세스 토큰}" \
  -H "Content-Type: application/json" \
  -d '{"subTagId":"creator_a1"}' \
  "https://sharelink.toss.im/openapi/sub-tags/delete"
```

#### 응답

```json
{
  "resultType": "SUCCESS",
  "success": {
    "subTagId": "creator_a1",
    "alreadyDeleted": false
  }
}
```

| 필드               | 타입      | 설명                                      |
| ---------------- | ------- | --------------------------------------- |
| `subTagId`       | string  | 삭제한 subTag                              |
| `alreadyDeleted` | boolean | `true`면 이미 삭제돼 있어 이번 호출로 바뀐 것이 없다는 뜻입니다 |

같은 요청을 여러 번 보내셔도 안전합니다. 두 번째부터는 `alreadyDeleted: true`로 내려갑니다. 등록된 적이 없는 `subTagId`는 `OPENAPI_SUB_TAG_NOT_FOUND`로 거절됩니다.

***

### 오류 코드

[공통 규약](/developers/developers/open-api/convention.md)의 공통 오류 코드에 더해, subTag 관리에서는 아래 값이 내려갈 수 있습니다. 원인 판별은 `error.errorCode`로 해 주세요.

| `errorCode`                             | 의미                                 | 조치                 |
| --------------------------------------- | ---------------------------------- | ------------------ |
| `OPENAPI_SUB_TAG_BULK_SIZE_INVALID`     | 등록 건수가 1\~100건을 벗어났습니다             | 100건 이하로 나눠 보내 주세요 |
| `OPENAPI_SUB_TAG_DUPLICATED_IN_REQUEST` | 한 요청에 같은 `subTagId`가 두 번 이상 들어갔습니다 | 요청 안에서 중복을 제거해 주세요 |
| `OPENAPI_SUB_TAG_INVALID_FORMAT`        | `subTagId` 형식이 규칙에 맞지 않습니다 (수정·삭제) | 위 값 규칙을 확인해 주세요    |
| `OPENAPI_SUB_TAG_LABEL_INVALID`         | `label`이 100자를 넘었습니다               | 100자 이하로 줄여 주세요    |
| `OPENAPI_SUB_TAG_NOT_FOUND`             | 등록된 subTag가 아닙니다 (미등록 또는 삭제됨)      | 목록 조회로 상태를 확인해 주세요 |

등록 API의 항목별 형식 위반은 오류가 아니라 `results[].status`의 `INVALID_FORMAT`으로 내려갑니다.

***

### 꼭 확인해 주세요

**subTag를 먼저 등록하셔야 링크 발급에 쓸 수 있습니다.** 등록하지 않은 `subTagId`로 [쉐어링크 발급](/developers/developers/open-api/api/link.md)을 요청하시면 `SHARELINK_OPENAPI_ACCESS_DENIED`로 거절됩니다. 다른 거래처가 등록한 값도 마찬가지입니다.

**subTagId는 링크 URL에 실리지 않습니다.** 제휴사 내부의 크리에이터 ID가 외부에 노출되지 않습니다.

**같은 상품이라도 `subTagId`가 다르면 다른 링크가 발급됩니다.** 링크의 동일성 판단 기준에 `subTagId`가 포함되기 때문입니다. 자세한 내용은 [쉐어링크 발급](/developers/developers/open-api/api/link.md)을 봐 주세요.

**subTag는 일 사용 상한을 쓰지 않습니다.** 상품을 반환하지 않는 호출이라 조회·발급 한도에서 차감되지 않습니다.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://sharelink-docs.toss.im/developers/developers/open-api/api/sub-tags.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
