GET/PATCH/DELETE /keys/{hash}
키 하나를 조회·수정·폐기한다
키 하나를 해시로 지목해 읽고, 이름·한도·사용 여부를 고치고, 영구 폐기한다. 세 메서드 모두 관리 키로만 호출한다.
GET https://openrouter.myip.co.kr/api/v1/keys/{hash}
PATCH https://openrouter.myip.co.kr/api/v1/keys/{hash}
DELETE https://openrouter.myip.co.kr/api/v1/keys/{hash}왜 해시로 지목하는가
평문 키는 발급 응답에서 딱 한 번 나가고 우리는 sha256(평문) 만 저장한다. 그래서 키를 가리킬 수 있는 이름은 그 해시뿐이다. openrouter 도 같은 구조이므로 필드명 hash 를 그대로 썼다.
# 평문 키가 손에 있다면 해시는 직접 계산할 수 있다
printf '%s' "sk-mo-v1-8f2b6d1e…" | sha256sum평문을 잃어버렸다면 해시는 GET /keys 목록에서 얻는다. 반대 방향 — 해시에서 평문 — 은 관리자를 포함해 누구도 할 수 없다.
인증
Authorization: Bearer sk-mo-mgmt-v1-…. 관리 키 전용이다. 추론 키로 부르면 401 invalid_api_key 다.
관리 키는 자기 계정의 키만 볼 수 있다. 다른 사용자의 키 해시를 넣으면 404 다 — 없는 키와 남의 키를 같은 응답으로 처리해서 해시의 존재 여부를 흘리지 않는다.
경로 파라미터
hashstring필수sha256(평문 키) 의 hex 64자. GET/POST /keys 응답의 hash 필드를 그대로 넣는다.
GET — 조회
키 객체 하나를 돌려준다. 필드는 GET /keys 의 항목과 완전히 같다.
curl "https://openrouter.myip.co.kr/api/v1/keys/9f2c1d0a7b3e4f5061728394a5b6c7d8e9f0112233445566778899aabbccddee" \
-H "Authorization: Bearer $MYIP_MANAGEMENT_KEY"{
"data": {
"created_at": "2026-09-01T02:11:40.881Z",
"updated_at": null,
"hash": "9f2c1d0a7b3e4f5061728394a5b6c7d8e9f0112233445566778899aabbccddee",
"label": "sk-mo-v1-au7…890",
"name": "production",
"disabled": false,
"limit": 100000,
"usage": 25500
}
}hashstring요청한 해시 그대로.
labelstring마스킹 문자열. 인증에는 쓸 수 없다.
disabledbooleantrue 면 추론이 되지 않는다. 사용자가 끈 경우와 상태가 active 가 아닌 모든 경우(잔액 소진 정지, 관리자 정지, 폐기)를 합친 값이다.
limitnumber | null사용 한도(원). null 이면 무제한.
usagenumber한도 기간의 사용액(원). 경계는 Asia/Seoul 기준이다.
GET /keys 목록에는 폐기된 키가 나오지 않지만, 해시를 직접 아는 폐기된 키는 이 경로로 여전히 읽힌다. 폐기 이력을 확인할 수 있어야 하기 때문이다. 그 키로 요청을 보내면 401 이다.
PATCH — 수정
보낸 필드만 바꾼다. 생략한 필드는 건드리지 않는다.
namestring새 이름. 빈 문자열이나 공백만 있는 값은 400 이다.
disabledbooleantrue 면 이 키를 끈다. false 면 다시 켠다. 불리언이 아니면 400 이다.
limitnumber | null새 사용 한도(원). null 을 명시적으로 보내면 한도가 해제된다. 필드를 아예 생략하는 것과 null 을 보내는 것은 다른 뜻이다.
curl -X PATCH "https://openrouter.myip.co.kr/api/v1/keys/9f2c1d0a7b3e4f5061728394a5b6c7d8e9f0112233445566778899aabbccddee" \
-H "Authorization: Bearer $MYIP_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "production (paused)", "disabled": true, "limit": 200000}'응답은 수정 후 키 객체다.
{
"data": {
"created_at": "2026-09-01T02:11:40.881Z",
"updated_at": "2026-09-04T05:40:12.907Z",
"hash": "9f2c1d0a7b3e4f5061728394a5b6c7d8e9f0112233445566778899aabbccddee",
"label": "sk-mo-v1-au7…890",
"name": "production (paused)",
"disabled": true,
"limit": 200000,
"usage": 25500
}
}한도만 해제하려면 이렇게 한다.
curl -X PATCH "https://openrouter.myip.co.kr/api/v1/keys/$KEY_HASH" \
-H "Authorization: Bearer $MYIP_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"limit": null}'DELETE — 폐기
키를 영구 폐기한다.
curl -X DELETE "https://openrouter.myip.co.kr/api/v1/keys/9f2c1d0a7b3e4f5061728394a5b6c7d8e9f0112233445566778899aabbccddee" \
-H "Authorization: Bearer $MYIP_MANAGEMENT_KEY"{ "data": { "success": true } }successboolean항상 true. 이미 폐기된 키를 다시 폐기해도 오류가 아니다(멱등).
폐기해도 그 키가 쌓은 사용 기록과 원장은 그대로 남는다. 이미 청구한 금액이 지워지면 회계가 맞지 않기 때문이다. 그래서 폐기 후에도 GET /credits 의 total_usage 는 줄지 않는다.
오류
| 상태 | error_type | 언제 |
|---|---|---|
| 400 | invalid_request | 본문이 JSON 이 아님. name 이 빈 문자열. disabled 가 불리언이 아님. limit 이 숫자도 null 도 아님 |
| 401 | invalid_api_key | 헤더 없음. 추론 키로 호출. 관리 키가 없거나 꺼졌거나 폐기됨 |
| 401 | expired_api_key | 관리 키가 만료됨 |
| 402 | insufficient_credits | 관리 키가 suspended_no_credit 상태 |
| 403 | key_suspended | 관리자가 관리 키를 정지함 |
| 404 | not_supported | 그 해시의 키가 없거나, 다른 사용자의 키다 |
| 500 | server | 그 밖의 서버 오류 |
404 본문은 이렇다. 해시가 존재하지 않는 경우와 남의 것인 경우가 글자 하나까지 같다 — 응답 차이로 해시의 존재를 알아내는 길을 막는다.
{
"error": {
"code": 404,
"message": "지원하지 않는 경로입니다: key 9f2c1d0a7b3e4f50…",
"metadata": { "error_type": "not_supported" }
}
}관련 문서
- GET/POST /keys — 키를 나열하고 발급한다
- GET /key · /auth/key — 지금 쓰는 키의 상태
- 사용 한도와 402 — 한도·잔액과 키 정지의 관계
- 오류와 디버깅 —
error_type전체 표
마지막 수정 2026. 9. 5.