Appendix C · KIS API KIS API 통합 레퍼런스 0%
📘 APPENDIX C

KIS API 통합 레퍼런스

엔드포인트 · TR_ID 전체 · 에러 코드 · 운영 패턴

Section 1

1. 시스템 개요 + 환경 구분

KIS API 시스템 특징

환경 2종 — 절대 섞이지 말 것

📗 모의투자 (교육용 · 우리 선택)
https://openapivts.koreainvestment.com:29443
⚠️ 실전투자 (실제 자본 소모)
https://openapi.koreainvestment.com:9443

TR_ID 명명 규칙

첫 글자 = 환경 구분:
T: 실전투자 (예: TTTC0802U)
V: 모의투자 (예: VTTC0802U)
FH: 시세 (실전/모의 공통, 예: FHKST01010100)
한 글자 차이로 실전/모의가 바뀌므로 매우 주의. 모의에서 T로 시작하는 TR_ID 쓰면 403.

필수 헤더 5개 (모든 API 공통)

헤더
content-typeapplication/json
authorizationBearer {access_token}
appkey발급받은 36자리 AppKey
appsecret발급받은 180자리 AppSecret
tr_id호출하려는 TR_ID
🚨 주문 시 추가 헤더
매수/매도/정정/취소 등 주문 관련 API는 위 5개 + hashkey 헤더 추가 필수. Hashkey 생성 절차는 Section 2 참조.
Section 2

2. OAuth 인증 + HashKey

Access Token 발급

POST OAuth2 Access Token 발급 AUTH
/oauth2/tokenP
24시간 유효 토큰 발급. 하루 1회 재사용 원칙 (과도 발급 시 차단).

Body (JSON)

grant_typestringclient_credentials 고정
appkeystring발급받은 36자리 AppKey
appsecretstring발급받은 180자리 AppSecret

Response 주요 필드

access_tokenstringBearer 토큰 본체
expires_inint만료까지 초 (86400 = 24시간)
access_token_token_expiredstring만료 시각 (YYYY-MM-DD HH:MM:SS)
Python 토큰 발급 코드
url = 'https://openapivts.koreainvestment.com:29443/oauth2/tokenP'
body = {
    'grant_type': 'client_credentials',
    'appkey': APP_KEY,
    'appsecret': APP_SECRET
}
response = requests.post(url, json=body, timeout=10)
token = response.json()['access_token']

HashKey 생성

주문 API 호출 전에 반드시 실행. 주문 Body를 먼저 해시 엔드포인트에 보내 HASH를 받고, 그 HASH를 실제 주문의 헤더에 첨부.

POST HashKey 생성 HASH
/uapi/hashkey
주문 Body와 완전히 동일한 JSON을 이 엔드포인트에 POST. 반환된 HASH 값을 실제 주문의 hashkey 헤더에 설정.

헤더 (공통 3개)

content-typestringapplication/json
appkeystringAppKey
appsecretstringAppSecret
🚨 HashKey 3대 주의사항
1. Body 한 글자라도 다르면 HASH 불일치 → EGW00121 에러
2. HashKey 생성 직후 수분 내로 주문 실행 (지연 시 무효화 가능성)
3. JSON 필드 순서·공백·타입 모두 동일해야. n8n에서는 Set 노드로 Body 변수 하나 만들고 두 번 참조하는 방식 권장
Python HashKey 생성 + 주문 예시
def get_hashkey(body: dict) -> str:
    """주문 Body로 HashKey 생성."""
    url = 'https://openapivts.koreainvestment.com:29443/uapi/hashkey'
    headers = {
        'content-type': 'application/json',
        'appkey': APP_KEY,
        'appsecret': APP_SECRET
    }
    r = requests.post(url, json=body, headers=headers)
    return r.json()['HASH']

# 사용 예: 매수 주문
order_body = {
    'CANO': CANO,
    'ACNT_PRDT_CD': '01',
    'PDNO': '005930',
    'ORD_DVSN': '01',
    'ORD_QTY': '10',
    'ORD_UNPR': '0'
}
hash_key = get_hashkey(order_body)

headers = {
    'content-type': 'application/json',
    'authorization': f'Bearer {token}',
    'appkey': APP_KEY,
    'appsecret': APP_SECRET,
    'tr_id': 'VTTC0802U',
    'hashkey': hash_key   # 여기!
}
# order_body는 완전히 동일한 것을 재사용
response = requests.post(order_url, json=order_body, headers=headers)
Section 3

