POST Buy Prop Challenge¶
Endpoint¶
POST /prop/challenge/buy
Description¶
Buys and activates a prop challenge in one request.
The server validates the payer account, creates a purchase record, enqueues the
challenge fee withdrawal, opens the first phase account in steps[0].account_group,
enqueues the initial challenge balance from that group's default_deposit, and
creates an active challenge record.
The initial balance is applied asynchronously. The new account remains read-only until its balance and equity reflect the configured deposit; the server then creates the runtime phase and its initial metric snapshot and enables trading. Therefore, a successful response with an active purchase and challenge does not guarantee that the phase row or first metric is already available. During this short funding-initialization interval, existing challenge reads may show no phase rows and metrics may be empty. Poll the existing challenge and metric endpoints for readiness instead of treating the temporary absence as a failed purchase. No response fields are added for this state.
Authorization¶
Available for authenticated customer sessions.
Request Parameters¶
| Name | Type | Required | Description |
|---|---|---|---|
program_id |
int | Yes | Active prop program id |
payer_login |
int | Yes | Customer account used as payer |
idempotency_key |
string | No | Retry key that prevents duplicate purchases |
Validation:
- program must be active
payer_loginmust belong to the authenticated customer- payer account must be enabled
- payer account group must have
account_mode = REAL - program currency must match payer account group currency
- payer balance must be greater than or equal to program price
- program must have at least one configured step
- first step
account_groupmust exist and haveaccount_mode = DEMO
Request Example¶
POST /prop/challenge/buy
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"program_id": 1,
"payer_login": 100001,
"idempotency_key": "3c68d3bf-d42c-4a6d-9a4c-80d5c3439f44"
}
Response Example¶
{
"accepted": true,
"idempotent": false,
"purchase": {
"id": 10,
"program_id": 1,
"customer_id": 5,
"payer_login": 100001,
"account_login": 2000100,
"status": 3,
"status_name": "active",
"next_action": "OPEN_CHALLENGE",
"can_retry": false,
"can_cancel": false,
"amount": 499.0,
"currency": "USD",
"conversion_rate": 1.0,
"amount_account_currency": 499.0,
"comment": "PROP_CHALLENGE_PURCHASE_ACTIVE",
"idempotency_key": "3c68d3bf-d42c-4a6d-9a4c-80d5c3439f44",
"payment_status": "paid",
"activation_status": "active",
"failure_reason": "",
"created_time": 1778160000,
"updated_time": 1778160000
},
"challenge": {
"id": 12,
"purchase_id": 10,
"program_id": 1,
"customer_id": 5,
"account_login": 2000100,
"current_phase_index": 1,
"status": 1,
"start_time": 1778160000,
"end_time": 0,
"created_time": 1778160000,
"updated_time": 1778160000
},
"account": {
"login": 2000100,
"group": "PROP-DEMO-100K",
"brand": "brand-a",
"currency": "USD",
"leverage": 100,
"enable": 1,
"customer_id": 5
},
"temporary_password": "a1b2c3d4e5f6",
"must_change_password": true,
"payment_order": 500100,
"initial_balance_order": 500101
}
If the same idempotency_key is sent again by the same customer, the server
returns the existing purchase with idempotent = true and related challenges.
Financial Operations¶
The request creates finance operations with reason = TR_REASON_PROP.
| Operation | Account | Command | Amount sign | Comment |
|---|---|---|---|---|
| Challenge fee | payer_login |
OP_BALANCE_OUT |
negative program price | PROP_CHALLENGE_PURCHASE |
| Initial challenge balance | created challenge account | OP_BALANCE_IN |
positive group default_deposit |
PROP_CHALLENGE_INITIAL_BALANCE |
| Payment rollback | payer_login |
OP_BALANCE_IN |
positive program price | PROP_CHALLENGE_PURCHASE_ROLLBACK |
| Initial balance rollback | created challenge account | OP_BALANCE_OUT |
negative group default_deposit |
PROP_CHALLENGE_INITIAL_BALANCE_ROLLBACK |
Finance api_data includes module, operation, program_id, purchase_id,
customer_id, payer_login, challenge_login, and idempotency_key.
For free programs (price = 0), payment_order is omitted and no fee
withdrawal/rollback operation is created.
Error Responses¶
| Code | Error | Description |
|---|---|---|
400 |
PROGRAM_DISABLED |
Program is not active |
400 |
INVALID_DEMO_GROUP |
Program demo group was not found |
400 |
DEMO_GROUP_REQUIRED |
Program demo group is not a DEMO group |
400 |
PAYER_ACCOUNT_NOT_REAL |
Payer account is not a REAL account |
400 |
CURRENCY_CONVERSION_REQUIRED |
Program and payer currencies do not match |
400 |
NOT_ENOUGH_FUNDS |
Payer balance is insufficient |
4xx/5xx |
PAYMENT_FAILED |
Fee withdrawal request was not accepted |
4xx/5xx |
ACCOUNT_CREATION_FAILED |
Challenge account was not created; payment rollback is requested |
4xx/5xx |
INITIAL_BALANCE_FAILED |
Initial balance was not requested; payment rollback is requested |
4xx/5xx |
CHALLENGE_CREATION_FAILED |
Challenge record was not created; payment and initial balance rollback are requested |
403 |
INVALID_PAYER_ACCOUNT |
Payer account does not belong to customer or is disabled |