# Switching from another provider

> Move an existing MT4/MT5 API integration to Tickwire by changing the base URL and the key, and what differs.

Source: https://tickwire.io/docs/switching/

Tickwire serves two API styles that existing clients already call:

- **The `/users/current/accounts/…` REST API.** Same paths, query parameters, field names and trade
  return codes. Authenticate with the `auth-token` header.
- **The `/v1` API and the terminal routes `/{mt4|mt5}/{id}/…`.** Same routes, field names,
  WebSocket topics and batch order endpoints. Authenticate with `X-API-Key` or `Authorization: Bearer`.

If your code calls one of these over plain HTTP, switching means a new base URL and a Tickwire key.
Other providers' official SDKs are their software under their licences, which can restrict use with
other services, so we don't support pointing them at Tickwire. Call the REST endpoints directly, or use
the Tickwire SDKs.

The examples use `curl`; set these first:

```bash
export TW=https://api.tickwire.io
export TW_KEY=your-api-key
```

## 1. Change the base URL and the key

Keep your HTTP client and send the same requests to Tickwire's host with your Tickwire key.

On the `/users/current/…` routes, the key goes in the same `auth-token` header:

```bash
curl -s "$TW/users/current/accounts/acc_7Qx/account-information" -H "auth-token: $TW_KEY"
```

On the `/v1` and terminal routes, both `X-API-Key` and `Authorization: Bearer` work, and WebSockets
take `?api_key=`:

```diff
- BASE = "https://<your current provider>/v1"
+ BASE = "https://api.tickwire.io/v1"
- KEY  = "<your current key>"
+ KEY  = "<your Tickwire key>"
```

