증권사 API 비교 — 한국투자와 토스증권을 둘 다 붙여 본 기록 (2026)

“증권사 API로 자동매매를 해 보려는데 어디로 시작하면 되나요.”

검색해 보면 증권사 네 다섯 곳을 한 표에 늘어놓은 비교 글이 먼저 나옵니다. 저는 그런 표를 만들 수 없습니다. 계좌를 열고 실제로 붙여 본 곳이 두 곳이기 때문입니다. 대신 그 두 곳은 실계좌에 붙여 운영하면서, 공식 문서만 보고는 알 수 없던 지점에서 몇 번 넘어졌습니다. 이 글은 그 기록입니다.

[30초 요약] 한국투자증권 KIS는 주문까지 붙일 때 쓰기 좋고, 호출 제한이 고정값이 아니라 시간대와 전체 부하에 따라 변합니다. 토스증권 OpenAPI는 조회·수집을 서버에서 돌릴 때 편하고(사용자 로그인이 없습니다), 대신 응답이 한 겹 더 감싸여 있어 문서대로 읽으면 빈 리스트가 나옵니다. 둘 다 “API 쓰는 값”을 따로 내지는 않았지만, 요율·정책은 각 사 공식 고지로 확인하셔야 합니다.

무엇을 비교했고, 무엇을 비교하지 않았나

  • 비교한 것: 한국투자증권 KIS Developers와 토스증권 OpenAPI. 둘 다 실계좌로 붙여서 운영했습니다.
  • 비교하지 않은 것: 키움, LS증권, 대신증권. 계좌도 실측도 없습니다. 공식 문서만 읽고 “써 봤다”처럼 적는 비교표는 만들지 않겠습니다. 그 세 곳이 궁금하면 각 사 개발자 포털을 직접 보시는 게 빠릅니다.
  • 이 글이 다루는 범위: 인증, 첫 호출, 응답 구조, 호출 제한, 주문 재시도. 수익률이나 전략은 다루지 않습니다.

한눈에 보는 차이

한국투자증권 KIS 토스증권 OpenAPI
인증 계좌 기반 App Key·App Secret으로 토큰 발급 OAuth2 client credentials (서버 간)
사용자 로그인 토큰 발급 과정에 계좌 정보 필요 없음 — 서버에서 바로 발급
토큰 수명 하루 단위(제 클라이언트는 23시간 기준으로 갱신) 24시간
계좌 지정 계좌번호를 앞 8자리·뒤 2자리로 나눠 전달 계좌 목록 조회로 `accountSeq`를 얻어 헤더에 넣음
응답 구조 `output` / `output1` / `output2` + `msg_cd` 전체가 `result` 안에 들어 있음
호출 제한 `EGW00201`로 명시적으로 튕김 조용히 막힘(에러 코드 없이 결과가 줄어듦)
모의투자 별도 호스트가 있음(실전과 주소가 다릅니다) 제가 쓰지 않아 확인하지 못했습니다
제가 붙인 범위 조회 + 주문 조회만(보유·예수금·주문내역)

인증 — 한쪽은 계좌의 키, 한쪽은 서버의 자격증명

KIS는 계좌에 API를 신청해서 App Key와 App Secret을 받고, 그걸로 접근 토큰을 발급받습니다. 토큰은 하루짜리여서, 매 호출마다 새로 받으면 금방 발급 제한에 걸립니다. 저는 토큰을 파일로 저장해 두고 23시간이 지나지 않았으면 그대로 재사용합니다.

토스는 조금 다릅니다. `client_id`와 `client_secret`으로 토큰을 받는 OAuth2 client credentials 방식이라, 사람이 로그인하는 단계가 아예 없습니다. 서버에서 돌리는 수집 작업에는 이 구조가 훨씬 편합니다. 라즈베리파이에 올려 두고 cron으로 돌릴 때 사람 손이 필요한 지점이 없다는 뜻입니다.

첫 호출에서 갈리는 지점 — 계좌를 어떻게 가리키나

