<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[placeOrder returns HTTP 400 with a completely empty body (no JSON) — reproducible with a real, valid instrument]]></title><description><![CDATA[<h2>Summary</h2>
<p dir="auto"><code>placeOrder</code> returns <code>HTTP 400</code> with a completely empty body (<code>Content-Length: 0</code>) — no <code>status</code>/<code>message</code>/<code>errorcode</code> JSON at all, so there's no error detail to act on. Reproducible with a real, valid instrument, not just a malformed request.</p>
<h2>Environment</h2>
<ul>
<li><code>smartapi-python</code> v1.5.5 (latest on PyPI)</li>
<li>App registered with a static primary IP (via SmartAPI dashboard → Add App)</li>
<li>Login (<code>generateSession</code> via client code + PIN + TOTP) succeeds every time</li>
</ul>
<h2>What works fine with the same session</h2>
<ul>
<li><code>getProfile</code></li>
<li><code>rmsLimit</code></li>
<li><code>orderBook</code></li>
<li><code>position</code></li>
<li><code>getMarketData</code></li>
</ul>
<h2>Headers sent (verified against the official Orders doc example, exact match)</h2>
<p dir="auto">Authorization: Bearer &lt;token&gt;<br />
Content-Type: application/json<br />
Accept: application/json<br />
X-UserType: USER<br />
X-SourceID: WEB<br />
X-ClientLocalIP: &lt;local ip&gt;<br />
X-ClientPublicIP: &lt;public ip&gt;<br />
X-MACAddress: &lt;mac&gt;<br />
X-PrivateKey: &lt;api key&gt;</p>
<h2>Steps to reproduce</h2>
<ol>
<li><code>placeOrder</code> with a deliberately invalid <code>tradingsymbol</code> / <code>symboltoken</code> — expected a normal validation-error JSON response, got empty <code>400</code> instead.</li>
<li><code>placeOrder</code> with a real, valid NSE equity symbol/token (e.g. <code>TCS-EQ</code>) and a realistic limit price — same empty <code>400</code>.</li>
<li>Tried both via the SDK's <code>placeOrder()</code> / <code>placeOrderFullResponse()</code> and via a raw <code>requests.post()</code> directly to <code>https://apiconnect.angelone.in/rest/secure/angelbroking/order/v1/placeOrder</code> with the same headers/payload — identical result either way.</li>
</ol>
<h2>What I've ruled out</h2>
<ul>
<li><strong>Not a header problem</strong> — verified the exact header set against the official Orders documentation page, line by line.</li>
<li><strong>Not insufficient funds/margin</strong> — the docs' own example of a real rejection (insufficient funds) returns a full JSON body with a human-readable <code>text</code> field. An empty body doesn't match that pattern.</li>
<li><strong>Possibly not market hours</strong> — tests were run outside market hours (~10:30 PM IST). Per the docs, off-hours orders should become AMO orders with a normal success response (<code>order_id</code> returned), not fail outright — so I'm not fully confident this explains it either, though I haven't yet confirmed the same request during live market hours.</li>
</ul>
<h2>Question</h2>
<p dir="auto">Has anyone else hit a zero-byte <code>400</code> specifically (not a JSON error) on <code>placeOrder</code>? Trying to determine whether this is account-specific (some provisioning step I'm missing) or a broader gateway issue.</p>
]]></description><link>https://smartapi.angelone.in/smartapi/forum/topic/5656/placeorder-returns-http-400-with-a-completely-empty-body-no-json-reproducible-with-a-real-valid-instrument</link><generator>RSS for Node</generator><lastBuildDate>Wed, 26 Aug 2026 08:35:03 GMT</lastBuildDate><atom:link href="https://smartapi.angelone.in/smartapi/forum/topic/5656.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 26 Aug 2026 00:16:57 GMT</pubDate><ttl>60</ttl></channel></rss>