Every endpoint is listed in the [API reference](https://tickwire.io/docs/reference/).

## 2. Re-create your accounts

Broker credentials can't be exported from another provider, so link each account again.

On the `/users/current/…` API, create it with the same `name`, `server`, `login`, `password`,
`magic` and `platform`. Your `tags` and `metadata` carry over as they are. Account creation takes the
`transaction-id` header and answers `202` with `Retry-After` while broker detection runs, so existing
provisioning code keeps its polling logic.

```bash
curl -s -X POST "$TW/users/current/accounts" \
  -H "auth-token: $TW_KEY" \
  -H "transaction-id: $(openssl rand -hex 16)" \
  -H "content-type: application/json" \
  -d '{"name": "my account", "platform": "mt5", "server": "YourBroker-Server",
       "login": "12345678", "password": "your-password", "magic": 1000}'
```

On the `/v1` API, `POST /v1/accounts` takes the same body (`platform`, `server`, `login`, `password`,
`nickname`, …). Each account's `rest_url` and `ws_url` point at Tickwire; keep using them as you do
now. They are `https://api.tickwire.io/{mt4|mt5}/{id}` and
`wss://api.tickwire.io/{mt4|mt5}/{id}/ws`, whatever region the account runs in. The account's
dedicated IP, if it has one, is where its broker traffic comes from; it is not an API address.

## 3. Run it

A typical flow on the `/users/current/…` API: wait for the account to connect, read it,
then trade.

```bash
# Health, with evidence (Tickwire extra)
curl -s "$TW/users/current/accounts/acc_7Qx/health" -H "auth-token: $TW_KEY"

# Open positions
curl -s "$TW/users/current/accounts/acc_7Qx/positions" -H "auth-token: $TW_KEY"

# A market order; clientId works as before, and Idempotency-Key makes retries safe
curl -s -X POST "$TW/users/current/accounts/acc_7Qx/trade" \
  -H "auth-token: $TW_KEY" \
  -H "Idempotency-Key: rf_1" \
  -H "X-Actor: migration-test" -H "X-Reason: first order after switching" \
  -H "content-type: application/json" \
  -d '{"actionType": "ORDER_TYPE_BUY", "symbol": "EURUSD", "volume": 0.01, "clientId": "rf_1"}'
```

For streaming, use the WebSocket on each account's `ws_url`, or Tickwire's
[plain WebSocket protocol](https://tickwire.io/docs/streaming/): JSON frames, one socket per account, from any language.

## What's the same

| Area | Endpoints |
|---|---|
| `/users/current` REST API | Paths, query parameters and field names on `/users/current/accounts/{id}/…`; trade `actionType`s, relative SL/TP units, expiration types and return codes; `clientId` handling; the `error`, `numericCode` and `stringCode` error fields; `transaction-id` and 202 polling on account creation |
| `/v1` API | `/v1/accounts`, `/v1/private-servers` (buy, resize, cancel, add/remove accounts, regions), `/v1/readonly-keys`, `/v1/subscription`, `/v1/wallet` |
| Batch trading | `POST /v1/orders` (up to 20 legs), `POST /v1/orders/close` with `symbol`, `symbol_match`, `kind`, `side`, `magic`, `tickets`, partial volume and `require_reachable`; per-leg statuses; `Idempotency-Key` |
| Terminal | `/{mt4\|mt5}/{id}/AccountSummary`, `AccountInfo`, `OpenedOrders`, `OrderHistory`, `PositionHistory`, `PriceHistory`, `SymbolInfo`, `symbols`, `getQuote`, `ServerTimezone`, `OrderSend`, `OrderModify`, `OrderClose`, `OrderCalcMargin`, `OrderCalcProfit`, `status`, `healthz`, `livez` |
| WebSocket | `/{mt4\|mt5}/{id}/ws` with the prices, bars, account, positions, trades and terminal topics; snapshot on subscribe; `warning` for slow consumers |
| Order results | `success`, `outcome` (`applied`, `no_change`, `partial`, `rejected`) and `is_effective` |

## What's different

- **Health is evidence-based.** An account is `CONNECTED` (or `connected`) only when our health
  monitor has seen the broker link, a successful account read and moving ticks. You may see accounts
  go disconnected that your current provider showed as fine. See [Health](https://tickwire.io/docs/health/).
- **Extra response fields.** Trade responses add `outcome`; unknown outcomes are checked against the
  terminal. See [Idempotency](https://tickwire.io/docs/idempotency/). Clients that ignore unknown fields are unaffected.
- **A new outcome value.** Order results can be `unknown` when a broker connection drops mid-order and
  the result can't be confirmed. Handle it like a timeout: retry with the same `Idempotency-Key`.
- **Timestamps.** UTC fields are real UTC. Broker-local times are in separate, labelled fields, not
  marked with a `Z`. If your code corrected broker times by hand, remove that correction. See
  [Time zones](https://tickwire.io/docs/time-zones/).
- **TLS.** Dedicated IPs have valid certificates. Remove any `verify=False`.
- **Key changes don't restart terminals.** Creating, rotating or re-scoping read-only keys doesn't
  take accounts offline.
- **Read-only keys are shown once.** Tickwire returns a read-only key's value only when you create or
  rotate it, and stores a hash: lists and reads answer `key: null` with a short `key_preview`. Store
  the key when you create it. If your code fetched keys from `GET /v1/readonly-keys` to use them,
  rotate the key instead and keep the new value.
- **Webhooks, `/health` and `/audit`.** Register a webhook instead of polling for status.
- **Pricing.** One monthly plan per account in USD. See [Pricing](https://tickwire.io/pricing/).

## What isn't supported

- Copy-trading services, an MT Manager API, hosted configuration links and demo-account generation.
  Calls to them fail with a clear error.
- `reliability: "high"` runs one instance per account today; cross-region replicas aren't offered.
- Expert-advisor upload.

## Checklist

1. Create a Tickwire key and point a staging copy of your app at Tickwire. Replay your usual calls.
2. Link one account and run your test suite against it.
3. Remove `verify=False` and any broker-time corrections. Store read-only keys when you create them.
4. Handle `outcome: "unknown"`.
5. Register a [webhook](https://tickwire.io/docs/webhooks/) for `account.health_changed`.
6. Move accounts one at a time or in small batches. Remove an account from your old provider only
   after the Tickwire copy is healthy. Never run two terminals on one prop-firm account at the same
   time.
