Close all positions across accounts
The kill switch for outages and incidents. Closes every open position at market and cancels every working order on every tradable account of your organization (allAccounts: true), or on the accounts you list (accountIds).
This does not lock accounts. Statuses do not change and traders can place new orders straight away. To stop trading as well, add a lockout with POST /organization/lockouts for the accounts concerned.
The run continues in the background and the call returns 202 with a runId at once. Follow it with GET /organization/flatten-runs/{runId} until status is completed: it reports accounts handled, positions closed, orders cancelled, and any account that could not be confirmed. Accounts that are already flat are left alone, so running it again is safe and covers anything that failed.
allAccounts covers accounts that are not started or in progress. Passed, failed, expired and turned-off accounts cannot trade; to close something left on one of them, list it in accountIds.
The resulting orders carry reason Admin flatten: <who> — <your reason> (trigger admin_flatten). Each account where something was closed or cancelled gets an ACCOUNT_UPDATED event with the counts; accounts with nothing to close get no event.
Send preview: true first to see how many accounts the run would cover. One run per organization at a time.
Requires manage permission on traders.
curl -X POST "https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten" \
-H "X-API-Key: hp_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"allAccounts": true, "reason": "Market data outage"}'
curl --request POST \
--url https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"reason": "Market data outage — closing all exposure",
"allAccounts": true,
"accountIds": [
"7c9e6679-7425-40de-944b-e07fc1f90ae7"
],
"preview": false
}
'import requests
url = "https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten"
payload = {
"reason": "Market data outage — closing all exposure",
"allAccounts": True,
"accountIds": ["7c9e6679-7425-40de-944b-e07fc1f90ae7"],
"preview": False
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
reason: 'Market data outage — closing all exposure',
allAccounts: true,
accountIds: ['7c9e6679-7425-40de-944b-e07fc1f90ae7'],
preview: false
})
};
fetch('https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reason' => 'Market data outage — closing all exposure',
'allAccounts' => true,
'accountIds' => [
'7c9e6679-7425-40de-944b-e07fc1f90ae7'
],
'preview' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten"
payload := strings.NewReader("{\n \"reason\": \"Market data outage — closing all exposure\",\n \"allAccounts\": true,\n \"accountIds\": [\n \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n ],\n \"preview\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"Market data outage — closing all exposure\",\n \"allAccounts\": true,\n \"accountIds\": [\n \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n ],\n \"preview\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reason\": \"Market data outage — closing all exposure\",\n \"allAccounts\": true,\n \"accountIds\": [\n \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n ],\n \"preview\": false\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"preview": true,
"scope": "all",
"total": 7180
}
}{
"success": true,
"data": {
"runId": "3f2a9c1e-8b7d-4e6f-a5c4-1d2e3f4a5b6c",
"status": "running",
"total": 7180,
"scope": "all"
}
}{
"success": false,
"statusCode": 400,
"error": "Bad Request",
"message": "2 of the account IDs are not accounts of your organization; nothing was started",
"code": "ACCOUNTS_NOT_FOUND",
"unknownAccountIds": [
"9b2e1f4c-3d5a-4b6c-8e7f-0a1b2c3d4e5f"
],
"unknownCount": 2
}{
"success": false,
"statusCode": 401,
"error": "Unauthorized",
"message": "Authentication required",
"code": "UNAUTHORIZED"
}{
"statusCode": 403,
"error": "Forbidden",
"message": "Your role does not have write access to \"Traders & accounts\"",
"code": "INSUFFICIENT_PERMISSIONS"
}{
"success": false,
"statusCode": 409,
"error": "Conflict",
"message": "A close-all run is already in progress for your organization; wait for it to finish",
"code": "FLATTEN_RUN_IN_PROGRESS",
"runId": "3f2a9c1e-8b7d-4e6f-a5c4-1d2e3f4a5b6c"
}{
"success": false,
"statusCode": 500,
"error": "Internal Server Error",
"message": "An unexpected error occurred",
"code": "INTERNAL_ERROR"
}Authorizations
Organization API key. Format: "hp_live_{key}". Organization admins manage the key in the dashboard.
Body
Why the positions are being closed. Recorded on every resulting order and on each affected account's event log.
3 - 200"Market data outage — closing all exposure"
Close positions on every tradable account of your organization (not started or in progress). Send this or accountIds, not both.
true true
Close positions on these accounts of your organization, whatever their status (1 to 5,000; duplicates are ignored). Send this or allAccounts, not both.
1 - 5000 elements["7c9e6679-7425-40de-944b-e07fc1f90ae7"]
When true, only report how many accounts the run would cover. Nothing is closed.
curl --request POST \
--url https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"reason": "Market data outage — closing all exposure",
"allAccounts": true,
"accountIds": [
"7c9e6679-7425-40de-944b-e07fc1f90ae7"
],
"preview": false
}
'import requests
url = "https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten"
payload = {
"reason": "Market data outage — closing all exposure",
"allAccounts": True,
"accountIds": ["7c9e6679-7425-40de-944b-e07fc1f90ae7"],
"preview": False
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
reason: 'Market data outage — closing all exposure',
allAccounts: true,
accountIds: ['7c9e6679-7425-40de-944b-e07fc1f90ae7'],
preview: false
})
};
fetch('https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reason' => 'Market data outage — closing all exposure',
'allAccounts' => true,
'accountIds' => [
'7c9e6679-7425-40de-944b-e07fc1f90ae7'
],
'preview' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten"
payload := strings.NewReader("{\n \"reason\": \"Market data outage — closing all exposure\",\n \"allAccounts\": true,\n \"accountIds\": [\n \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n ],\n \"preview\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"Market data outage — closing all exposure\",\n \"allAccounts\": true,\n \"accountIds\": [\n \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n ],\n \"preview\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hyperprop.com/platform/v1/organization/trading-accounts/flatten")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reason\": \"Market data outage — closing all exposure\",\n \"allAccounts\": true,\n \"accountIds\": [\n \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n ],\n \"preview\": false\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"preview": true,
"scope": "all",
"total": 7180
}
}{
"success": true,
"data": {
"runId": "3f2a9c1e-8b7d-4e6f-a5c4-1d2e3f4a5b6c",
"status": "running",
"total": 7180,
"scope": "all"
}
}{
"success": false,
"statusCode": 400,
"error": "Bad Request",
"message": "2 of the account IDs are not accounts of your organization; nothing was started",
"code": "ACCOUNTS_NOT_FOUND",
"unknownAccountIds": [
"9b2e1f4c-3d5a-4b6c-8e7f-0a1b2c3d4e5f"
],
"unknownCount": 2
}{
"success": false,
"statusCode": 401,
"error": "Unauthorized",
"message": "Authentication required",
"code": "UNAUTHORIZED"
}{
"statusCode": 403,
"error": "Forbidden",
"message": "Your role does not have write access to \"Traders & accounts\"",
"code": "INSUFFICIENT_PERMISSIONS"
}{
"success": false,
"statusCode": 409,
"error": "Conflict",
"message": "A close-all run is already in progress for your organization; wait for it to finish",
"code": "FLATTEN_RUN_IN_PROGRESS",
"runId": "3f2a9c1e-8b7d-4e6f-a5c4-1d2e3f4a5b6c"
}{
"success": false,
"statusCode": 500,
"error": "Internal Server Error",
"message": "An unexpected error occurred",
"code": "INTERNAL_ERROR"
}