MetaKit gives you a REST API for MetaTrader 5. You connect an MT5 account once, and everything after that is HTTP — balances, trade history, live positions, tick data, copy trading, and webhooks. No Windows VPS, no terminal process to keep alive.
This guide takes you from a new account to your first working API call. It takes about ten minutes, most of which is waiting for a terminal to connect.
The one concept to understand first
Almost everything in MetaKit hangs off a single idea: a slot is a paid seat, and connecting an MT5 account occupies one.
- Buy a slot → you have an empty seat.
- Connect an MT5 account → it fills the seat.
- Disconnect the account → the seat is free again, and you can put a different account in it.
Two tiers, and the choice matters because it decides what the account can do:
| Tier | What it allows |
|---|---|
readonly | Read account data, trades, analytics, and market data. Trade endpoints are rejected. |
full | Everything above, plus placing and modifying trades. Required for an account to be a copier follower. |
Disconnecting an account frees its slot but does not cancel the subscription — you keep the seat and can reuse it. Cancelling a slot is a separate, deliberate action, and it is refused while an account still occupies it.
Step 1: create your account
Sign up at app.metakit.cloud. You'll be asked to verify your email address — do that before continuing, since some notifications depend on a confirmed address.
Onboarding then walks you through four steps: terms, your profile, choosing a plan, and connecting your first account. You can skip the last two and do them later from the dashboard.
Step 2: buy a slot
In the dashboard, go to Settings → Billing. Pick a tier and complete checkout.
A few things worth knowing:
- The first purchase asks for a card. Later purchases reuse the saved card with no re-entry.
- A slot starts a monthly subscription, one per slot.
- If you need to buy slots programmatically — provisioning seats for your own
customers, say —
POST /v1/slotsdoes that, but it requires a card already on file. An API client can't render a card form, so the first one has to be added in the dashboard.
Step 3: connect an MT5 account
From Accounts, choose Add account. You'll need four things:
- Login number — the numeric MT5 account ID
- Password — investor (read-only) or master password
- Broker — search by name; this fills in the broker ID
- Server — must match the broker's server name exactly, e.g.
ICMarketsSC-Demo
Use an investor password if you only need to read data. It cannot place trades, which makes it the safer credential to hand to any system.
Connecting takes a minute — that's normal
MetaKit runs a real, isolated MT5 terminal per account. Starting one takes roughly 30 seconds, and can take several minutes the first time an unusual broker is used, because a broker-specific terminal image has to be prepared.
The account moves through these states:
| Status | Meaning |
|---|---|
provisioning | Preparing a broker-specific terminal image |
starting | Connecting to the broker |
connected | Ready — all endpoints work |
error | Could not connect, or lost the connection |
invalid_credentials | The broker rejected the login |
disconnected | Stopped |
provisioning and starting are both normal. Wait for connected before
expecting data — market-data endpoints return 502 until then.
If you land on invalid_credentials, the login itself is wrong: check the
password type and the exact server string. Retrying won't help.
Step 4: create an API key
Go to Settings → API keys → Create API Key. Two choices matter:
Scope. Pick readonly unless you genuinely need to write. A read-only key
can only make GET requests; a write attempt returns 403 insufficient_scope.
This is the single most useful safety setting in the product — especially if
the key goes into a script, a CI job, or an AI agent.
Expiry. Presets from 30 days to a year, a custom date, or no expiry. Prefer a fixed expiry for anything you hand to a third-party tool.
The full key is shown once, at creation. Copy it then — only a prefix and last four characters are stored afterwards.
export METAKIT_KEY="stk_live_..."Note the key scope and the slot tier both use the words "readonly" and "full",
but they are different gates and both apply. A full key still cannot trade on
an account connected to a readonly slot.
Step 5: your first API call
Check what you're working with:
curl https://api.metakit.cloud/v1/accounts \
-H "Authorization: Bearer $METAKIT_KEY"{
"data": [
{
"id": 2,
"account_name": "My Account",
"account_number": 40317,
"status": "connected",
"currency": "USD",
"balance": 406944.0,
"equity": 406944.0,
"open_trades": 3
}
],
"page": 1,
"limit": 25,
"total": 1
}That id — a small integer, not a UUID — is what you use everywhere else.
Reading trade history
curl "https://api.metakit.cloud/v1/accounts/2/deals?from=2026-01-01&limit=50" \
-H "Authorization: Bearer $METAKIT_KEY"Live open positions
curl https://api.metakit.cloud/v1/accounts/2/positions \
-H "Authorization: Bearer $METAKIT_KEY"Computed performance
This one is worth knowing about early, because it saves real work:
curl https://api.metakit.cloud/v1/accounts/2/performance \
-H "Authorization: Bearer $METAKIT_KEY"It returns Sharpe ratio, maximum drawdown, win rate, profit factor, and a daily equity series — computed server-side from closed positions. You don't have to pull thousands of raw deals and reduce them yourself.
Everything belonging to an account nests under it:
/v1/accounts/{id}/positions, /v1/accounts/{id}/candles, and so on. The
account is always part of the path, never a query parameter.
Step 6: stop polling, use webhooks
Polling works, but webhooks are better for anything long-lived. Register an endpoint under Settings → Webhooks and you'll receive events as they happen:
- Account —
account.connected,account.error,account.deleted - Trade —
position.opened,position.closed,position.modified,order.placed,order.filled,order.cancelled - Copier —
copier.trade_copied,copier.trade_skipped,copier.orphan,copier.error
Every delivery is signed with HMAC-SHA256. Verify the X-MetaKit-Signature
header against your endpoint's secret before trusting a payload — the
webhook documentation has a copy-paste
verification snippet for Node and Python.
Waiting for account.connected is much nicer than polling a status field every
five seconds.
Common first-time problems
502 upstream_error on every market-data call. The account isn't
connected. Check its status first — this is the single most common cause.
403 insufficient_scope. A read-only key tried to write. Create a full
key, or reconsider whether that code should be writing at all.
401 key_expired. The key passed its expiry date. Create a new one.
402 no_slots_available. No free slot of the requested tier. Either buy
another, or disconnect an account to free the one you have.
Account stuck on invalid_credentials. Wrong password type or server
string. Investor and master passwords are different; the server name must match
the broker's exactly.
Where to go next
- Connect an account from Python — the same flow in code, with proper status handling.
- API documentation — the full endpoint reference.
- llms.txt — the complete API written for coding agents. If you're building with an AI assistant, point it here and it will have everything it needs.
If you get stuck, email [email protected].