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.

Base URL: http://localhost:8080
API Version: /api/v1
WebSocket: 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

GET /healthz

Check service health status with version information.

curl http://localhost:8080/healthz
GET /readyz

Readiness probe for Kubernetes/container orchestration.

curl http://localhost:8080/readyz
GET /liveness

Liveness probe for Kubernetes/container orchestration.

curl http://localhost:8080/liveness

Orderbook Endpoints

GET /orderbook?symbol=BBRI

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"
GET /orderbooks

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:

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
Note: WebSocket errors are returned in the subscription acknowledgment message with status: "error" and an error description.

Rate Limiting

The API implements rate limiting to ensure fair usage:

Best Practices

Additional Resources