# 키 관리 — /v1/keys

> 관리 키로 학생 키를 한 번에 만들고 · 한도와 기한을 바꾸고 · 끕니다.

> 원문: https://oneport.kr/docs/reference/keys

학기 초에 학생 서른 명의 키를 만들고, 학기 끝에 한 번에 끄는 일을 스크립트로 하실 때 쓰는 문이에요. 대시보드 API 키 화면에서 하는 일과 같은 규칙으로 돌아요 — 키 자리가 모자라면 하나도 안 만들고, 초·중·고 학교 지갑의 새 키는 학생 키가 기본이에요.

> **⚠️ 관리 키로만 불러요**
>
> 이 문은 sk-so- 키를 받지 않아요. 대시보드 API 키 화면 아래 「관리 키」에서 지갑 주인이 sk-som- 으로 시작하는 관리 키를 만들어 주세요. 관리 키로는 AI 를 못 부르고, 관리 키를 만든 분이 지갑 주인이 아니게 되면 저절로 닫혀요. 관리 키를 가진 사람은 이 지갑의 키를 모두 끌 수 있으니 학생 코드에 넣지 마세요.

**학생 키 30개 — 하루 한도 · 학기 끝 날까지**

```bash
curl https://oneport.kr/v1/keys \
  -H "Authorization: Bearer $ONEPORT_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "count": 30, "name_prefix": "3학년 2반", "daily_limit_credits": 300, "expires_on": "2027-02-28" }'
```

응답 data 의 줄마다 key 칸에 원문이 들어 있어요. 원문은 이 응답에서 한 번만 나가요 — 바로 나눠 드리거나 안전한 곳에 보관하세요. 중간에 멈추면 그때까지 만든 키(원문 포함)를 201 로 드리고 incomplete: true 와 error 를 같이 실어요 — 모자란 만큼 다시 부르시면 돼요.

## 문 다섯

**경로**

| 파라미터 | 받는 값 | 저희가 하는 일 |
| --- | --- | --- |
| `GET /v1/keys` | limit · offset | 켜진 API 키 목록이에요(사람의 채팅 키는 빼요 · 최근 것 먼저). limit 은 1–500, 기본 100이고 total · has_more 를 같이 드려요. |
| `POST /v1/keys` | JSON | 키를 하나 또는 여러 개 만들어요. count 는 100까지이고, 키 자리가 모자라면 하나도 안 만들어요. |
| `GET /v1/keys/{id}` | 키 id | 키 하나를 봐요. 다른 지갑의 id · 꺼진 키 · 사람의 채팅 키는 404 예요. |
| `PATCH /v1/keys/{id}` | JSON | 보낸 칸만 고쳐요. null 을 보내면 그 한도나 기한을 지워요. 바뀐 줄을 그대로 돌려드려요. |
| `DELETE /v1/keys/{id}` | 키 id | 키를 꺼요. 바로 막히고 되돌릴 수 없어요 — 다시 필요하면 새로 만드세요. |

## 만들기 · 고치기 칸

**요청 본문 (JSON)**

| 파라미터 | 받는 값 | 저희가 하는 일 |
| --- | --- | --- |
| `count` | 정수 1–100 | 만들 개수예요. 안 보내시면 하나예요. 여러 개면 이름 끝에 1, 2, 3 … 을 붙여요(만들기만). 동시에 보낸 다른 요청과 겹쳐 자리를 넘으면 이번에 만든 키를 모두 끄고 409 로 알려드려요. |
| `name · name_prefix` | 문자열 (40자 · 20자) | 키 이름이에요. 하나면 name(없으면 name_prefix) 그대로, 여러 개면 name_prefix 뒤에 번호를 붙여요. 고칠 때 name 에 null 을 보내면 이름을 지워요. 「채팅 · 」으로 시작하는 이름은 팀 채팅 키 이름이라 못 써요. |
| `audience` | student · teacher | 학생 키면 웹 검색 · 웹 페이지 읽기 · 원격 MCP · 영상 만들기가 막혀요. 초·중·고 학교 지갑은 안 보내시면 학생이에요. 쓰임새를 나누지 않는 지갑에 student 를 보내면 400 이에요. |
| `monthly_limit_credits` | 정수 크레딧 또는 null | 이 키의 이번 달 한도예요. null 이면 지갑 크레딧까지 써요. 다음 달 1일 한국 시간 0시에 다시 열려요. |
| `daily_limit_credits` | 정수 크레딧 또는 null | 이 키의 오늘 한도예요. 월 한도보다 클 수 없고, 한국 시간 0시에 다시 열려요. |
| `expires_on` | 날짜 YYYY-MM-DD 또는 null | 이 날까지 써요. 그다음 날 한국 시간 0시에 저절로 닫혀요. 오늘보다 이른 날은 받지 않아요 — 지금 끄려면 DELETE 예요. |

**응답 한 줄**

```json
{
  "object": "api_key",
  "id": "8f0c…",
  "name": "3학년 2반 1",
  "key_prefix": "sk-so-a1b2c3…",
  "audience": "student",
  "monthly_limit_credits": null,
  "month_used_credits": 0,
  "daily_limit_credits": 300,
  "day_used_credits": 0,
  "expires_at": "2027-02-28T15:00:00.000Z",
  "usable_until": "2027-02-28",
  "created_at": "2026-10-15T01:00:00.000Z",
  "last_used_at": null,
  "key": "sk-so-…"
}
```

key 칸(원문)은 만들 때 응답에만 있어요. 목록 · 하나 보기 · 고치기 응답엔 없어요. 위 표에 없는 칸 이름(예: monthly_limit · expires_at)을 보내시면 그냥 넘기지 않고 400 으로 이름을 알려드려요. 오류는 401(관리 키가 아니거나 닫힘) · 400(칸이 틀림 · 자리가 모자람) · 404(그 키가 없음) · 409(다른 요청과 겹쳐 자리를 넘음) · 503(저희 쪽 일시 장애)이에요.

