{"openapi":"3.0.0","paths":{"/store/keys":{"get":{"operationId":"StoreController_getKeys","parameters":[],"responses":{"200":{"description":"Array of key strings"}},"summary":"Get all keys that have data","tags":["store"]},"post":{"operationId":"StoreController_getMultiSeries","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeysQueryDto"}}}},"responses":{"200":{"description":"Map of key → DataPoint[]"}},"summary":"Get time series for multiple keys","tags":["store"]}},"/store/snapshot":{"get":{"operationId":"StoreController_getSnapshot","parameters":[],"responses":{"200":{"description":"Map of key → last DataPoint | null"}},"summary":"Get snapshot: all keys with their latest point","tags":["store"]}},"/store/key/{key}/latest":{"get":{"operationId":"StoreController_getLatest","parameters":[{"name":"key","required":true,"in":"path","schema":{"example":"binance|ETHUSDT|bidPrice","type":"string"}}],"responses":{"200":{"description":"Last DataPoint"},"404":{"description":"Key not found or no data"}},"summary":"Get latest point for a key","tags":["store"]}},"/store/key/{key}":{"get":{"operationId":"StoreController_getSeries","parameters":[{"name":"key","required":true,"in":"path","schema":{"example":"binance|ETHUSDT|bidPrice","type":"string"}},{"name":"from","required":false,"in":"query","description":"Start timestamp (ms, inclusive)","schema":{"example":1700000000000,"type":"number"}},{"name":"to","required":false,"in":"query","description":"End timestamp (ms, inclusive)","schema":{"example":1700000099000,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Return last N points","schema":{"example":100,"type":"number"}}],"responses":{"200":{"description":"Array of DataPoint"}},"summary":"Get time series for a key with optional filtering","tags":["store"]},"delete":{"operationId":"StoreController_deleteSeries","parameters":[{"name":"key","required":true,"in":"path","schema":{"example":"binance|ETHUSDT|bidPrice","type":"string"}}],"responses":{"200":{"description":"Series deleted"}},"summary":"Delete all data for a key","tags":["store"]}},"/store/write":{"post":{"operationId":"StoreController_writePoint","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WritePointDto"}}}},"responses":{"201":{"description":"Point written successfully"}},"summary":"Write a single data point","tags":["store"]}},"/store/write/batch":{"post":{"operationId":"StoreController_writeBatch","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteBatchDto"}}}},"responses":{"201":{"description":"Points written successfully"}},"summary":"Write multiple data points in one request","tags":["store"]}},"/store":{"delete":{"operationId":"StoreController_clearStore","parameters":[],"responses":{"200":{"description":"Store cleared"}},"summary":"Clear entire store","tags":["store"]}},"/store/memory":{"get":{"description":"Returns per-key and aggregate estimated memory usage. Sizes are computed as the JSON-serialized byte length of key + data series.","operationId":"StoreController_getTotalMemory","parameters":[],"responses":{"200":{"description":"Memory usage report for all keys"}},"summary":"Get estimated memory usage for all keys","tags":["store"]}},"/store/key/{key}/memory":{"get":{"operationId":"StoreController_getKeyMemory","parameters":[{"name":"key","required":true,"in":"path","schema":{"example":"binance|ETHUSDT|bidPrice","type":"string"}}],"responses":{"200":{"description":"Memory usage for the key"},"404":{"description":"Key not found"}},"summary":"Get estimated memory usage for a single key","tags":["store"]}},"/store/memory/keys":{"post":{"operationId":"StoreController_getMemoryForKeys","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemoryQueryDto"}}}},"responses":{"200":{"description":"Memory usage report for the requested keys"}},"summary":"Get estimated memory usage for a list of keys","tags":["store"]}},"/store/clients":{"get":{"description":"Returns all currently connected WebSocket clients with their socket ID, remote IP, remote port, subscription state, and connection duration. `subscribedKeys` is `null` when connected but not yet subscribed, `\"all\"` when subscribed to all keys, or an array of specific key strings.","operationId":"StoreController_getConnectedClients","parameters":[],"responses":{"200":{"description":"Connected clients report","content":{"application/json":{"schema":{"example":{"total":2,"clients":[{"id":"abc123","subscribedKeys":["binance|ETHUSDT|bidPrice"],"connectedAt":1700000000000,"connectedForMs":34200,"remoteAddress":"192.168.1.10","remotePort":54321},{"id":"def456","subscribedKeys":"all","connectedAt":1700000001000,"connectedForMs":33200,"remoteAddress":"10.0.0.5","remotePort":60001}]}}}}}},"summary":"Get connected WebSocket clients","tags":["store"]}},"/store/clients/{id}":{"delete":{"description":"Forcefully disconnects the specified client. Returns 404 if the client is not connected.","operationId":"StoreController_disconnectClient","parameters":[{"name":"id","required":true,"in":"path","description":"Socket ID of the client to disconnect","schema":{"example":"abc123","type":"string"}}],"responses":{"200":{"description":"Client disconnected","content":{"application/json":{"schema":{"example":{"disconnected":true}}}}},"404":{"description":"Client not found"}},"summary":"Disconnect a WebSocket client by socket ID","tags":["store"]}}},"info":{"title":"ArbiDex Market Data","description":"In-memory time-series store for market data. Supports REST API for reading/writing, WebSocket (Socket.IO) for real-time subscriptions, and OpenAPI documentation for AI agents.\n\n**Authentication:** if `API_KEY` is set in environment, supply it via `x-api-key` header or `?api_key=` query param. If `API_KEY` is not configured the API is open (development mode).","version":"1.0","contact":{}},"tags":[{"name":"store","description":""}],"servers":[],"components":{"securitySchemes":{"x-api-key":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"KeysQueryDto":{"type":"object","properties":{"keys":{"example":["binance|ETHUSDT|bidPrice","mexc|ETHUSDT|askPrice"],"description":"List of keys","type":"array","items":{"type":"string"}},"from":{"type":"number","example":1700000000000,"description":"Start timestamp (ms, inclusive)"},"to":{"type":"number","example":1700000099000,"description":"End timestamp (ms, inclusive)"},"limit":{"type":"number","example":100,"description":"Return last N points per key"}},"required":["keys"]},"WritePointDto":{"type":"object","properties":{"key":{"type":"string","example":"binance|ETHUSDT|bidPrice","description":"Store key"},"value":{"type":"number","example":3500.5,"description":"Numeric value"},"timestamp":{"type":"number","example":1700000000000,"description":"Unix timestamp in ms (defaults to Date.now())"}},"required":["key","value"]},"WriteBatchDto":{"type":"object","properties":{"points":{"description":"Array of points to write","type":"array","items":{"$ref":"#/components/schemas/WritePointDto"}}},"required":["points"]},"MemoryQueryDto":{"type":"object","properties":{"keys":{"example":["binance|ETHUSDT|bidPrice","mexc|ETHUSDT|askPrice"],"description":"List of keys to estimate memory usage for","type":"array","items":{"type":"string"}}},"required":["keys"]}}}}