API reference

Every Forex Investment endpoint — customer and admin — with the permission each admin route gates on, the KYC feature each money route asserts, the tables behind them and the enums they accept.

3 min readUpdated 3 August 2026api, endpoints, permissions, tables, enums

Two API surfaces. Everything under /api/forex is scoped to the calling customer and carries no permission — it is gated by KYC features instead. Everything under /api/admin/forex carries an explicit permission.

Conventions

The platform pins the HTTP status at 200 and puts the real outcome in the body. Read the body, always. A withdrawal approval that was refused because it would breach the customer's cap comes back with a 200 and a message saying so; a client branching on the status code renders it as a green toast over money that never moved.

Two more things that catch integrators:

  • Amounts are DOUBLE, not decimal. Do not use them for exact accounting arithmetic without rounding deliberately.
  • An investment carries no currency. The unit of account is on the plan it was bought against. Any sum over forex_investment.amount without a group by the plan's currency is a number that does not exist.
  • Profit is signed at settlement, but only since v6.1.2. Rows settled before that hold a loss as a positive number beside a LOSS result. Apply CASE WHEN result = 'LOSS' THEN -ABS(profit) ELSE profit END to anything you sum.

Customer endpoints

Public

GET/api/forex/landing
Landing-page payload: statistics, featured plans, six months of performance, signals, recent completions
GET/api/forex/stats
Platform statistics: active investors, invested capital per currency, average return

Both are unauthenticated. Money totals on each are grouped by the plan's currency with the largest pool headlined and named; the average return is a mean of per-row ratios, so it stays valid on a mixed-currency install.

Plans and durations

GET/api/forex/plan
Enabled plans only, with filtering, search and sorting
GET/api/forex/plan/{id}
One plan
GET/api/forex/plan/{id}/duration
The durations this plan actually offers
GET/api/forex/duration
Every duration on the platform, ordered HOUR, DAY, WEEK, MONTH then ascending

The plan list accepts activeTab (all or trending), search, minProfit, maxInvestment and sortBy (popularity, profit or minInvestment). It excludes defaultProfit, defaultResult and status from every response, so the configured outcome is never visible to the buyer, and it computes an invested total per plan which is what popularity sorts by.

GET /api/forex/duration returns every duration on the platform. Only the ones returned by GET /api/forex/plan/{id}/duration can actually be used against that plan — anything else is refused at investment time.

Accounts

GET/api/forex/account
The caller's DEMO and LIVE accounts, provisioning whichever is missing
GET/api/forex/account/{id}
One account the caller owns
POST/api/forex/account/{id}/deposit
Fund a LIVE account from a wallet. Settles immediately
POST/api/forex/account/{id}/withdraw
Request a withdrawal to a wallet. Creates a PENDING transaction
GET/api/forex/account/{id}/signal
The signals assigned to this account

The account list is a read that writes: it provisions any missing account type on first access, claiming an unowned row of that type if one exists and creating an inactive empty one otherwise. LIVE provisioning is skipped — silently, and without failing the request — for a customer who does not hold create_forex_account.

Deposit body: type (wallet type), currency, amount, requestNonce (8–128 characters, required), and optionally chain. Withdraw body is the same without the nonce.

Both are rate-limited to five per minute.

Investments

GET/api/forex/investment
The caller's investments, paginated and filterable
GET/api/forex/investment/active
Only the ACTIVE ones
POST/api/forex/investment
Open an investment. Requires planId, durationId, amount and acceptTerms
GET/api/forex/investment/{id}
One investment in full, with its plan and duration
PUT/api/forex/investment/{id}/status
One investment's status. Reads only, despite the verb

Creation is rate-limited to ten per hour. acceptTerms must be true; the acceptance time and terms version are stored on the investment.

Everything else

GET/api/forex/transaction
The caller's forex transactions only — deposits and withdrawals
GET/api/forex/overview
The caller's dashboard: totals, chart data, plan distribution, recent investments
GET/api/forex/signal
The caller's signals across every account they hold, paginated

KYC gates on customer routes

