Getting started with MetaKit

6 min readMetaKit

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:

TierWhat it allows
readonlyRead account data, trades, analytics, and market data. Trade endpoints are rejected.
fullEverything 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/slots does 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:

StatusMeaning
provisioningPreparing a broker-specific terminal image
startingConnecting to the broker
connectedReady — all endpoints work
errorCould not connect, or lost the connection
invalid_credentialsThe broker rejected the login
disconnectedStopped

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].