튜토리얼약 14분 읽기

토스증권 오픈API 시작하기 — 신청부터 파이썬 첫 연결까지

증권사 자동매매 API를 뭘 골라야 하나를 정리하면서 토스증권 오픈API를 처음 들여다봤다. 2026년 상반기에 새로 열린 서비스라 검색해봐도 참고할 글이 많지 않았고, 그래서 오히려 "지금 붙여보고 남기는 기록"이 값어치가 있겠다고 생각했다. 다만 나는 토스증권 실계좌로 이 API를 직접 운영해본 적이 없다. 그래서 이 글은 실전 후기가 아니라, 공식 문서와 공개된 자료를 교차 확인해 정리한 개념·절차 가이드다.

이 글의 범위

이 글에서 다루는 사실은 전부 토스증권 오픈API 공식 문서(developers.tossinvest.com)와 여러 공개 안내 자료를 대조해 확인한 범위 안에서만 서술한다. 확인이 안 되는 세부(정확한 신청 화면 UI, 요청 한도의 구체적 수치, 각 엔드포인트의 정확한 경로)는 추정해서 채우지 않고 "확인되지 않는다" 또는 "공식 문서에서 카테고리별로 확인해야 한다"고 명시한다. 실계좌·실키·실제 화면 캡처는 없다.

토스증권 오픈API가 다른 증권사 API와 구조적으로 뭐가 다른지는 앞서 증권사 자동매매 API 비교에서 이미 짚었다. 이 글은 그중 토스증권 하나만 떼어내 신청부터 첫 연결까지의 순서를 더 깊게 다룬다.

왜 지금 토스증권 오픈API인가

토스증권 오픈API는 2026년 상반기에 새로 공개된 서비스다. 공식 문서(llms.txt)에 따르면 기준 서버는 표준 REST 방식으로 제공되고, 인증·시장데이터·종목정보·시장정보(환율·휴장일)·계좌·자산·주문 기능을 국내(KRX)와 미국 주식 양쪽에 대해 하나의 API로 함께 제공한다. 국내·미국을 따로 붙일 필요 없이 계좌·주문 구조를 공유한다는 점이 키움 미국주식 REST API처럼 별도 카테고리로 나뉜 기존 API들과 가장 눈에 띄게 다른 지점이다.

신규 서비스라 아직 커뮤니티 자료가 얇은 것도 사실이다. 그런데 이건 단점이자 동시에 지금 시작하는 사람에게는 기회이기도 하다 — 막혔을 때 참고할 사례는 적지만, 그만큼 검색 경쟁도 낮다.

신청과 client_id·secret 발급 흐름

토스증권 오픈API를 쓰려면 먼저 신청 절차를 거쳐 인증 정보를 발급받아야 한다. 공개된 안내 자료들을 종합하면 대략 이런 흐름이다.

  1. 토스증권 앱 또는 PC 웹(WTS)에서 Open API 관련 메뉴로 들어간다
  2. 이용 약관에 동의한다
  3. 신청이 처리되면 client_idclient_secret이 발급된다

여러 안내 자료에서는 토스증권 계좌를 보유한 고객이면 별도 심사 서류 없이 신청할 수 있다고 설명한다. 다만 정확한 자격 요건, 메뉴 이름, 화면 구성은 신규 서비스 특성상 공지 없이 바뀔 수 있으므로, 실제로 신청할 때는 반드시 토스증권 공식 안내 페이지(corp.tossinvest.com/ko/open-api) 기준으로 확인해야 한다. 이 글에서는 그 화면을 다루지 않는다.

client_id와 client_secret은 계좌에 접근할 수 있는 열쇠라는 점에서 다른 증권사의 App Key/Secret과 성격이 같다. 키움증권 REST API 시작하기에서 다뤘던 것과 동일한 원칙이 그대로 적용된다.

OAuth 2.0 Client Credentials 인증 흐름 — 의사코드

공식 문서는 이 API의 인증 방식을 명확히 규정한다. "모든 API는 OAuth 2.0 Client Credentials Grant로 발급받은 access token을 사용한다"는 것이다. 사용자 로그인 리다이렉트 같은 단계 없이, 서버가 자기 자격증명(client_id·client_secret)만으로 토큰을 받는 서버-투-서버 인증 방식이다.

App Key / Secret Access Token 발급받음 인증 헤더로 API 요청 잔고·시세 데이터 응답 발급요청 토큰 첨부 응답 키·토큰은 코드가 아니라 환경변수로 — 절대 커밋 금지
증권사 REST API 인증 흐름 — 키로 토큰을 발급받아 이후 요청 헤더에 싣는 공통 패턴

큰 흐름은 다른 증권사 REST API와 다르지 않다 — 증권사 REST API 인증 개념에서 다룬 패턴 그대로, 자격증명으로 토큰을 받고 이후 요청 헤더에 실어 보낸다.

python 코드 보기
import os

