WebAPI
Brief
The CPlugin Cloud WebAPI is a JSON API that lets you manage MT4/MT5 servers from any HTTP-enabled client. It has two faces sharing the same authentication: a RESTful interface for request/response calls and a realtime SignalR endpoint (Web Sockets, Long Polling and other transports) for streaming data — quotes, margin updates, online users and open orders as they happen.
v2 is in production, at cloud.mywebapi.com, and is what this page walks you through. Every v2 response is the same envelope — { data, error, meta } — over /api/v2/… paths.
Get set up in Toolbox — once
Everything below happens once per project, not per script or per call. Credentials and platform registration outlive any single integration.
- Create your Toolbox account. Sign in at toolbox.cplugin.com (or pre.toolbox.cplugin.com for the free Sandbox — no billing, no SLA, no time limit).
- Register your trade platform. In Toolbox, click Add platform in the sidebar, name it and pick MT4 or MT5. Open its settings page and enter your MT4/MT5 manager connection — address, login, password. This is the only place that connection lives; the WebAPI reaches your server through it.
- Create an API client. Go to WebAPI → API Clients and create one. The client secret is shown only once — copy both it and the client id somewhere safe (a secret manager, not a chat log).
That's your setup done. Every SDK call and every script from here on just reuses that same client id/secret.
Three steps to your first call
The fastest way in is the official SDK for your language: it handles OAuth2 (token discovery, caching, refresh), retries and typing, so you skip the raw HTTP plumbing.
TypeScript / JavaScript
0.3.0 · npm: @mywebapi.com/sdk · repo: CPlugin/mywebapi.com-sdk-js
.NET
0.3.0 · NuGet: MyWebApi.Sdk · repo: CPlugin/mywebapi.com-sdk-dotnet
PowerShell
0.3.0 · Gallery: MyWebApi · repo: CPlugin/mywebapi.com-sdk-powershell
Python
0.3.0 · PyPI: mywebapi-sdk · repo: CPlugin/mywebapi.com-sdk-py
0.x — minor releases may still break compatibility, so pin an exact version.1. Install.
TypeScript / JavaScript:
bun add @mywebapi.com/sdk
.NET:
dotnet add package MyWebApi.Sdk
PowerShell:
Install-Module MyWebApi -Scope CurrentUser
Python (3.10 or later; the import name is cplugin_webapi_sdk):
pip install mywebapi-sdk
2. Construct the client with your Toolbox credentials, and make a call. Environment presets (prod / staging) resolve the right host for you — no URLs to remember.
TypeScript / JavaScript:
import { CPluginWebApiClient } from '@mywebapi.com/sdk'
const client = new CPluginWebApiClient({
env: 'prod', // or 'staging' for the Sandbox
clientId: process.env.CPLUGIN_WEBAPI_CLIENT_ID!,
clientSecret: process.env.CPLUGIN_WEBAPI_CLIENT_SECRET!,
})
const tp = 'your-tradeplatform-uuid' // from Toolbox → your platform's settings page
const time = await client.mt4.getServerTime(tp)
console.log('MT4 server time:', time)
.NET:
using CPlugin.SaaSWebApi.Client;
using var client = new CPluginWebApiClient(CPluginEnvironment.Prod, clientId, clientSecret);
var platforms = await client.ListTradePlatformsAsync();
var tp = Guid.Parse(platforms[0]!["id"]!.GetValue<string>());
var mt4 = client.MT4(tp);
var time = await mt4.ServerTimeAsync();
Console.WriteLine($"MT4 server time: {time}");
PowerShell:
$secret = ConvertTo-SecureString $env:CPLUGIN_WEBAPI_CLIENT_SECRET -AsPlainText -Force
$session = Connect-MyWebApi -Environment Production -ClientId $env:CPLUGIN_WEBAPI_CLIENT_ID -ClientSecret $secret
$tp = (Get-MyWebApiTradePlatform -Connection $session)[0].id
Get-MT4ServerTime -Connection $session -TradePlatform $tp
Python:
import os
from cplugin_webapi_sdk import CPluginWebApiClient
with CPluginWebApiClient(
env="prod", # or "staging" for the Sandbox
client_id=os.environ["CPLUGIN_WEBAPI_CLIENT_ID"],
client_secret=os.environ["CPLUGIN_WEBAPI_CLIENT_SECRET"],
) as client:
tp = "your-tradeplatform-uuid" # from Toolbox → your platform's settings page
time = client.mt4.get_server_time(tp)
print("MT4 server time:", time)
3. You're good to go. Token acquisition, caching and refresh all happen inside the client you just built — call any other v2 method on mt4/mt5 (or the matching cmdlet) the same way, and reuse the same client/session for the rest of your integration.
Errors surface as a typed ApiError (TS/.NET) or from the error field the cmdlets unwrap for you, carrying a stable code and an activityId for support.
Authentication, without the SDK
The WebAPI uses OAuth2 (Client Credentials flow): exchange your client id/secret for a bearer token at auth.cplugin.net, then present it on every REST call and SignalR connection. See Authorization for the raw HTTP flow if you're not using one of the SDKs above.
Each MT4/MT5 server you registered in Toolbox is identified by a trade platform id; pass it wherever a v2 method requires one.
REST
Rooted at https://cloud.mywebapi.com, versioned in the path (/api/v2/…). Every request carries the bearer token in the Authorization header.
curl https://cloud.mywebapi.com/api/v2/MT4/{tradePlatform}/ServerTime \
-H "Authorization: Bearer $ACCESS_TOKEN"
The full v2 method catalogue — request/response schemas and a "try it" console — lives in the v2 Swagger reference.
Timeouts and retries
Every request addressed to a trade platform has a deadline. If the MT4/MT5 server does not answer in time, you get a response anyway — you never wait minutes on a request that hangs inside the trading server.
| Kind of operation | Default timeout | Examples |
|---|---|---|
| Trade operation | 5 s | TradeTransaction, DealerSend, DealerBalance, balance fixes |
| Read | 10 s | users, accounts, groups, symbols, margin levels |
| Change | 15 s | creating or updating users, groups, symbols, configuration |
| History and reports | 30 s | trade history, deals, journal, charts, ticks, reports |
| Server maintenance | 60 s | restarts, backups, synchronisation, external commands |
The Swagger reference shows the default of each operation.
Setting your own timeout
Send the X-Request-Timeout header with a number of seconds from 1 to 300 — shorter for a latency-sensitive screen, longer for a big report. Clients that cannot set headers can use the requestTimeout query parameter instead. The value actually applied comes back in the X-Request-Timeout-Applied response header.
curl https://cloud.mywebapi.com/api/v2/MT4/{tradePlatform}/UserRecordsRequest \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "X-Request-Timeout: 20"
In the SDKs (0.3.0 and later) it is an option of every call, with a client-wide default:
| SDK | Per call | Client-wide default |
|---|---|---|
| TypeScript / JavaScript | { requestTimeout: 20 } (seconds) as the last argument | requestTimeout in the client options |
| .NET | new CallOptions { RequestTimeout = TimeSpan.FromSeconds(20) } | CPluginWebApiClientOptions.RequestTimeout |
| PowerShell | -RequestTimeout 20 on any cmdlet | Connect-MyWebApi -RequestTimeout 20 |
| Python | request_timeout=20 | request_timeout of the client |
The SDKs wait for the server's answer about 30 seconds longer than the timeout they send, because opening the connection to the trading server may extend the server's deadline. Their errors expose the outcome (OutcomeUnknown, Timeout, Busy and the X-Request-Outcome value) and helpers that tell whether a repeat is safe. No SDK repeats a trade or a change by itself. Without an SDK, keep your HTTP client's own timeout about 30 seconds longer than the value you send, so that you receive the server's answer instead of cutting the connection yourself.
What a timeout means
| Situation | v2 error.code | v1 status | X-Request-Outcome | Safe to repeat? |
|---|---|---|---|---|
| A read did not complete in time | Timeout | 504 | timeout | Yes — nothing was changed |
| A trade or change did not complete in time | OutcomeUnknown | 504 | unknown | Not blindly — see below |
| Too many requests are already waiting for this trade platform | Busy | 503 | not-started | Yes — it was not sent to the server |
| A request with the same idempotency key is still being processed | OutcomeUnknown | 409 | in-progress | Yes, with the same key — see below |
OutcomeUnknown does not mean the operation failed. The trading server may still complete it after the deadline. Repeating a trade blindly can execute it twice. Check the result first — the account's orders, positions or balance, or the record you changed — or repeat it with the same idempotency key.Repeating trades safely: idempotency keys
Send an Idempotency-Key header (any unique string up to 255 characters, for example a GUID you generate per operation) with every trade or change you might need to repeat. The server executes a key only once:
- the first request with the key is executed;
- while it is still running, a request with the same key is not executed again — it gets
in-progress(v1409, v2OutcomeUnknown); - once the first request has finished, a request with the same key gets its original result, without executing it again — even if the first caller had already received
OutcomeUnknown; - a timed-out read,
Busy, a temporary connection error or an error response do not keep the key, so repeating with the same key executes the request again; - the result of an operation that finished after its caller got
OutcomeUnknownis kept for the key for at least one hour after it finished; an answer delivered in time is kept for one minute, or forcacheTimeoutseconds if you send that query parameter; - if the outcome of a timed-out operation cannot be determined, the key stays taken for one hour — check the outcome yourself and use a new key;
- keys are private to your API client and to the operation: the same key value used by another client, or on another operation of yours, is a different key;
- if the key cannot be recorded at the moment, a change is refused without being executed (
Busy, v1503,X-Request-Outcome: not-started) — repeat it with the same key.
So the reliable way to repeat a trade after OutcomeUnknown is: wait a moment, then send exactly the same request with the same Idempotency-Key.
Realtime calls
SignalR hub calls addressed to a trade platform, and connecting to the v2 hubs, fail with an error after 60 s. Streams are not limited — they run as long as you are subscribed.
Realtime
Realtime data uses SignalR over Web Sockets (with Long Polling and other transports as fallback): a two-way connection so updates arrive automatically once you subscribe — no polling. Ticks, margin updates, trade events, user and symbol updates all stream this way, with automatic reconnection handled inside the SDKs.
Connect to the v2 hub (mt4 or mt5), passing the trade platform id and bearer token:
const connection = new signalR.HubConnectionBuilder()
.withUrl(`https://cloud.mywebapi.com/hubs/mt4/v2?tradePlatform=${tp}`, {
accessTokenFactory: () => access_token,
})
.build()
await connection.start()
for await (const tick of connection.stream('StreamTicks', 'EURUSD')) {
console.log(tick)
}
The SDKs wrap this behind typed helpers (streamTicks, StreamTicksAsync, Connect-MT4Realtime + Register-MT4Realtime) so you rarely need to touch the hub directly.
Environments & pricing
There are two environments; the free Sandbox is the staging environment — a full-featured copy of production with no billing and no SLA. Build and test as long as you need; billing starts only when you connect to production.
| Component | Sandbox (staging) | Production |
|---|---|---|
| Toolbox | pre.toolbox.cplugin.com | toolbox.cplugin.com |
| WebAPI | pre.mywebapi.com | cloud.mywebapi.com |
Point the SDK at the Sandbox with the staging environment preset while you build, then switch to prod. See Pricing and terms for what you pay on production.
Firewall settings
Whitelist the source IP addresses below in your MT4/MT5 firewall settings so the WebAPI can reach your servers without being blocked:
| IP | DNS |
|---|---|
142.132.146.30 | m3.mywebapi.com |
157.90.214.22 | m4.mywebapi.com |
5.223.43.1 | m9.mywebapi.com |
88.99.65.181 | pre.mywebapi.com |
Cloud
We run a swarm of WebAPI instances to minimise latency, increase uptime and spread load. A DNS traffic manager resolves cloud.mywebapi.com to the instance closest to you (lowest ping); if any instance goes down you are automatically routed to another within a second. We regularly analyse usage and can spin up an additional server in the region of any customer who would benefit.

