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`.
Authorization
appToken writeApp 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" } ] }}