KIS는 계좌번호를 앞 8자리(CANO)와 뒤 2자리(상품코드)로 쪼개서 보냅니다. 처음 붙일 때 가장 많이 틀리는 곳입니다.

토스는 계좌번호를 직접 쓰지 않습니다. 먼저 계좌 목록을 조회해 `accountSeq`를 얻고, 이후 호출에서는 그 값을 헤더(`X-Tossinvest-Account`)에 넣습니다. 즉 첫 호출은 반드시 계좌 목록 조회입니다.

문서대로 읽으면 빈 리스트가 나옵니다

제가 가장 오래 헤맨 부분입니다. 토스 응답은 데이터가 `result` 한 겹 안에 들어 있습니다. 스펙에 적힌 이름만 보고 바로 꺼내면 아무것도 없는 것처럼 보입니다.

# 문서 보고 짠 코드 — 계좌가 있는데도 빈 리스트가 나왔다
accounts = data.get("accounts", [])

# 실제 응답을 찍어 보고 고친 코드
accounts = data.get("result", data).get("accounts", [])

보유 종목도 같습니다. `result` 안에 평가금액·손익 같은 요약이 있고 종목별 내역은 그 안의 `items[]`에 있습니다. 주문 내역의 페이징 커서(`nextCursor`)도 `result` 안쪽입니다. 저는 이걸 두 번에 걸쳐 고쳤습니다. 계좌 목록에서 먼저 발견했고, 보유·주문에서 같은 문제를 또 만났습니다.

교훈은 단순합니다. 스펙을 읽고 짠 다음, 첫 응답을 한 번은 그대로 찍어 보십시오. 필드 이름이 문서와 다를 수 있다는 전제로 시작하면 반나절을 아낍니다.

호출 제한 — KIS는 한도가 고정이 아닙니다

KIS에서 초당 호출이 많으면 `EGW00201`(초당 거래건수 초과)이 돌아옵니다. 문제는 그 한도가 항상 같지 않다는 점입니다. 2026-07-28에 같은 코드로 시간대를 바꿔 측정한 결과입니다.

시점 호출 간격 성공
미국장 개장 중(새벽 1시), 해외 조회 0.25초 62%
장 마감 후(밤 9시), 국내·해외 0.3초 30/30
장 마감 후(밤 9시) 0.05초 27/30

밤에는 0.05초 간격도 대부분 통과하는데, 미국장이 열려 있는 시간에는 0.25초로도 셋 중 하나가 튕깁니다. 한도가 내 계좌만의 숫자가 아니라 전체 부하와 함께 움직인다는 뜻입니다.

그래서 저는 “간격을 얼마로 둘까”를 테스트 성공률만 보고 정하지 않습니다. 감시 주기와 함께 봅니다. 10초마다 포지션과 스캔을 한 바퀴 도는 구조에서

  • 간격 1.0초 → 한 바퀴 9.5초 (10초 주기에 여유 0.5초)
  • 간격 0.5초 → 한 바퀴 6.0초 (여유 4초)

여유 0.5초는 한 번만 느려져도 주기를 넘깁니다. 지금은 간격 0.5초에 유량 제한 전용 백오프(1초·3초·9초) 를 붙여서, 피크 시간의 실패는 재시도가 받아내게 두었습니다. 참고로 처음 쓰던 0.3초는 재시도가 없던 시절 2026-07-27 오전 9시 1분부터 30분 사이에 `EGW00201`을 6건 냈습니다. 한 번의 관측이라 “0.3초면 반드시 막힌다”는 뜻은 아니고, 장 초반처럼 붐비는 구간에서는 간격만으로 버틸 수 없다는 사례입니다.

토스는 반대입니다. 코드가 돌아오지 않습니다. 결과가 조용히 줄어들기 때문에, 받아온 건수를 직접 세어 보지 않으면 성공처럼 보이는 실패가 됩니다.

주문을 붙일 거라면 — 재시도 규칙을 먼저 정하세요