3. 국내주식 시세 API

GET 주식 현재가 시세 FHKST01010100
/uapi/domestic-stock/v1/quotations/inquire-price
실시간 현재가 + 전일 대비 + 거래량 + PER/PBR.

Query Parameters

FID_COND_MRKT_DIV_CODEstringJ (주식/ETF/ETN)
FID_INPUT_ISCDstring6자리 종목코드 (예: 005930)

Response output 주요 필드

stck_prprstring현재가 (문자열 숫자)
prdy_vrssstring전일 대비
prdy_ctrtstring전일 대비율 (%)
stck_oprcstring시가
stck_hgprstring고가
stck_lwprstring저가
acml_volstring누적 거래량
perstring주가수익비율 (PER)
pbrstring주가순자산비율 (PBR)
GET 주식 일자별 시세 (최근 30일) FHKST01010400
/uapi/domestic-stock/v1/quotations/inquire-daily-price
최근 30일 OHLCV. 기술적 지표 계산의 기초.

Query Parameters

FID_COND_MRKT_DIV_CODEstringJ
FID_INPUT_ISCDstring종목코드
FID_PERIOD_DIV_CODEstringD(일)/W(주)/M(월)
FID_ORG_ADJ_PRCstring0(수정주가 아님)/1(수정주가)
GET 주식 기간별 시세 (사용자 정의 기간) FHKST03010100
/uapi/domestic-stock/v1/quotations/inquire-daily-itemchartprice
최대 100일 + 시작/종료일 지정 가능. 일봉 차트 데이터.

Query Parameters

FID_COND_MRKT_DIV_CODEstringJ
FID_INPUT_ISCDstring종목코드
FID_INPUT_DATE_1string시작일 (YYYYMMDD)
FID_INPUT_DATE_2string종료일 (YYYYMMDD)
FID_PERIOD_DIV_CODEstringD/W/M/Y
FID_ORG_ADJ_PRCstring0/1
GET 주식 호가/예상체결 FHKST01010200
/uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn
매수/매도 10호가 + 예상 체결가. 지정가 주문 전 참고.
Section 4

4. 국내주식 주문 API

POST 주식 현금 매수 VTTC0802U
/uapi/domestic-stock/v1/trading/order-cash
실전 TR_ID: TTTC0802U. HashKey 필수.

Body 파라미터

CANOstring계좌번호 앞 8자리
ACNT_PRDT_CDstring계좌 상품코드 뒤 2자리 (예: 01)
PDNOstring종목코드 6자리
ORD_DVSNstring주문구분 (아래 표 참조)
ORD_QTYstring주문 수량 (문자열)
ORD_UNPRstring지정가 단가 (시장가는 "0")

ORD_DVSN 주요 값

코드의미
00지정가 (ORD_UNPR 필수)
01시장가 (ORD_UNPR="0")
02조건부지정가
03최유리지정가
04최우선지정가
05장전 시간외
06장후 시간외

Response output

KRX_FWDG_ORD_ORGNOstring거래소 전송 기관번호
ODNOstring주문번호 (정정/취소에 사용)
ORD_TMDstring주문 시각 (HHMMSS)
POST 주식 현금 매도 VTTC0801U
/uapi/domestic-stock/v1/trading/order-cash
매수와 동일한 엔드포인트. TR_ID만 VTTC0801U로 변경. Body 구조 동일.
매수/매도 분기 로직
Python에서: tr_id = 'VTTC0802U' if side == 'buy' else 'VTTC0801U'. n8n에서: IF 노드 또는 Set 노드 조건부.
POST 주식 주문 정정/취소 VTTC0803U
/uapi/domestic-stock/v1/trading/order-rvsecncl
미체결 주문 변경 or 취소.

Body 주요 필드

CANOstring계좌번호 앞 8자리
ACNT_PRDT_CDstring계좌 상품코드
KRX_FWDG_ORD_ORGNOstring원주문의 거래소 기관번호
ORGN_ODNOstring원주문번호
ORD_DVSNstring주문구분
RVSE_CNCL_DVSN_CDstring01(정정) / 02(취소)
ORD_QTYstring정정 수량 (일부 취소 시)
ORD_UNPRstring정정 단가
QTY_ALL_ORD_YNstringY(잔량 전부)/N(일부)
Section 5

