@PythonUserX
Why would close position return 403 on paper accounts for a valid open position? Can open/queued orders lock shares and cause 403 instead of a clearer quantity-available error?
Yes. If there are existing open orders to sell that are part of the position you’re trying to close, the request will fail with a 403 error. Here is a typical log entry for such a failure. You can check your request body for the error message:
{"timestamp":"2026-03-05T14:13:56.810Z", "method":"DELETE", "path":"/papertrader/api/v2/positions/AIFF", "status_code":403,"err_body":"{\"available\":\"0\",\"code\":40310000,\"existing_qty\":\"544\",\"held_for_orders\":\"544\",\"message\":\"insufficient qty available for order (requested: 544, available: 0)\",\"symbol\":\"AIFF\"}","user_agent":"APCA-TRADE-SDK-PY/3.2.0"}
Is there a recommended cancel-open-orders-then-close sequence for after-hours exits?
First, cancel any open orders. Wait until the order’s status is canceled. Then submit a limit day order with a ‘marketable’ limit price. For a sell order, that means the limit price should be less than or equal to the current quoted bid price. Do not make the price much lower than the bid; perhaps stay within 5-10% of the bid, otherwise the order may be rejected due to ‘fat finger protection’ rules.
For extended hours, what is Alpaca’s recommended “fastest reliable exit” pattern: close_position, marketable limit, or explicit cancel/replace loop?
The steps above would be the best approach. The close position method creates market orders and not limit orders, and therefore would not execute in extended hour trading
Are there known intermittent paper-trading backend issues that can temporarily block close attempts and later self-resolve (as with AIFF)?
There are no intermittent issues. The only reason you would ever get a 403 error is if there are existing sell orders. You may experience them as ‘intermittent’ simply because they may not be open sell orders all the time.
What response codes/messages should bots treat as retryable vs terminal for sell-close logic?
Errors are generally never ‘retryable’. They do not fix themselves. The single exception to this is a 500 error. That is an API timeout error. In that case, one doesn’t know if the request succeeded or failed before timing out. In that case, generally retry. However, if submitting an order, there is a chance that the initial request succeeded, and you will end up submitting a duplicate order. To avoid this, include a client order ID in the request. Why? If the initial order succeeded, the second order will be rejected due to a duplicate client order ID. This happens very infrequently, but it is probably good programming practice to account for these edge cases.