Feature Guards
deposit_forex POST /api/forex/account/{id}/deposit
withdraw_forex POST /api/forex/account/{id}/withdraw
invest_forex POST /api/forex/investment
create_forex_account Provisioning a LIVE account on GET /api/forex/account

Admin endpoints

Dashboard

GET/api/admin/forexpermission: access.forex
Every dashboard figure: per-currency pools, registry counts, chart data, recent investments

Accepts timeframe of 1m, 3m or 1y, which scopes the volume chart only.

Accounts

GET/api/admin/forex/accountpermission: view.forex.account
All forex accounts
POST/api/admin/forex/accountpermission: create.forex.account
Create an account. Refused if the user already has one of that type
GET/api/admin/forex/account/{id}permission: view.forex.account
One account
PUT/api/admin/forex/account/{id}permission: edit.forex.account
Update an account
DELETE/api/admin/forex/account/{id}permission: delete.forex.account
Delete one account
DELETE/api/admin/forex/accountpermission: delete.forex.account
Delete a selection
PUT/api/admin/forex/account/{id}/statuspermission: edit.forex.account
Toggle one account's status
PUT/api/admin/forex/account/statuspermission: edit.forex.account
Toggle a selection's status
PUT/api/admin/forex/account/{id}/signalpermission: edit.forex.account
Replace the signals assigned to an account. Send the complete list

Plans

GET/api/admin/forex/planpermission: view.forex.plan
All plans
POST/api/admin/forex/planpermission: create.forex.plan
Create a plan, with its durations
GET/api/admin/forex/plan/{id}permission: view.forex.plan
One plan
PUT/api/admin/forex/plan/{id}permission: edit.forex.plan
Update a plan. Re-runs the numeric validation
DELETE/api/admin/forex/plan/{id}permission: delete.forex.plan
Delete one plan. Refused while active investments use it
DELETE/api/admin/forex/planpermission: delete.forex.plan
Delete a selection
PUT/api/admin/forex/plan/{id}/statuspermission: edit.forex.plan
Toggle one plan's status
PUT/api/admin/forex/plan/statuspermission: edit.forex.plan
Toggle a selection's status

Both write routes reject negative figures, inverted amount limits, inverted profit ranges, and a profit percentage outside the plan's own advertised band. Add ?force=true to a delete for a permanent removal — which is refused while any investment references the plan, settled ones included.

Durations

GET/api/admin/forex/durationpermission: view.forex.duration
All durations
GET/api/admin/forex/duration/optionspermission: view.forex.duration
Durations formatted as pickable options, e.g. "7 DAY"
POST/api/admin/forex/durationpermission: create.forex.duration
Create a duration
GET/api/admin/forex/duration/{id}permission: view.forex.duration
One duration
PUT/api/admin/forex/duration/{id}permission: edit.forex.duration
Update a duration
DELETE/api/admin/forex/duration/{id}permission: delete.forex.duration
Delete one duration. Refused while active investments use it
DELETE/api/admin/forex/durationpermission: delete.forex.duration
Delete a selection

Investments

GET/api/admin/forex/investmentpermission: view.forex.investment
All investments
POST/api/admin/forex/investmentpermission: create.forex.investment
Create an investment. Debits the principal from the user's LIVE account
GET/api/admin/forex/investment/{id}permission: view.forex.investment
One investment
PUT/api/admin/forex/investment/{id}permission: edit.forex.investment
Update an investment. Amount is immutable; status goes through the refunding transition
PUT/api/admin/forex/investment/{id}/statuspermission: edit.forex.investment
Move one investment's status, refunding the principal when it leaves ACTIVE
PUT/api/admin/forex/investment/statuspermission: edit.forex.investment
Move a selection's status, each row in its own transaction
DELETE/api/admin/forex/investment/{id}permission: delete.forex.investment
Delete one investment. Refused while ACTIVE
DELETE/api/admin/forex/investmentpermission: delete.forex.investment
Delete a selection
POST/api/admin/forex/investment/recoverpermission: edit.forex.investment
Re-arm a CANCELLED investment, reclaiming its refund first

Signals

