Trading API FAQ
1. Why am I receiving an HTTP 403 error (Forbidden)?
A 403 error is returned when:
- The request is missing authentication headers
- The authentication credentials are invalid
- Your account does not have sufficient permissions
Make sure your request includes all required headers. See Authentication Overview for details.
2. Do I need to handle signatures when using the Webull SDK?
No. The SDK handles signature generation automatically. You only need to provide your App Key and App Secret when initializing the client.
3. How long does API application approval take?
The review and approval process typically takes 1–2 business days. You can install the SDK and explore the test environment while waiting.
4. Why was my order rejected?
Common reasons:
- Insufficient buying power or margin
- The market is closed for the asset you're trading
- Invalid order parameters (e.g., price outside allowed range, unsupported order type)
- Missing required trading agreements (especially for event contracts and options)
Check the error message in the API response for specific details.
5. What is a client_order_id and why is it required?
The client_order_id is a unique identifier you generate for each order. It allows you to track, modify, and cancel orders. Each client_order_id must be unique across all your orders. Use a UUID to ensure uniqueness.
6. How do I receive real-time order status updates?
Use the Trade Event Subscription via gRPC streaming. It pushes updates for fills, cancellations, modifications, and failures in real time. See Getting Started for a code example.
7. Are there any fees for using the Trading API?
There are no additional charges for trading via the OpenAPI. Trading fees are the same as those in the Webull App. For the current fee schedule, see Webull Pricing.
8. Why am I getting INVALID_TOKEN even though my token is valid?
This error can be misleading. In many cases, it actually indicates a signature mismatch rather than a token issue. Common causes:
- The JSON body used for MD5 computation differs from what's actually sent in the request (e.g., using
json=bodyin Python'srequests.post()instead of serializing manually) - Extra whitespace in the JSON body
- Incorrect URL encoding of the signature string
See Signature — JSON Body Serialization for detailed debugging steps.
9. Why does the strategy of my multi-leg order differ from the option_strategy I sent?
option_strategy is provided for reference only and is not used for order validation. The system determines the actual strategy from the composition of legs (number of legs, option types, strikes, expirations, and sides). See Options — Supported Strategies.
10. How do I modify a multi-leg option order?
Call Replace Order with a legs array that contains every leg of the order (each item with the leg id and quantity). A replace request cannot change the strategy structure; to add or remove legs, or to change strike price, expiration date, or side, cancel the order and place a new one. See Modifying Multi-Leg Orders.
11. How do I close only one leg of a multi-leg position?
Place an order with leg_in_or_out set to LEG_OUT and position_id set to the target position, obtained from Account Positions. position_id is required whenever leg_in_or_out is specified. See Leg In / Leg Out.