{
  "openapi": "3.1.0",
  "info": {
    "title": "Sabeq Quantitative Trading Intelligence API",
    "version": "1.0.0",
    "description": "Programmatic API for retrieving algorithmic swing trade predictions, real-time confluence scores, and index breadth on the Egyptian Exchange (EGX). Designed for autonomous AI agents, quant researchers, and algorithmic trading systems.\n\n### API Versioning Policy\nSabeq enforces URL path versioning (`/v1/`) combined with semantic `API-Version` response headers. Active stable version is `1.0.0`.\n\n### Deprecation Policy\nDeprecated endpoints and fields follow standard RFC 8594 `Deprecation` and `Sunset` headers. A minimum 6-month formal deprecation notice is guaranteed prior to retirement of any endpoint.\n\n### Rate Limiting & Quotas\nAPI traffic is governed by standard IETF RateLimit response headers (`RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`, `RateLimit-Policy`). When quota is exceeded, HTTP 429 Too Many Requests is returned with a `Retry-After` header and RFC 9457 Problem Details payload.",
    "x-api-versioning": {
      "strategy": "URL path (/v1/) and response header (API-Version)",
      "current_version": "1.0.0",
      "supported_versions": ["1.0.0"],
      "version_header": "API-Version"
    },
    "x-deprecation-policy": {
      "notice_period_months": 6,
      "deprecation_headers": ["Deprecation", "Sunset", "Link"],
      "policy_url": "https://sabeq.org/docs/deprecations",
      "stability": "stable"
    },
    "contact": {
      "name": "Sabeq Quantitative Technologies Support",
      "email": "support@sabeq.org",
      "url": "https://sabeq.org/contact"
    },
    "license": {
      "name": "Proprietary Commercial",
      "url": "https://sabeq.org/terms"
    }
  },
  "servers": [
    {
      "url": "https://sabeq.org/v1",
      "description": "Production Worldwide HTTPS Gateway (v1)"
    },
    {
      "url": "https://sabeq.org/api",
      "description": "Production Standard Gateway"
    },
    {
      "url": "http://192.168.1.41:3000/v1",
      "description": "Local High-Speed Trading LAN Host (v1)"
    }
  ],
  "paths": {
    "/v1/indices/overview": {
      "get": {
        "summary": "EGX Indices Quantitative Radar Overview (v1)",
        "description": "Retrieves comprehensive quantitative ratings, mathematical confluence scores, RSI, MACD, risk-reward ratios, and multi-phase timelines for all 10 EGX indices (EGX 30, EGX 70 EWI, EGX 100 EWI, Tamayuz, EGX T-Bonds, etc.).",
        "operationId": "getIndicesOverviewV1",
        "parameters": [
          {
            "name": "swing",
            "in": "query",
            "required": false,
            "description": "Swing horizon code: 1w (1 Week / 5 sessions) or 2w (2 Weeks / 10 sessions).",
            "schema": {
              "type": "string",
              "enum": ["1w", "2w"],
              "default": "2w"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Array of evaluated EGX indices with quantitative indicators.",
            "headers": {
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimit-Limit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimit-Remaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimit-Reset" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimit-Policy" },
              "API-Version": { "$ref": "#/components/headers/API-Version" }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/IndicesOverviewResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/400BadRequest" },
          "401": { "$ref": "#/components/responses/401Unauthorized" },
          "404": { "$ref": "#/components/responses/404NotFound" },
          "429": { "$ref": "#/components/responses/429TooManyRequests" },
          "500": { "$ref": "#/components/responses/500InternalServerError" }
        }
      }
    },
    "/api/indices/overview": {
      "get": {
        "summary": "EGX Indices Quantitative Radar Overview (Legacy Alias)",
        "description": "Legacy alias routing directly to /v1/indices/overview. Standard API-Version header is returned.",
        "operationId": "getIndicesOverviewLegacy",
        "parameters": [
          {
            "name": "swing",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["1w", "2w"], "default": "2w" }
          }
        ],
        "responses": {
          "200": {
            "description": "Array of evaluated EGX indices with quantitative indicators.",
            "headers": {
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimit-Limit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimit-Remaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimit-Reset" },
              "API-Version": { "$ref": "#/components/headers/API-Version" }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/IndicesOverviewResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/400BadRequest" },
          "404": { "$ref": "#/components/responses/404NotFound" },
          "429": { "$ref": "#/components/responses/429TooManyRequests" },
          "500": { "$ref": "#/components/responses/500InternalServerError" }
        }
      }
    },
    "/v1/sabeq/top5": {
      "get": {
        "summary": "Top 5 Algorithmic Swing Trade Picks (v1)",
        "description": "Returns top 5 EGX stock selections evaluated by mathematical confluence across 35+ technical indicators, VWAP defense, and institutional order flow with net 1.1% transaction friction pre-deducted.",
        "operationId": "getTop5PicksV1",
        "parameters": [
          {
            "name": "swing",
            "in": "query",
            "required": false,
            "description": "Target swing time horizon: 1d (Day Swing), 1w (1 Week), 2w (2 Weeks), 1m (1 Month).",
            "schema": {
              "type": "string",
              "enum": ["1d", "1w", "2w", "1m"],
              "default": "1w"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked Top 5 stock opportunities.",
            "headers": {
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimit-Limit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimit-Remaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimit-Reset" },
              "API-Version": { "$ref": "#/components/headers/API-Version" }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Top5PicksResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/400BadRequest" },
          "401": { "$ref": "#/components/responses/401Unauthorized" },
          "404": { "$ref": "#/components/responses/404NotFound" },
          "429": { "$ref": "#/components/responses/429TooManyRequests" },
          "500": { "$ref": "#/components/responses/500InternalServerError" }
        }
      }
    },
    "/api/sabeq/top5": {
      "get": {
        "summary": "Top 5 Algorithmic Swing Trade Picks (Legacy Alias)",
        "description": "Legacy alias routing directly to /v1/sabeq/top5.",
        "operationId": "getTop5PicksLegacy",
        "parameters": [
          {
            "name": "swing",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["1d", "1w", "2w", "1m"], "default": "1w" }
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked Top 5 stock opportunities.",
            "headers": {
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimit-Limit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimit-Remaining" },
              "API-Version": { "$ref": "#/components/headers/API-Version" }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Top5PicksResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/400BadRequest" },
          "404": { "$ref": "#/components/responses/404NotFound" },
          "429": { "$ref": "#/components/responses/429TooManyRequests" },
          "500": { "$ref": "#/components/responses/500InternalServerError" }
        }
      }
    },
    "/cli": {
      "get": {
        "summary": "Sabeq CLI Tool Documentation",
        "description": "Returns documentation and usage guide for the official Sabeq command-line interface. Supports content negotiation (HTML / Markdown).",
        "operationId": "getCliDocs",
        "responses": {
          "200": {
            "description": "CLI documentation in HTML or Markdown.",
            "content": {
              "text/html": {},
              "text/markdown": {}
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "summary": "Agent Instructions and LLM Index",
        "description": "Returns machine-readable markdown guidelines for autonomous LLM agents.",
        "operationId": "getLlmsTxt",
        "responses": {
          "200": {
            "description": "Plain text or Markdown instructions.",
            "content": {
              "text/plain": {},
              "text/markdown": {}
            }
          }
        }
      }
    }
  },
  "components": {
    "headers": {
      "RateLimit-Limit": {
        "description": "Maximum number of requests permitted in the current quota window (120 req/min).",
        "schema": { "type": "integer", "example": 120 }
      },
      "RateLimit-Remaining": {
        "description": "Number of requests remaining in the current quota window.",
        "schema": { "type": "integer", "example": 115 }
      },
      "RateLimit-Reset": {
        "description": "Number of seconds remaining until the quota window resets.",
        "schema": { "type": "integer", "example": 45 }
      },
      "RateLimit-Policy": {
        "description": "Quota window specification following IETF draft-7.",
        "schema": { "type": "string", "example": "120;w=60" }
      },
      "Retry-After": {
        "description": "Number of seconds client must pause before retrying following a 429 response.",
        "schema": { "type": "integer", "example": 60 }
      },
      "API-Version": {
        "description": "Active semantic API version of the response.",
        "schema": { "type": "string", "example": "1.0.0" }
      }
    },
    "schemas": {
      "ProblemDetails": {
        "type": "object",
        "required": ["type", "title", "status", "error"],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "A URI reference identifying the specific error type.",
            "example": "https://sabeq.org/docs/errors#resource-not-found"
          },
          "title": {
            "type": "string",
            "description": "Short human-readable summary of the problem type.",
            "example": "RESOURCE NOT FOUND"
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code generated by the origin server.",
            "example": 404
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem.",
            "example": "The requested API endpoint '/v1/nonexistent' does not exist."
          },
          "instance": {
            "type": "string",
            "description": "The specific URI endpoint that caused the error.",
            "example": "/v1/nonexistent"
          },
          "error": {
            "type": "object",
            "required": ["code", "message", "hint"],
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable standardized error code.",
                "example": "ENDPOINT_NOT_FOUND"
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation of why the request failed.",
                "example": "The requested endpoint does not exist."
              },
              "hint": {
                "type": "string",
                "description": "Actionable resolution instructions for developers and autonomous agents.",
                "example": "Consult the API documentation at https://sabeq.org/developers or OpenAPI schema at https://sabeq.org/openapi.json."
              },
              "retry_after": {
                "type": "integer",
                "description": "Seconds to wait before retrying (included on 429 responses).",
                "example": 60
              },
              "docs_url": {
                "type": "string",
                "format": "uri",
                "example": "https://sabeq.org/developers"
              },
              "openapi_url": {
                "type": "string",
                "format": "uri",
                "example": "https://sabeq.org/openapi.json"
              },
              "timestamp": {
                "type": "string",
                "format": "date-time",
                "example": "2026-10-08T07:30:00.000Z"
              }
            }
          }
        }
      },
      "IndicesOverviewResponse": {
        "type": "object",
        "required": ["ok", "indices"],
        "properties": {
          "ok": { "type": "boolean", "example": true },
          "indices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "string", "example": "EGX30" },
                "name": { "type": "string", "example": "EGX 30 Index" },
                "nameAr": { "type": "string", "example": "مؤشر إيجي إكس 30" },
                "quantitative": {
                  "type": "object",
                  "properties": {
                    "verdict": { "type": "string", "example": "BULLISH_CONFLUENCE" },
                    "confluenceScore": { "type": "number", "example": 87.5 },
                    "actionSummary": { "type": "string", "example": "Institutional accumulation confirmed." }
                  }
                },
                "pricing": {
                  "type": "object",
                  "properties": {
                    "currentPrice": { "type": "number", "example": 31250.4 },
                    "entryZone": { "type": "string", "example": "31000 - 31200" },
                    "targetPrice": { "type": "number", "example": 33500.0 },
                    "stopLossPrice": { "type": "number", "example": 30200.0 },
                    "riskRewardRatio": { "type": "string", "example": "2.8:1" }
                  }
                }
              }
            }
          }
        }
      },
      "Top5PicksResponse": {
        "type": "object",
        "required": ["ok", "top5Week"],
        "properties": {
          "ok": { "type": "boolean", "example": true },
          "top5Week": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "rank": { "type": "integer", "example": 1 },
                "symbol": { "type": "string", "example": "COMI" },
                "nameAr": { "type": "string", "example": "البنك التجاري الدولي" },
                "score": { "type": "number", "example": 94.2 },
                "entry": { "type": "number", "example": 86.5 },
                "target": { "type": "number", "example": 98.0 },
                "stop": { "type": "number", "example": 82.5 },
                "riskReward": { "type": "string", "example": "2.9:1" }
              }
            }
          }
        }
      }
    },
    "responses": {
      "400BadRequest": {
        "description": "Bad Request — Invalid parameters or request syntax.",
        "headers": {
          "API-Version": { "$ref": "#/components/headers/API-Version" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimit-Remaining" }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          },
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      },
      "401Unauthorized": {
        "description": "Unauthorized — Valid JWT token is required via Authorization Bearer header or cookie.",
        "headers": {
          "API-Version": { "$ref": "#/components/headers/API-Version" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimit-Remaining" }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          },
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      },
      "403Forbidden": {
        "description": "Forbidden — Client lacks permissions for requested resource.",
        "headers": {
          "API-Version": { "$ref": "#/components/headers/API-Version" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimit-Remaining" }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          },
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      },
      "404NotFound": {
        "description": "Not Found — The specified resource or endpoint does not exist.",
        "headers": {
          "API-Version": { "$ref": "#/components/headers/API-Version" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimit-Remaining" }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          },
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      },
      "429TooManyRequests": {
        "description": "Too Many Requests — Rate limit exceeded. Adhere to Retry-After header before repeating.",
        "headers": {
          "RateLimit-Limit": { "$ref": "#/components/headers/RateLimit-Limit" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimit-Remaining" },
          "RateLimit-Reset": { "$ref": "#/components/headers/RateLimit-Reset" },
          "Retry-After": { "$ref": "#/components/headers/Retry-After" },
          "API-Version": { "$ref": "#/components/headers/API-Version" }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          },
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      },
      "500InternalServerError": {
        "description": "Internal Server Error — Unexpected engine exception.",
        "headers": {
          "API-Version": { "$ref": "#/components/headers/API-Version" }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          },
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Supply Sabeq JWT token via 'Authorization: Bearer <token>' header."
      },
      "cookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "sabeq_token",
        "description": "Session authentication via cookie."
      }
    }
  }
}
