Skip to main content

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​

caution

Accessing market data (both historical and real-time) for US stocks and ETFs 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 for details.

Step 1: Install the SDK​

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

Step 2: Fetch Historical Data​

This example retrieves 1-minute candlestick bars for AAPL:

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>", "us")
api_client.add_endpoint("us", "<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())
API Endpoints
  • Production: api.webull.com
  • Test: api.sandbox.webull.com

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:

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>",
"us",
"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()
Streaming Endpoints

For US server-to-server integrations:

EnvironmentHTTP host for subscribe/unsubscribeMQTT endpoint
Productionapi.webull.comdata-api.webull.com:1883
Testapi.sandbox.webull.comdata-api.sandbox.webull.com:1883

The HTTP host and MQTT broker are intentionally different. Pass the HTTP host as http_host, the MQTT hostname as mqtt_host, and use the same session_id for the subscribe request and MQTT ClientId. The official SDK uses TCP port 1883 with TLS enabled by default.

If you prefer not to use the SDK for streaming, see Data Streaming API for the raw MQTT integration guide.

What's Next​