계좌조회 API 문서
계좌조회 API 개요
Bank API는 국내 은행 계좌의 거래내역을 조회할 수 있는 REST API입니다. 간단한 HTTP 요청으로 은행 데이터를 연동할 수 있습니다.
Base URL
https://api.bankapi.co.kr
테스트용 API Key
아래 키를 사용하여 바로 테스트해볼 수 있습니다:
API Key: {{API_KEY}}
Secret Key: {{SECRET_KEY}}
주의: 위 키는 테스트 전용입니다. 실제 서비스에서는 반드시 본인의 API Key를 발급받아 사용하세요. 테스트 키는 Rate Limit이 제한되어 있으며, 예고 없이 변경될 수 있습니다.
계좌조회 API 인증 방식
API 요청 시 Authorization 헤더에 API Key와 Secret Key를 포함해야 합니다.
Private Mode (권장)
API Key와 Secret Key를 콜론(:)으로 연결하여 Bearer 토큰으로 전송합니다.
Authorization: Bearer {apiKey}:{secretKey}
인증 예시
Authorization: Bearer {{API_KEY}}:{{SECRET_KEY}}
계좌거래내역 조회
지정한 기간의 계좌 거래내역을 조회합니다.
/v1/transactions
요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
bankCode |
string | 필수 | 은행 코드 (NH, KB, WR, IBK). 신한 SH는 로그인 기반 조회 사용 |
accountNumber |
string | 필수 | 계좌번호 (하이픈 없이) |
accountPassword |
string | 필수 | 계좌 비밀번호 |
residentNumber |
string | 필수 | 주민등록번호 앞 6자리 |
startDate |
string | 필수 | 조회 시작일 (YYYYMMDD) |
endDate |
string | 필수 | 조회 종료일 (YYYYMMDD) |
은행 코드
| 코드 | 은행명 | 코드 | 은행명 |
|---|---|---|---|
NH |
농협은행 | KB |
KB국민은행 |
WR |
우리은행 | IBK |
기업은행 |
SH |
신한은행 (로그인 기반 → 아래 섹션 사용) |
코드 예제
curl -X POST https://api.bankapi.co.kr/v1/transactions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{API_KEY}}:{{SECRET_KEY}}" \
-d '{
"bankCode": "NH",
"accountNumber": "{{ACCOUNT_NUMBER}}",
"accountPassword": "1234",
"residentNumber": "800101",
"startDate": "20260101",
"endDate": "20260110"
}'
응답 예시
{
"success": true,
"transactions": [
{
"date": "2026-01-10",
"time": "14:30:25",
"description": "스마트출금",
"displayName": "스타벅스",
"counterparty": "스타벅스코리아",
"amount": 50000,
"balance": 1234567,
"type": "withdrawal",
"branch": "강남"
},
{
"date": "2026-01-09",
"time": "09:15:00",
"description": "FBS입금",
"displayName": "",
"counterparty": "홍길동",
"amount": 3000000,
"balance": 1284567,
"type": "deposit",
"branch": "국민 0068738"
}
],
"accountInfo": {
"accountNumber": "{{ACCOUNT_NUMBER}}",
"balance": 1284567
}
}
응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
date |
string | 거래일자 — 은행에 따라 YYYY-MM-DD 또는 YYYY/MM/DD 형식 |
time |
string | 거래시간 (HH:MM:SS) |
type |
string | 입출금 구분 ("deposit" 또는 "withdrawal") |
amount |
number | 거래금액 |
balance |
number | 거래 후 잔액 |
description |
string | 거래 유형 (예: 카드결제, 스마트출금, FBS입금) |
displayName |
string | 내통장표시내용/거래내용 — 은행에 따라 통장 표시 이름 또는 거래내용이 들어갑니다 (빈 문자열일 수 있음) |
counterparty |
string | 의뢰인/수취인 — 상대방 이름 또는 거래내용 (KB·IBK 지원, 그 외 은행은 빈 문자열일 수 있음) |
branch |
string | 거래점 — 은행에 따라 상대은행이 들어갈 수 있음 (빈 문자열일 수 있음) |
memo |
string | 메모 (빈 문자열일 수 있음) |
accountInfo: 응답에는 계좌 요약 정보accountInfo가 함께 옵니다.accountNumber·balance는 공통이며, 은행에 따라 예금 종류(accountName)·예금주명(accountHolder)이 포함될 수 있습니다.
에러 응답
{
"success": false,
"error": "ACCOUNT_COOLDOWN",
"message": "동일 계좌는 5분에 1회만 조회할 수 있습니다. 잠시 후 다시 시도해 주세요.",
"retryAfterSec": 540
}
{
"success": false,
"error": "QUERY_QUOTA_EXCEEDED",
"message": "조회 한도(30분당 30회)를 초과했습니다.",
"retryAfterSec": 1200
}
{
"success": false,
"error": "TOO_MANY_REQUESTS",
"message": "요청 한도(30분당 60회)를 초과했습니다.",
"retryAfterSec": 800
}
{
"success": false,
"error": "Invalid API Key"
}
참고: 별도의 계좌 등록 절차 없이 바로 조회할 수 있습니다. 단 같은 계좌는 5분에 1회, 30분당 최대 30회(성공 기준)·60회(요청 기준)까지 조회할 수 있습니다.
로그인 기반 거래내역 조회 (신한)
신한은행처럼 홈페이지 ID/PW 로그인이 필요한 은행의 거래내역을 조회합니다. 로그인 1회로 등록된 여러 계좌를 한 번에 조회합니다(배치). 무로그인 4개 은행(농협·국민·우리·기업)은 위 거래내역 조회를 사용하세요.
/v1/transactions/login
요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
bankCode |
string | 필수 | 은행 코드 (현재 SH 신한) |
loginId |
string | 필수 | 인터넷뱅킹 이용자 ID |
loginPassword |
string | 필수 | 인터넷뱅킹 로그인 비밀번호 |
accounts |
array | 필수 | 조회할 계좌 목록(1개 이상). 각 항목: { accountNumber, accountPassword } — 계좌번호(하이픈 없이)와 계좌 비밀번호(4자리) |
startDate |
string | 필수 | 조회 시작일 (YYYYMMDD) |
endDate |
string | 필수 | 조회 종료일 (YYYYMMDD) |
sortOrder |
string | 선택 | 정렬: recent(최근거래순, 기본) 또는 old(과거거래순) |
지원 은행: 신한은행(SH) — 인터넷뱅킹 회원이 간편계좌관리에 등록한 간편계좌를 조회합니다. 로그인 자격증명·계좌 비밀번호는 저장·기록하지 않고 조회에만 사용합니다.
코드 예제
curl -X POST https://api.bankapi.co.kr/v1/transactions/login \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{API_KEY}}:{{SECRET_KEY}}" \
-d '{
"bankCode": "SH",
"loginId": "{{LOGIN_ID}}",
"loginPassword": "{{LOGIN_PASSWORD}}",
"accounts": [
{ "accountNumber": "{{ACCOUNT_NUMBER}}", "accountPassword": "{{ACCOUNT_PASSWORD}}" }
],
"startDate": "20260101",
"endDate": "20260131",
"sortOrder": "recent"
}'
응답 예시
{
"success": true,
"results": [
{
"accountNumber": "{{ACCOUNT_NUMBER}}",
"success": true,
"accountInfo": {
"accountNumber": "{{ACCOUNT_NUMBER}}",
"accountName": "쏠편한 입출금통장(저축예금)",
"accountHolder": "홍길동",
"balance": 1284567
},
"transactions": [
{
"date": "2026/01/10",
"time": "14:30:25",
"description": "타행이체",
"displayName": "",
"counterparty": "홍길동",
"amount": 50000,
"balance": 1234567,
"type": "withdrawal",
"branch": "종로중"
}
]
}
]
}
응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
success |
boolean | 로그인 성공 여부. 계좌별 성공/실패는 results[].success로 구분 |
results |
array | 계좌별 결과 배열. 각 원소는 무로그인 단건 응답과 동일한 형태(구분용 accountNumber 포함) |
results[].accountNumber |
string | 해당 계좌번호 (결과 구분용) |
results[].success |
boolean | 해당 계좌 조회 성공 여부 |
results[].transactions |
array | 거래내역 배열 (거래내역 조회와 동일 필드) |
results[].accountInfo |
object | 계좌 요약: accountNumber, accountName, accountHolder, balance |
results[].error |
string | 실패 시 에러 코드 (선택) |
참고: 신한은 인터넷뱅킹 로그인이 필요하며, 로그인 1회로 accounts의 여러 계좌를 순차 조회합니다. 같은 계좌 5분 1회 등 조회 제한은 아래와 동일하게 적용됩니다.
계좌조회 API Rate Limiting
거래내역 조회는 남용 방지를 위해 아래 제한이 적용됩니다. 제한 초과 시 429 에러가 반환됩니다.
| 제한 | 기준 | 한도 | 에러 코드 |
|---|---|---|---|
| 동일 계좌 재조회 | 계좌별 (전역 · 키/IP 무관) | 5분당 1회 | ACCOUNT_COOLDOWN |
| 조회 횟수(성공 기준) | API Key별 · IP별 | 30분당 30회 | QUERY_QUOTA_EXCEEDED |
| 요청 횟수(성공+실패) | API Key별 | 30분당 60회 | TOO_MANY_REQUESTS |
Retry-After 헤더
제한에 걸리면 응답 헤더와 본문(retryAfterSec)에서 재시도까지 남은 시간(초)을 확인할 수 있습니다:
HTTP/1.1 429 Too Many Requests Retry-After: 540
실전: 429 자동 재시도 (복붙 가능)
제한에 걸리면 retryAfterSec만큼 기다렸다 재시도하는 패턴입니다. 응답 파싱까지 포함해 바로 쓸 수 있습니다.
const API_KEY = '{{API_KEY}}';
const SECRET_KEY = '{{SECRET_KEY}}';
async function getTransactions(body, maxRetries = 2) {
for (let attempt = 0; ; attempt++) {
const res = await fetch('https://api.bankapi.co.kr/v1/transactions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}:${SECRET_KEY}`
},
body: JSON.stringify(body)
});
const data = await res.json();
// 429(제한) 이면 retryAfterSec 만큼 대기 후 재시도
if (res.status === 429 && attempt < maxRetries) {
const waitSec = data.retryAfterSec || Number(res.headers.get('Retry-After')) || 60;
console.log(`Rate limit(${data.error}) — ${waitSec}s 후 재시도`);
await new Promise(r => setTimeout(r, waitSec * 1000));
continue;
}
if (!res.ok) throw new Error(data.error || `HTTP ${res.status}`);
return data.transactions;
}
}
// 사용 예
const txs = await getTransactions({
bankCode: 'NH', accountNumber: '{{ACCOUNT_NUMBER}}', accountPassword: '1234',
residentNumber: '800101', startDate: '20260101', endDate: '20260110'
});
txs.forEach(t => console.log(`${t.date} ${t.type} ${t.amount}원 (잔액 ${t.balance})`));
import requests, time
API_KEY = '{{API_KEY}}'
SECRET_KEY = '{{SECRET_KEY}}'
def get_transactions(body, max_retries=2):
for attempt in range(max_retries + 1):
res = requests.post(
'https://api.bankapi.co.kr/v1/transactions',
headers={
'Content-Type': 'application/json',
'Authorization': f'Bearer {API_KEY}:{SECRET_KEY}'
},
json=body
)
data = res.json()
# 429(제한) 이면 retryAfterSec 만큼 대기 후 재시도
if res.status_code == 429 and attempt < max_retries:
wait = data.get('retryAfterSec') or int(res.headers.get('Retry-After', 60))
print(f"Rate limit({data['error']}) — {wait}s 후 재시도")
time.sleep(wait)
continue
res.raise_for_status()
return data['transactions']
# 사용 예
txs = get_transactions({
'bankCode': 'NH', 'accountNumber': '{{ACCOUNT_NUMBER}}', 'accountPassword': '1234',
'residentNumber': '800101', 'startDate': '20260101', 'endDate': '20260110'
})
for t in txs:
print(f"{t['date']} {t['type']} {t['amount']}원 (잔액 {t['balance']})")
팁:ACCOUNT_COOLDOWN(같은 계좌 5분)은 대기가 길어 자동 재시도보다 폴링 주기를 5분 이상으로 두는 편이 낫습니다. 자동 재시도는QUERY_QUOTA_EXCEEDED·TOO_MANY_REQUESTS처럼 짧은 일시적 초과에 유용합니다.
계좌조회 API 에러 코드
API 요청 실패 시 반환되는 에러 코드입니다.
| 코드 | 상태 | 설명 |
|---|---|---|
400 |
Bad Request | 잘못된 요청 파라미터 |
401 |
Unauthorized | 인증 실패 (API Key/Secret Key 오류) |
403 |
Forbidden | 접근 권한 없음 |
404 |
Not Found | 존재하지 않는 엔드포인트 |
429 |
Too Many Requests | Rate Limit 초과 |
500 |
Internal Server Error | 서버 내부 오류 |
에러 응답 형식
error는 에러 코드 문자열이고, 제한(429)일 때는 retryAfterSec(재시도까지 남은 초)이 함께 옵니다.
{
"success": false,
"error": "ACCOUNT_COOLDOWN",
"message": "동일 계좌는 5분에 1회만 조회할 수 있습니다. 잠시 후 다시 시도해 주세요.",
"retryAfterSec": 540
}
계좌조회 API 보안
Bank API는 사용자의 금융 정보 보호를 최우선으로 합니다.
계좌 정보 보호
Bank API는 어떠한 경우에도 계좌 정보를 데이터베이스에 저장하지 않습니다.
- 계좌번호, 비밀번호, 주민등록번호 등 민감 정보는 API 요청 처리 후 즉시 폐기됩니다
- 거래내역 데이터는 서버에 저장되지 않으며, 실시간으로 은행에서 조회하여 전달합니다
- 서버 로그에도 민감 정보는 기록되지 않습니다
- 계좌번호를 식별용 해시(SHA-256)로도 저장하지 않습니다 — 조회 제한은 서버 메모리에서만 임시 처리됩니다
API Key 보안
- API Key와 Secret Key는 SHA-256으로 해시하여 저장합니다
- 평문 키는 최초 발급 시 한 번만 표시되며, 이후 복구가 불가능합니다
- 키가 유출된 경우 즉시 새로운 키를 발급받으세요
통신 보안
- 모든 API 통신은 TLS 1.2 이상의 HTTPS로 암호화됩니다
- HTTP 요청은 자동으로 HTTPS로 리다이렉트됩니다
API 테스트
API를 직접 테스트해보고 싶으신가요? 회원가입 없이 바로 실제 API를 호출해볼 수 있습니다.