class TossAuthClient:
    def __init__(self, client_id: str, client_secret: str, base_url: str):
        self.client_id = client_id
        self.client_secret = client_secret
        self.base_url = base_url
        self._token = None
        self._token_expires_at = None

    def get_access_token(self) -> str:
        """토큰이 없거나 만료됐으면 client_credentials 그랜트로 재발급"""
        if self._token and not self._is_expired():
            return self._token
        response = self._request_token_client_credentials()
        self._token = response["access_token"]
        self._token_expires_at = response["expires_at"]
        return self._token

    def _request_token_client_credentials(self) -> dict:
        """실제로는 공식 문서에 명시된 토큰 발급 엔드포인트에
        grant_type=client_credentials 로 POST"""
        raise NotImplementedError

    def _is_expired(self) -> bool:
        raise NotImplementedError


auth = TossAuthClient(
    client_id=os.environ["TOSS_CLIENT_ID"],
    client_secret=os.environ["TOSS_CLIENT_SECRET"],
    base_url=os.environ["TOSS_API_BASE_URL"],
)

여기서 중요한 건 base_url과 자격증명을 코드에 직접 적지 않고 환경변수로 주입한다는 점이다. 실제 토큰 발급 엔드포인트의 정확한 경로와 요청 파라미터는 공식 문서 기준으로 그대로 따라야 한다 — 이 글은 그 경로를 임의로 단정하지 않는다.

파이썬 첫 연동 — 잔고·시세 조회까지

토큰을 받은 뒤에는 다른 REST API와 마찬가지로 헤더에 실어 요청을 보낸다. 공식 문서가 밝힌 카테고리 구성을 보면, 잔고·보유주식은 "계좌·자산" 그룹에, 시세는 "시장데이터" 그룹에 속한다. 처음 연동할 때는 이 두 가지 — 잔고 조회와 시세 조회 — 만 성공시키는 걸 목표로 잡는 게 적당하다. 주문은 실제 자금이 움직이는 영역이라 별도로 신중하게 다뤄야 한다.

python 코드 보기
class TossAccountClient:
    def __init__(self, auth_client: TossAuthClient):
        self.auth_client = auth_client

    def get_holdings(self, account_ref: str) -> dict:
        """계좌·자산 카테고리 — 보유 종목·잔고 조회"""
        token = self.auth_client.get_access_token()
        headers = {
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
        }
        response = self._call_holdings_endpoint(headers, account_ref)
        return {
            "cash": response["cash"],
            "holdings": response["holdings"],
        }

    def _call_holdings_endpoint(self, headers, account_ref):
        raise NotImplementedError


class TossMarketDataClient:
    def __init__(self, auth_client: TossAuthClient):
        self.auth_client = auth_client

    def get_price(self, symbol: str) -> dict:
        """시장데이터 카테고리 — 국내·미국 시세 조회"""
        token = self.auth_client.get_access_token()
        headers = {"Authorization": f"Bearer {token}"}
        response = self._call_price_endpoint(headers, symbol)
        return {"symbol": symbol, "price": response["price"]}

    def _call_price_endpoint(self, headers, symbol):
        raise NotImplementedError

_call_holdings_endpoint_call_price_endpoint 안에 실제로 들어갈 요청 경로·파라미터는 공식 문서를 그대로 참고해서 채워야 하는 부분이라 이 글에서는 비워뒀다. 여기서 중요한 건 인증 클라이언트(TossAuthClient)를 두 클라이언트가 공유하는 구조다 — 토큰 캐싱·만료 재발급 로직을 한 곳에만 두면, 잔고든 시세든 주문이든 새 기능을 추가할 때마다 인증 로직을 다시 짤 필요가 없다.

시작 전 알아둘 함정

오늘의 정리

  1. 토스증권 오픈API는 2026년 상반기에 새로 열린 서비스로, OAuth 2.0 Client Credentials 방식의 서버-투-서버 인증을 쓰고 국내(KRX)·미국 주식을 하나의 API로 함께 제공한다.
  2. 신청은 토스증권 앱 또는 PC 웹(WTS)의 Open API 메뉴에서 진행되고, 발급받은 client_id·client_secret은 다른 증권사의 App Key/Secret과 마찬가지로 비밀번호와 동급으로 다뤄야 한다.
  3. API 레벨의 별도 모의투자 환경이 확인되지 않으므로, 처음 붙일 때는 조회성 API부터 소량으로 검증하고 주문은 가장 나중에 다룬다.
  4. 공식 SDK는 없고 커뮤니티 자료도 아직 얇다 — 대신 요청 한도·에러 처리 같은 운영 설계는 증권사에 무관하게 먼저 갖춰두는 게 신규 API일수록 더 중요하다.

다음 글에서는 이렇게 첫 연결에 성공한 뒤, 잔고 조회 응답을 실제로 파싱해서 쓰는 지점까지 더 들어가볼 예정이다.


이 글에서 다룬 토스증권 오픈API 관련 내용은 공식 문서와 공개된 자료를 교차 확인해 서술했으며, 확인되지 않는 세부는 추정하지 않고 그대로 밝혔습니다. 실계좌번호·API 키·실제 화면은 담고 있지 않습니다. 이 글은 투자 조언이 아니며 특정 증권사·종목·매매기법을 추천하지 않습니다. 수익을 보장하지 않으며, 투자 손실은 투자자 본인의 책임입니다.

← 전체 글 목록