Portfolio API
Auto-generated from
openapi-snapshot.json. Do not edit by hand — changes are overwritten byscripts/docs/generate_api_reference.py.
15 endpoints in this group.
GET /api/portfolio/archive-stats
Archive Stats
Row counts and date range for the snapshot and intraday tables.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional | |
account_id | query | — | optional |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
POST /api/portfolio/backfill/csv
Backfill From Csv
Deprecated stub — use /api/portfolio/backfill/upload instead.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
POST /api/portfolio/backfill/save
Backfill Save
Request body: application/json
Responses
| Code | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
POST /api/portfolio/backfill/upload
Backfill Upload
Upload a CSV of historical position snapshots and upsert into daily_position_snapshots.
Expected CSV columns (flexible header matching): symbol, date, quantity, avg_cost, market_price, market_value Optional: unrealized_pnl, day_change_pct, source
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
year | query | integer | optional | |
source_type | query | string | optional | |
tenant_id | query | integer | optional |
Request body: multipart/form-data
Responses
| Code | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
DELETE /api/portfolio/data
Delete Year Data
Soft-delete a year’s realized_trades + daily_position_snapshots.
Both tables get deleted_at = now() on still-active rows. No row is
physically removed (see migration 0115_soft_delete_realized_dps).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional | |
year | query | integer | required |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
POST /api/portfolio/eod
Run Eod Ingestion
Trigger end-of-day Schwab position fetch + snapshot save.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
GET /api/portfolio/eod/run-log
Get Eod Run Log
Return recent EOD snapshot runs grouped by snapshot_date.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional | |
account_id | query | — | optional | |
limit | query | integer | optional |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
POST /api/portfolio/eod/trigger
Run Eod Ingestion
Trigger end-of-day Schwab position fetch + snapshot save.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
GET /api/portfolio/fees-summary
Fees Summary
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
days | query | integer | optional | |
account_hash | query | — | optional |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
GET /api/portfolio/pnl
Get Pnl Series
Daily P&L time series. P0-8: limit capped at 100.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional | |
account_id | query | — | optional | |
start_date | query | — | optional | |
end_date | query | — | optional | |
limit | query | integer | optional | Page size (max 100). |
cursor | query | — | optional | Opaque pagination cursor from a previous page’s next_cursor. |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
GET /api/portfolio/realized-trades
Get Realized Trades
Return realized trades from broker statement uploads, newest first.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional | |
account_id | query | — | optional | |
year | query | — | optional | |
symbol | query | — | optional | |
limit | query | integer | optional |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
GET /api/portfolio/snapshots
Get Snapshots
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional | |
account_id | query | — | optional | |
start_date | query | — | optional | |
end_date | query | — | optional | |
as_of_date | query | — | optional | |
latest_only | query | boolean | optional | |
limit | query | integer | optional |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
POST /api/portfolio/snapshots
Save Snapshots
Request body: application/json
Responses
| Code | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
POST /api/portfolio/snapshots/archive
Archive Snapshots
- Move daily_position_snapshots older than keep_snapshot_years to archive table.
- Roll up 5-min intraday bars older than keep_intraday_years into market_data_daily (preserving OHLCV + VWAP) before deleting them.
- Purge intraday bars beyond the retention window.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional | |
keep_snapshot_years | query | integer | optional | |
keep_intraday_years | query | integer | optional |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
DELETE /api/portfolio/trades
Delete Trades
Soft-delete realized_trades for the given tenant + year.
Sets deleted_at = now() on already-active rows (idempotent — rows
that are already soft-deleted are skipped). Returns the number of rows
that transitioned to soft-deleted in this call.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tenant_id | query | integer | optional | |
year | query | integer | required |
Responses
| Code | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |