Simulator
Simulator
Simulator tools let operators test launch, trade, redemption, webhook, and wallet-adjustment flows in staging without touching the real operator wallet for simulator-tagged users.
When simulator works now
Simulator is staging/local only and user-scoped.
- normal staging users still use the operator's real
balance_adapter_type, usuallyrest_v1 - dedicated simulator-user APIs set and preserve
metadata.simulator = true - launch metadata cannot set, clear, or override simulator classification
- simulator endpoints operate only on server-classified simulator users
- production returns
404 SIMULATOR_DISABLED
Reserve a fresh external user ID: simulator upserts reject an ID belonging to a normal user with 409 EXTERNAL_USER_ID_NOT_AVAILABLE_FOR_SIMULATION. Direct balance replacement does not erase idempotency history; use new keys for new drills, and preserve old keys for repeats of the same operation.
Main endpoints
GET /api/operator/simulator/usersPOST /api/operator/simulator/usersGET /api/operator/simulator/users/{id}PATCH /api/operator/simulator/users/{id}POST /api/operator/simulator/users/{id}/operationsGET /api/operator/simulator/wallets/{externalUserId}PUT /api/operator/simulator/wallets/{externalUserId}POST /api/operator/simulator/operations
See full contract at /docs/operator-api/simulator.
Recommended flow
- Create the simulator user through Simulator Users or the dedicated simulator-user API; it forces the server-side classification.
- Set the starting simulator wallet balance.
- Launch the same
external_user_id; do not sendmetadata.simulatoras a routing control. - Choose Opinion or enabled Polyflight and follow the real launch URL.
- Confirm product, wallet-operation, ticket/trade, and webhook evidence.
- Run the required payout/refund/compensation or Opinion sell/redemption flow.
The separate operator simulator's Webhooks page shows Opinion delivery attempts with webhooks:read; its Beacon API key must also have polyflight:read to include Polyflight delivery attempts. A key lacking that scope still shows Opinion attempts and an explicit Polyflight limitation. Received signed callbacks remain visible separately. Ensure Beacon Endpoint creates or reactivates the simulator receiver endpoint and synchronizes its signing secret after rotation, without changing saved event subscriptions or unrelated URLs. Edit subscriptions explicitly if needed. Inspect camelCase Polyflight monetary snapshots as exact integer IDR minor units (no scaling or FX conversion) and distinguish owed payouts/refunds from confirmed credits. Opinion trade callbacks report balance_spent; interpret with trade side/status rather than assuming a completed debit. Replay an already acknowledged 2xx only after confirming durable event_id deduplication.
Example wallet setup
curl -X PUT "$BASE_URL/api/operator/simulator/wallets/test-user-001" \
-H "Authorization: Bearer ***" \
-H "Content-Type: application/json" \
-d '{
"balance_minor": 500000
}'
Example simulator mutation
curl -X POST "$BASE_URL/api/operator/simulator/operations" \
-H "Authorization: Bearer ***" \
-H "Content-Type: application/json" \
-d '{
"external_user_id": "test-user-001",
"direction": "debit",
"amount_minor": 10000,
"idempotency_key": "simulator:drill:001"
}'
This direct adjustment changes simulated balance only. It does not create a trade/ticket, settle a result, or emit that product's business webhook. To inspect those effects, use the real launched product flow with the dedicated simulator user.
Controlled HTTP wallet drills
The separate Operator Simulator's user wallet drill offers off, debit_applied_then_timeout, credit_applied_then_timeout, and definite_rejection, with dedicated-test-user confirmation before enabling a fault. Its contract-test scenarios also cover identical/conflicting duplicate requests. These settings are not controls in the dashboard Simulator Users form and are not ordinary launch metadata.
The built-in simulator path bypasses external REST v1 transport for simulator users. A separate HTTP wallet drill tests adapter request/response handling; neither substitutes for the operator's own ledger, permanent idempotency, authentication and reconciliation implementation.
What to confirm
- idempotent repeat with same key returns same operation
- resulting statuses match docs in
/docs/reference/statuses - webhook events arrive for completed business actions
Safe usage rules
- use dedicated staging users only
- do not switch the whole operator off
rest_v1just to use simulator drills - keep deterministic
idempotency_keyper drill step - reset simulated balance between independent drills only after reconciling outstanding operations; a reset is not financial resolution and must not clear or reuse recorded idempotency keys
- do not use simulator evidence as proof of real operator wallet readiness