조회는 실패하면 다시 부르면 됩니다. 주문은 아닙니다. 응답이 애매할 때 무심코 다시 POST를 보내면 같은 주문이 두 번 들어갈 수 있습니다.

제 규칙은 하나입니다. 주문 POST는 유량 제한(`EGW00201`)일 때만 재시도합니다. 그 코드는 “접수되지 않았다”가 확실하기 때문입니다. 그 외의 오류는 재시도하지 않고 멈춘 뒤, 주문 내역을 조회해서 실제로 들어갔는지 확인합니다.

여기에 하나 더. KIS는 5xx 응답 본문에도 `msg_cd`가 실려 옵니다. HTTP 상태만 보고 본문을 버리면 유량 제한을 일시 장애로 오해하고, 잘못된 재시도 규칙을 적용하게 됩니다.

그래서 어느 쪽으로 시작할까

  • 보유 종목·예수금·거래내역을 서버에서 정기적으로 모으고 싶다 → 토스. 사용자 로그인이 없어서 무인 운영이 깔끔합니다. 단 `result` 래퍼와 건수 확인을 처음부터 넣으세요.
  • 주문까지 자동으로 넣을 생각이다 → KIS. 대신 호출 간격·백오프·재시도 규칙을 코드 짜기 전에 정하세요.
  • 아직 뭘 할지 모르겠다 → 조회부터. 주문은 규칙을 정한 뒤에 붙이는 게 맞습니다. 저도 조회 자동화를 먼저 돌린 뒤에 주문을 붙였습니다.
  • 윈도우가 아닌 환경에서 돌린다 → 두 곳 다 HTTP 호출이라 OS 제약이 없었습니다. 구형 COM/OCX 방식 API는 윈도우가 필요합니다.

자주 묻는 질문

API 쓰는 데 돈이 드나요? 제가 두 곳을 쓰면서 ‘API 이용료’ 명목으로 따로 낸 것은 없었습니다. 다만 매매에는 수수료·세금이 그대로 붙고, 시세 정보 이용료가 별도인 경우도 있습니다. 요율과 정책은 바뀌므로 각 사 공식 고지로 확인하세요. 이 글의 숫자로 판단하지 마십시오.

모의투자로 먼저 연습할 수 있나요? KIS는 모의투자용 호스트가 따로 있습니다. 주소가 실전과 다르다는 점만 주의하세요. 코드에서 실전/모의를 분기할 때 호스트를 함께 바꿔야 합니다. 토스 쪽은 제가 모의 환경을 쓰지 않아 확인하지 못했습니다.

둘 다 붙이면 좋은가요? 조회를 토스로, 주문을 KIS로 나눠 쓸 수는 있지만 계좌가 둘로 나뉩니다. 저는 수집과 매매를 같은 계좌로 보는 게 편해서, 용도마다 한쪽을 정해 씁니다.

파이썬이 아니어도 되나요? 둘 다 HTTP라 언어 제약은 없습니다. 자료가 많은 쪽은 파이썬입니다.

처음 붙이는 데 얼마나 걸리나요? 인증과 첫 조회까지는 반나절이면 됩니다. 제가 시간을 쓴 쪽은 늘 그다음, 응답 구조와 호출 제한이었습니다.

함께 읽으면 좋은 글

각 증권사별 상세한 함정은 따로 정리해 뒀습니다. 한국투자증권은 한국투자증권 API 사용법과 함정에, 토스증권은 토스증권 OpenAPI 파이썬 실전 가이드에 있습니다. 이걸 어디에 올려 두고 돌릴지는 라즈베리파이 투자 자동화 서버에, 돌고 있다고 믿었다가 아니었던 이야기는 내 코드가 이렇게 돈다고 확신했는데에 적었습니다.

API를 붙이는 일은 생각보다 쉽고, 붙인 다음을 믿을 수 있게 만드는 일이 생각보다 오래 걸립니다.

※ 본 글은 운영 기록이며 특정 증권사·종목·매매 시점의 권유가 아닙니다. 수수료·호출 한도·서비스 정책은 각 사 공식 고지를 확인하십시오.

Leave a Comment