5. 계좌/잔고 조회 API

GET 주식 잔고 조회 VTTC8434R
/uapi/domestic-stock/v1/trading/inquire-balance
보유 종목 리스트 (output1) + 계좌 요약 (output2).

Query 필수 파라미터

CANOstring계좌번호 앞 8자리
ACNT_PRDT_CDstring계좌 상품코드
AFHR_FLPR_YNstringN (시간외 제외)
INQR_DVSNstring01 (대출일별) / 02 (종목별)
UNPR_DVSNstring01 (현재가)
FUND_STTL_ICLD_YNstringN
FNCG_AMT_AUTO_RDPT_YNstringN
PRCS_DVSNstring00 (전일 매매 포함) / 01 (제외)
CTX_AREA_FK100string최초: 공란 / 연속조회: 이전 응답값
CTX_AREA_NK100string최초: 공란

output1 (보유 종목 리스트)

pdnostring종목코드
prdt_namestring종목명
hldg_qtystring보유 수량
pchs_avg_pricstring매입평균가
prprstring현재가
evlu_amtstring평가금액
evlu_pfls_amtstring평가손익
evlu_pfls_rtstring평가손익률 (%)

output2 (계좌 요약)

dnca_tot_amtstring예수금 총액
tot_evlu_amtstring총 평가금액
asst_icdc_amtstring자산증감액
asst_icdc_erng_rtstring자산증감수익률
GET 주문 가능 조회 VTTC8908R
/uapi/domestic-stock/v1/trading/inquire-psbl-order
특정 종목 매수 가능 수량/금액 조회. 주문 전 필수 체크.
GET 일별 주문 체결 조회 VTTC8001R
/uapi/domestic-stock/v1/trading/inquire-daily-ccld
당일/과거 주문 내역 + 체결 상태.
Section 6

6. TR_ID 전체 맵

기능모의실전HTTP
시세공통
주식 현재가FHKST01010100GET
주식 호가/예상체결FHKST01010200GET
일자별 시세FHKST01010400GET
기간별 시세FHKST03010100GET
투자자별 매매FHKST01010900GET
체결가 조회FHKST01010300GET
주문
현금 매수VTTC0802UTTTC0802UPOST
현금 매도VTTC0801UTTTC0801UPOST
정정/취소VTTC0803UTTTC0803UPOST
신용 매수VTTC0852UTTTC0852UPOST
신용 매도VTTC0851UTTTC0851UPOST
계좌/잔고
잔고 조회VTTC8434RTTTC8434RGET
주문 가능VTTC8908RTTTC8908RGET
일별 주문체결VTTC8001RTTTC8001RGET
정정취소가능 주문VTTC0081RTTTC0081RGET
해외주식 (참고)
해외 현재가HHDFS00000300GET
해외 매수 (미국)VTTT1002UTTTT1002UPOST
해외 매도 (미국)VTTT1006UTTTT1006UPOST
🔑 암기 원칙: 첫 글자만 외우세요. 실전은 T, 모의는 V, 시세는 FH. 나머지는 포털에서 검색.
Section 7

7. 에러 코드 + 대응법

자주 만나는 에러 코드 20선

코드원인 + 대응
EGW00121HashKey 불일치 — 주문 Body와 HashKey 생성 Body가 다름. 완전히 동일한 객체로 두 번 호출할 것
EGW00123토큰 만료. 재발급 필요 (expires_in 체크)
EGW00133앱키·시크릿 오류 또는 승인 대기 중. KIS Developers 포털 확인
EGW00201호출 유량 초과 (Rate Limit) — 실전 20TPS / 모의 2TPS. Wait 노드 또는 sleep 추가
EGW00205요청 타임아웃. 네트워크 or API 장애. 재시도
EGW00007필수 파라미터 누락. Query/Body 재확인
APBK0013(정상) 주문 전송 완료. 에러 아님
APBK0912매수 가능 금액 부족. 예수금 or 미체결 주문 확인
APBK0919매도 가능 수량 부족. 실제 보유 수량 재확인
APBK0916주문 가격 오류. 호가 단위(틱 사이즈) 준수 필요
APBK0650장 마감 후 주문. 정규장 시간 확인 (09:00-15:30)
APBK7005시장가 + 가격 입력 오류. 시장가는 ORD_UNPR="0"
APBK0511거래정지 종목. 종목 상태 확인
APBK0522상한가/하한가 도달. 지정가 조정
OPSP0002TR_ID와 URL 불일치. 엔드포인트 재확인
OPSP0003실전/모의 환경 불일치 (T/V 접두어 실수)
OPSP1001계좌번호 오류. CANO 8자리 + ACNT_PRDT_CD 2자리
401 Unauthorized헤더 authorization 누락 또는 잘못된 Bearer 토큰
403 Forbidden권한 없음. KIS Developers 서비스 승인 필요 or 모의투자 신청
500 Internal Server ErrorKIS 서버 장애. 잠시 후 재시도. 지속 시 고객센터 문의

