Skip to content

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_login must 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_group must exist and have account_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