Stream SEC Filings in Real-Time Using Python

This guide provides a step-by-step approach to connect to the Stream API with Python, enabling you to receive newly published SEC filings in real-time.

Begin with the installation of the WebSocket library by executing the following command in your terminal:

pip install websockets

After installation, proceed to copy the Python script provided below into a file on your local machine. Ensure you replace YOUR_API_KEY with your actual API key obtained from your account.

With these preparations complete, you're ready to execute the Python script. The script will continuously listen for new filings and output their metadata in your terminal as soon as they are made available on EDGAR.

Python
1 import asyncio
2 import websockets
3 import json
4
5 API_KEY = "YOUR_API_KEY" # Replace this with your actual API key
6 SERVER_URL = "wss://stream.sec-api.io"
7 WS_ENDPOINT = SERVER_URL + "?apiKey=" + API_KEY
8
9 async def websocket_client():
10 try:
11 async with websockets.connect(WS_ENDPOINT) as websocket:
12 print("✅ Connected to:", SERVER_URL)
13
14 while True:
15 message = await websocket.recv()
16 filings = json.loads(message)
17 for f in filings:
18 print(f["accessionNo"], f["formType"], f["filedAt"], f["cik"])
19
20 except Exception as e:
21 print(f"An unexpected error occurred: {e}")
22
23
24 asyncio.run(websocket_client())

Advanced Example: Auto-Reconnect, Heartbeats, and Keep-Alives

This advanced Python code sample introduces a robust reconnection mechanism. It enables the client to monitor the connection status actively and perform an automatic reconnection if the connection drops. The strategy involves dispatching a heartbeat ping to the server at 30-second intervals, awaiting a pong response. Should the server fail to reply within a 5-second window, the client terminates the current connection and initiates a new connection process, thereby maintaining continuous connectivity.

Python
1 import asyncio
2 import websockets
3 import json
4
5 API_KEY = "YOUR_API_KEY" # Replace this with your actual API key
6 SERVER_URL = "wss://stream.sec-api.io"
7 WS_ENDPOINT = SERVER_URL + "?apiKey=" + API_KEY
8
9
10 async def send_ping(websocket):
11 while True:
12 try:
13 pong_waiter = await websocket.ping()
14 await asyncio.wait_for(pong_waiter, timeout=5) # Wait for a pong within 5 seconds
15 await asyncio.sleep(30) # Send ping every 30 seconds
16 except Exception as e:
17 print(f"An error occurred while sending ping: {e}")
18 await websocket.close() # Close the connection if an error occurs
19 return
20
21
22 async def websocket_client():
23 retry_counter = 0
24 max_retries = 5
25 ping_task = None
26
27 while retry_counter < max_retries:
28 try:
29 async with websockets.connect(WS_ENDPOINT) as websocket:
30 print("✅ Connected to:", SERVER_URL)
31 retry_counter = 0
32 # Start the ping/pong keep-alive routine
33 ping_task = asyncio.create_task(send_ping(websocket))
34 # Start the message-receiving loop
35 while True:
36 message = await websocket.recv()
37 filings = json.loads(message)
38 for f in filings:
39 print(f["accessionNo"], f["formType"], f["filedAt"], f["cik"])
40
41 except Exception as e:
42 retry_counter += 1
43
44 print(f"Connection closed with message: {e}")
45 print(f"Reconnecting in 5 sec... (Attempt {retry_counter}/{max_retries})")
46
47 # Cancel the ping task
48 if ping_task is not None:
49 try:
50 ping_task.cancel()
51 await ping_task
52 except Exception:
53 pass # Ignore any exceptions
54 ping_task = None
55
56 await asyncio.sleep(5) # Wait for 5 seconds before reconnecting
57
58 print("Maximum reconnection attempts reached. Stopping client.")
59
60
61 asyncio.run(websocket_client())

Example for Connecting to Deprecated Legacy Endpoints

This example illustrates the process of connecting to legacy streaming endpoints that are marked for deprecation. Please be advised that these endpoints will be phased out on April 5, 2024. To ensure uninterrupted access and take advantage of enhanced functionality, we strongly recommend migrating to the newly available endpoint as soon as possible.

pip install python-engineio==3.14.2 python-socketio[client]==4.6.0
Python
1 import socketio
2
3 sio = socketio.Client()
4
5 @sio.on('connect', namespace='/all-filings')
6 def on_connect():
7 print("Connected to https://api.sec-api.io:3334/all-filings")
8
9 @sio.on('filing', namespace='/all-filings')
10 def on_filings(filing):
11 print(filing)
12
13 sio.connect('https://api.sec-api.io:3334?apiKey=YOUR_API_KEY', namespaces=['/all-filings'], transports=["websocket"])
14 sio.wait()