에러 응답 구조

에러 JSON 예시
{
  "rt_cd": "1",             // 0=성공, 1=실패
  "msg_cd": "EGW00121",     // 에러 코드
  "msg1": "해쉬키가 일치하지 않습니다."
}
에러 자동 처리 패턴
rt_cd가 "0"이 아니면 에러. msg_cd로 분류 → Rate Limit이면 재시도, 토큰 만료면 재발급, 나머지는 Discord 알림.
Python 에러 핸들러 예시
def handle_kis_response(response):
    data = response.json()
    if data.get('rt_cd') == '0':
        return data['output']
    
    code = data.get('msg_cd')
    
    if code == 'EGW00201':
        time.sleep(2)
        raise RetryableError('Rate limit')
    elif code == 'EGW00123':
        refresh_token()
        raise RetryableError('Token expired')
    elif code in ['APBK0912', 'APBK0919']:
        notify_discord(f'자금/수량 부족: {data[\"msg1\"]}')
    
    raise Exception(f'KIS Error {code}: {data[\"msg1\"]}')
Section 8

8. Rate Limit + 운영 패턴

Rate Limit 정책

환경초당 호출 수 (TPS)비고
실전투자20 TPS시세·주문 모두 합산
모의투자2 TPS실전보다 엄격. 0.5초 간격 보장 필요
토큰 발급1일 ≈ 24회 권장과도 시 장기 차단 가능
🚨 모의투자 Rate Limit 특별 주의
모의투자는 2 TPS. 빠르게 여러 종목을 조회하면 바로 EGW00201. 반복문에서 time.sleep(0.6) 또는 n8n Wait 노드 0.6초 필수 삽입.

운영 패턴 5가지

① 토큰 캐싱 패턴
Google Sheets에 access_token + expiry 저장. 사용 시 만료 시각 체크 후 재사용. 하루 1회 재발급으로 API 호출 절약.
② Rate Limit 백오프 패턴
EGW00201 받으면 exponential backoff: 1초 → 2초 → 4초 → 8초 순으로 재시도. 최대 3회.
③ 2단계 승인 패턴
에이전트 주문 제안 → Discord 버튼 승인 → 실제 실행. 자동화 레벨을 점진적으로 높이는 안전장치.
④ Dry Run 테스트 패턴
주문 코드를 Hashkey 생성까지만 실행하고 실제 주문 전에 중단. Body가 정확한지 먼저 검증 후 활성화.
⑤ Error Trigger 분리 패턴
메인 워크플로와 에러 처리 워크플로를 분리. n8n Settings → Error Workflow 지정. 주문 실패 시 즉시 Discord 알림.

장 시간 (중요)

시간대주문 가능 여부
정규장 09:00 ~ 15:30✓ 즉시 체결 (시장가) / 지정가 대기
시간외 단일가 16:00 ~ 18:00✓ 별도 TR_ID (ORD_DVSN: 06)
장전 시간외 08:30 ~ 08:40ORD_DVSN: 05
주말·공휴일✗ 대기 주문도 안 됨 (APBK0650)
Schedule 트리거 최적 시간
08:30: 장 개장 전 분석 + 주문 준비
09:05: 개장 5분 후 실제 주문 실행 (변동성 피크 피하기)
15:15: 마감 전 청산 검토
18:00: 일일 성과 집계 + Sheets 기록

로깅 필수 항목

📘 APPENDIX C COMPLETE
KIS API 통합 레퍼런스
8 sections · 15 endpoints · 20 error codes
2026 · ZeroOneAI Education