> 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/open-api/api/sub-tags.md).

# subTag 관리

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

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

***

## 값 규칙

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

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

***

## subTag 등록

한 번에 **1\~100건**을 등록합니다. 수만 건을 등록하셔야 한다면 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건이 되밀리지 않습니다.

다만 건수가 1\~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 목록 조회

등록해 두신 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/open-api/convention.md)의 **커서 페이징** 과 같습니다.

***

## 표시 이름 수정

`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/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`으로 내려갑니다.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
