# /order/liquidatePosition

**URL:** <https://community.tradovate.com/t/order-liquidateposition/8598>\
**Category:** API Developers\
**Created:** [January 24, 2024, 9:50pm UTC](https://community.tradovate.com/t/order-liquidateposition/8598 "2024-01-24T21:50:46Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Donald\_Fellars](https://avatars.discourse-cdn.com/v4/letter/d/f4b2a3/32.png) [@Donald\_Fellars](https://community.tradovate.com/u/Donald_Fellars)\
**Post date:** [January 24, 2024, 9:50pm UTC](https://community.tradovate.com/t/order-liquidateposition/8598/1 "2024-01-24T21:50:47Z")

</div>

@Alexander I have `/order/liquidatePosition` and `orderstrategy/startorderstrategy` working individually. But when I first liquidate followed by starting a new strategy, my strategy also gets closed out right away. I see the commands are sent out about 100ms apart, and I receive the a[{“s”:200,“i”:2,“d”:{}}]’ for each command about 100ms apart as well. But my StartOrderStrategy. gets cancelled right after getting placed. Any ideas on how long a `/order/liquidatePosition` stays in effect?

```auto
2024-01-24:14:20:32,097 DEBUG [protocol.py:698] > TEXT 'order/liquidateposition\n2\n\n{"accountId":XXX...ull,"isAutomated":true}' [121 bytes]
2024-01-24:14:20:32,163 DEBUG [protocol.py:548] < TEXT 'a[{"s":200,"i":2,"d":{}}]' [25 bytes]
2024-01-24:14:20:32,226 DEBUG [protocol.py:698] > TEXT 'orderstrategy/startorderstrategy\n3\n\n{"symbol...ilingStop\\":false}]}"}' [362 bytes]
2024-01-24:14:20:32,293 DEBUG [protocol.py:548] < TEXT 'a[{"s":200,"i":3,"d":{"orderStrategy":{"id":XXX...essionId":XXXX}}}]' [487 bytes]

```

---

<div class="post-metadata">

**Author:** ![Donald\_Fellars](https://avatars.discourse-cdn.com/v4/letter/d/f4b2a3/32.png) [@Donald\_Fellars](https://community.tradovate.com/u/Donald_Fellars)\
**Post date:** [January 31, 2024, 11:34pm UTC](https://community.tradovate.com/t/order-liquidateposition/8598/2 "2024-01-31T23:34:30Z")

</div>

@BWeis do you have any thoughts on this?

---

<div class="post-metadata">

**Author:** ![Donald\_Fellars](https://avatars.discourse-cdn.com/v4/letter/d/f4b2a3/32.png) [@Donald\_Fellars](https://community.tradovate.com/u/Donald_Fellars)\
**Post date:** [July 4, 2024, 2:06am UTC](https://community.tradovate.com/t/order-liquidateposition/8598/3 "2024-07-04T02:06:50Z")

</div>

This is still a problem. I tried creating other work arounds, but I keep coming back to this.

If I place an order right after calling the liquidate command it enters and exits the new order right away.

---

<div class="post-metadata">

**Author:** ![GooberHelmut](https://avatars.discourse-cdn.com/v4/letter/g/3bc359/32.png) [@GooberHelmut](https://community.tradovate.com/u/GooberHelmut)\
**Post date:** [May 14, 2026, 4:11pm UTC](https://community.tradovate.com/t/order-liquidateposition/8598/4 "2026-05-14T16:11:55Z")

</div>

For anyone still landing here: I probed this endpoint against the demo API today and the body schema that’s been guessed at across this and the  
sibling threads is:

POST /order/liquidatePosition  
{  
“accountId”: ,  
“contractId”: \<numeric, \> 0\>,  
“admin”: ,  
“customTag50”: “”  
}

| Body | Response |
| --- | --- |
| {} | 400 missing required field “admin” |
| {“accountId”: N} | 400 missing required field “admin” |
| {“accountId”: N, “isAutomated”: true} | 400 missing required field “admin” |
| {“accountId”: N, “admin”: false} | 400 contractId must be \> 0 |
| {“accountId”: N, “contractId”: 99999, “admin”: false} | 404 (contract validated) |
| {“accountId”: N, “positions”: [id], “admin”: false} | 400 contractId must be \> 0 |
| {“accountId”: N, “contractId”: \<real, flat\>, “admin”: false} | 200 {} |

Three takeaways:

1. admin is mandatory. A lot of the example bodies floating around forget it because the debug-log dumps you see make it look optional. It isn’t  
— you’ll get a 400 every time.
2. It’s per-(accountId, contractId), not by positionId. The positions: [id] body shape several threads suggest is silently ignored — Tradovate  
reads contractId and looks up the netPos server-side itself.
3. It’s race-safe. If the position closed in the gap between your /position/list and your liquidatePosition POST, you get a clean 200 {} no-op.  
That’s the killer reason to prefer this over a synthesized opposite-side placeOrder, which would open a fresh reverse position in exactly that  
race.
