{"components":{"schemas":{"Account":{"properties":{"active":{"type":"boolean"},"cloud_connected":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"ea":{"$ref":"#/components/schemas/EaTruth"},"ea_connected":{"description":"Display truth (ea.online), not the stale flag","type":"boolean"},"ea_version":{"nullable":true,"type":"string"},"id":{"type":"integer"},"label":{"type":"string"},"mt5_login":{"nullable":true,"type":"string"},"server":{"description":"Broker MT5 server (mt5_server)","nullable":true,"type":"string"},"type":{"type":"string"}},"type":"object"},"AccountListResponse":{"properties":{"accounts":{"items":{"$ref":"#/components/schemas/Account"},"type":"array"}},"type":"object"},"EaStatusResponse":{"properties":{"accounts":{"items":{"$ref":"#/components/schemas/EaStatusRow"},"type":"array"}},"type":"object"},"EaStatusRow":{"properties":{"ea":{"$ref":"#/components/schemas/EaTruth"},"ea_connected":{"type":"boolean"},"ea_version":{"nullable":true,"type":"string"},"id":{"type":"integer"},"label":{"type":"string"},"last_ping":{"format":"date-time","nullable":true,"type":"string"}},"type":"object"},"EaTruth":{"description":"Display truth of the EA: online when the HTTP ping is fresh OR the push connection is alive.","properties":{"online":{"type":"boolean"},"ping_fresh":{"type":"boolean"},"push_fresh":{"type":"boolean"},"telemetry_degraded":{"type":"boolean"},"via":{"enum":["ping","push",null],"nullable":true,"type":"string"}},"type":"object"},"Error":{"properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error"],"type":"object"},"Signal":{"properties":{"account_id":{"nullable":true,"type":"integer"},"action":{"type":"string"},"close_price":{"nullable":true,"type":"number"},"close_time":{"format":"date-time","nullable":true,"type":"string"},"created_at":{"format":"date-time","type":"string"},"executed_lot":{"nullable":true,"type":"number"},"execution_ms":{"nullable":true,"type":"integer"},"filter_reason":{"nullable":true,"type":"string"},"id":{"type":"integer"},"lot":{"type":"number"},"mt5_retcode":{"nullable":true,"type":"integer"},"open_price":{"nullable":true,"type":"number"},"open_time":{"format":"date-time","nullable":true,"type":"string"},"outcome":{"enum":["WIN","LOSS","BREAKEVEN",null],"nullable":true,"type":"string"},"pnl_money":{"description":"In account currency","nullable":true,"type":"number"},"pnl_pips":{"nullable":true,"type":"number"},"price":{"nullable":true,"type":"number"},"reason_code":{"nullable":true,"type":"string"},"result_message":{"nullable":true,"type":"string"},"sl":{"nullable":true,"type":"number"},"status":{"type":"string"},"strategy_tag":{"nullable":true,"type":"string"},"symbol":{"type":"string"},"tp":{"nullable":true,"type":"number"},"trade_comment":{"nullable":true,"type":"string"}},"type":"object"},"SignalResponse":{"properties":{"signal":{"$ref":"#/components/schemas/Signal"}},"type":"object"},"SignalSubmit":{"properties":{"account_id":{"description":"Your account id (from GET /api/v1/accounts)","type":"integer"},"action":{"description":"closebuy/closesell are non-directional: they close ALL positions of the symbol; use close with side for one direction","enum":["buy","sell","close","closebuy","closesell","close_all","buy_limit","sell_limit","buy_stop","sell_stop","modify","cancel","replace"],"type":"string"},"breakeven":{"nullable":true,"type":"number"},"comment":{"maxLength":31,"type":"string"},"dry_run":{"default":true,"description":"true = validate and preview only (read scope is enough); false = send live (the key needs the trade scope)","type":"boolean"},"entry_pct":{"nullable":true,"type":"number"},"entry_pips":{"nullable":true,"type":"number"},"idempotency_key":{"description":"Optional. Same key within 24 h = not sent again (duplicate: true). Live only; a webhook rejection frees it for a retry.","maxLength":100,"type":"string"},"lot":{"default":0,"description":"0 = the EA sizes from account risk","type":"number"},"order_type":{"description":"Pending type filter (cancel/replace)","nullable":true,"type":"string"},"percent":{"description":"Partial close percent (close)","nullable":true,"type":"number"},"price":{"description":"Entry price (pendings/replace)","nullable":true,"type":"number"},"side":{"description":"buy/sell (directional close or cancel filter)","nullable":true,"type":"string"},"sl":{"nullable":true,"type":"number"},"symbol":{"type":"string"},"tp":{"nullable":true,"type":"number"},"tp1":{"nullable":true,"type":"number"},"tp2":{"nullable":true,"type":"number"},"tp3":{"nullable":true,"type":"number"},"tp4":{"nullable":true,"type":"number"},"tp5":{"nullable":true,"type":"number"},"trailing":{"nullable":true,"type":"number"}},"required":["action","symbol"],"type":"object"},"SignalSubmitResponse":{"properties":{"dry_run":{"type":"boolean"},"duplicate":{"description":"true when the idempotency_key was already used: nothing was sent","nullable":true,"type":"boolean"},"ok":{"type":"boolean"},"queued":{"nullable":true,"type":"boolean"},"webhook":{"nullable":true,"type":"object"},"would_send":{"type":"object"}},"type":"object"},"SignalsPage":{"properties":{"next_before":{"nullable":true,"type":"integer"},"signals":{"items":{"$ref":"#/components/schemas/Signal"},"type":"array"}},"type":"object"},"User":{"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"description":"Masked: pa***@gmail.com","type":"string"},"id":{"type":"integer"},"plan":{"type":"string"},"subscription_expires_at":{"format":"date-time","nullable":true,"type":"string"},"trial_ends_at":{"format":"date-time","nullable":true,"type":"string"}},"type":"object"},"UserResponse":{"properties":{"user":{"$ref":"#/components/schemas/User"}},"type":"object"}},"securitySchemes":{"bearerAuth":{"description":"Personal API key with sfk_ prefix","scheme":"bearer","type":"http"}}},"info":{"description":"SFConnect (Trader, Pro and Elite plans). Access to YOUR SignalForge data: accounts, EA status, signal history with outcome tracking and signal submission to YOUR EA (dry_run by default). Create a personal key (sfk_...) from the API keys card at the bottom of your dashboard home. Rate limits: 60 requests/min and 10 signals/min per key per instance (the service runs more than one instance, so a short burst can pass; 429 responses carry Retry-After).","title":"SignalForge SFConnect API","version":"1.1.0"},"openapi":"3.0.3","paths":{"/api/v1/accounts":{"get":{"operationId":"listAccounts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountListResponse"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Unauthorized: missing or invalid Bearer sfk_ key"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Rate limit exceeded (see Retry-After header)"}},"summary":"Your MT5 accounts and EA state"}},"/api/v1/ea/status":{"get":{"operationId":"getEaStatus","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EaStatusResponse"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Unauthorized: missing or invalid Bearer sfk_ key"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Rate limit exceeded (see Retry-After header)"}},"summary":"EA status per account (version, ping, online)"}},"/api/v1/me":{"get":{"operationId":"getMe","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Unauthorized: missing or invalid Bearer sfk_ key"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Rate limit exceeded (see Retry-After header)"}},"summary":"Your user (plan, masked email, dates)"}},"/api/v1/signals":{"get":{"operationId":"listSignals","parameters":[{"in":"query","name":"limit","schema":{"default":50,"maximum":200,"type":"integer"}},{"description":"Pagination: id from next_before","in":"query","name":"before","schema":{"type":"integer"}},{"in":"query","name":"account_id","schema":{"type":"integer"}},{"description":"Only signals created at or after this moment (YYYY-MM-DD or ISO datetime)","in":"query","name":"since","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalsPage"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request parameter"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Unauthorized: missing or invalid Bearer sfk_ key"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Rate limit exceeded (see Retry-After header)"}},"summary":"Your signal history (newest first)"},"post":{"operationId":"submitSignal","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalSubmit"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalSubmitResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request parameter"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Unauthorized: missing or invalid Bearer sfk_ key"},"403":{"description":"Plan without trading (plan_no_trading) or live send with a key without the trade scope (scope_required)"},"404":{"description":"Account not found (yours only)"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Rate limit exceeded (see Retry-After header)"}},"summary":"Submit a signal to YOUR EA (dry_run=true by default)"}},"/api/v1/signals/{id}":{"get":{"operationId":"getSignal","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalResponse"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Unauthorized: missing or invalid Bearer sfk_ key"},"404":{"description":"Not found"}},"summary":"One signal (only yours; 404 otherwise)"}}},"security":[{"bearerAuth":[]}],"servers":[{"url":"https://api.signalforge-ai.com"}]}
