This document provides example request and subscription payloads for receiving candlestick data via WebSocket.
Candle Real-Time Stream Transmission Guide
Data Transmission Interval
The real-time stream transmission interval for candle data is 1 second.
Data Generation Information
Candles are generated only when trades occur during the given time period and the candle data changes compared to the previous candle. Even if 1 second passes, if no trades occur, no real-time candle data stream is transmitted.
Additionally, if the requested candle data for the specified interval has not yet been generated at the time of the request, the data for the previous time interval is sent first.
The same
candle_date_timedata may be transmitted multiple times.Due to the nature of real-time candle streams handling requests of various time units, it is difficult to guarantee a perfect transmission interval, and candle data for the same time period may be sent multiple times depending on the trade timing. The most recently received data is the latest; please refer to the
candle_date_timefield to update the values before use.
WebSocket Endpoint
| Type | Endpoint |
|---|---|
| Public | wss://{region}-api.upbit.com/websocket/v1 |
Use the endpoint for your region.
| Region | Endpoint |
|---|---|
| Singapore | wss://sg-api.upbit.com/websocket/v1 |
| Indonesia | wss://id-api.upbit.com/websocket/v1 |
| Thailand | wss://th-api.upbit.com/websocket/v1 |
Request Message Format
To request announcement data, after establishing a WebSocket connection, create a JSON Object with the structure below and include it as a Data Type Object in the request message.
For the complete WebSocket request message specification, including the Ticket and Format Objects, refer to the WebSocket Usage and Error Guide.
| Field Name | Type | Description | Required | Default |
|---|---|---|---|---|
| type | String | Data type to receive. Set to candle.{unit} to receive candle data. | Required | |
| codes | List:String | List of trading pairs to receive. Must be requested in uppercase. | Required | |
| is_only_snapshot | Boolean | Provide snapshot data only | Optional | false |
| is_only_realtime | Boolean | Provide real-time data only | Optional | false |
| format | String | Data format to receive.DEFAULT: Default format.SIMPLE: Simplified format with abbreviated field names.JSON_LIST: List format.SIMPLE_LIST: List format with abbreviated field names. | Required |
Custom function for Orderbook Unit quantity is addedYou can adjust the quantity of Orderbook Units only for orderbook-type packets. Please input the market code and unit quantity as follows.
Format: {code}.{count}
Example: SGD-BTC.5, SGD-ETH.5
Supported values for count: 1, 5, 15, 30
If an unsupported value is specified, it defaults to 30.
Subscription Data Specification
When a new announcement is published or an existing announcement is updated, real-time stream data is returned as follows.
| Field Name | Abbreviation | Description | Type | Value Example |
|---|---|---|---|---|
| type | ty | Type | String | candle.1s: 1-second candlecandle.1m: 1-minute candlecandle.3m: 3-minute candlecandle.5m: 5-minute candlecandle.10m: 10-minute candlecandle.15m: 15-minute candlecandle.30m: 30-minute candlecandle.60m: 60-minute candlecandle.240m: 240-minute candle |
| code | cd | Pair code (e.g., SGD-BTC) | String | |
| candle_date_time_utc | cdttmu | Candle base time (UTC) Format: yyyy-MM-dd'T'HH:mm:ss | String | |
| opening_price | op | Opening price | Double | |
| high_price | hp | High price | Double | |
| low_price | lp | Low price | Double | |
| trade_price | tp | Closing price | Double | |
| candle_acc_trade_volume | catv | Accumulated trade volume | Double | |
| candle_acc_trade_price | catp | Accumulated trade amount | Double | |
| timestamp | tms | Timestamp (ms) | Long | |
| stream_type | st | Stream type | String | SNAPSHOT: SnapshotREALTIME: Real-time |
Examples
Subscription Request Example
[
{
"ticket": "0e66c0ac-7e13-43ef-91fb-2a87c2956c49"
},
{
"type": "candle.1s",
"codes": ["SGD-BTC","SGD-ETH"]
},
{
"format": "DEFAULT"
}
]Subscription Data Example
{
"type": "candle.1s",
"code": "SGD-BTC",
"candle_date_time_utc": "2025-01-02T04:41:51",
"opening_price": 130155.0000000,
"high_price": 130155.0000000,
"low_price": 130155.0000000,
"trade_price": 130155.0000000,
"candle_acc_trade_volume": 0.00003473,
"candle_acc_trade_price": 4.520283150000000,
"timestamp": 1735792911165,
"stream_type": "REALTIME"
}
{
"type": "candle.1s",
"code": "SGD-ETH",
"candle_date_time_utc": "2025-01-02T04:42:59",
"opening_price": 4654.0000000,
"high_price": 4654.0000000,
"low_price": 4654.0000000,
"trade_price": 4654.0000000,
"candle_acc_trade_volume": 0.00086015,
"candle_acc_trade_price": 4.003138100000000,
"timestamp": 1735792979607,
"stream_type": "REALTIME"
}Error Information
If an error occurs after establishing a WebSocket connection and sending a request, the response is returned in the following JSON format.
{
"error": {
"name": "ERROR_CODE",
"message": "ERROR_MESSAGE"
}
}The main error codes that may be returned are listed below.
error.name | Reason | Recommended Action |
|---|---|---|
INVALID_AUTH | Missing authentication information or authentication token verification failure | When using a Private WebSocket endpoint, make sure you are connected to the correct endpoint and that the Authorization header contains a valid authentication token. |
WRONG_FORMAT | Invalid request message format | Make sure the request message follows the WebSocket request format. Check the Object structure as well as the type and value of each field. |
NO_TICKET | Missing ticket field | Make sure the request message includes a Ticket Object and the ticket field. |
NO_TYPE | Missing type field | Make sure the Data Type Object includes the type field and specify the data type to subscribe to. |
NO_CODES | Missing codes field | Check whether the subscribed data type requires the codes field and specify the trading pair codes to receive. |
INVALID_PARAM | Missing required request field or unsupported value | Make sure all required fields are included and that each field contains a supported value. |
Too Many Requests | Request rate limit exceeded | Wait until another request can be made, then retry. Refer to the Rate Limits section for details. |
I'm a teapot | Requests are temporarily restricted due to repeated Too Many Requests errors | Check the restriction period included in the response and retry after the specified time has passed. |
Rate Limits
APIs are grouped into Rate Limit groups. APIs within the same group share the same per-second request limit.
The maximum number of requests allowed per Rate Limit group may change after prior notice according to service policy, and additional restrictions may be applied depending on service conditions. For details, refer to Rate Limits.
| Rate Limit Group | Policy | Applied By |
|---|---|---|
websocket-connect | Up to 5 connections per second | IP |
websocket-message | Up to 5 messages per second and 100 messages per minute | Connection |
Managing WebSocket Rate LimitsUnlike REST API responses, WebSocket does not provide the number of remaining requests. Clients should track the number of WebSocket connection attempts and data request messages they send to ensure compliance with the applicable rate limits. If a rate limit is reached, wait for an appropriate period before sending another request..
