import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Getting Started

A quick guide to get you from zero to your first market data request. We'll install the SDK, set up authentication, and run two examples: fetching historical bars and subscribing to real-time quotes.

## Prerequisites

- Python 3.8–3.13 or Java JDK 8+
- App Key and App Secret. See [Trading API Application](../authentication/TradingAPIApplication.md) or use the shared [test accounts](../sdk.md#test-accounts).

:::caution
Accessing market data (both historical and real-time) requires an active OpenAPI market data subscription. If you receive a 403 error when running the examples below, you likely need to subscribe first. See [Subscribe Advanced Quotes](subscribe-quotes.md) for details.

Currently, test accounts only have access to market data APIs and real-time streaming for the symbol **AAPL**.
:::

## Step 1: Install the SDK

<Tabs groupId="programming-language">
  <TabItem value="python" label="Python" default>

```bash
pip3 install --upgrade webull-openapi-python-sdk
```

  </TabItem>
  <TabItem value="java" label="Java">

```xml
<dependency>
    <groupId>com.webull.openapi</groupId>
    <artifactId>webull-openapi-java-sdk</artifactId>
    <version>1.0.3</version>
</dependency>
```

  </TabItem>
</Tabs>

## Step 2: Fetch Historical Data

This example retrieves 1-minute candlestick bars for AAPL:

```python
from webull.data.common.category import Category
from webull.data.common.timespan import Timespan
from webull.core.client import ApiClient
from webull.data.data_client import DataClient

api_client = ApiClient("<your_app_key>", "<your_app_secret>", "hk")
api_client.add_endpoint("hk", "<api_endpoint>")

data_client = DataClient(api_client)

# Single symbol
res = data_client.market_data.get_history_bar("AAPL", Category.US_STOCK.name, Timespan.M1.name)
if res.status_code == 200:
    print("History bar:", res.json())

# Batch query (multiple symbols)
res = data_client.market_data.get_batch_history_bar(
    ["AAPL", "TSLA"], Category.US_STOCK.name, Timespan.M1.name, 1
)
if res.status_code == 200:
    print("Batch history bar:", res.json())
```

:::tip API Endpoints
- Production: `api.webull.hk`
- Sandbox: `api.sandbox.webull.hk`
:::

## Step 3: Subscribe to Real-Time Quotes

This example connects to the MQTT streaming service and subscribes to real-time quote, snapshot, and tick data for AAPL:

```python
from webull.data.common.category import Category
from webull.data.common.subscribe_type import SubscribeType
from webull.data.data_streaming_client import DataStreamingClient

data_streaming_client = DataStreamingClient(
    "<your_app_key>",
    "<your_app_secret>",
    "hk",
    "demo_session_1",
    http_host="<api_endpoint>",
    mqtt_host="<data_api_endpoint>",
)

def on_connect(client, api_client, session_id):
    print("Connected:", client.get_session_id())
    client.subscribe(
        ["AAPL"],
        Category.US_STOCK.name,
        [SubscribeType.QUOTE.name, SubscribeType.SNAPSHOT.name, SubscribeType.TICK.name],
    )

def on_message(client, topic, quotes):
    print("Topic:", topic, "Data:", quotes)

def on_subscribe(client, api_client, session_id):
    print("Subscribed:", client.get_session_id())

data_streaming_client.on_connect_success = on_connect
data_streaming_client.on_quotes_message = on_message
data_streaming_client.on_subscribe_success = on_subscribe
data_streaming_client.connect_and_loop_forever()
```

:::info Streaming Endpoints
- Production MQTT: `data-api.webull.hk`
- Sandbox MQTT: `data-api.sandbox.webull.hk`
:::

If you prefer not to use the SDK for streaming, see [Data Streaming API](data-streaming-api.md) for the raw MQTT integration guide.

## What's Next

- [Data API](data-api.md) — HTTP endpoints for historical and snapshot data
- [Data Streaming API](data-streaming-api.md) — MQTT protocol details for real-time streaming
- [Market Data API Overview](overview.md) — Full list of available endpoints and rate limits
