Confirm a mass credit
Credits every account the preview marked for a credit, by the amount it showed, as one batch with your reason and tag. Returns 202 with the credit job; follow it like the preview (GET /organization/jobs/{jobId}, items, export), pause, resume or cancel it.
Each credit is applied to the live account exactly once, alongside any trading on it. Each credited account gets an account.updated event with trigger balance_adjustment (batch ID, tag and reason) and an account.balance_changed event with reason adjustment.
The preview must have completed with no failed item, be less than 24 hours old, and not have been confirmed before. Send its summary.creditAmount as expectedTotalAmount.
Requires manage permission on traders.
curl -X POST "https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews/5d1c7a2e-3b4f-4c8d-9e0a-1b2c3d4e5f60/confirm" \
-H "X-API-Key: hp_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"reason": "US-open outage, 21 October", "tag": "incident-2026-10-21", "expectedTotalAmount": 1830220.5}'
curl --request POST \
--url https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews/{jobId}/confirm \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"reason": "US-open outage, 21 October",
"tag": "incident-2026-10-21",
"expectedTotalAmount": 1830220.5
}
'import requests
url = "https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews/{jobId}/confirm"
payload = {
"reason": "US-open outage, 21 October",
"tag": "incident-2026-10-21",
"expectedTotalAmount": 1830220.5
}
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: 'US-open outage, 21 October',
tag: 'incident-2026-10-21',
expectedTotalAmount: 1830220.5
})
};
fetch('https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews/{jobId}/confirm', 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/{jobId}/confirm",
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' => 'US-open outage, 21 October',
'tag' => 'incident-2026-10-21',
'expectedTotalAmount' => 1830220.5
]),
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/{jobId}/confirm"
payload := strings.NewReader("{\n \"reason\": \"US-open outage, 21 October\",\n \"tag\": \"incident-2026-10-21\",\n \"expectedTotalAmount\": 1830220.5\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/{jobId}/confirm")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"US-open outage, 21 October\",\n \"tag\": \"incident-2026-10-21\",\n \"expectedTotalAmount\": 1830220.5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews/{jobId}/confirm")
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\": \"US-open outage, 21 October\",\n \"tag\": \"incident-2026-10-21\",\n \"expectedTotalAmount\": 1830220.5\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": 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": "Job not found",
"code": "JOB_NOT_FOUND"
}{
"success": false,
"statusCode": 409,
"error": "Conflict",
"message": "The preview totals 1830220.50, not 1830000.00",
"code": "PREVIEW_NOT_READY"
}{
"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.
Path Parameters
Body
Why the accounts are credited. Recorded on every adjustment, the account activity and the webhook.
3 - 200"US-open outage, 21 October"
Your name for this credit (letters, digits, ., _, :, -); one credit per tag.
3 - 80^[A-Za-z0-9._:-]+$"incident-2026-10-21"
The preview's summary.creditAmount
1830220.5
curl --request POST \
--url https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews/{jobId}/confirm \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"reason": "US-open outage, 21 October",
"tag": "incident-2026-10-21",
"expectedTotalAmount": 1830220.5
}
'import requests
url = "https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews/{jobId}/confirm"
payload = {
"reason": "US-open outage, 21 October",
"tag": "incident-2026-10-21",
"expectedTotalAmount": 1830220.5
}
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: 'US-open outage, 21 October',
tag: 'incident-2026-10-21',
expectedTotalAmount: 1830220.5
})
};
fetch('https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews/{jobId}/confirm', 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/{jobId}/confirm",
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' => 'US-open outage, 21 October',
'tag' => 'incident-2026-10-21',
'expectedTotalAmount' => 1830220.5
]),
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/{jobId}/confirm"
payload := strings.NewReader("{\n \"reason\": \"US-open outage, 21 October\",\n \"tag\": \"incident-2026-10-21\",\n \"expectedTotalAmount\": 1830220.5\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/{jobId}/confirm")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"US-open outage, 21 October\",\n \"tag\": \"incident-2026-10-21\",\n \"expectedTotalAmount\": 1830220.5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hyperprop.com/platform/v1/organization/balance-adjustments/previews/{jobId}/confirm")
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\": \"US-open outage, 21 October\",\n \"tag\": \"incident-2026-10-21\",\n \"expectedTotalAmount\": 1830220.5\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": 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": "Job not found",
"code": "JOB_NOT_FOUND"
}{
"success": false,
"statusCode": 409,
"error": "Conflict",
"message": "The preview totals 1830220.50, not 1830000.00",
"code": "PREVIEW_NOT_READY"
}{
"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"
}