Preview a mass credit
Starts a preview job: for each selected account, what the rules would credit, or why it is left out, with an explanation. Nothing is changed.
The call returns 202 with the job at once; the work runs in the background in batches, so any number of accounts can be previewed. Follow it with GET /organization/jobs/{jobId} (progress and totals) and read the outcome per account with GET /organization/jobs/{jobId}/items.
Pick the accounts with selection: all (every account of the organization), filter (plan, status, type, creation date), or list (account ids or account numbers in accounts, up to 10,000 per call; for a longer list send deferStart: true, add the rest with POST .../previews/{jobId}/inputs, then POST .../previews/{jobId}/start).
Passed, failed and expired accounts are never credited: they are listed as skipped (ACCOUNT_CLOSED). Review warnings before confirming: BALANCE_TRAIL_MISMATCH means the account’s recorded balance changes for these fills do not add up to their P&L, so the loss may never have reached its balance.
A completed preview can be confirmed within 24 hours.
Requires manage permission on traders.
curl -X POST "https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews" \
-H "X-API-Key: hp_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"rules": {"windowStart": "2026-10-21T13:30:00Z", "windowEnd": "2026-10-21T14:15:00Z"}, "selection": {"mode": "all"}}'
curl --request POST \
--url https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"templateId": "<string>",
"rules": {
"windowStart": "2026-10-21T13:30:00Z",
"windowEnd": "2026-10-21T14:15:00Z",
"lossBasis": "net",
"includeFees": true,
"maxCreditPerAccount": null,
"minCreditPerAccount": null,
"countTowardDailyPnl": false,
"moveHighWaterMark": false,
"requireFlat": false,
"skipAlreadyCredited": true
},
"accounts": [
"<string>"
],
"deferStart": false
}
'import requests
url = "https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews"
payload = {
"templateId": "<string>",
"rules": {
"windowStart": "2026-10-21T13:30:00Z",
"windowEnd": "2026-10-21T14:15:00Z",
"lossBasis": "net",
"includeFees": True,
"maxCreditPerAccount": None,
"minCreditPerAccount": None,
"countTowardDailyPnl": False,
"moveHighWaterMark": False,
"requireFlat": False,
"skipAlreadyCredited": True
},
"accounts": ["<string>"],
"deferStart": 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({
templateId: '<string>',
rules: {
windowStart: '2026-10-21T13:30:00Z',
windowEnd: '2026-10-21T14:15:00Z',
lossBasis: 'net',
includeFees: true,
maxCreditPerAccount: null,
minCreditPerAccount: null,
countTowardDailyPnl: false,
moveHighWaterMark: false,
requireFlat: false,
skipAlreadyCredited: true
},
accounts: ['<string>'],
deferStart: false
})
};
fetch('https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews', 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/balance-adjustments/previews",
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([
'templateId' => '<string>',
'rules' => [
'windowStart' => '2026-10-21T13:30:00Z',
'windowEnd' => '2026-10-21T14:15:00Z',
'lossBasis' => 'net',
'includeFees' => true,
'maxCreditPerAccount' => null,
'minCreditPerAccount' => null,
'countTowardDailyPnl' => false,
'moveHighWaterMark' => false,
'requireFlat' => false,
'skipAlreadyCredited' => true
],
'accounts' => [
'<string>'
],
'deferStart' => 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/balance-adjustments/previews"
payload := strings.NewReader("{\n \"templateId\": \"<string>\",\n \"rules\": {\n \"windowStart\": \"2026-10-21T13:30:00Z\",\n \"windowEnd\": \"2026-10-21T14:15:00Z\",\n \"lossBasis\": \"net\",\n \"includeFees\": true,\n \"maxCreditPerAccount\": null,\n \"minCreditPerAccount\": null,\n \"countTowardDailyPnl\": false,\n \"moveHighWaterMark\": false,\n \"requireFlat\": false,\n \"skipAlreadyCredited\": true\n },\n \"accounts\": [\n \"<string>\"\n ],\n \"deferStart\": 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/balance-adjustments/previews")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"templateId\": \"<string>\",\n \"rules\": {\n \"windowStart\": \"2026-10-21T13:30:00Z\",\n \"windowEnd\": \"2026-10-21T14:15:00Z\",\n \"lossBasis\": \"net\",\n \"includeFees\": true,\n \"maxCreditPerAccount\": null,\n \"minCreditPerAccount\": null,\n \"countTowardDailyPnl\": false,\n \"moveHighWaterMark\": false,\n \"requireFlat\": false,\n \"skipAlreadyCredited\": true\n },\n \"accounts\": [\n \"<string>\"\n ],\n \"deferStart\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews")
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 \"templateId\": \"<string>\",\n \"rules\": {\n \"windowStart\": \"2026-10-21T13:30:00Z\",\n \"windowEnd\": \"2026-10-21T14:15:00Z\",\n \"lossBasis\": \"net\",\n \"includeFees\": true,\n \"maxCreditPerAccount\": null,\n \"minCreditPerAccount\": null,\n \"countTowardDailyPnl\": false,\n \"moveHighWaterMark\": false,\n \"requireFlat\": false,\n \"skipAlreadyCredited\": true\n },\n \"accounts\": [\n \"<string>\"\n ],\n \"deferStart\": false\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "5d1c7a2e-3b4f-4c8d-9e0a-1b2c3d4e5f60",
"kind": "mass_credit.preview",
"type": "preview",
"state": "running",
"parentJobId": "<string>",
"createdBy": "ops@yourfirm.com",
"createdAt": "<string>",
"startedAt": "<string>",
"finishedAt": "<string>",
"heartbeatAt": "<string>",
"progress": {
"total": 120000,
"processed": 48200,
"succeeded": 9100,
"failed": 0,
"skipped": 39100,
"planning": false,
"percent": 40.2
},
"summary": {
"credits": 9100,
"creditAmount": 1830220.5,
"lossAmount": 1902118.25,
"capped": 120,
"warnings": 14,
"skip_ACCOUNT_CLOSED": 30000,
"skip_NO_FILLS": 9100
},
"lastError": "<string>",
"rules": {
"windowStart": "2026-10-21T13:30:00Z",
"windowEnd": "2026-10-21T14:15:00Z",
"lossBasis": "net",
"includeFees": true,
"maxCreditPerAccount": null,
"minCreditPerAccount": null,
"countTowardDailyPnl": false,
"moveHighWaterMark": false,
"requireFlat": false,
"skipAlreadyCredited": true
},
"selection": {
"mode": "all",
"filters": {
"planIds": [
"<string>"
],
"statuses": [
"in_progress"
],
"types": [
"evaluation"
],
"createdFrom": "2023-11-07T05:31:56Z",
"createdTo": "2023-11-07T05:31:56Z"
}
},
"templateId": "<string>",
"expiresAt": "<string>",
"batchId": "<string>",
"tag": "<string>",
"reason": "<string>",
"previewJobId": "<string>",
"applyJobId": "<string>",
"expected": {
"accounts": 123,
"totalAmount": 123
}
}
}{
"success": true,
"data": {
"id": "5d1c7a2e-3b4f-4c8d-9e0a-1b2c3d4e5f60",
"kind": "mass_credit.preview",
"type": "preview",
"state": "running",
"parentJobId": "<string>",
"createdBy": "ops@yourfirm.com",
"createdAt": "<string>",
"startedAt": "<string>",
"finishedAt": "<string>",
"heartbeatAt": "<string>",
"progress": {
"total": 120000,
"processed": 48200,
"succeeded": 9100,
"failed": 0,
"skipped": 39100,
"planning": false,
"percent": 40.2
},
"summary": {
"credits": 9100,
"creditAmount": 1830220.5,
"lossAmount": 1902118.25,
"capped": 120,
"warnings": 14,
"skip_ACCOUNT_CLOSED": 30000,
"skip_NO_FILLS": 9100
},
"lastError": "<string>",
"rules": {
"windowStart": "2026-10-21T13:30:00Z",
"windowEnd": "2026-10-21T14:15:00Z",
"lossBasis": "net",
"includeFees": true,
"maxCreditPerAccount": null,
"minCreditPerAccount": null,
"countTowardDailyPnl": false,
"moveHighWaterMark": false,
"requireFlat": false,
"skipAlreadyCredited": true
},
"selection": {
"mode": "all",
"filters": {
"planIds": [
"<string>"
],
"statuses": [
"in_progress"
],
"types": [
"evaluation"
],
"createdFrom": "2023-11-07T05:31:56Z",
"createdTo": "2023-11-07T05:31:56Z"
}
},
"templateId": "<string>",
"expiresAt": "<string>",
"batchId": "<string>",
"tag": "<string>",
"reason": "<string>",
"previewJobId": "<string>",
"applyJobId": "<string>",
"expected": {
"accounts": 123,
"totalAmount": 123
}
}
}{
"success": false,
"statusCode": 400,
"error": "Bad Request",
"message": "The window must have ended: `windowEnd` is in the future",
"code": "VALIDATION_ERROR"
}{
"success": false,
"statusCode": 401,
"error": "Unauthorized",
"message": "Authentication required",
"code": "UNAUTHORIZED"
}{
"statusCode": 403,
"error": "Forbidden",
"message": "Insufficient permissions",
"code": "INSUFFICIENT_PERMISSIONS"
}{
"success": false,
"statusCode": 404,
"error": "Not Found",
"message": "Template not found",
"code": "TEMPLATE_NOT_FOUND"
}{
"success": false,
"statusCode": 500,
"error": "Internal Server Error",
"message": "An unexpected error occurred",
"code": "INTERNAL_ERROR"
}{
"success": false,
"statusCode": 503,
"error": "Error",
"message": "Mass credit is not available yet; nothing was changed",
"code": "FEATURE_NOT_READY"
}Authorizations
Organization API key. Format: "hp_live_{key}". Organization admins manage the key in the dashboard.
Body
Start from a template: its rules (and selection), overridden by rules and selection in this request
How the credit is computed. Every field is optional (a template or the defaults fill the rest), except the window, which the request or the template must give.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Selection list: account ids or account numbers (up to 10,000; duplicates are ignored)
100001 - 64Selection list: create a draft to add more accounts to before starting
curl --request POST \
--url https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"templateId": "<string>",
"rules": {
"windowStart": "2026-10-21T13:30:00Z",
"windowEnd": "2026-10-21T14:15:00Z",
"lossBasis": "net",
"includeFees": true,
"maxCreditPerAccount": null,
"minCreditPerAccount": null,
"countTowardDailyPnl": false,
"moveHighWaterMark": false,
"requireFlat": false,
"skipAlreadyCredited": true
},
"accounts": [
"<string>"
],
"deferStart": false
}
'import requests
url = "https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews"
payload = {
"templateId": "<string>",
"rules": {
"windowStart": "2026-10-21T13:30:00Z",
"windowEnd": "2026-10-21T14:15:00Z",
"lossBasis": "net",
"includeFees": True,
"maxCreditPerAccount": None,
"minCreditPerAccount": None,
"countTowardDailyPnl": False,
"moveHighWaterMark": False,
"requireFlat": False,
"skipAlreadyCredited": True
},
"accounts": ["<string>"],
"deferStart": 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({
templateId: '<string>',
rules: {
windowStart: '2026-10-21T13:30:00Z',
windowEnd: '2026-10-21T14:15:00Z',
lossBasis: 'net',
includeFees: true,
maxCreditPerAccount: null,
minCreditPerAccount: null,
countTowardDailyPnl: false,
moveHighWaterMark: false,
requireFlat: false,
skipAlreadyCredited: true
},
accounts: ['<string>'],
deferStart: false
})
};
fetch('https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews', 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/balance-adjustments/previews",
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([
'templateId' => '<string>',
'rules' => [
'windowStart' => '2026-10-21T13:30:00Z',
'windowEnd' => '2026-10-21T14:15:00Z',
'lossBasis' => 'net',
'includeFees' => true,
'maxCreditPerAccount' => null,
'minCreditPerAccount' => null,
'countTowardDailyPnl' => false,
'moveHighWaterMark' => false,
'requireFlat' => false,
'skipAlreadyCredited' => true
],
'accounts' => [
'<string>'
],
'deferStart' => 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/balance-adjustments/previews"
payload := strings.NewReader("{\n \"templateId\": \"<string>\",\n \"rules\": {\n \"windowStart\": \"2026-10-21T13:30:00Z\",\n \"windowEnd\": \"2026-10-21T14:15:00Z\",\n \"lossBasis\": \"net\",\n \"includeFees\": true,\n \"maxCreditPerAccount\": null,\n \"minCreditPerAccount\": null,\n \"countTowardDailyPnl\": false,\n \"moveHighWaterMark\": false,\n \"requireFlat\": false,\n \"skipAlreadyCredited\": true\n },\n \"accounts\": [\n \"<string>\"\n ],\n \"deferStart\": 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/balance-adjustments/previews")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"templateId\": \"<string>\",\n \"rules\": {\n \"windowStart\": \"2026-10-21T13:30:00Z\",\n \"windowEnd\": \"2026-10-21T14:15:00Z\",\n \"lossBasis\": \"net\",\n \"includeFees\": true,\n \"maxCreditPerAccount\": null,\n \"minCreditPerAccount\": null,\n \"countTowardDailyPnl\": false,\n \"moveHighWaterMark\": false,\n \"requireFlat\": false,\n \"skipAlreadyCredited\": true\n },\n \"accounts\": [\n \"<string>\"\n ],\n \"deferStart\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews")
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 \"templateId\": \"<string>\",\n \"rules\": {\n \"windowStart\": \"2026-10-21T13:30:00Z\",\n \"windowEnd\": \"2026-10-21T14:15:00Z\",\n \"lossBasis\": \"net\",\n \"includeFees\": true,\n \"maxCreditPerAccount\": null,\n \"minCreditPerAccount\": null,\n \"countTowardDailyPnl\": false,\n \"moveHighWaterMark\": false,\n \"requireFlat\": false,\n \"skipAlreadyCredited\": true\n },\n \"accounts\": [\n \"<string>\"\n ],\n \"deferStart\": false\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "5d1c7a2e-3b4f-4c8d-9e0a-1b2c3d4e5f60",
"kind": "mass_credit.preview",
"type": "preview",
"state": "running",
"parentJobId": "<string>",
"createdBy": "ops@yourfirm.com",
"createdAt": "<string>",
"startedAt": "<string>",
"finishedAt": "<string>",
"heartbeatAt": "<string>",
"progress": {
"total": 120000,
"processed": 48200,
"succeeded": 9100,
"failed": 0,
"skipped": 39100,
"planning": false,
"percent": 40.2
},
"summary": {
"credits": 9100,
"creditAmount": 1830220.5,
"lossAmount": 1902118.25,
"capped": 120,
"warnings": 14,
"skip_ACCOUNT_CLOSED": 30000,
"skip_NO_FILLS": 9100
},
"lastError": "<string>",
"rules": {
"windowStart": "2026-10-21T13:30:00Z",
"windowEnd": "2026-10-21T14:15:00Z",
"lossBasis": "net",
"includeFees": true,
"maxCreditPerAccount": null,
"minCreditPerAccount": null,
"countTowardDailyPnl": false,
"moveHighWaterMark": false,
"requireFlat": false,
"skipAlreadyCredited": true
},
"selection": {
"mode": "all",
"filters": {
"planIds": [
"<string>"
],
"statuses": [
"in_progress"
],
"types": [
"evaluation"
],
"createdFrom": "2023-11-07T05:31:56Z",
"createdTo": "2023-11-07T05:31:56Z"
}
},
"templateId": "<string>",
"expiresAt": "<string>",
"batchId": "<string>",
"tag": "<string>",
"reason": "<string>",
"previewJobId": "<string>",
"applyJobId": "<string>",
"expected": {
"accounts": 123,
"totalAmount": 123
}
}
}{
"success": true,
"data": {
"id": "5d1c7a2e-3b4f-4c8d-9e0a-1b2c3d4e5f60",
"kind": "mass_credit.preview",
"type": "preview",
"state": "running",
"parentJobId": "<string>",
"createdBy": "ops@yourfirm.com",
"createdAt": "<string>",
"startedAt": "<string>",
"finishedAt": "<string>",
"heartbeatAt": "<string>",
"progress": {
"total": 120000,
"processed": 48200,
"succeeded": 9100,
"failed": 0,
"skipped": 39100,
"planning": false,
"percent": 40.2
},
"summary": {
"credits": 9100,
"creditAmount": 1830220.5,
"lossAmount": 1902118.25,
"capped": 120,
"warnings": 14,
"skip_ACCOUNT_CLOSED": 30000,
"skip_NO_FILLS": 9100
},
"lastError": "<string>",
"rules": {
"windowStart": "2026-10-21T13:30:00Z",
"windowEnd": "2026-10-21T14:15:00Z",
"lossBasis": "net",
"includeFees": true,
"maxCreditPerAccount": null,
"minCreditPerAccount": null,
"countTowardDailyPnl": false,
"moveHighWaterMark": false,
"requireFlat": false,
"skipAlreadyCredited": true
},
"selection": {
"mode": "all",
"filters": {
"planIds": [
"<string>"
],
"statuses": [
"in_progress"
],
"types": [
"evaluation"
],
"createdFrom": "2023-11-07T05:31:56Z",
"createdTo": "2023-11-07T05:31:56Z"
}
},
"templateId": "<string>",
"expiresAt": "<string>",
"batchId": "<string>",
"tag": "<string>",
"reason": "<string>",
"previewJobId": "<string>",
"applyJobId": "<string>",
"expected": {
"accounts": 123,
"totalAmount": 123
}
}
}{
"success": false,
"statusCode": 400,
"error": "Bad Request",
"message": "The window must have ended: `windowEnd` is in the future",
"code": "VALIDATION_ERROR"
}{
"success": false,
"statusCode": 401,
"error": "Unauthorized",
"message": "Authentication required",
"code": "UNAUTHORIZED"
}{
"statusCode": 403,
"error": "Forbidden",
"message": "Insufficient permissions",
"code": "INSUFFICIENT_PERMISSIONS"
}{
"success": false,
"statusCode": 404,
"error": "Not Found",
"message": "Template not found",
"code": "TEMPLATE_NOT_FOUND"
}{
"success": false,
"statusCode": 500,
"error": "Internal Server Error",
"message": "An unexpected error occurred",
"code": "INTERNAL_ERROR"
}{
"success": false,
"statusCode": 503,
"error": "Error",
"message": "Mass credit is not available yet; nothing was changed",
"code": "FEATURE_NOT_READY"
}