GET/api/admin/forex/signalpermission: view.forex.signal
All signals
POST/api/admin/forex/signalpermission: create.forex.signal
Create a signal. Title and image are both required
GET/api/admin/forex/signal/{id}permission: view.forex.signal
One signal
PUT/api/admin/forex/signal/{id}permission: edit.forex.signal
Update a signal
PUT/api/admin/forex/signal/{id}/statuspermission: edit.forex.signal
Toggle one signal's status
PUT/api/admin/forex/signal/statuspermission: edit.forex.signal
Toggle a selection's status
DELETE/api/admin/forex/signal/{id}permission: delete.forex.signal
Delete one signal
DELETE/api/admin/forex/signalpermission: delete.forex.signal
Delete a selection

Deposits

GET/api/admin/forex/depositpermission: view.forex.deposit
The deposit queue — core transactions of type FOREX_DEPOSIT
PUT/api/admin/forex/deposit/{id}permission: edit.forex.deposit
Reverse a completed deposit. Send status REJECTED
DELETE/api/admin/forex/deposit/{id}permission: delete.forex.deposit
Delete one deposit record
DELETE/api/admin/forex/depositpermission: delete.forex.deposit
Delete a selection

Withdrawals

GET/api/admin/forex/withdrawpermission: view.forex.withdraw
The withdrawal queue — core transactions of type FOREX_WITHDRAW
PUT/api/admin/forex/withdraw/{id}permission: edit.forex.withdraw
Approve or reject. Only COMPLETED or REJECTED; only the description is editable
DELETE/api/admin/forex/withdraw/{id}permission: delete.forex.withdraw
Delete one withdrawal record. Refused while PENDING
DELETE/api/admin/forex/withdrawpermission: delete.forex.withdraw
Delete a selection. Refused if any is PENDING

Tables

Table Holds Notes
forex_plan Plans Soft-deleted (paranoid) — filter deletedAt
forex_duration Terms Soft-deleted
forex_plan_duration Plan-to-duration links The join that scopes a duration to a plan
forex_investment Investments Soft-deleted. Cascades from forex_plan and forex_duration at the database level
forex_account DEMO and LIVE accounts userId is nullable — an unowned row is a claimable pre-provisioned account
forex_signal Signals Soft-deleted
forex_account_signal Account-to-signal links
transaction Deposits and withdrawals Core table. Filter on type

Transaction types written by this addon

Type Written when Status
FOREX_DEPOSIT A customer funds a forex account COMPLETED immediately; REJECTED after a reversal
FOREX_WITHDRAW A customer requests a withdrawal PENDING, then COMPLETED or REJECTED by an admin
FOREX_INVESTMENT An investment is opened COMPLETED — an audit row, not a money movement of its own

Enums

Column Values
forex_account.type DEMO, LIVE
forex_duration.timeframe HOUR, DAY, WEEK, MONTH
forex_investment.status ACTIVE, COMPLETED, CANCELLED, REJECTED
forex_investment.result WIN, LOSS, DRAW
forex_plan.defaultResult WIN, LOSS, DRAW
forex_plan.walletType FIAT or SPOT — anything else cannot be funded

Key columns

Worth knowing if you query directly:

Column Means
forex_plan.profitPercentage What settlement actually pays
forex_plan.defaultProfit A fallback percentage, used only when profitPercentage is unusable
forex_plan.minProfit / maxProfit The advertised band. Validation only — not paid
forex_plan.status false means invisible to customers and closed to new money
forex_account.currency / walletType The binding, set by the account's first movement. null means unbound
forex_account.dailyWithdrawn / monthlyWithdrawn Counters, advanced on approval
forex_account.lastWithdrawReset / lastMonthlyWithdrawReset Independent window anchors
forex_investment.roiPercentage Written at settlement. Preferred over the plan when present
forex_investment.profit The signed effect on the principal
forex_investment.metadata On a cancelled investment, carries principalRefunded
forex_investment.termsAcceptedAt / termsVersion Stored at creation

The cron

Job Category Every
processForexInvestments forex 1 hour

It can be triggered manually from /admin/system/cron. Doing so while the scheduled tick is running is safe — every settlement is a conditional update on a locked row, so a duplicate run pays nothing.