Documentation
Complete guide to using Winvest Market Service
Getting Started
Winvest Market Service provides real-time market data from the Indonesia Stock Exchange (IDX) ITCH protocol through REST API and WebSocket connections.
http://localhost:8080API Version:
/api/v1WebSocket:
ws://localhost:8080/ws
REST API
All endpoints are also available under /api/v1 prefix. For complete API reference with request/response schemas, see Interactive API Documentation (Swagger).
Health Check Endpoints
Check service health status with version information.
curl http://localhost:8080/healthz
Readiness probe for Kubernetes/container orchestration.
curl http://localhost:8080/readyz
Liveness probe for Kubernetes/container orchestration.
curl http://localhost:8080/liveness
Orderbook Endpoints
Retrieve orderbook data for a specific symbol.
Query Parameters:
symbol(required) - Stock symbol (e.g., "BBRI", "BBCA", "TLKM")
Alternative: /api/v1/orderbook?symbol=BBRI
curl "http://localhost:8080/orderbook?symbol=BBRI"
Retrieve all available orderbooks.
Alternative: /api/v1/orderbooks
curl http://localhost:8080/orderbooks
WebSocket API
Connect to the WebSocket endpoint to receive real-time market data updates.
Connection
const ws = new WebSocket('ws://localhost:8080/ws');
Subscription Commands
Send JSON commands to subscribe or unsubscribe from market data streams.
Subscribe to Symbol
{
"type": "subscribe",
"request_id": "req-123",
"payload": {
"topics": [
{
"symbol": "BBRI",
"channels": ["orderbook", "trade"]
}
],
"format": "text"
}
}
Subscribe to All Symbols
{
"type": "subscribe_all",
"request_id": "req-124"
}
Unsubscribe
{
"type": "unsubscribe",
"request_id": "req-125",
"payload": {
"topics": [
{
"symbol": "BBRI",
"channels": ["orderbook"]
}
]
}
}
Response Formats
The service supports two response formats:
- Text (default) - Pipe-delimited plain text for high-performance parsing
- JSON - Structured JSON objects
By default, responses are sent in text format. To use JSON format, specify it in subscription command:
{
"type": "subscribe",
"payload": {
"format": "text",
"topics": [...]
}
}
Channels
| Channel | Description |
|---|---|
orderbook |
Real-time orderbook updates (bids and asks) |
trade |
Trade execution events |
* |
All channels for a symbol |
Message Types
Subscription Acknowledgment
Text format (default):
ACK|ok|req-123|BBRI:orderbook,BBRI:trade|
JSON format (when specified):
{
"type": "subscription_ack",
"request_id": "req-123",
"status": "ok",
"payload": {
"accepted": [
{"symbol": "BBRI", "channels": ["orderbook", "trade"]}
],
"failed": []
}
}
Orderbook Event
Text format (default):
EVT|orderbook|BBRI|4755.0|100|4750@1000@5,4745@900@4|4760@800@3
JSON format (when specified):
{
"type": "event",
"channel": "orderbook",
"symbol": "BBRI",
"data": {
"last_price": 4755.0,
"last_qty": 100,
"bids": [...],
"asks": [...]
}
}
Trade Event
Text format (default):
EVT|trade|TLKM|123456|3820.0|200|2025111201|2025111202|2025-11-12T15:30:00Z
JSON format (when specified):
{
"type": "event",
"channel": "trade",
"symbol": "TLKM",
"data": {
"trade_id": 123456,
"price": 3820.0,
"quantity": 200,
"timestamp": "2025-11-12T15:30:00Z"
}
}
Examples
JavaScript WebSocket Client
const ws = new WebSocket('ws://localhost:8080/ws');
ws.onopen = () => {
// Subscribe to BBRI orderbook and trades
ws.send(JSON.stringify({
type: 'subscribe',
request_id: 'req-1',
payload: {
topics: [{
symbol: 'BBRI',
channels: ['orderbook', 'trade']
}]
// format: 'text' is default, use 'json' to override
}
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log('Received:', message);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
Go REST API Client
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
type OrderBook struct {
Symbol string `json:"Symbol"`
Bids []Bid `json:"Bids"`
Asks []Ask `json:"Asks"`
}
func main() {
resp, err := http.Get("http://localhost:8080/orderbook?symbol=BBRI")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var orderbook OrderBook
json.Unmarshal(body, &orderbook)
fmt.Printf("Orderbook for %s\n", orderbook.Symbol)
}
Error Handling
The API uses standard HTTP status codes:
| Status Code | Description |
|---|---|
200 |
Success |
400 |
Bad Request - Invalid parameters |
404 |
Not Found - Symbol or resource not found |
500 |
Internal Server Error |
status: "error" and an error description.
Rate Limiting
The API implements rate limiting to ensure fair usage:
- REST API: 10 requests per second, burst of 20
- WebSocket: No rate limit on subscriptions, but connection limits may apply
Best Practices
- Use WebSocket for real-time data instead of polling REST endpoints
- Specify only the channels you need to reduce bandwidth
- Use text format for high-frequency trading applications
- Implement reconnection logic for WebSocket connections
- Handle ping/pong messages to keep connections alive
- Monitor connection health using
/healthzendpoint