{
 "openapi": "3.1.0",
 "info": {
  "title": "Trade Eyes Business API",
  "version": "1.0.0"
 },
 "servers": [
  {
   "url": "https://tradeeyes.app"
  }
 ],
 "components": {
  "securitySchemes": {
   "bearerAuth": {
    "type": "http",
    "scheme": "bearer"
   }
  },
  "schemas": {
   "TradePlan": {
    "type": "object",
    "properties": {
     "side": {
      "type": "string",
      "enum": [
       "long",
       "short"
      ]
     },
     "entry": {
      "type": "number",
      "exclusiveMinimum": 0
     },
     "stop": {
      "type": "number",
      "exclusiveMinimum": 0
     },
     "target": {
      "type": "number",
      "exclusiveMinimum": 0
     },
     "quantity": {
      "type": "number",
      "exclusiveMinimum": 0
     },
     "equity": {
      "type": "number",
      "exclusiveMinimum": 0
     },
     "rationale": {
      "type": "string",
      "minLength": 10,
      "maxLength": 4000
     }
    },
    "required": [
     "side",
     "entry",
     "stop",
     "target",
     "quantity",
     "equity",
     "rationale"
    ]
   },
   "Transaction": {
    "type": "object",
    "properties": {
     "trade_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100
     },
     "timestamp": {
      "type": "string",
      "format": "date-time",
      "description": "Timezone offset required; evaluated in UTC"
     },
     "symbol": {
      "type": "string",
      "minLength": 1,
      "maxLength": 40
     },
     "currency": {
      "type": "string",
      "pattern": "^[A-Z]{3}$"
     },
     "pnl": {
      "type": "number"
     },
     "equity_before": {
      "type": "number",
      "exclusiveMinimum": 0
     },
     "entry": {
      "type": [
       "number",
       "null"
      ],
      "exclusiveMinimum": 0
     },
     "stop": {
      "type": [
       "number",
       "null"
      ],
      "exclusiveMinimum": 0
     },
     "quantity": {
      "type": [
       "number",
       "null"
      ],
      "exclusiveMinimum": 0
     }
    },
    "required": [
     "trade_id",
     "timestamp",
     "symbol",
     "currency",
     "pnl",
     "equity_before",
     "entry",
     "stop",
     "quantity"
    ]
   },
   "BrokerMarketData": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "symbol",
     "timeframe",
     "currency",
     "asOf",
     "candles"
    ],
    "properties": {
     "symbol": {
      "type": "string",
      "minLength": 1,
      "maxLength": 40,
      "pattern": "^[A-Za-z0-9._:/-]+$"
     },
     "timeframe": {
      "type": "string",
      "enum": [
       "1m",
       "5m",
       "15m",
       "30m",
       "1h",
       "4h",
       "1d",
       "1w"
      ]
     },
     "currency": {
      "type": "string",
      "pattern": "^[A-Z]{3}$"
     },
     "asOf": {
      "type": "string",
      "format": "date-time"
     },
     "candles": {
      "type": "array",
      "minItems": 30,
      "maxItems": 500,
      "description": "Unique ascending timestamps not after asOf; low <= open/close <= high.",
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "timestamp",
        "open",
        "high",
        "low",
        "close",
        "volume"
       ],
       "properties": {
        "timestamp": {
         "type": "string",
         "format": "date-time"
        },
        "open": {
         "type": "number",
         "exclusiveMinimum": 0
        },
        "high": {
         "type": "number",
         "exclusiveMinimum": 0
        },
        "low": {
         "type": "number",
         "exclusiveMinimum": 0
        },
        "close": {
         "type": "number",
         "exclusiveMinimum": 0
        },
        "volume": {
         "type": [
          "number",
          "null"
         ],
         "minimum": 0
        }
       }
      }
     }
    }
   }
  }
 },
 "paths": {
  "/api/public/business/v1/sessions": {
   "post": {
    "summary": "sessions",
    "security": [
     {
      "bearerAuth": []
     }
    ],
    "responses": {
     "200": {
      "description": "Completed"
     },
     "202": {
      "description": "Job running"
     },
     "400": {
      "description": "Invalid fields or unavailable access"
     },
     "401": {
      "description": "Credential rejected"
     },
     "403": {
      "description": "Origin rejected"
     },
     "422": {
      "description": "Generation failed; quota released"
     },
     "429": {
      "description": "Daily limit for this end user reached"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "origin": {
          "type": "string",
          "format": "uri"
         },
         "endUserId": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_.:@-]{1,128}$",
          "description": "Stable end-user identifier, stored only as a hash; required when the organization sets a daily per-end-user limit."
         }
        },
        "required": [
         "origin"
        ]
       }
      }
     }
    }
   }
  },
  "/api/public/business/v1/analyze": {
   "post": {
    "summary": "analyze",
    "security": [
     {
      "bearerAuth": []
     }
    ],
    "responses": {
     "200": {
      "description": "Completed"
     },
     "202": {
      "description": "Job running"
     },
     "400": {
      "description": "Invalid fields or unavailable access"
     },
     "401": {
      "description": "Credential rejected"
     },
     "403": {
      "description": "Origin rejected"
     },
     "422": {
      "description": "Generation failed; quota released"
     },
     "429": {
      "description": "Daily limit for this end user reached"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "requestId": {
          "type": "string",
          "format": "uuid"
         },
         "image": {
          "type": "string",
          "maxLength": 12000000,
          "description": "PNG/JPEG/WebP raster data URL, at most 8 MB decoded"
         },
         "plan": {
          "anyOf": [
           {
            "$ref": "#/components/schemas/TradePlan"
           },
           {
            "type": "null"
           }
          ]
         },
         "endUserId": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_.:@-]{1,128}$",
          "description": "Stable end-user identifier, stored only as a hash; required when the organization sets a daily per-end-user limit."
         },
         "lang": {
          "type": "string",
          "enum": [
           "en",
           "id",
           "es",
           "pt",
           "fr",
           "de",
           "it",
           "nl",
           "ru",
           "pl",
           "tr",
           "ar",
           "hi",
           "zh",
           "zh-TW",
           "ja",
           "ko",
           "vi",
           "th",
           "ms",
           "fil",
           "bn",
           "ur",
           "fa",
           "uk",
           "sv"
          ],
          "description": "Response language; defaults to the organization setting."
         }
        },
        "required": [
         "requestId",
         "image",
         "plan"
        ]
       }
      }
     }
    },
    "parameters": [
     {
      "in": "header",
      "name": "X-Trade-Eyes-Parent-Origin",
      "required": false,
      "description": "Required with a widget session; exact bound parent origin. Widget requests run inside the app iframe.",
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/api/public/business/v1/status": {
   "get": {
    "summary": "status",
    "security": [
     {
      "bearerAuth": []
     }
    ],
    "responses": {
     "200": {
      "description": "Completed"
     },
     "202": {
      "description": "Job running"
     },
     "400": {
      "description": "Invalid fields or unavailable access"
     },
     "401": {
      "description": "Credential rejected"
     },
     "403": {
      "description": "Origin rejected"
     },
     "422": {
      "description": "Generation failed; quota released"
     }
    },
    "parameters": [
     {
      "in": "query",
      "name": "id",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     },
     {
      "in": "header",
      "name": "X-Trade-Eyes-Parent-Origin",
      "required": false,
      "description": "Required with a widget session; exact bound parent origin. Widget requests run inside the app iframe.",
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/api/public/business/v1/risk": {
   "post": {
    "summary": "risk",
    "security": [
     {
      "bearerAuth": []
     }
    ],
    "responses": {
     "200": {
      "description": "Completed"
     },
     "202": {
      "description": "Job running"
     },
     "400": {
      "description": "Invalid fields or unavailable access"
     },
     "401": {
      "description": "Credential rejected"
     },
     "403": {
      "description": "Origin rejected"
     },
     "422": {
      "description": "Generation failed; quota released"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "requestId": {
          "type": "string",
          "format": "uuid"
         },
         "accountId": {
          "type": "string",
          "format": "uuid"
         },
         "source": {
          "type": "string",
          "minLength": 2,
          "maxLength": 160
         },
         "rows": {
          "type": "array",
          "maxItems": 2000,
          "items": {
           "$ref": "#/components/schemas/Transaction"
          },
          "minItems": 1
         }
        },
        "required": [
         "requestId",
         "accountId",
         "source",
         "rows"
        ]
       }
      }
     }
    }
   }
  },
  "/api/public/business/v1/instrument": {
   "post": {
    "summary": "Analyze broker-supplied instrument OHLC",
    "security": [
     {
      "bearerAuth": []
     }
    ],
    "parameters": [
     {
      "name": "X-Trade-Eyes-Parent-Origin",
      "in": "header",
      "schema": {
       "type": "string"
      },
      "description": "Required for widget sessions; exact bound parent HTTPS origin."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "additionalProperties": false,
        "required": [
         "requestId",
         "marketData",
         "plan"
        ],
        "properties": {
         "requestId": {
          "type": "string",
          "format": "uuid"
         },
         "marketData": {
          "$ref": "#/components/schemas/BrokerMarketData"
         },
         "plan": {
          "anyOf": [
           {
            "$ref": "#/components/schemas/TradePlan"
           },
           {
            "type": "null"
           }
          ]
         },
         "endUserId": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_.:@-]{1,128}$",
          "description": "Stable end-user identifier, stored only as a hash; required when the organization sets a daily per-end-user limit."
         },
         "lang": {
          "type": "string",
          "enum": [
           "en",
           "id",
           "es",
           "pt",
           "fr",
           "de",
           "it",
           "nl",
           "ru",
           "pl",
           "tr",
           "ar",
           "hi",
           "zh",
           "zh-TW",
           "ja",
           "ko",
           "vi",
           "th",
           "ms",
           "fil",
           "bn",
           "ur",
           "fa",
           "uk",
           "sv"
          ],
          "description": "Response language; defaults to the organization setting."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "jobId, status, result with derived market evidence and AI interpretation"
     },
     "202": {
      "description": "Existing job running"
     },
     "400": {
      "description": "Invalid fields or access"
     },
     "401": {
      "description": "Invalid or revoked credential"
     },
     "403": {
      "description": "Origin or request ownership mismatch"
     },
     "422": {
      "description": "Generation failed; quota released"
     },
     "429": {
      "description": "Daily limit for this end user reached"
     }
    }
   }
  }
 }
}