{
  "protocol": "FIX 4.4",
  "gateway": { "prod": "fix.bitwyre.com:4434", "sandbox": "fix-sandbox.bitwyre.com:4434" },
  "authentication": {
    "mechanism": "Logon (A) with ApiKey in RawData, HMAC-SHA256 signature in Username field",
    "required_tags": ["49 (SenderCompID)", "56 (TargetCompID=BITWYRE)", "108 (HeartBtInt)", "553 (Username = HMAC-SHA256(apiKey|timestamp))", "96 (RawData = apiKey)", "95 (RawDataLength)"]
  },
  "session_behavior": {
    "heartbeat_interval_secs": 30,
    "test_request_timeout_secs": 60,
    "resend_support": true,
    "sequence_reset_support": true,
    "drop_copy_available": "On request — separate SenderCompID in read-only mode"
  },
  "messages": [
    {
      "msgType": "D",
      "name": "New Order Single",
      "direction": "client -> gateway",
      "required_fields": ["11 ClOrdID", "55 Symbol", "54 Side", "38 OrderQty", "40 OrdType", "59 TimeInForce", "60 TransactTime"],
      "optional_fields": ["44 Price", "99 StopPx", "18 ExecInst", "1 Account"],
      "notes": "Side: 1=Buy, 2=Sell. OrdType: 1=Market, 2=Limit, 3=Stop, 4=Stop-Limit. TimeInForce: 0=Day, 1=GTC, 3=IOC, 4=FOK."
    },
    {
      "msgType": "F",
      "name": "Order Cancel Request",
      "direction": "client -> gateway",
      "required_fields": ["11 ClOrdID", "41 OrigClOrdID", "55 Symbol", "54 Side", "60 TransactTime"]
    },
    {
      "msgType": "G",
      "name": "Order Cancel/Replace Request",
      "direction": "client -> gateway",
      "required_fields": ["11 ClOrdID", "41 OrigClOrdID", "55 Symbol", "54 Side", "38 OrderQty", "40 OrdType", "60 TransactTime"]
    },
    {
      "msgType": "8",
      "name": "Execution Report",
      "direction": "gateway -> client",
      "required_fields": ["37 OrderID", "11 ClOrdID", "17 ExecID", "150 ExecType", "39 OrdStatus", "55 Symbol", "54 Side", "38 OrderQty", "14 CumQty", "151 LeavesQty", "6 AvgPx"],
      "optional_fields": ["31 LastPx", "32 LastQty", "136 NoMiscFees", "137 MiscFeeAmt", "138 MiscFeeCurr"]
    },
    {
      "msgType": "9",
      "name": "Order Cancel Reject",
      "direction": "gateway -> client",
      "required_fields": ["37 OrderID", "11 ClOrdID", "41 OrigClOrdID", "39 OrdStatus", "434 CxlRejResponseTo", "102 CxlRejReason"]
    },
    {
      "msgType": "V",
      "name": "Market Data Request",
      "direction": "client -> gateway",
      "required_fields": ["262 MDReqID", "263 SubscriptionRequestType", "264 MarketDepth", "146 NoRelatedSym"]
    },
    {
      "msgType": "W",
      "name": "Market Data — Snapshot / Full Refresh",
      "direction": "gateway -> client",
      "required_fields": ["262 MDReqID", "55 Symbol", "268 NoMDEntries"]
    },
    {
      "msgType": "X",
      "name": "Market Data — Incremental Refresh",
      "direction": "gateway -> client",
      "required_fields": ["262 MDReqID", "268 NoMDEntries"]
    },
    {
      "msgType": "BE",
      "name": "User Request",
      "direction": "client -> gateway",
      "purpose": "Passwordless session logon using a previously-issued API key signature"
    }
  ],
  "symbols": {
    "format": "BASE/QUOTE for spot, BASE-USD PERP for perpetual futures",
    "examples": ["BTC/USDT", "ETH/USDT", "SOL/USDT", "BTC-USD PERP", "ETH-USD PERP", "SOL-USD PERP"]
  },
  "rate_limits": {
    "order_rate_limit_per_session_per_sec": 100,
    "cancel_all_burst": 500,
    "market_data_subscriptions_per_session": 64
  },
  "notes": [
    "SenderCompID must be registered in your account settings before first logon.",
    "Sandbox credentials are independent from production — cross-environment logon is rejected at the transport layer.",
    "Drop-copy sessions cannot place orders; any D/F/G/G message is rejected with Reject (3) and SessionRejectReason=99.",
    "Timestamps in tags 52 (SendingTime) and 60 (TransactTime) are UTC in FIX 'YYYYMMDD-HH:MM:SS.sss' format."
  ]
}
