PaymentPlans

Create Bulk Payment Plan Operation

Sets (`upsert`) or removes (`delete`) the payment plan of every (IB type, trading group, symbol) cell matched by the selection. The IB types are resolved at creation time and frozen in `params.resolved.userGroupIds`; the operation itself runs in the background on the shared `payment_plan_import` queue, so poll the details endpoint for `status`. Rules: - `plan` is required for `upsert` and must be absent for `delete`; it uses the same keys and aliases as the symbol preference API. - The formula must be allowed for the platform provider (`spread` only on MetaTrader 5 / B2Trader). - `percentage` (Markup %) is deprecated and rejected with **422** `invalidPlan`; use `percentage_v2` (Markup % v2). - `ratio` for `spread` and `percentage_v2` must be greater than 0 and less than 100. - `max_amount` requires exactly one IB type; its `levelTable` may not define more levels than that type has. - `planRows` (IB types × live group/symbol pairs) must not exceed the tenant cap returned by the coverage endpoint. Structural validation errors return **400** with field details. Semantic rejections return **422** with a machine-readable `error.code`: `capExceeded`, `emptySelection`, `unknownPlatform`, `unknownUserGroup`, `invalidPlan`, `formulaNotAllowedForProvider`, `maxAmountRequiresSingleUserGroup`, `invalidLevelTable`. A tenant without the River queue provisioned returns **503** with code `queueUnavailable`.

POST
/payment-plans/bulk

Authorization

appToken write
AuthorizationBearer <token>

App access token issued by POST /tokens (client credentials). Full-access Apps hold the read and write scopes, read-only Apps hold read only. Send it as Authorization: Bearer <token>.

In: header

Scope: write

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/payment-plans/bulk" \  -H "Content-Type: application/json" \  -d '{    "action": "upsert",    "selection": {      "platformId": "32a6e381-64f4-4911-86b6-3bf681b64d23"    }  }'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "status": "pending"}
{  "message": "string",  "code": "string",  "errors": {    "property1": [      "string"    ],    "property2": [      "string"    ]  },  "details": [    {      "field": "string",      "issue": "string"    }  ]}
{  "message": "string",  "code": "string",  "errors": {    "property1": [      "string"    ],    "property2": [      "string"    ]  },  "details": [    {      "field": "string",      "issue": "string"    }  ]}
{  "error": {    "message": "This App is read-only and cannot perform this operation.",    "code": "insufficient_scope"  }}
{  "error": {    "message": "string",    "code": "capExceeded",    "details": [      {        "field": "string",        "issue": "string"      }    ]  }}
{  "message": "string",  "code": "string",  "errors": {    "property1": [      "string"    ],    "property2": [      "string"    ]  },  "details": [    {      "field": "string",      "issue": "string"    }  ]}
{  "error": {    "message": "string",    "code": "capExceeded",    "details": [      {        "field": "string",        "issue": "string"      }    ]  }}