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
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"
}'
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 wallet state between drills when needed
- do not use simulator evidence as proof of real operator wallet readiness
