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

Landing-page payload: statistics, featured plans, six months of performance, signals, recent completions
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

Enabled plans only, with filtering, search and sorting
One plan
The durations this plan actually offers
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

The caller's DEMO and LIVE accounts, provisioning whichever is missing
One account the caller owns
Fund a LIVE account from a wallet. Settles immediately
Request a withdrawal to a wallet. Creates a PENDING transaction
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

The caller's investments, paginated and filterable
Only the ACTIVE ones
Open an investment. Requires planId, durationId, amount and acceptTerms
One investment in full, with its plan and duration
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

The caller's forex transactions only — deposits and withdrawals
The caller's dashboard: totals, chart data, plan distribution, recent investments
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

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

All forex accounts
Create an account. Refused if the user already has one of that type
One account
Update an account
Delete one account
Delete a selection
Toggle one account's status
Toggle a selection's status
Replace the signals assigned to an account. Send the complete list

Plans

All plans
Create a plan, with its durations
One plan
Update a plan. Re-runs the numeric validation
Delete one plan. Refused while active investments use it
Delete a selection
Toggle one plan's status
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

All durations
Durations formatted as pickable options, e.g. "7 DAY"
Create a duration
One duration
Update a duration
Delete one duration. Refused while active investments use it
Delete a selection

Investments

All investments
Create an investment. Debits the principal from the user's LIVE account
One investment
Update an investment. Amount is immutable; status goes through the refunding transition
Move one investment's status, refunding the principal when it leaves ACTIVE
Move a selection's status, each row in its own transaction
Delete one investment. Refused while ACTIVE
Delete a selection
Re-arm a CANCELLED investment, reclaiming its refund first

Signals

All signals
Create a signal. Title and image are both required
One signal
Update a signal
Toggle one signal's status
Toggle a selection's status
Delete one signal
Delete a selection

Deposits

The deposit queue — core transactions of type FOREX_DEPOSIT
Reverse a completed deposit. Send status REJECTED
Delete one deposit record
Delete a selection

Withdrawals

The withdrawal queue — core transactions of type FOREX_WITHDRAW
Approve or reject. Only COMPLETED or REJECTED; only the description is editable
Delete one withdrawal record. Refused while PENDING
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.