주소
고팍스 REST API 서버 주소는 다음과 같습니다.
https://api.gopax.co.kr
인증
import base64, hashlib, hmac, json, requests, time
API_KEY = '<입력하세요>'
SECRET = '<입력하세요>'
def call(need_auth, method, path, body_json=None, recv_window=None):
method = method.upper()
if need_auth:
timestamp = str(int(time.time() * 1000))
include_querystring = method == 'GET' and path.startswith('/orders?')
p = path if include_querystring else path.split('?')[0]
msg = 't' + timestamp + method + p
msg += (str(recv_window) if recv_window else '') + (json.dumps(body_json) if body_json else '')
raw_secret = base64.b64decode(SECRET)
raw_signature = hmac.new(raw_secret, str(msg).encode('utf-8'), hashlib.sha512).digest()
signature = base64.b64encode(raw_signature)
headers = {'api-key': API_KEY, 'timestamp': timestamp, 'signature': signature}
if recv_window:
headers['receive-window'] = str(recv_window)
else:
headers = {}
req_func = {'GET': requests.get, 'POST': requests.post, 'DELETE': requests.delete}[method]
resp = req_func(url='https://api.gopax.co.kr' + path, headers=headers, json=body_json)
return {
'statusCode': resp.status_code,
'body': resp.json(),
'header': dict(resp.headers),
}
post_orders_req_body = {
'side': 'buy', 'type': 'limit', 'amount': 1,
'price': 10000, 'tradingPairName': 'BTC-KRW'
}
print(call(True, 'POST', '/orders', post_orders_req_body, 200))
print(call(True, 'GET', '/orders'))
print(call(True, 'GET', '/orders?includePast=true'))
print(call(True, 'GET', '/trades?limit=1'))
print(call(False, 'GET', '/trading-pairs/BTC-KRW/book?level=1'))
const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
const crypto = require('crypto');
const API_KEY = '<입력하세요>';
const SECRET = '<입력하세요>';
function call(needAuth, method, path, bodyJson = null, recvWindow = null) {
const bodyStr = bodyJson ? JSON.stringify(bodyJson) : '';
const http = new XMLHttpRequest();
const methodInUpperCase = method.toUpperCase();
http.open(methodInUpperCase, `https://api.gopax.co.kr${path}`, false);
if (needAuth) {
const timestamp = new Date().getTime();
const includeQuerystring = methodInUpperCase === 'GET' && path.startsWith('/orders?');
const p = includeQuerystring ? path : path.split('?')[0];
const msg = `t${timestamp}${methodInUpperCase}${p}${recvWindow || ''}${bodyStr}`;
const rawSecret = Buffer.from(SECRET, 'base64');
const signature = crypto.createHmac('sha512', rawSecret).update(msg).digest('base64');
http.setRequestHeader('api-key', API_KEY);
http.setRequestHeader('timestamp', timestamp);
http.setRequestHeader('signature', signature);
if (recvWindow) {
http.setRequestHeader('receive-window', recvWindow);
}
}
http.send(bodyStr);
return {
statusCode: http.status,
body: JSON.parse(http.responseText),
header: http.getAllResponseHeaders(),
};
}
function printAllDepth(json) {
console.dir(json, { depth: null });
}
const postOrdersReqBody = {
side: 'buy', type: 'limit', amount: 1,
price: 10000, tradingPairName: 'BTC-KRW',
};
printAllDepth(call(true, 'POST', '/orders', postOrdersReqBody, 200));
printAllDepth(call(true, 'GET', '/orders'));
printAllDepth(call(true, 'GET', '/orders?includePast=true'));
printAllDepth(call(true, 'GET', '/trades?limit=1'));
printAllDepth(call(false, 'GET', '/trading-pairs/BTC-KRW/book?level=1'));
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha512"
"encoding/base64"
"encoding/json"
"io/ioutil"
"log"
"net/http"
"strconv"
"strings"
"time"
)
const (
apiKey = "<입력하세요>"
secret = "<입력하세요>"
)
func call(
needAuth bool, method string, path string,
body map[string]interface{}, // can be nil
recvWindow int, // set -1 not to assign
) *map[string]interface{} {
method = strings.ToUpper(method)
var bodyBytes []byte = nil
if body != nil {
bodyBytes, _ = json.Marshal(body)
}
req, _ := http.NewRequest(method, "https://api.gopax.co.kr"+path, bytes.NewBuffer(bodyBytes))
if needAuth {
timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10)
msg := "t" + timestamp + method
if method == "GET" && strings.HasPrefix(path, "/orders?") {
msg += path
} else {
msg += strings.Split(path, "?")[0]
}
if recvWindow != -1 {
msg += strconv.Itoa(recvWindow)
req.Header.Set("receive-window", strconv.Itoa(recvWindow))
}
if bodyBytes != nil {
msg += string(bodyBytes)
}
rawSecret, _ := base64.StdEncoding.DecodeString(secret)
mac := hmac.New(sha512.New, rawSecret)
mac.Write([]byte(msg))
signature := base64.StdEncoding.EncodeToString(mac.Sum(nil))
req.Header.Set("api-key", apiKey)
req.Header.Set("timestamp", timestamp)
req.Header.Set("signature", signature)
}
resp, resp_err := (&http.Client{}).Do(req)
if resp_err != nil {
panic(resp_err)
}
defer resp.Body.Close()
respBodyBytes, _ := ioutil.ReadAll(resp.Body)
return &map[string]interface{}{
"statusCode": resp.StatusCode,
"body": string(respBodyBytes),
"header": resp.Header,
}
}
func main() {
postOrderReqBody := map[string]interface{}{
"side": "buy", "type": "limit", "amount": 1,
"price": 10000, "tradingPairName": "BTC-KRW",
}
log.Print(*call(true, "POST", "/orders", postOrderReqBody, 200))
log.Print(*call(true, "GET", "/orders", nil, -1))
log.Print(*call(true, "GET", "/orders?includePast=true", nil, -1))
log.Print(*call(true, "GET", "/trades?limit=1", nil, -1))
log.Print(*call(false, "GET", "/trading-pairs/BTC-KRW/book?level=1", nil, -1))
}
고팍스 REST API를 사용하기 위해서는 고팍스 웹사이트를 통해 발급받은 API Key 및 Secret을 필요로 합니다.
- 현재 시점의 timestamp를 소수점 없이 밀리세컨드 단위로 구합니다.
- 다음 문자열들을 연결하여 msg를 생성합니다.
- 문자열 't'
- timestamp
- 요청 메서드를 대문자로 (e.g. 'GET')
- 요청 경로 (e.g. '/orders')
- 요청 바디 (바디가 없는 경우는 생략)
- secret을 base64로 디코딩하여 raw secret을 구합니다.
- msg를 raw secret으로 SHA512 HMAC 서명하여 raw signature를 생성합니다.
- raw signature를 base64로 인코딩하여 signature를 구합니다.
- 요청 헤더에 api-key, timestamp, signature를 추가합니다.
리시브 윈도
사용자가 설정한 특정 수치 이상으로 네트워크 레이턴시 발생 시에 서버에서 주문을 거절하도록 만드는, 선택적으로 이용할 수 있는 부가 기능입니다. 값으로는 200 ~ 60000이 허용되며 단위는 밀리세컨드입니다. "해당 주문이 x 밀리세컨드 내에 서버에 도달하지 않으면 거절하시오"라는 의미입니다. 활용 방법은 다음과 같습니다.
- 시그니쳐 생성 과정 중 msg에 "API 경로" 항목 바로 뒤에 리시브 윈도를 삽입하세요.
- HTTP 요청 헤더에 receive-window를 추가하세요.
주문의 서버 도달 시점의 시간이 사용자의 타임스탬프에 리시브 윈도를 더한 시간보다 늦은 경우 서버에서 주문을 거절합니다.
개인 API
개인 API는 인증 과정이 반드시 필요한 API입니다.
잔고 조회
GET /balances
호출 예시
경로
GET /balances
요청
없음
응답
[
{
"asset": "KRW", # 자산 이름
"avail": 1759466.76, # 주문 가능 보유 수량
"hold": 16500, # 오더북에 올라가 있는 미체결 수량
"pendingWithdrawal": 0, # 출금 처리 중인 수량
"lastUpdatedAt": "1600684352032" # 해당 잔고 최근 갱신 시간
},
{
"asset": "ETH",
"avail": 100979.57523727,
"hold": 50.02,
"pendingWithdrawal": 0,
"lastUpdatedAt": "1600686162591"
},
...
]
특정 자산 잔고 조회
GET /balances/<AssetName>
호출 예시
경로
GET /balances/ETH
요청
없음
응답
{
"asset": "ETH", # 자산 이름
"avail": 100979.57523727, # 주문 가능 보유 수량
"hold": 50.02, # 오더북에 올라가 있는 미체결 수량
"pendingWithdrawal": 0, # 출금 처리 중인 수량
"lastUpdatedAt": "1600686162591" # 해당 잔고 최근 갱신 시간
}
주문 조회
부분 체결 혹은 미체결된 주문들을 조회할 수 있습니다.
GET /orders
쿼리스트링 | 필수여부 | 기본값 | 설명 |
---|---|---|---|
includePast | 선택 | false | true일 경우 완전 체결 혹은 취소된 주문들도 조회 결과에 포함됨 (완전 체결 혹은 취소 시점부터 10분 동안만 조회가 가능) |
pagination | 선택 | false | 리턴되는 주문 수가 3천 개를 초과할 경우에는 true로 설정하여 페이지 별로 1천 개씩 접근 필요 |
tradingPairName | 선택 | - | 해당 거래쌍 주문 조회 (BTC-KRW, ETH-KRW ...) |
status | 선택 | - | 주문 상태별로 조회 (placed, cancelled, completed, updated, reserved) |
since | 선택 | - | 시작 시점 타임 스탬프 (밀리세컨드 단위) |
filterByUpdatedAt | 선택 | false | since와 함께 사용 true: 시작 시점이 updatedAt 기준 false: 시작 시점이 createdAt 기준 |
limit | 선택 | - | 최대 주문 개수 |
tail | 선택 | false | limit과 함께 사용 true: 최근 주문부터 limit 만큼 데이터 조회 false: 오래된 주문부터 limit 만큼 데이터 조회 |
호출 예시
경로
GET /orders
요청
없음
응답
[
{
"id": "453324", # 주문 ID
"clientOrderId": "zeckrw23456", # 클라이언트 오더 ID (존재할 경우에 한하여 표시됨)
"status": "updated", # placed(미체결), cancelled(취소됨), completed(전체 체결됨), updated(일부 체결됨), reserved(예약됨)
"forcedCompletionReason": undefined, # 주문 중도 취소된 경우에 한하여 그 사유로 protection/timeInForce 중 하나
"tradingPairName": "ZEC-KRW", # 오더북
"side": "buy", # buy(구매), sell(판매)
"type": "limit", # limit(지정가), market(시장가)
"price": 1000000, # 주문 가격
"stopPrice": undefined, # 감시 가격 (예약가 주문에 한하여 표시됨)
"amount": 4, # 최초 주문 수량
"remaining": 1, # 오더북에 남아 있는 미체결 주문 수량
"protection": "yes", # 최초 체결가 기준 ±10% 초과되는 주문 취소 여부로 yes/no 중 하나
"timeInForce": "gtc", # 지정가 주문 유형으로 gtc/po/ioc/fok 중 하나
"createdAt": "2020-09-25T04:06:20.000Z", # 주문 넣은 시간
"updatedAt": "2020-09-25T04:06:29.000Z", # 주문 업데이트 시간
"balanceChange": {
"baseGross": 3, # base 자산 잔고 gross 변화 (이 경우 ZEC)
"baseFee": {
"taking": 0, # taker 포지션으로 발생한 base 자산 수수료
"making": -0.0012 # maker 포지션으로 발생한 base 자산 수수료
},
"baseNet": 2.9988, # base 자산 잔고 net 변화 (이 경우 ZEC)
"quoteGross": -3000000, # quote 자산 잔고 gross 변화 (이 경우 KRW)
"quoteFee": {
"taking": 0, # taker 포지션으로 발생한 quote 자산 수수료
"making": 0 # maker 포지션으로 발생한 quote 자산 수수료
},
"quoteNet": -3000000 # quote 자산 잔고 net 변화 (이 경우 KRW)
}
},
...
]
특정 주문 조회
GET /orders/<OrderId>
또는 GET /orders/clientOrderId/<ClientOrderID>
호출 예시
경로
GET /orders/453324
요청
없음
응답
{
"id": "453324", # 주문 ID
"clientOrderId": "zeckrw23456", # 클라이언트 오더 ID (존재할 경우에 한하여 표시됨)
"status": "updated", # placed(미체결), cancelled(취소됨), completed(전체 체결됨), updated(일부 체결됨), reserved(예약됨)
"forcedCompletionReason": undefined, # 주문 중도 취소된 경우에 한하여 그 사유로 protection/timeInForce 중 하나
"tradingPairName": "ZEC-KRW", # 오더북
"side": "buy", # buy(구매), sell(판매)
"type": "limit", # limit(지정가), market(시장가)
"price": 1000000, # 주문 가격
"stopPrice": undefined, # 감시 가격 (예약가 주문에 한하여 표시됨)
"amount": 4, # 최초 주문 수량
"remaining": 1, # 오더북에 남아 있는 미체결 주문 수량
"protection": "yes", # 최초 체결가 기준 ±10% 초과되는 주문 취소 여부로 yes/no 중 하나
"timeInForce": "gtc", # 지정가 주문 유형으로 gtc/po/ioc/fok 중 하나
"createdAt": "2020-09-25T04:06:20.000Z", # 주문 넣은 시간
"updatedAt": "2020-09-25T04:06:29.000Z", # 주문 업데이트 시간
"balanceChange": {
"baseGross": 3, # base 자산 잔고 gross 변화 (이 경우 ZEC)
"baseFee": {
"taking": 0, # taker 포지션으로 발생한 base 자산 수수료
"making": -0.0012 # maker 포지션으로 발생한 base 자산 수수료
},
"baseNet": 2.9988, # base 자산 잔고 net 변화 (이 경우 ZEC)
"quoteGross": -3000000, # quote 자산 잔고 gross 변화 (이 경우 KRW)
"quoteFee": {
"taking": 0, # taker 포지션으로 발생한 quote 자산 수수료
"making": 0 # maker 포지션으로 발생한 quote 자산 수수료
},
"quoteNet": -3000000 # quote 자산 잔고 net 변화 (이 경우 KRW)
}
}
주문 등록
POST /orders
호출 예시
경로
POST /orders
요청
{
"clientOrderId": "test4321", # 선택 | 클라이언트 오더 ID로 최대 20자이고 [a-zA-Z0-9_-] 문자 사용 가능
"tradingPairName": "BCH-KRW", # 필수 | 오더북
"side": "sell", # 필수 | buy(구매), sell(판매)
"type": "limit", # 필수 | limit(지정가), market(시장가)
"price": 11000000, # 필수 (지정가에 한함) | 주문 가격
"stopPrice": 12000000, # 선택 (값이 있으면 예약가 주문으로 처리됨) | 감시 가격
"amount": 0.5, # 필수 | 주문 수량
"protection": "no", # 선택 (디폴트 no) | 최초 체결가 기준 ±10% 초과되는 주문 취소 여부로 yes/no 중 택일
"timeInForce": "gtc" # 선택 (지정가에 한하며 디폴트는 gtc) | 지정가 주문 유형으로 gtc/po/ioc/fok 중 택일
}
응답
{
"id": "453327", # 주문 ID
"clientOrderId": "test4321", # 클라이언트 오더 ID (존재할 경우에 한하여 표시됨)
"status": "reserved", # placed(미체결), cancelled(취소됨), completed(전체 체결됨), updated(일부 체결됨), reserved(예약됨)
"forcedCompletionReason": undefined, # 주문 중도 취소된 경우에 한하여 그 사유로 protection/timeInForce 중 하나
"tradingPairName": "BCH-KRW", # 오더북
"side": "sell", # buy(구매), sell(판매)
"type": "limit", # limit(지정가), market(시장가)
"price": 11000000, # 주문 가격
"stopPrice": 12000000, # 감시 가격 (예약가 주문에 한하여 표시됨)
"amount": 0.5, # 최초 주문 수량
"remaining": 0.5, # 오더북에 남아 있는 미체결 주문 수량
"protection": "no", # 최초 체결가 기준 ±10% 초과되는 주문 취소 여부로 yes/no 중 하나
"timeInForce": "gtc", # 지정가 주문 유형으로 gtc/po/ioc/fok 중 하나
"createdAt": "2020-09-25T04:51:31.000Z", # 주문 넣은 시간
"balanceChange": {
"baseGross": 0, # base 자산 잔고 gross 변화 (이 경우 BCH)
"baseFee": {
"taking": 0, # taker 포지션으로 발생한 base 자산 수수료
"making": 0 # maker 포지션으로 발생한 base 자산 수수료
},
"baseNet": 0, # base 자산 잔고 net 변화 (이 경우 BCH)
"quoteGross": 0, # quote 자산 잔고 gross 변화 (이 경우 KRW)
"quoteFee": {
"taking": 0, # taker 포지션으로 발생한 quote 자산 수수료
"making": 0 # maker 포지션으로 발생한 quote 자산 수수료
},
"quoteNet": 0 # quote 자산 잔고 net 변화 (이 경우 KRW)
}
}
주문 취소
DELETE /orders/<OrderId>
또는 DELETE /orders/clientOrderId/<ClientOrderID>
호출 예시
경로
DELETE /orders/453327
요청
없음
응답
{}
체결 기록 조회
GET /trades
쿼리스트링 | 필수여부 | 기본값 | 설명 |
---|---|---|---|
limit | 선택 | - | 반환되는 항목의 개수 (최대 100) |
pastmax | 선택 | - | 이 ID보다 오래된 데이터를 조회 |
latestmin | 선택 | - | 이 ID보다 새로운 최신 데이터를 조회 |
after | 선택 | - | 이 타임스탬프 이후의 데이터를 조회 (초 단위) |
before | 선택 | - | 이 타임스탬프 이전의 데이터를 조회 (초 단위) |
deepSearch | 선택 | false | true인 경우에 한하여 한 달 이상 지난 데이터까지 모두 포함하여 조회 (다른 파라미터들보다 더 높은 우선순위를 가짐) |
tradingPairName | 선택 | - | 해당 거래쌍의 데이터 조회 (BTC-KRW, ETH-KRW...) |
호출 예시
경로
GET /trades
요청
없음
응답
[
{
"id": 73953, # 체결 이벤트 ID
"orderId": 453324, # 주문 ID
"baseAmount": 3, # 체결된 base 자산 수량
"quoteAmount": 3000000, # 체결된 quote 자산 수량
"fee": 0.0012, # 수수료
"price": 1000000, # 체결 가격
"timestamp": "2020-09-25T04:06:30.000Z", # 체결 시간
"side": "buy", # buy(구매), sell(판매)
"feeAsset": "KRW", # 수수료 자산
"tradingPairName": "ZEC-KRW", # 오더북
"position": "maker" # maker(메이커), taker(테이커)
},
...
]
입출금 기록 조회
GET /deposit-withdrawal-status
쿼리스트링 | 필수여부 | 기본값 | 설명 |
---|---|---|---|
limit | 선택 | - | 반환되는 항목의 개수 (최대 20) |
latestmin | 선택 | - | 이 ID보다 오래된 데이터를 조회 |
after | 선택 | - | 이 타임스탬프 이후의 데이터를 조회 (ms 단위) |
before | 선택 | - | 이 타임스탬프 이전의 데이터를 조회 (ms 단위) |
completedOnly | 선택 | false | 완료된 입출금 내역만 조회 (true/false 중 택일) |
asset | 선택 | - | 해당 자산의 입출금 내역 조회 (BTC, ETH ...) |
호출 예시
경로
GET /deposit-withdrawal-status
요청
없음
응답
[
{
"id": 640, # 입출금 이벤트 ID
"asset": "BTC", # 자산 이름
"type": "crypto_withdrawal", # fiat_withdrawal(원화출금), fiat_deposit(원화입금), crypto_withdrawal(크립토출금), crypto_deposit(크립토입금)
"netAmount": 0.0001, # 입출금 자산의 수량
"feeAmount": 0.0005, # 수수료 (없을 경우 null)
"status": "completed", # reviewing(심사중), rejected(심사거절), processing(처리중), failed(처리실패), completed(처리완료)
"reviewStartedAt": 1595556218, # 입출금 요청 시간
"completedAt": 1595556902, # 입출금 처리 완료 시간 (처리완료 상태가 아닐 경우 null)
"txId": "eaca5ad3...", # 트랜잭션 ID
"sourceAddress": null, # 보낸 사람 주소 (크립토입금일 경우 값 존재)
"destinationAddress: "3H8...", # 받을 사람 주소 (크립토출금일 경우 값 존재)
"destinationMemoId": null # 받을 사람 주소의 메모 ID
},
...
]
가상자산 입금 주소 조회
GET /crypto-deposit-addresses
호출 예시
경로
GET /crypto-deposit-addresses
요청
없음
응답
[
{
"asset": "BTC", # 자산 이름
"address": "1CwC2cMFu1jRQUBtw925cENbT1kctJBMdm", # 입금 주소
"memoId": null, # 메모 ID (메모 ID를 통한 입금인 경우만 존재)
"createdAt": 1594802312 # 입금 주소 생성 시간
},
...
]
가상자산 출금 주소 조회
GET /crypto-withdrawal-addresses
호출 예시
경로
GET /crypto-withdrawal-addresses
요청
없음
응답
[
{
"asset": "BTC", # 자산 이름
"address": "3QEdPvg2XuK8Q1tGU1RpyzxkkEsiLkvQF3", # 출금 주소
"memoId": null, # 메모 ID (메모 ID를 통한 출금인 경우만 존재)
"nickname": "My External BTC Address", # 출금 주소 별칭
"createdAt": 1588417815 # 출금 주소 등록 시간
}
...
]
가상자산 출금
POST /withdrawals
호출 예시
경로
POST /withdrawals
요청
{
"asset": "BCH", # 필수 | 자산 이름
"nickname": "WithdrawalAddress", # 필수 | 출금 주소 별칭
"amount": "10000000000", # 필수 | 출금 수량
}
응답
없음
공개 API
공개 API는 인증 과정 없이 이용할 수 있습니다. 즉, 요청 헤더에 인증에 요구되는 내용을 넣지 않고도 호출할 수 있는 API입니다.
자산 목록 조회
GET /assets
호출 예시
경로
GET /assets
요청
없음
응답
[
...,
{
"id": "ETH", # 자산 이름
"name": "이더리움", # 자산 이름 (국문)
"englishName": "Ethereum", # 자산 이름 (영문)
"scale": 8, # 자산 최대 소수점 자리수
"withdrawalFee": 0.03, # 출금 수수료
"withdrawalAmountMin": 0.015 # 출금 최소 금액
},
...
]
거래쌍 목록 조회
GET /trading-pairs
호출 예시
경로
GET /trading-pairs
요청
없음
응답
[
{
"id": 1, # 거래쌍 ID
"name": "ETH-KRW", # 거래쌍 이름
"baseAsset": "ETH", # base 자산
"quoteAsset": "KRW", # quote 자산
"baseAssetScale": 8, # base 자산 최대 소수점 자리수
"quoteAssetScale": 0, # quote 자산 최대 소수점 자리수
"priceMin": 1, # 최소 주문 가격
"restApiOrderAmountMin": { # REST API 통해 주문 시 최소 주문 수량
"limitAsk": {
"amount": 1000,
"unit": "KRW"
},
"limitBid": {
"amount": 1000,
"unit": "KRW"
},
"marketAsk": {
"amount": 0.001,
"unit": "ETH"
},
"marketBid": {
"amount": 1000,
"unit": "KRW"
}
},
"makerFeePercent": 0.2, # 메이커 거래 수수료 퍼센트
"takerFeePercent": 0.2 # 테이커 거래 수수료 퍼센트
},
...
]
가격 틱 사이즈 조회
GET /trading-pairs/<TradingPair>/price-tick-size
호출 예시
경로
GET /trading-pairs/BTC-KRW/price-tick-size
요청
없음
응답
[
{ startPrice: 1, tickSize: 1 },
{ startPrice: 5000, tickSize: 5 },
{ startPrice: 10000, tickSize: 10 },
{ startPrice: 50000, tickSize: 50 },
{ startPrice: 100000, tickSize: 100 },
{ startPrice: 500000, tickSize: 500 },
{ startPrice: 2000000, tickSize: 1000 }
]
티커 조회
GET /trading-pairs/<TradingPair>/ticker
호출 예시
경로
GET /trading-pairs/BTC-KRW/ticker
요청
없음
응답
{
"price": 15393000, # 오더북 상의 현재 가격
"ask": 15397000, # 오더북 상의 현재 가장 낮은 매도 가격
"askVolume": 0.56, # 오더북 상의 현재 가장 낮은 매도 가격의 수량
"bid": 15393000, # 오더북 상의 현재 가장 높은 매수 가격
"bidVolume": 1.9513, # 오더북 상의 현재 가장 높은 매수 가격의 수량
"volume": 487.43035427, # 최근 24시간 누적 거래량 (base 자산 단위로 이 예시에서는 BTC)
"quoteVolume": 7319576689.34135, # 최근 24시간 누적 거래량 (quote 자산 단위로 이 예시에서는 KRW)
"time": "2020-10-28T02:05:55.958Z" # 티커 최근 갱신 시간
}
오더북 조회
GET /trading-pairs/<TradingPair>/book
쿼리스트링 | 필수여부 | 기본값 | 설명 |
---|---|---|---|
level | 선택 | 3 | 1 = 매수 및 매도 각 1개 2 = 매수 및 매도 각 50개 3 = 전체 |
호출 예시
경로
GET /trading-pairs/BTC-KRW/book
요청
없음
응답
{
"sequence": 110815766,
"ask": [ # 오더북 판매 엔트리 목록
[
"110815528", # 오더북 엔트리 고유번호 (변화 발생 시마다 +1)
12371000, # 오더북 엔트리 가격
0.808, # 오더북 엔트리 물량
"1601030126425" # 오더북 엔트리 업데이트 시간
],
...
],
"bid": [ # 오더북 구매 엔트리 목록
...,
[
"108223577",
11870000,
0.72446908,
"1600956121521"
]
]
}
체결 기록 조회
GET /trading-pairs/<TradingPair>/trades
쿼리스트링 | 필수여부 | 기본값 | 설명 |
---|---|---|---|
limit | 선택 | - | 반환되는 항목의 개수 (최대 100) |
pastmax | 선택 | - | 이 ID보다 오래된 데이터를 조회 |
latestmin | 선택 | - | 이 ID보다 새로운 최신 데이터를 조회 |
after | 선택 | - | 이 타임스탬프 이후의 데이터를 조회 (초 단위) |
before | 선택 | - | 이 타임스탬프 이전의 데이터를 조회 (초 단위) |
호출 예시
경로
GET /trading-pairs/BTC-KRW/trades
요청
없음
응답
[
{
"time": "2020-09-25T11:10:29.000Z", # 체결 시간
"date": 1601032229, # 체결 시간 초 단위 타임스탬프
"id": 21876490, # 체결 이벤트 ID
"price": 12353000, # 체결 가격
"amount": 0.2951, # 체결 수량 (base 자산 단위로 이 예시에서는 BTC)
"side": "sell" # buy(구매), sell(판매)
},
...
]
최근 24시간 통계 조회
GET /trading-pairs/<TradingPair>/stats
호출 예시
경로
GET /trading-pairs/BTC-KRW/stats
요청
없음
응답
{
"open": 12132000, # 24시간 전 가격
"high": 12543000, # 최근 24시간 동안 최고가
"low": 12059000, # 최근 24시간 동안 최저가
"close": 12349000, # 현재 가격 (1분마다 갱신됨)
"volume": 332.12915604, # 최근 24시간 누적 거래량 (base 자산 단위로 이 예시에서는 BTC)
"time": "2020-09-25T11:13:47.371Z" # 최근 통계 업데이트 시간
}
최근 24시간 통계 조회 (모든 거래쌍)
GET /trading-pairs/stats
호출 예시
경로
GET /trading-pairs/stats
요청
없음
응답
[
{
"name": "ETH-KRW", # 거래쌍
"open": 394200, # 24시간 전 가격
"high": 409900, # 최근 24시간 동안 최고가
"low": 388700, # 최근 24시간 동안 최저가
"close": 397200, # 현재 가격 (1분마다 갱신됨)
"volume": 4017.90526766, # 최근 24시간 누적 거래량 (base 자산 단위로 이 예시에서는 BTC)
"time": "2020-09-25T11:14:14.866Z" # 최근 통계 업데이트 시간
},
...
]
차트 데이터 조회
GET /trading-pairs/<TradingPair>/candles
쿼리스트링 | 필수여부 | 기본값 | 설명 |
---|---|---|---|
start | 필수 | - | 시작 시점 타임스탬프 (밀리세컨드 단위) |
end | 필수 | - | 종료 시점 타임스탬프 (밀리세컨드 단위) |
interval | 필수 | - | 각 구간 길이 (분 단위로, 1/5/30/1440 중 택일) |
limit | 선택 | 1024 | 반환되는 항목의 개수 (최대 1024) |
호출 예시
경로
GET /trading-pairs/BTC-KRW/candles?start=1601032379683&end=1601033046191&interval=1
요청
없음
응답
[
...,
[
1601032200000, # 구간 시작 시간
12353000, # 구간 최저가
12361000, # 구간 최고가
12361000, # 구간 시가
12353000, # 구간 종가
0.5902 # 구간 누적 거래량 (base 자산 단위로 이 예시에서는 BTC)
],
...
]
투자유의 정보 조회
GET /trading-pairs/cautions
쿼리스트링 | 필수여부 | 기본값 | 설명 |
---|---|---|---|
showActive | 선택 | false | true : Risk가 있는 항목만 노출, false : 전체 항목 노출 |
호출 예시
경로
GET /trading-pairs/cautions?showActive=true
요청
없음
응답
[
{
"id": 1, # 거래쌍 ID
"name": "ETH-KRW", # 거래쌍 이름
"alertLevel": 0, # Alert Level - 정상(0), 주의(1), 경고(2)
"isPriceChange": false, # 가격 급등 또는 급락 여부
"isMonopolyBuy": false, # (deprecated)
"isLowLiquidity": false, # (deprecated)
"isSoarTradingVolume": false, # 거래량 급등 또는 급락 여부
"isSoarDepositAmount": false, # 입금량 급등 또는 급락 여부
"isGlobalPriceDifference": false, # 가격 차이 발생 여부
"isMonopolyTrading": false, # 소수 계정 거래 집중
},
...
]
전체 티커 조회
GET /tickers
전체 티커 목록을 조회합니다.
호출 예시
경로
GET /tickers
요청
없음
응답
[
{
'baseVolume': 0.02, # 최근 24시간 누적 거래량 (base 자산 단위로 이 예시에서는 BTC)
'high': 37300000, # 최근 24시간 최고 거래 가격
'highestBid': 0, # 오더북 상의 현재 가장 높은 매수 가격
'last': 37300000, # 오더북 상의 현재 가격
'lastTraded': 1665640796413, # 최근 거래 시각(Unix time)
'low': 37300000, # 최근 24시간 최저 거래 가격
'lowestAsk': 0, # 오더북 상의 현재 가장 낮은 매도 가격
'open': 37300000, # 거래시작가, 한국시간(KST) 기준 00시 이후 첫 거래가 체결된 가격
'quoteVolume': 746000, # 최근 24시간 누적 거래량 (quote 자산 단위로 이 예시에서는 KRW)
'tradingPairName': 'BTC-KRW' # 오더북
},
...
{
'baseVolume': 0,
'high': 9000000,
'highestBid': 9000000,
'last': 9000000,
'lastTraded': 1629260634639,
'low': 9000000,
'lowestAsk': 9000000,
'open': 9000000,
'quoteVolume': 0,
'tradingPairName': 'UNC-KRW'
}
]
서버 시간 조회
GET /time
호출 예시
경로
GET /time
요청
없음
응답
{
"serverTime": 1601033421109 # 밀리세컨드 단위 타임스탬프
}
공지사항 조회
GET /notices
쿼리스트링 | 필수여부 | 기본값 | 설명 |
---|---|---|---|
limit | 선택 | 20 | 페이지별 아이템 개수 (최대 20) |
page | 선택 | 0 | 페이지 번호 (0부터 시작) |
type | 선택 | 0 | 타입 (0 = 구분 없음, 1 = 일반 공지, 2 = 상장, 3 = 이벤트) |
format | 선택 | 0 | 양식 (0 = HTML, 1 = 일반 텍스트) |
호출 예시
경로
GET /notices?format=1
요청
없음
응답
[
{
"id": 531, # 공지사항 ID
"type": 1, # 공지사항 타입
"title": "정기점검", # 공지사항 제목
"content": "곧 정기점검이 있을 예정입니다", # 공지사항 내용
"createdAt": "2020-12-29T01:24:13.000Z" # 공지사항 생성 시간
"updatedAt": "2020-12-29T01:24:13.000Z" # 공지사항 갱신 시간
},
...
]
호출 속도 제한
- 개인 API는 API Key를 기준으로, 공개 API는 IP당 호출 횟수가 제한됩니다.
- 기본적으로 최근 1초의 구간 안에서 최대 20번의 호출이 가능합니다. 예외는 다음과 같습니다.
- FOK 타입 주문 또는 GET /trades?deepSearch=false인 경우 최근 1초의 구간 안에서 최대 2번의 호출이 가능합니다.
- GET /trading-pairs/<TradingPair>/book 또는 GET /trades?deepSearch=true인 경우 1초의 구간 안에서 최대 1번의 호출이 가능합니다.
- 서버에서 보내는 응답 전문 헤더에 최근 1초 동안 사용한 호출 횟수 및 잔량이 명시되어 있습니다.
- x-gopax-ip-addr-used-weight : 최근 1초 동안 사용한 IP 기반 호출 횟수
- x-gopax-ip-addr-left-weight : IP 기반 호출 횟수 잔량
- x-gopax-api-key-used-weight : 최근 1초 동안 사용한 API Key 기반 호출 횟수
- x-gopax-api-key-left-weight : API Key 기반 호출 횟수 잔량
- 호출 횟수 제한을 초과하면 429 (요청 한도 초과) 상태 코드가 반환됩니다.
API Key 만료 정책
- API Key 발급 시점으로 부터 1년의 만료일자가 적용됩니다.
- 2024-11-19 일자 부터 적용이 되는 정책으로 이전에 등록된 API Key의 만료일자는 정책 적용시점으로 부터 계산됩니다.
- 만료일자 갱신은 불가능하며 새롭게 발급을 진행해야 합니다.
- API Key 발급 시 사전에 등록한 IP는 가상자산 출금에 대해서만 제한되어 적용됩니다.
에러
HTTP 에러 상태 코드
Status Code | Description |
---|---|
400 | Bad Request - Invalid request format |
401 | Not Authorized - Invalid API key |
403 | Forbidden - Not Permitted to access requested resource |
404 | Not Found |
429 | Too many requests - API rate limit exceeded |
500 | Internal server error - Temporary problem with the service |
에러
{
"100": "Invalid Asset",
"101": "Invalid Trading Pair",
"102": "Invalid User",
"104": "Not Enabled Trading Pair",
"105": "Not Activated Trading Pair",
"106": "Not Enabled Asset",
"107": "Invalid Amount",
"108": "Invalid Price",
"201": "Insufficient Balance",
"202": "Invalid Id",
"203": "Invalid Numbers Overflow",
"204": "Not Allowed Bid Order",
"206": "Invalid Option Combination",
"10004": "Not Authorized", # check again your signing logic
"10006": "User Not Found",
"10033": "Asset Not Allowed",
"10041": "Invalid Exchange",
"10044": "Invalid Asset Id",
"10052": "Order Server Not Available", # stop trading for a while if it happens
"10056": "No Registered Asset",
"10057": "No Registered Trading Pair",
"10058": "No Such Asset Code",
"10059": "No Such Trading Pair",
"10061": "Invalid Trading Pair Id",
"10062": "Invalid Chart Interval",
"10064": "User Locked",
"10069": "No Such Order Id",
"10074": "Send To Order Server Failed", # stop trading for a while if it happens
"10105": "Rate Limit Exceeded", # you are causing too much traffic
"10108": "Nonce Too Low",
"10155": "Invalid Api Key",
"10157": "Invalid Price",
"10166": "Invalid Chart Range",
"10195": "Invalid Internal Data",
"10204": "Not Hedge Token User", # visit the website and agree on using Pro market
"10212": "Too Small Quote Amount",
"10221": "No Such Client Order Id",
"10222": "Client Order Id Being Used",
"10223": "Soon Expired Client Order Id",
"10227": "Invalid Client Order Id Format",
"10229": "Invalid Signature",
"10230": "No Api Key",
"10231": "No Nonce And Timestamp",
"10232": "Nonce Too High",
"10233": "Unusable Api Key",
"10234": "Cannot Check Rate Limit",
"10255": "Too Long Request Body",
"10256": "Unparsable Request Body",
"10263": "Timestamp Too Low",
"10264": "Timestamp Too High",
"10265": "Choose Either Nonce Or Timestamp",
"10296": "Invalid Receive Window",
"10297": "Invalid Timestamp To Check Receive Window",
"10298": "Fail To Meet Server Arrival Deadline",
"10319": "Pagination Required",
"10358": "Invalid Order Type",
"10359": "Invalid Order Side",
"10360": "Invalid Order Status",
"10361": "Invalid Time In Force",
"10362": "Invalid Protection",
"10364": "Ip Address Banned Temporarily", # you are causing too much traffic
"10367": "Mandatory Query String Missing"
}
변경이력
2024-11-19
기능 추가
- 가상자산 출금을 위한
POST /withdrawals
기능 추가
정책 변경
- API Key 만료일자 정책 적용
- 발급시점 기준으로 1년으로 제한되며 기존에 발급된 API Key 는 정책적용 시점이 기준이 됩니다.
2024-10-07
정책 변경
- 원화 최소 주문금액 변경 (10,000 KRW -> 1,000 KRW)
2023-07-25
응답 데이터 추가
GET /trading-pairs/cautions
의 응답 데이터에 경고 종목isSoarTradingVolume
,isSoarDepositAmount
,isGlobalPriceDifference
,isMonopolyTrading
추가GET /trading-pairs/cautions
의 응답 데이터에 경고 종목isMonopolyBuy
,isLowLiquidity
deprecated
2022-02-07
기능 변경
GET /assets
영문 자산명 속성 추가 (englishName)
2022-10-25
기능 추가
GET /tickers
전체 티커 조회 기능 추가
2022-10-14
기능 변경
GET /trades
응답에서 수수료 자산 속성 추가 (feeAsset)POST /orders
거래 수수료 정책 변경에 따른 문구 추가- 모든 거래 수수료는 거래쌍의 quote 자산으로 지불됩니다. (2022년 11월 1일 정기점검 이후 적용)
- 매도 주문의 경우 매도 완료 후 얻게된 quote 자산에 대하여 수수료율을 적용합니다. 예를 들어, 매도 거래에서 10,000원을 받은 사용자가 거래 수수료로 20원(수수료율 0.2% 가정)을 지불한 후 사용자는 9980원을 받게 됩니다.
- 매수 주문의 경우 매수자는 주문을 한 quote amount 외에 수수료를 지불할 수 있는 충분한 잔고가 필요합니다. (quote balance > order quote amount + fee (amount * fee rate)) 예를 들어, 사용자가 10,000원 매수 주문 시, 최소 10,020원 필요합니다. (수수료율 0.2% 가정)
- https://www.gopax.co.kr/notice/1303
2022-09-06
기능 추가
- 투자유의 정보 추가
2021-05-25
기능 변경
GET /trading-pairs/<TradingPair>/book
의 호출을 1초당 최대 1회로 제한 (변경 전: 1초당 최대 20회 호출)- 실시간 오더북 열람을 위해서는 Websocket API의 "오더북 구독" 사용 권장
2021-03-02
기능 추가
GET /orders?tradingPairName=ETH-KRW
거래쌍별 주문 조회 옵션 추가GET /orders?status=completed
주문 상태 옵션 추가GET /orders?since=1601032379683&filterByUpdatedAt=true
createdAt/updatedAt을 기준으로 시작 시점 설정 옵션 추가GET /orders?limit=1000&tail=true
최대 데이터 개수 옵션, 최신 주문이나 오래된 주문 기준으로 조회 옵션 추가GET /trades?tradingPairName=BTC-KRW
거래쌍별 체결 기록 옵션 추가GET /deposit-withdrawal-status?asset=BTC
자산별 입출금 기록 조회 옵션 추가GET /trading-pairs/BTC-KRW/candles?limit=1024
차트 데이터 개수 옵션 추가
2021-02-24
기능 변경
- 시스템 안정성 향상을 위해 주문 취소 혹은 완전 체결 후 열람 가능 기간을 1시간에서 10분으로 축소
2021-01-12
기능 추가
GET /trading-pairs/<TradingPair>/price-tick-size
기능 추가
2020-12-29
기능 추가
GET /notices
기능 추가
2020-10-28
응답 데이터 추가
GET /assets
응답 데이터에scale
,withdrawalFee
, 그리고withdrawalAmountMin
추가GET /trading-pairs
응답 데이터에baseAssetScale
,quoteAssetScale
,priceMin
, 그리고restApiOrderAmountMin
추가GET /trading-pairs/<TradingPair>/tickers
응답 데이터에quoteVolume
추가
2020-10-06
문서 개선
- 문서 가독성 개선 및 간결화
2020-08-26
기능 추가
GET /orders?pagination=true
옵션 추가 제공하여 페이지네이션 제공
2020-08-18
응답 데이터 추가
GET /balances
와GET /trading-pairs/<Trading Pair>/book
의 응답 데이터에 최근 갱신 시간 추가
2020-08-11
기능 변경
GET /trades?deepSearch=true
옵션 추가
2020-06-30
기능 추가
GET /orders?includePast=true
옵션 추가 제공하여 완전 체결 및 취소된 주문 목록 열람 기능 지원
2020-06-09
기능 추가
- 오더 데이터 제공 시, 해당 오더로 인한 사용자 잔고 변화를 쉽게 파악 가능하도록 balanceChange를 함께 제공
- balanceChange 내에 메이커 수수료와 테이커 수수료를 구분지어 기술함
2020-05-26
기능 추가
- 고급 기능 중 하나인 RECEIVE-WINDOW를 도입하여 최대 허용 가능한 네트워크 레이턴시 값을 고객이 직접 지정할 수 있게 하여줌
2020-05-13
기능 추가
- 고객 편의성을 위해 기존의 Nonce를 대체할 목적으로 Timestamp 도입
2020-03-24
기능 추가
- 입출금 내역 조회
- 가상자산(암호화폐) 입금 주소 조회
- 가상자산(암호화폐) 출금 주소 조회
- 서버 시간 조회
2020-03-07
정책 변경
- Nonce migration 및 Nonce 상한선 설정 (Nonce의 과도한 증가로 인한 문제 개선)
2020-02-25
기능 추가
- Client Order Id : 주문 등록시 유저 임의의 Order ID로 주문 가능
2020-02-19
기능 추가
- 예약 주문(Stop Order) : Stop Price에 현재가가 도달했을시 미리 지정한 형태의 주문을 등록
2020-01-07
기능 추가
- Order protection : 주문시 해당 주문의 최초 체결가를 기준, 10%를 초과한 가격에 매도/매수 주문이 체결되는 것을 막는 주문 보호기능입니다. 가격이 10%를 초과하게 되면 해당주문의 잔량은 취소
- PO(Post Only) : 즉시 체결할 수 있는 상대주문이 있으면 주문을 취소하고, 그렇지 않으면 주문을 전량 등록하는 조건
- IOC(Immediate-Or-Cancel Order) : 호가의 접수시점에서 호가한 수량 중 매매계약을 체결할 수 있는 수량에 대하여는 매매거래를 성립시키고, 매매계약이 체결되지 아니한 수량은 취소하는 조건(즉시체결, 잔량취소)
- FOK(Fill-Or-Kill Order) : 호가의 접수시점에서 호가한 수량의 전부에 대하여 매매계약을 체결할 수 있는 경우에는 매매거래를 성립시키고, 그러하지 아니한 경우에는 당해수량의 전부를 취소하는 조건(전량체결, 전량취소)
2018-08-08
기능 추가
- Market order : 가격을 지정하지 않고 현재 시장에 나와있는 가격으로 체결
2017-12-16
기능
- 인증이 필요한 호출
- 잔액 조회하기
- 자산 이름에 따라 잔액 조회하기
- 주문 조회하기
- 주문 ID로 주문 조회하기
- 주문 등록하기
- 주문 ID로 주문 취소하기
- 사용자 거래 기록 조회하기
- 인증이 필요하지 않은 요청
- 자산 조회하기
- 특정 거래쌍 조회하기
- 특정 거래쌍의 거래량 조회하기
- 특정 거래쌍의 호가창 조회하기
- 최근 체결 거래 조회하기
- 특정 거래쌍의 최근 24시간 통계 조회하기
- 특정 거래쌍의 과거 기록 조회하기
- 모든 거래쌍의 최근 24시간 통계 조회하기