Base URL: http://localhost:5000/api
Currently, no authentication is required. Authentication can be added as a middleware layer later.
GET /api/accountsResponse:
[
{
"id": 1,
"name": "Zerodha",
"description": "Indian broker - NSE/BSE",
"created_at": "2024-12-14T10:30:00",
"updated_at": "2024-12-14T10:30:00"
}
]POST /api/accounts
Content-Type: application/json
{
"name": "Zerodha",
"description": "Indian broker - NSE/BSE"
}PUT /api/brokers/{id}
Content-Type: application/json
{
"name": "Updated Name",
"description": "Updated description"
}DELETE /api/accounts/{id}GET /api/stocksResponse:
[
{
"id": 1,
"symbol": "AAPL",
"name": "Apple Inc.",
"exchange": "NASDAQ",
"sector": "Technology",
"current_price": 178.50,
"last_updated": "2024-12-14T10:30:00",
"created_at": "2024-12-14T10:30:00"
}
]POST /api/stocks
Content-Type: application/json
{
"symbol": "AAPL",
"name": "Apple Inc.",
"exchange": "NASDAQ",
"sector": "Technology",
"current_price": 178.50
}Note: Symbol will be automatically converted to uppercase.
PUT /api/stocks/{id}
Content-Type: application/json
{
"current_price": 180.25
}GET /api/holdingsResponse:
[
{
"id": 1,
"broker_id": 1,
"broker_name": "Zerodha",
"stock_id": 1,
"stock_symbol": "AAPL",
"stock_name": "Apple Inc.",
"quantity": 10,
"average_price": 150.00,
"current_price": 178.50,
"invested_value": 1500.00,
"current_value": 1785.00,
"gain_loss": 285.00,
"gain_loss_percentage": 19.00,
"notes": "Long term investment",
"created_at": "2024-12-14T10:30:00",
"updated_at": "2024-12-14T10:30:00"
}
]POST /api/holdings
Content-Type: application/json
{
"broker_id": 1,
"stock_id": 1,
"quantity": 10,
"average_price": 150.00,
"notes": "Long term investment"
}Validation:
broker_id,stock_id,quantity, andaverage_priceare required- Broker and stock must exist
- Combination of broker_id and stock_id must be unique
PUT /api/holdings/{id}
Content-Type: application/json
{
"quantity": 15,
"average_price": 155.00,
"notes": "Updated notes"
}DELETE /api/holdings/{id}GET /api/portfolio/summaryResponse:
{
"total_invested": 50000.00,
"total_current_value": 58500.00,
"total_gain_loss": 8500.00,
"total_gain_loss_percentage": 17.00,
"holdings_count": 8,
"brokers_count": 3
}GET /api/portfolio/by-brokerResponse:
[
{
"broker_id": 1,
"broker_name": "Zerodha",
"total_invested": 25000.00,
"total_current_value": 28500.00,
"total_gain_loss": 3500.00,
"total_gain_loss_percentage": 14.00,
"holdings_count": 3
}
]GET /api/portfolio/top-performersResponse:
{
"top_gainers": [
{
"holding": { /* holding object */ },
"gain_loss_percentage": 25.50
}
],
"top_losers": [
{
"holding": { /* holding object */ },
"gain_loss_percentage": -5.20
}
]
}POST /api/prices/update/{symbol}Example:
POST /api/prices/update/AAPLResponse:
{
"symbol": "AAPL",
"current_price": 178.50,
"last_updated": "2024-12-14T10:30:00"
}POST /api/prices/update-allResponse:
{
"updated": ["AAPL", "MSFT", "GOOGL"],
"failed": [
{
"symbol": "INVALID",
"error": "Price not available"
}
],
"updated_count": 3,
"failed_count": 1
}GET /api/prices/fetch/{symbol}Example:
GET /api/prices/fetch/TSLAResponse:
{
"symbol": "TSLA",
"name": "Tesla, Inc.",
"current_price": 242.80,
"exchange": "NASDAQ",
"sector": "Consumer Cyclical",
"market_cap": 769234000000,
"currency": "USD"
}- NSE: Add
.NSsuffix - e.g.,RELIANCE.NS,TCS.NS,INFY.NS - BSE: Add
.BOsuffix - e.g.,RELIANCE.BO
- Use plain symbol - e.g.,
AAPL,MSFT,GOOGL,TSLA
Refer to yfinance documentation for symbol formats for other exchanges.
{
"error": "Name is required"
}{
"error": "Stock not found"
}{
"error": "Broker already exists"
}{
"error": "Failed to fetch stock price: Connection timeout"
}No rate limits currently implemented. Consider adding rate limiting for production use, especially for price update endpoints to avoid overwhelming the yfinance API.
CORS is enabled for the following origins (configurable in .env):
http://localhost:5173(Vue.js dev server)http://localhost:3000(alternative frontend)
GET /api/transactions- List all transactionsPOST /api/transactions- Record new transactionGET /api/holdings/{id}/transactions- Get transactions for a holding
POST /api/auth/register- User registrationPOST /api/auth/login- User loginPOST /api/auth/logout- User logoutGET /api/auth/me- Get current user
GET /api/reports/performance- Performance over timeGET /api/reports/allocation- Asset allocation breakdownGET /api/reports/export- Export portfolio data (CSV/PDF)
GET /api/corporate-events/Response:
[
{
"id": 1,
"stock_id": 1,
"stock_symbol": "AAPL",
"event_type": "SPLIT",
"event_date": "2026-04-01",
"ratio": 2.0,
"quantity": null,
"amount": null,
"related_stock_id": null,
"related_stock_symbol": null,
"notes": "2-for-1 split"
}
]GET /api/corporate-events/{id}Response:
{
"id": 1,
"stock_id": 1,
"stock_symbol": "AAPL",
"event_type": "SPLIT",
"event_date": "2026-04-01",
"ratio": 2.0,
"quantity": null,
"amount": null,
"related_stock_id": null,
"related_stock_symbol": null,
"notes": "2-for-1 split"
}POST /api/corporate-events/
Content-Type: application/json
{
"stock_id": 1,
"event_type": "SPLIT",
"event_date": "2026-04-01",
"ratio": 2.0,
"notes": "2-for-1 split"
}Response:
{
"id": 2,
"stock_id": 1,
"stock_symbol": "AAPL",
"event_type": "SPLIT",
"event_date": "2026-04-01",
"ratio": 2.0,
"quantity": null,
"amount": null,
"related_stock_id": null,
"related_stock_symbol": null,
"notes": "2-for-1 split"
}PUT /api/corporate-events/{id}
Content-Type: application/json
{
"ratio": 3.0,
"notes": "3-for-1 split"
}Response:
{
"id": 2,
"stock_id": 1,
"stock_symbol": "AAPL",
"event_type": "SPLIT",
"event_date": "2026-04-01",
"ratio": 3.0,
"quantity": null,
"amount": null,
"related_stock_id": null,
"related_stock_symbol": null,
"notes": "3-for-1 split"
}DELETE /api/corporate-events/{id}Response:
204 No Content
Error Responses:
- 400 Bad Request: Invalid data or missing required fields
- 404 Not Found: Event not found
GET /api/transactionsResponse:
[
{
"id": 1,
"account_id": 1,
"stock_id": 1,
"transaction_type": "BUY",
"quantity": 10,
"price": 150.00,
"transaction_date": "2026-04-01T10:00:00",
"fees": 10.0,
"notes": "Initial buy",
"created_at": "2026-04-01T10:00:00"
}
]POST /api/transactions
Content-Type: application/json
{
"account_id": 1,
"stock_id": 1,
"transaction_type": "BUY",
"quantity": 10,
"price": 150.00,
"transaction_date": "2026-04-01T10:00:00",
"fees": 10.0,
"notes": "Initial buy"
}Response:
{
"id": 2,
"account_id": 1,
"stock_id": 1,
"transaction_type": "BUY",
"quantity": 10,
"price": 150.00,
"transaction_date": "2026-04-01T10:00:00",
"fees": 10.0,
"notes": "Initial buy",
"created_at": "2026-04-01T10:00:00"
}PUT /api/transactions/{id}
Content-Type: application/json
{
"quantity": 12,
"price": 155.00,
"notes": "Updated quantity"
}Response:
{
"id": 2,
"account_id": 1,
"stock_id": 1,
"transaction_type": "BUY",
"quantity": 12,
"price": 155.00,
"transaction_date": "2026-04-01T10:00:00",
"fees": 10.0,
"notes": "Updated quantity",
"created_at": "2026-04-01T10:00:00"
}DELETE /api/transactions/{id}Response:
204 No Content
Error Responses:
- 400 Bad Request: Invalid data or missing required fields
- 404 Not Found: Transaction not found
- 409 Conflict: Duplicate or conflicting transaction
# 1. Create a broker
curl -X POST http://localhost:5000/api/brokers -H "Content-Type: application/json" -d '{\"name\":\"My Broker\",\"description\":\"Test broker\"}'
# 2. Fetch stock info (to verify symbol)
curl http://localhost:5000/api/prices/fetch/AAPL
# 3. Create a stock
curl -X POST http://localhost:5000/api/stocks -H "Content-Type: application/json" -d '{\"symbol\":\"AAPL\",\"name\":\"Apple Inc.\",\"exchange\":\"NASDAQ\",\"sector\":\"Technology\",\"current_price\":178.50}'
# 4. Create a holding
curl -X POST http://localhost:5000/api/holdings -H "Content-Type: application/json" -d '{\"broker_id\":1,\"stock_id\":1,\"quantity\":10,\"average_price\":150.00}'
# 5. Get portfolio summary
curl http://localhost:5000/api/portfolio/summaryGET /healthResponse:
{
"status": "ok",
"message": "Portfolio Tracker API is running"
}