{
  "openapi": "3.1.0",
  "info": {
    "title": "Lantern by Fintrens Algo Integration API",
    "version": "1.0.0",
    "description": "Register algos, push signals, report health, upload backtests and read marketplace data.",
    "contact": {
      "email": "services@fintrens.com"
    }
  },
  "servers": [
    {
      "url": "https://fintrens.com/lantern/api/v1",
      "description": "Live"
    },
    {
      "url": "https://fintrens.com/lantern/sandbox-api/v1",
      "description": "Sandbox"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "Leg": {
        "type": "object",
        "required": [
          "side",
          "symbol",
          "exchange",
          "qty_per_lot",
          "lots_per_lakh",
          "order_type",
          "price"
        ],
        "properties": {
          "side": {
            "type": "string",
            "enum": [
              "BUY",
              "SELL"
            ]
          },
          "symbol": {
            "type": "string"
          },
          "exchange": {
            "type": "string",
            "enum": [
              "NSE",
              "NFO",
              "BSE",
              "MCX"
            ]
          },
          "qty_per_lot": {
            "type": "integer"
          },
          "lots_per_lakh": {
            "type": "number"
          },
          "order_type": {
            "type": "string",
            "enum": [
              "LIMIT"
            ]
          },
          "price": {
            "type": "number"
          }
        }
      },
      "Signal": {
        "type": "object",
        "required": [
          "algo_id",
          "client_ref",
          "action",
          "ts",
          "legs"
        ],
        "properties": {
          "algo_id": {
            "type": "string"
          },
          "client_ref": {
            "type": "string"
          },
          "action": {
            "type": "string",
            "enum": [
              "ENTRY",
              "EXIT",
              "MODIFY"
            ]
          },
          "parent_signal_id": {
            "type": "string"
          },
          "ts": {
            "type": "string",
            "format": "date-time"
          },
          "valid_till": {
            "type": "string",
            "format": "date-time"
          },
          "legs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Leg"
            }
          },
          "risk": {
            "type": "object",
            "properties": {
              "stop_loss_pct": {
                "type": "number"
              },
              "target_pct": {
                "type": "number"
              },
              "max_slippage_bps": {
                "type": "number"
              }
            }
          }
        }
      },
      "Algo": {
        "type": "object",
        "required": [
          "name",
          "category",
          "strategy",
          "exchange",
          "instrument",
          "segment",
          "holding",
          "min_allocation",
          "max_allocation",
          "stop_loss_pct",
          "pricing"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "category": {
            "type": "string",
            "enum": [
              "non_directional",
              "directional",
              "market_neutral"
            ]
          },
          "strategy": {
            "type": "string"
          },
          "exchange": {
            "type": "string"
          },
          "instrument": {
            "type": "string"
          },
          "segment": {
            "type": "string",
            "enum": [
              "FO",
              "CASH",
              "COMMODITY",
              "CURRENCY"
            ]
          },
          "holding": {
            "type": "string"
          },
          "min_allocation": {
            "type": "integer"
          },
          "max_allocation": {
            "type": "integer"
          },
          "stop_loss_pct": {
            "type": "number"
          },
          "pricing": {
            "type": "object",
            "properties": {
              "monthly_fee": {
                "type": "integer"
              },
              "profit_share_pct": {
                "type": "number"
              },
              "slots": {
                "type": "integer"
              }
            }
          },
          "summary": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        }
      },
      "Heartbeat": {
        "type": "object",
        "required": [
          "algo_id",
          "ts",
          "state"
        ],
        "properties": {
          "algo_id": {
            "type": "string"
          },
          "ts": {
            "type": "string",
            "format": "date-time"
          },
          "state": {
            "type": "string",
            "enum": [
              "RUNNING",
              "PAUSED",
              "ERROR"
            ]
          },
          "open_positions": {
            "type": "integer"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/algos": {
      "post": {
        "summary": "Register an algo",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Algo"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/algos/{algo_id}": {
      "get": {
        "summary": "Get algo",
        "parameters": [
          {
            "name": "algo_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "patch": {
        "summary": "Update algo",
        "parameters": [
          {
            "name": "algo_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/algos/{algo_id}/submit": {
      "post": {
        "summary": "Submit for verification",
        "parameters": [
          {
            "name": "algo_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Queued"
          }
        }
      }
    },
    "/signals": {
      "post": {
        "summary": "Push a signal",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Signal"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued"
          },
          "409": {
            "description": "Duplicate client_ref"
          },
          "422": {
            "description": "Risk rejected"
          }
        }
      }
    },
    "/signals/{signal_id}": {
      "get": {
        "summary": "Signal fill status",
        "parameters": [
          {
            "name": "signal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/signals/{signal_id}/cancel": {
      "post": {
        "summary": "Cancel unfilled legs",
        "parameters": [
          {
            "name": "signal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/heartbeat": {
      "post": {
        "summary": "Heartbeat",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Heartbeat"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Accepted"
          }
        }
      }
    },
    "/backtests": {
      "post": {
        "summary": "Upload backtest",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "algo_id": {
                    "type": "string"
                  },
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "slippage_bps": {
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued for verification"
          }
        }
      }
    },
    "/backtests/{backtest_id}": {
      "get": {
        "summary": "Backtest verification result",
        "parameters": [
          {
            "name": "backtest_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/marketplace/algos": {
      "get": {
        "summary": "List algos (public)",
        "security": [],
        "parameters": [
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "cagr",
                "max_drawdown",
                "sharpe",
                "win_rate",
                "stop_loss",
                "min_allocation"
              ]
            }
          },
          {
            "name": "risk",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "segment",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/marketplace/algos/{slug}": {
      "get": {
        "summary": "Algo performance data (public)",
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/marketplace/combine": {
      "get": {
        "summary": "Combined metrics for a set of algos (public)",
        "security": [],
        "parameters": [
          {
            "name": "algos",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "comma-separated slugs"
          },
          {
            "name": "alloc",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "comma-separated allocations"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "webhooks": {
    "signal.filled": {
      "post": {
        "summary": "Signal fully filled or expired",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "signal.rejected": {
      "post": {
        "summary": "Signal rejected",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "algo.paused": {
      "post": {
        "summary": "Algo paused",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "payout.settled": {
      "post": {
        "summary": "Monthly payout settled",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  }
}