> For the complete documentation index, see [llms.txt](https://docs.scaleconnect.com.au/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.scaleconnect.com.au/api/rest-api/scaleapp-rest-api/timeline.md).

# Timeline

Financial timeline, events, and projections (60+ endpoints)

## GET /v1/timeline/test

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/test":{"get":{"operationId":"TimelineController_test_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## Get personal financial timeline with events

> Retrieves detailed personal financial timeline including income, expenses, and life events for timeline widgets.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalTimelineResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"User identifier"},"label":{"type":"string","description":"User name/label"},"startDate":{"type":"string","description":"Timeline start date"},"endDate":{"type":"string","description":"Timeline end date"},"events":{"description":"Array of timeline items (income, expenses, etc.)","type":"array","items":{"$ref":"#/components/schemas/TimelineItemDto"}},"personalEvents":{"description":"Array of personal financial events","type":"array","items":{"$ref":"#/components/schemas/PersonalEventDto"}}},"required":["id","label","startDate","endDate","events","personalEvents"]},"TimelineItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Item identifier"},"label":{"type":"string","description":"Item label"},"startDate":{"type":"string","description":"Start date of this item"},"endDate":{"type":"string","description":"End date of this item"},"value":{"type":"number","description":"Current/initial value"},"events":{"description":"Array of events affecting this item","type":"array","items":{"$ref":"#/components/schemas/TimelineItemEventDto"}}},"required":["id","label","startDate","endDate","value","events"]},"TimelineItemEventDto":{"type":"object","properties":{"id":{"type":"string","description":"Event identifier"},"type":{"type":"string","description":"Type of event","enum":["GROSS_ANUAL_SALARY","LIVING_EXPENSES","HECS_HELP_LOAN","DEPENDENTS","SIDE_HUSTLE_INCOME","RECURRING_BONUSES","PERSONAL_LOANS","PAYG_TAX","MISC_INVESTMENT_CASHFLOWS"]},"date":{"type":"string","description":"Date when event occurs"},"value":{"type":"number","description":"Value at this event"}},"required":["id","type","date","value"]},"PersonalEventDto":{"type":"object","properties":{"type":{"type":"string","description":"Type of personal event","enum":["capital_growth","personal_expense","personal_loan","repayment","capital_transaction","reportable_fringe_benefit","company_dividend","trust_distribution","entity_cash_flow","salary_sacrifice","personal_deduction","GROSS_ANUAL_SALARY","LIVING_EXPENSES","HECS_HELP_LOAN","DEPENDENTS","SIDE_HUSTLE_INCOME","RECURRING_BONUSES","ONE_OFF_BONUSES","PERSONAL_LOANS","PAYG_TAX"]},"date":{"type":"string","description":"Date when event occurs","format":"date-time"},"amount":{"type":"number","description":"Amount associated with the event"},"name":{"type":"string","description":"Event name/description"},"frequency":{"type":"string","description":"Frequency of event occurrence"}},"required":["type","date","amount","name","frequency"]}}},"paths":{"/v1/timeline/personal":{"get":{"description":"Retrieves detailed personal financial timeline including income, expenses, and life events for timeline widgets.","operationId":"TimelineController_personalTimeline_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"Optional strategy/control centre ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved personal timeline","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalTimelineResponseDto"}}}},"401":{"description":"Unauthorized"}},"summary":"Get personal financial timeline with events","tags":["Timeline"]}}}}
```

## Batch timeline enrichment for many userIds

> Broker-scoped. Returns personal + property timeline (and, for \`triggerUserIds\`, meeting triggers) for a page of userIds in one request, replacing the per-row fan-out on the /client timeline view. Requested userIds are intersected with the broker's own client set.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/batch":{"post":{"description":"Broker-scoped. Returns personal + property timeline (and, for `triggerUserIds`, meeting triggers) for a page of userIds in one request, replacing the per-row fan-out on the /client timeline view. Requested userIds are intersected with the broker's own client set.","operationId":"TimelineController_batchTimeline_v1","parameters":[],"responses":{"201":{"description":""}},"summary":"Batch timeline enrichment for many userIds","tags":["Timeline"]}}}}
```

## GET /v1/timeline/property

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/property":{"get":{"operationId":"TimelineController_propertyTimeline_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## Get property-specific timeline with events

> Retrieves detailed timeline for a specific property including rental income, expenses, and capital events.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PropertyTimelineResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Property identifier"},"label":{"type":"string","description":"Property label/address"},"startDate":{"type":"string","description":"Timeline start date"},"endDate":{"type":"string","description":"Timeline end date"},"events":{"description":"Array of property events (rental income, expenses, etc.)","type":"array","items":{"$ref":"#/components/schemas/TimelineItemDto"}}},"required":["id","label","startDate","endDate","events"]},"TimelineItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Item identifier"},"label":{"type":"string","description":"Item label"},"startDate":{"type":"string","description":"Start date of this item"},"endDate":{"type":"string","description":"End date of this item"},"value":{"type":"number","description":"Current/initial value"},"events":{"description":"Array of events affecting this item","type":"array","items":{"$ref":"#/components/schemas/TimelineItemEventDto"}}},"required":["id","label","startDate","endDate","value","events"]},"TimelineItemEventDto":{"type":"object","properties":{"id":{"type":"string","description":"Event identifier"},"type":{"type":"string","description":"Type of event","enum":["GROSS_ANUAL_SALARY","LIVING_EXPENSES","HECS_HELP_LOAN","DEPENDENTS","SIDE_HUSTLE_INCOME","RECURRING_BONUSES","PERSONAL_LOANS","PAYG_TAX","MISC_INVESTMENT_CASHFLOWS"]},"date":{"type":"string","description":"Date when event occurs"},"value":{"type":"number","description":"Value at this event"}},"required":["id","type","date","value"]}}},"paths":{"/v1/timeline/property/{id}":{"get":{"description":"Retrieves detailed timeline for a specific property including rental income, expenses, and capital events.","operationId":"TimelineController_propertyTimelime_v1","parameters":[{"name":"id","required":true,"in":"path","description":"Property identifier (UUID)","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"Optional strategy/control centre ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved property timeline","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyTimelineResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Property not found"}},"summary":"Get property-specific timeline with events","tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-income

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/personal-income":{"get":{"operationId":"TimelineController_listPersonalIncome_v1","parameters":[{"name":"name","required":true,"in":"query","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## POST /v1/timeline/personal-income

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalIncomeDto":{"type":"object","properties":{"date":{"format":"date-time","type":"string"},"endDate":{"format":"date-time","type":"string"},"amount":{"type":"number","description":"The amount of income"},"name":{"type":"string","description":"The name of the income source"},"frequency":{"type":"string","description":"The frequency of the income","enum":["WEEKLY","MONTHLY","BI_MONTHLY","QUARTERLY","SEMI_ANUAL","ANNUAL","ONE_OFF"]}},"required":["date","endDate","amount","name","frequency"]}}},"paths":{"/v1/timeline/personal-income":{"post":{"operationId":"TimelineController_addPersonalIncome_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalIncomeDto"}}}},"responses":{"201":{"description":""}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-income/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/personal-income/{id}":{"get":{"operationId":"TimelineController_getPersonalIncome_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## PUT /v1/timeline/personal-income/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalIncomeDto":{"type":"object","properties":{"date":{"format":"date-time","type":"string"},"endDate":{"format":"date-time","type":"string"},"amount":{"type":"number","description":"The amount of income"},"name":{"type":"string","description":"The name of the income source"},"frequency":{"type":"string","description":"The frequency of the income","enum":["WEEKLY","MONTHLY","BI_MONTHLY","QUARTERLY","SEMI_ANUAL","ANNUAL","ONE_OFF"]}},"required":["date","endDate","amount","name","frequency"]}}},"paths":{"/v1/timeline/personal-income/{id}":{"put":{"operationId":"TimelineController_editPersonalIncome_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalIncomeDto"}}}},"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## DELETE /v1/timeline/personal-income/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/personal-income/{id}":{"delete":{"operationId":"TimelineController_deletePersonalIncome_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## POST /v1/timeline/personal-expense

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalExpenseDto":{"type":"object","properties":{"date":{"type":"string","description":"The date when the expense starts"},"endDate":{"type":"string","description":"The end date of the expense period"},"amount":{"type":"number","description":"The amount of the expense"},"name":{"type":"string","description":"The name of the expense"},"frequency":{"type":"string","description":"The frequency of the expense","enum":["WEEKLY","MONTHLY","BI_MONTHLY","QUARTERLY","SEMI_ANUAL","ANNUAL","ONE_OFF"]},"type":{"type":"string","description":"The type of the expense","enum":["LIVING_EXPENSES","COUNCIL_RATES","BODY_CORPORATE_FEES","WATER_AND_ELECTRICITY","MANAGEMENT_FEES","LANDLORDS_INSURANCE","BUILDING_INSURANCE","OFFSET_ACCOUNT_FEE","HECS_HELP_LOAN","OTHERS"]}},"required":["date","endDate","amount","name","frequency","type"]}}},"paths":{"/v1/timeline/personal-expense":{"post":{"operationId":"TimelineController_personalexpense_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalExpenseDto"}}}},"responses":{"201":{"description":""}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-expense/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/personal-expense/{id}":{"get":{"operationId":"TimelineController_getPersonalExpense_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## PUT /v1/timeline/personal-expense/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalExpenseDto":{"type":"object","properties":{"date":{"type":"string","description":"The date when the expense starts"},"endDate":{"type":"string","description":"The end date of the expense period"},"amount":{"type":"number","description":"The amount of the expense"},"name":{"type":"string","description":"The name of the expense"},"frequency":{"type":"string","description":"The frequency of the expense","enum":["WEEKLY","MONTHLY","BI_MONTHLY","QUARTERLY","SEMI_ANUAL","ANNUAL","ONE_OFF"]},"type":{"type":"string","description":"The type of the expense","enum":["LIVING_EXPENSES","COUNCIL_RATES","BODY_CORPORATE_FEES","WATER_AND_ELECTRICITY","MANAGEMENT_FEES","LANDLORDS_INSURANCE","BUILDING_INSURANCE","OFFSET_ACCOUNT_FEE","HECS_HELP_LOAN","OTHERS"]}},"required":["date","endDate","amount","name","frequency","type"]}}},"paths":{"/v1/timeline/personal-expense/{id}":{"put":{"operationId":"TimelineController_updatePersonalExpense_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalExpenseDto"}}}},"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## DELETE /v1/timeline/personal-expense/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/personal-expense/{id}":{"delete":{"operationId":"TimelineController_deletePersonalExpense_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## POST /v1/timeline/personal-loan

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalLoanDto":{"type":"object","properties":{"loanName":{"type":"string","description":"The name of the loan"},"loanStartDate":{"type":"string","description":"The start date of the loan"},"termInYears":{"type":"number","description":"The term of the loan in years"},"initialAmount":{"type":"number","description":"The initial amount of the loan"},"interestRate":{"type":"number","description":"The interest rate of the loan"},"repaymentAmount":{"type":"number","description":"The repayment amount for the loan"},"frequency":{"type":"string","description":"The frequency of the loan repayments","enum":["MONTHLY","FORTNIGHTLY","WEEKLY","WEEKS_PER_FORTNIGHT"]},"balloonPayment":{"type":"number","description":"The balloon payment amount at the end of the loan term"},"type":{"type":"string","enum":["PERSONAL","CAR","BUSINESS","ASSET_FINANCE"],"description":"PERSONAL | CAR | BUSINESS | ASSET_FINANCE. BUSINESS and ASSET_FINANCE added for Entities & Commercial (the two ported loan modals); Postgres enum extended by migration 1790000000002."},"isExistingLoan":{"type":"boolean","description":"Whether the loan is new (false), existing (true), or left unspecified (null).","nullable":true}},"required":["loanName","loanStartDate","termInYears","initialAmount","interestRate","repaymentAmount","frequency","balloonPayment","type"]}}},"paths":{"/v1/timeline/personal-loan":{"post":{"operationId":"TimelineController_addPersonalLoan_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalLoanDto"}}}},"responses":{"201":{"description":""}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-loan/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/personal-loan/{id}":{"get":{"operationId":"TimelineController_getPersonalLoan_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## PUT /v1/timeline/personal-loan/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UpdatePersonalLoanDto":{"type":"object","properties":{"loanName":{"type":"string","description":"The name of the loan"},"loanStartDate":{"type":"string","description":"The start date of the loan"},"termInYears":{"type":"number","description":"The term of the loan in years"},"initialAmount":{"type":"number","description":"The initial amount of the loan"},"interestRate":{"type":"number","description":"The interest rate of the loan"},"repaymentAmount":{"type":"number","description":"The repayment amount for the loan"},"frequency":{"type":"string","description":"The frequency of the loan repayments","enum":["MONTHLY","FORTNIGHTLY","WEEKLY","WEEKS_PER_FORTNIGHT"]},"balloonPayment":{"type":"number","description":"The balloon payment amount at the end of the loan term"},"type":{"type":"string","enum":["PERSONAL","CAR","BUSINESS","ASSET_FINANCE"],"description":"PERSONAL | CAR | BUSINESS | ASSET_FINANCE. BUSINESS and ASSET_FINANCE added for Entities & Commercial (the two ported loan modals); Postgres enum extended by migration 1790000000002."},"isExistingLoan":{"type":"boolean","description":"Whether the loan is new (false), existing (true), or left unspecified (null).","nullable":true}}}}},"paths":{"/v1/timeline/personal-loan/{id}":{"put":{"operationId":"TimelineController_editPersonalLoan_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePersonalLoanDto"}}}},"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## DELETE /v1/timeline/personal-loan/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/personal-loan/{id}":{"delete":{"operationId":"TimelineController_deletePersonalLoan_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## POST /v1/timeline/capital-transaction

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CapitalTransactionDto":{"type":"object","properties":{"amount":{"type":"number","description":"The amount involved in the capital transaction"},"date":{"type":"string","description":"The date of the capital transaction"},"cashProceeds":{"type":"number","description":"The cash proceeds from the capital transaction"},"type":{"type":"string","description":"The type of the capital transaction","enum":["gain","loss"]}},"required":["amount","date","cashProceeds","type"]}}},"paths":{"/v1/timeline/capital-transaction":{"post":{"operationId":"TimelineController_addCapitalTransaction_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapitalTransactionDto"}}}},"responses":{"201":{"description":""}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/capital-transaction/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/capital-transaction/{id}":{"get":{"operationId":"TimelineController_getCapitalTransaction_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## PUT /v1/timeline/capital-transaction/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CapitalTransactionDto":{"type":"object","properties":{"amount":{"type":"number","description":"The amount involved in the capital transaction"},"date":{"type":"string","description":"The date of the capital transaction"},"cashProceeds":{"type":"number","description":"The cash proceeds from the capital transaction"},"type":{"type":"string","description":"The type of the capital transaction","enum":["gain","loss"]}},"required":["amount","date","cashProceeds","type"]}}},"paths":{"/v1/timeline/capital-transaction/{id}":{"put":{"operationId":"TimelineController_updateCapitalTransaction_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapitalTransactionDto"}}}},"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## DELETE /v1/timeline/capital-transaction/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/capital-transaction/{id}":{"delete":{"operationId":"TimelineController_deleteCapitalTransaction_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## POST /v1/timeline/repayment

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"RepaymentDto":{"type":"object","properties":{"loanId":{"type":"string","description":"The UUID of the loan associated with the repayment"},"repaymentDate":{"type":"string","description":"The date of the repayment"},"repaymentAmount":{"type":"number","description":"The amount of the repayment"}},"required":["loanId","repaymentDate","repaymentAmount"]}}},"paths":{"/v1/timeline/repayment":{"post":{"operationId":"TimelineController_addRepayment_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepaymentDto"}}}},"responses":{"201":{"description":""}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/repayment/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/repayment/{id}":{"get":{"operationId":"TimelineController_getRepayment_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## PUT /v1/timeline/repayment/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UpdateRepaymentDto":{"type":"object","properties":{"loanId":{"type":"string","description":"The UUID of the loan associated with the repayment"},"repaymentDate":{"type":"string","description":"The date of the repayment"},"repaymentAmount":{"type":"number","description":"The amount of the repayment"}}}}},"paths":{"/v1/timeline/repayment/{id}":{"put":{"operationId":"TimelineController_updateRepayment_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRepaymentDto"}}}},"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## DELETE /v1/timeline/repayment/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"RepaymentDto":{"type":"object","properties":{"loanId":{"type":"string","description":"The UUID of the loan associated with the repayment"},"repaymentDate":{"type":"string","description":"The date of the repayment"},"repaymentAmount":{"type":"number","description":"The amount of the repayment"}},"required":["loanId","repaymentDate","repaymentAmount"]}}},"paths":{"/v1/timeline/repayment/{id}":{"delete":{"operationId":"TimelineController_deleteRepayment_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepaymentDto"}}}},"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-loans

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/personal-loans":{"get":{"operationId":"TimelineController_getPersonalLoans_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/property-timeline-v2/{id}

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/property-timeline-v2/{id}":{"get":{"operationId":"TimelineController_getPropertyTimelineV2_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## POST /v1/timeline/summary

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/summary":{"post":{"operationId":"TimelineController_getSummary_v1","parameters":[{"name":"date","required":true,"in":"query","schema":{"type":"number"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-summary

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/timeline/personal-summary":{"get":{"operationId":"TimelineController_getPersonalSummary_v1","parameters":[{"name":"date","required":true,"in":"query","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/property-summary

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TimelinePropertySummaryDto":{"type":"object","properties":{"occupancyRate":{"type":"number","description":"Stored property occupancy fraction (0–1), null when unavailable. Not a preview default.","nullable":true},"propertyValue":{"type":"number","description":"Property value"},"debt":{"type":"number","description":"Debt"},"equity":{"type":"number","description":"Equity"},"debtRepayments":{"type":"number","description":"Debt repayments"},"grossYield":{"type":"number","description":"Gross yield"},"capitalGrowth":{"type":"number","description":"Capital growth"}},"required":["occupancyRate","propertyValue","debt","equity","debtRepayments","grossYield","capitalGrowth"]}}},"paths":{"/v1/timeline/property-summary":{"get":{"operationId":"TimelineController_getPropertySummary_v1","parameters":[{"name":"date","required":true,"in":"query","schema":{"type":"string"}},{"name":"propertyId","required":true,"in":"query","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":"Property summary retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelinePropertySummaryDto"}}}}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-level-strategy

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TimelinePersonalSummaryDto":{"type":"object","properties":{"cashSavings":{"type":"number","description":"Cash savings"},"portfolioValue":{"type":"number","description":"Portfolio value"},"debt":{"type":"number","description":"Debt"},"equity":{"type":"number","description":"Equity"}},"required":["cashSavings","portfolioValue","debt","equity"]}}},"paths":{"/v1/timeline/personal-level-strategy":{"get":{"operationId":"TimelineController_getPersonalLevelStrategy_v1","parameters":[{"name":"date","required":true,"in":"query","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":"Personal level strategy retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelinePersonalSummaryDto"}}}}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-level-user1

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TimelinePersonalSummaryDto":{"type":"object","properties":{"cashSavings":{"type":"number","description":"Cash savings"},"portfolioValue":{"type":"number","description":"Portfolio value"},"debt":{"type":"number","description":"Debt"},"equity":{"type":"number","description":"Equity"}},"required":["cashSavings","portfolioValue","debt","equity"]}}},"paths":{"/v1/timeline/personal-level-user1":{"get":{"operationId":"TimelineController_getPersonalLevelUser1_v1","parameters":[{"name":"date","required":true,"in":"query","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":"Personal level user1 retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelinePersonalSummaryDto"}}}}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-level-user2

>

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TimelinePersonalSummaryDto":{"type":"object","properties":{"cashSavings":{"type":"number","description":"Cash savings"},"portfolioValue":{"type":"number","description":"Portfolio value"},"debt":{"type":"number","description":"Debt"},"equity":{"type":"number","description":"Equity"}},"required":["cashSavings","portfolioValue","debt","equity"]}}},"paths":{"/v1/timeline/personal-level-user2":{"get":{"operationId":"TimelineController_getPersonalLevelUser2_v1","parameters":[{"name":"date","required":true,"in":"query","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional","schema":{"type":"string"}}],"responses":{"200":{"description":"Personal level user2 retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelinePersonalSummaryDto"}}}}},"tags":["Timeline"]}}}}
```

## GET /v1/timeline/reportable-fringe-benefit

> List reportable fringe benefit events for a strategy

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ReportableFringeBenefitResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Reportable fringe benefits for that month, $ (≥ 0). Workbook PERSONAL!2178 (User 1) / 2186 (User 2) \"Reportable Fringe Benefits\"; summed into 2182 / 2190 \"Total HECS Repayment Income\". Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2178 vs 2186."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/reportable-fringe-benefit":{"get":{"operationId":"ReportableFringeBenefitController_list_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2178); partner's id → User 2 (PERSONAL!2186), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReportableFringeBenefitResponseDto"}}}}}},"summary":"List reportable fringe benefit events for a strategy","tags":["Timeline"]}}}}
```

## Add reportable fringe benefits for a month (HECS repayment income)

> Personal-level quick action, same pattern as personal-income / personal-loan. One $ value for one person in one month → workbook PERSONAL!2178 (User 1) / 2186 (User 2) "Reportable Fringe Benefits", feeding 2182 / 2190 "Total HECS Repayment Income". The person is \`?userId=\` (client = User 1, partner = User 2). Several events in the same month sum. Appears on GET /v1/timeline/personal as type REPORTABLE\_FRINGE\_BENEFIT. Not read by the model until PERSONAL!2175–2190 is ported into sheet-all.ts.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ReportableFringeBenefitDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Reportable fringe benefits for that month, $ (≥ 0). Workbook PERSONAL!2178 (User 1) / 2186 (User 2) \"Reportable Fringe Benefits\"; summed into 2182 / 2190 \"Total HECS Repayment Income\". Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."}},"required":["date","amount"]},"ReportableFringeBenefitResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Reportable fringe benefits for that month, $ (≥ 0). Workbook PERSONAL!2178 (User 1) / 2186 (User 2) \"Reportable Fringe Benefits\"; summed into 2182 / 2190 \"Total HECS Repayment Income\". Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2178 vs 2186."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/reportable-fringe-benefit":{"post":{"description":"Personal-level quick action, same pattern as personal-income / personal-loan. One $ value for one person in one month → workbook PERSONAL!2178 (User 1) / 2186 (User 2) \"Reportable Fringe Benefits\", feeding 2182 / 2190 \"Total HECS Repayment Income\". The person is `?userId=` (client = User 1, partner = User 2). Several events in the same month sum. Appears on GET /v1/timeline/personal as type REPORTABLE_FRINGE_BENEFIT. Not read by the model until PERSONAL!2175–2190 is ported into sheet-all.ts.","operationId":"ReportableFringeBenefitController_add_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2178); partner's id → User 2 (PERSONAL!2186), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportableFringeBenefitDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportableFringeBenefitResponseDto"}}}}},"summary":"Add reportable fringe benefits for a month (HECS repayment income)","tags":["Timeline"]}}}}
```

## GET /v1/timeline/reportable-fringe-benefit/{id}

> Get one reportable fringe benefit event

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ReportableFringeBenefitResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Reportable fringe benefits for that month, $ (≥ 0). Workbook PERSONAL!2178 (User 1) / 2186 (User 2) \"Reportable Fringe Benefits\"; summed into 2182 / 2190 \"Total HECS Repayment Income\". Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2178 vs 2186."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/reportable-fringe-benefit/{id}":{"get":{"operationId":"ReportableFringeBenefitController_get_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2178); partner's id → User 2 (PERSONAL!2186), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportableFringeBenefitResponseDto"}}}}},"summary":"Get one reportable fringe benefit event","tags":["Timeline"]}}}}
```

## PUT /v1/timeline/reportable-fringe-benefit/{id}

> Update a reportable fringe benefit event (partial)

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UpdateReportableFringeBenefitDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Reportable fringe benefits for that month, $ (≥ 0). Workbook PERSONAL!2178 (User 1) / 2186 (User 2) \"Reportable Fringe Benefits\"; summed into 2182 / 2190 \"Total HECS Repayment Income\". Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."}}},"ReportableFringeBenefitResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Reportable fringe benefits for that month, $ (≥ 0). Workbook PERSONAL!2178 (User 1) / 2186 (User 2) \"Reportable Fringe Benefits\"; summed into 2182 / 2190 \"Total HECS Repayment Income\". Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2178 vs 2186."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/reportable-fringe-benefit/{id}":{"put":{"operationId":"ReportableFringeBenefitController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2178); partner's id → User 2 (PERSONAL!2186), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReportableFringeBenefitDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportableFringeBenefitResponseDto"}}}}},"summary":"Update a reportable fringe benefit event (partial)","tags":["Timeline"]}}}}
```

## DELETE /v1/timeline/reportable-fringe-benefit/{id}

> Delete a reportable fringe benefit event

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ReportableFringeBenefitResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Reportable fringe benefits for that month, $ (≥ 0). Workbook PERSONAL!2178 (User 1) / 2186 (User 2) \"Reportable Fringe Benefits\"; summed into 2182 / 2190 \"Total HECS Repayment Income\". Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2178 vs 2186."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/reportable-fringe-benefit/{id}":{"delete":{"operationId":"ReportableFringeBenefitController_remove_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2178); partner's id → User 2 (PERSONAL!2186), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportableFringeBenefitResponseDto"}}}}},"summary":"Delete a reportable fringe benefit event","tags":["Timeline"]}}}}
```

## List company dividends for a strategy

> Entity-level quick action — every Company's monthly dividend events on this strategy, ordered by month then creation. Filter one Company with \`?entityId=\`. Cells PERSONAL!1814–1818 (slot 3; +7 rows per slot). Each row also appears on GET /v1/timeline/personal as \`company\_dividend\`. Not read by the model until the adapter emits Inputs\_EntityDefinitions with DividendsClaimed\[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CompanyDividendResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Company entity the dividend is claimed from."},"date":{"type":"string","format":"date","description":"The month claimed in (YYYY-MM-DD, as stored)."},"owner1Amount":{"type":"number","description":"PERSONAL!1814 (slot 3), $."},"owner2Amount":{"type":"number","description":"PERSONAL!1815 (slot 3), $."},"owner3Amount":{"type":"number","description":"PERSONAL!1816 (slot 3), $."},"owner4Amount":{"type":"number","description":"PERSONAL!1817 (slot 3), $."},"owner5Amount":{"type":"number","description":"PERSONAL!1818 (slot 3), $."},"totalAmount":{"type":"number","description":"Sum of the five owner amounts — the block Total (PERSONAL!1819 for slot 3), which `2020 Dividends declared (all cos)` sums across Company entities. Derived, not stored."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Amount","owner2Amount","owner3Amount","owner4Amount","owner5Amount","totalAmount","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/company-dividend":{"get":{"description":"Entity-level quick action — every Company's monthly dividend events on this strategy, ordered by month then creation. Filter one Company with `?entityId=`. Cells PERSONAL!1814–1818 (slot 3; +7 rows per slot). Each row also appears on GET /v1/timeline/personal as `company_dividend`. Not read by the model until the adapter emits Inputs_EntityDefinitions with DividendsClaimed[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).","operationId":"CompanyDividendController_list_v1","parameters":[{"name":"entityId","required":false,"in":"query","description":"Only dividends for this Company entity.","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CompanyDividendResponseDto"}}}}}},"summary":"List company dividends for a strategy","tags":["Timeline"]}}}}
```

## Add a company dividend for a month

> Entity-level quick action: a Company's dividend claimed in one month as five owner amounts (owner slots 1–5 = \`/v1/entities\` \`owners\[]\`, INPUTS!243–247). Cells: PERSONAL!1814–1818 for the first related entity (workbook slot 3), +7 rows per further slot; the block Total (1819) is returned as \`totalAmount\` and feeds \`2020 Dividends declared (all cos)\` → franking / grossed-up → User 1/2 (2021–2029, 2128/2129). 0 / omitted owner = nothing to that owner. The entity must be a Company (else 400) in this strategy (else 404). Appears on GET /v1/timeline/personal as \`company\_dividend\`. Not read by the model until the adapter emits Inputs\_EntityDefinitions with DividendsClaimed\[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CompanyDividendDto":{"type":"object","properties":{"entityId":{"type":"string","description":"The Company entity (from `/v1/entities`) claiming the dividend. Must be in the request's strategy (else 404) and `entityType = Company` (else 400)."},"date":{"type":"string","format":"date","description":"The month the dividend is claimed in, YYYY-MM-DD — the PERSONAL column whose M$4..M$5 bounds contain it. Any day in the month works; stored as given."},"owner1Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 1 (`/v1/entities` `owners[0]`, INPUTS!243) in the month. Workbook PERSONAL!1814 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 0)`. 0 / omitted = nothing to this owner."},"owner2Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 2 (`/v1/entities` `owners[1]`, INPUTS!244) in the month. Workbook PERSONAL!1815 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 1)`. 0 / omitted = nothing to this owner."},"owner3Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 3 (`/v1/entities` `owners[2]`, INPUTS!245) in the month. Workbook PERSONAL!1816 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 2)`. 0 / omitted = nothing to this owner."},"owner4Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 4 (`/v1/entities` `owners[3]`, INPUTS!246) in the month. Workbook PERSONAL!1817 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 3)`. 0 / omitted = nothing to this owner."},"owner5Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 5 (`/v1/entities` `owners[4]`, INPUTS!247) in the month. Workbook PERSONAL!1818 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 4)`. 0 / omitted = nothing to this owner."}},"required":["entityId","date"]},"CompanyDividendResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Company entity the dividend is claimed from."},"date":{"type":"string","format":"date","description":"The month claimed in (YYYY-MM-DD, as stored)."},"owner1Amount":{"type":"number","description":"PERSONAL!1814 (slot 3), $."},"owner2Amount":{"type":"number","description":"PERSONAL!1815 (slot 3), $."},"owner3Amount":{"type":"number","description":"PERSONAL!1816 (slot 3), $."},"owner4Amount":{"type":"number","description":"PERSONAL!1817 (slot 3), $."},"owner5Amount":{"type":"number","description":"PERSONAL!1818 (slot 3), $."},"totalAmount":{"type":"number","description":"Sum of the five owner amounts — the block Total (PERSONAL!1819 for slot 3), which `2020 Dividends declared (all cos)` sums across Company entities. Derived, not stored."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Amount","owner2Amount","owner3Amount","owner4Amount","owner5Amount","totalAmount","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/company-dividend":{"post":{"description":"Entity-level quick action: a Company's dividend claimed in one month as five owner amounts (owner slots 1–5 = `/v1/entities` `owners[]`, INPUTS!243–247). Cells: PERSONAL!1814–1818 for the first related entity (workbook slot 3), +7 rows per further slot; the block Total (1819) is returned as `totalAmount` and feeds `2020 Dividends declared (all cos)` → franking / grossed-up → User 1/2 (2021–2029, 2128/2129). 0 / omitted owner = nothing to that owner. The entity must be a Company (else 400) in this strategy (else 404). Appears on GET /v1/timeline/personal as `company_dividend`. Not read by the model until the adapter emits Inputs_EntityDefinitions with DividendsClaimed[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).","operationId":"CompanyDividendController_add_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDividendDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDividendResponseDto"}}}}},"summary":"Add a company dividend for a month","tags":["Timeline"]}}}}
```

## Get one company dividend

> Entity-level quick action — one Company's monthly dividend event, by id; 404 unless it belongs to this strategy. Cells PERSONAL!1814–1818 (slot 3; +7 rows per slot). Appears on GET /v1/timeline/personal as \`company\_dividend\`. Not read by the model until the adapter emits Inputs\_EntityDefinitions with DividendsClaimed\[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CompanyDividendResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Company entity the dividend is claimed from."},"date":{"type":"string","format":"date","description":"The month claimed in (YYYY-MM-DD, as stored)."},"owner1Amount":{"type":"number","description":"PERSONAL!1814 (slot 3), $."},"owner2Amount":{"type":"number","description":"PERSONAL!1815 (slot 3), $."},"owner3Amount":{"type":"number","description":"PERSONAL!1816 (slot 3), $."},"owner4Amount":{"type":"number","description":"PERSONAL!1817 (slot 3), $."},"owner5Amount":{"type":"number","description":"PERSONAL!1818 (slot 3), $."},"totalAmount":{"type":"number","description":"Sum of the five owner amounts — the block Total (PERSONAL!1819 for slot 3), which `2020 Dividends declared (all cos)` sums across Company entities. Derived, not stored."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Amount","owner2Amount","owner3Amount","owner4Amount","owner5Amount","totalAmount","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/company-dividend/{id}":{"get":{"description":"Entity-level quick action — one Company's monthly dividend event, by id; 404 unless it belongs to this strategy. Cells PERSONAL!1814–1818 (slot 3; +7 rows per slot). Appears on GET /v1/timeline/personal as `company_dividend`. Not read by the model until the adapter emits Inputs_EntityDefinitions with DividendsClaimed[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).","operationId":"CompanyDividendController_get_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDividendResponseDto"}}}}},"summary":"Get one company dividend","tags":["Timeline"]}}}}
```

## Update a company dividend (partial)

> Entity-level quick action — any subset of the POST fields. A new \`entityId\` must be a Company in this strategy; \`totalAmount\` is re-derived. Cells PERSONAL!1814–1818 (slot 3; +7 rows per slot). Appears on GET /v1/timeline/personal as \`company\_dividend\`. Not read by the model until the adapter emits Inputs\_EntityDefinitions with DividendsClaimed\[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UpdateCompanyDividendDto":{"type":"object","properties":{"entityId":{"type":"string","description":"The Company entity (from `/v1/entities`) claiming the dividend. Must be in the request's strategy (else 404) and `entityType = Company` (else 400)."},"date":{"type":"string","format":"date","description":"The month the dividend is claimed in, YYYY-MM-DD — the PERSONAL column whose M$4..M$5 bounds contain it. Any day in the month works; stored as given."},"owner1Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 1 (`/v1/entities` `owners[0]`, INPUTS!243) in the month. Workbook PERSONAL!1814 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 0)`. 0 / omitted = nothing to this owner."},"owner2Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 2 (`/v1/entities` `owners[1]`, INPUTS!244) in the month. Workbook PERSONAL!1815 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 1)`. 0 / omitted = nothing to this owner."},"owner3Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 3 (`/v1/entities` `owners[2]`, INPUTS!245) in the month. Workbook PERSONAL!1816 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 2)`. 0 / omitted = nothing to this owner."},"owner4Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 4 (`/v1/entities` `owners[3]`, INPUTS!246) in the month. Workbook PERSONAL!1817 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 3)`. 0 / omitted = nothing to this owner."},"owner5Amount":{"type":"number","default":0,"minimum":0,"description":"Dividend $ claimed by owner slot 5 (`/v1/entities` `owners[4]`, INPUTS!247) in the month. Workbook PERSONAL!1818 for the first related entity (workbook slot 3); +7 rows per further entity slot. Port: `personalCompanyClaimedDividend(section, beneficiary = 4)`. 0 / omitted = nothing to this owner."}}},"CompanyDividendResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Company entity the dividend is claimed from."},"date":{"type":"string","format":"date","description":"The month claimed in (YYYY-MM-DD, as stored)."},"owner1Amount":{"type":"number","description":"PERSONAL!1814 (slot 3), $."},"owner2Amount":{"type":"number","description":"PERSONAL!1815 (slot 3), $."},"owner3Amount":{"type":"number","description":"PERSONAL!1816 (slot 3), $."},"owner4Amount":{"type":"number","description":"PERSONAL!1817 (slot 3), $."},"owner5Amount":{"type":"number","description":"PERSONAL!1818 (slot 3), $."},"totalAmount":{"type":"number","description":"Sum of the five owner amounts — the block Total (PERSONAL!1819 for slot 3), which `2020 Dividends declared (all cos)` sums across Company entities. Derived, not stored."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Amount","owner2Amount","owner3Amount","owner4Amount","owner5Amount","totalAmount","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/company-dividend/{id}":{"put":{"description":"Entity-level quick action — any subset of the POST fields. A new `entityId` must be a Company in this strategy; `totalAmount` is re-derived. Cells PERSONAL!1814–1818 (slot 3; +7 rows per slot). Appears on GET /v1/timeline/personal as `company_dividend`. Not read by the model until the adapter emits Inputs_EntityDefinitions with DividendsClaimed[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).","operationId":"CompanyDividendController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCompanyDividendDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDividendResponseDto"}}}}},"summary":"Update a company dividend (partial)","tags":["Timeline"]}}}}
```

## Delete a company dividend

> Entity-level quick action — removes the Company's dividend for that month, so the block cells go back to 0. Returns the deleted row. Cells PERSONAL!1814–1818 (slot 3; +7 rows per slot). The \`company\_dividend\` dot leaves GET /v1/timeline/personal. Not read by the model until the adapter emits Inputs\_EntityDefinitions with DividendsClaimed\[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CompanyDividendResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Company entity the dividend is claimed from."},"date":{"type":"string","format":"date","description":"The month claimed in (YYYY-MM-DD, as stored)."},"owner1Amount":{"type":"number","description":"PERSONAL!1814 (slot 3), $."},"owner2Amount":{"type":"number","description":"PERSONAL!1815 (slot 3), $."},"owner3Amount":{"type":"number","description":"PERSONAL!1816 (slot 3), $."},"owner4Amount":{"type":"number","description":"PERSONAL!1817 (slot 3), $."},"owner5Amount":{"type":"number","description":"PERSONAL!1818 (slot 3), $."},"totalAmount":{"type":"number","description":"Sum of the five owner amounts — the block Total (PERSONAL!1819 for slot 3), which `2020 Dividends declared (all cos)` sums across Company entities. Derived, not stored."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Amount","owner2Amount","owner3Amount","owner4Amount","owner5Amount","totalAmount","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/company-dividend/{id}":{"delete":{"description":"Entity-level quick action — removes the Company's dividend for that month, so the block cells go back to 0. Returns the deleted row. Cells PERSONAL!1814–1818 (slot 3; +7 rows per slot). The `company_dividend` dot leaves GET /v1/timeline/personal. Not read by the model until the adapter emits Inputs_EntityDefinitions with DividendsClaimed[0..4] per entity slot and the port's personalCompanyClaimedDividend reads per period (it currently ignores date).","operationId":"CompanyDividendController_remove_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDividendResponseDto"}}}}},"summary":"Delete a company dividend","tags":["Timeline"]}}}}
```

## List trust distribution overrides for a strategy

> Entity-level quick action — every Trust's dated overrides of its distribution split on this strategy, ordered by the snapped June then creation. Filter one Trust with \`?entityId=\`. Cells PERSONAL!M1350:M1354 (slot 3; +63 rows per slot). Each row also appears on GET /v1/timeline/personal as \`trust\_distribution\`. Not read by the model until the adapter emits Inputs\_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TrustDistributionResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Trust entity the override applies to."},"date":{"type":"string","format":"date","description":"The 30 June the event was snapped to (YYYY-06-30) — the PERSONAL column in which the percents apply."},"owner1Percent":{"type":"number","description":"PERSONAL!M1350 (slot 3), 0–100."},"owner2Percent":{"type":"number","description":"PERSONAL!M1351 (slot 3), 0–100."},"owner3Percent":{"type":"number","description":"PERSONAL!M1352 (slot 3), 0–100."},"owner4Percent":{"type":"number","description":"PERSONAL!M1353 (slot 3), 0–100."},"owner5Percent":{"type":"number","description":"PERSONAL!M1354 (slot 3), 0–100."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Percent","owner2Percent","owner3Percent","owner4Percent","owner5Percent","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/trust-distribution":{"get":{"description":"Entity-level quick action — every Trust's dated overrides of its distribution split on this strategy, ordered by the snapped June then creation. Filter one Trust with `?entityId=`. Cells PERSONAL!M1350:M1354 (slot 3; +63 rows per slot). Each row also appears on GET /v1/timeline/personal as `trust_distribution`. Not read by the model until the adapter emits Inputs_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).","operationId":"TrustDistributionController_list_v1","parameters":[{"name":"entityId","required":false,"in":"query","description":"Only overrides for this Trust entity.","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TrustDistributionResponseDto"}}}}}},"summary":"List trust distribution overrides for a strategy","tags":["Timeline"]}}}}
```

## Add a trust distribution override for a financial year

> Entity-level quick action: the Trust's dated override of its standing distribution split (\`/v1/entities\` \`trust.cashDistribution.owner1..5Percent\`, PERSONAL!J1350:J1354). One event = one Trust entity + one financial year + five owner percentages. \`date\` may be any day; it is stored snapped to that FY's 30 June because the distribution fires in the June column only (PERSONAL!M590). Cells: PERSONAL!M1350:M1354 for the first related entity (workbook slot 3), +63 rows per further slot; 0 / omitted = keep the entity default. Percents must sum to ≤ 100 (else 400); the entity must be a Trust (else 400) in this strategy (else 404). Appears on GET /v1/timeline/personal as \`trust\_distribution\`. Not read by the model until the adapter emits Inputs\_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TrustDistributionDto":{"type":"object","properties":{"entityId":{"type":"string","description":"The Trust entity (from `/v1/entities`) whose distribution split this overrides. Must be in the request's strategy (else 404) and `entityType = Trust` (else 400)."},"date":{"type":"string","format":"date","description":"Any day in the financial year the override is for, YYYY-MM-DD. Stored and returned snapped to that FY's 30 June (Australian FY: July–December → 30 June of the next calendar year; January–June → 30 June of the same year), because the distribution only fires in the June column (PERSONAL!M590 = MONTH(M$4)=6). PUT with a new `date` re-snaps."},"owner1Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 1 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner1Percent`). Workbook PERSONAL!M1350 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1350, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."},"owner2Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 2 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner2Percent`). Workbook PERSONAL!M1351 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1351, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."},"owner3Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 3 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner3Percent`). Workbook PERSONAL!M1352 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1352, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."},"owner4Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 4 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner4Percent`). Workbook PERSONAL!M1353 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1353, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."},"owner5Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 5 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner5Percent`). Workbook PERSONAL!M1354 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1354, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."}},"required":["entityId","date"]},"TrustDistributionResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Trust entity the override applies to."},"date":{"type":"string","format":"date","description":"The 30 June the event was snapped to (YYYY-06-30) — the PERSONAL column in which the percents apply."},"owner1Percent":{"type":"number","description":"PERSONAL!M1350 (slot 3), 0–100."},"owner2Percent":{"type":"number","description":"PERSONAL!M1351 (slot 3), 0–100."},"owner3Percent":{"type":"number","description":"PERSONAL!M1352 (slot 3), 0–100."},"owner4Percent":{"type":"number","description":"PERSONAL!M1353 (slot 3), 0–100."},"owner5Percent":{"type":"number","description":"PERSONAL!M1354 (slot 3), 0–100."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Percent","owner2Percent","owner3Percent","owner4Percent","owner5Percent","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/trust-distribution":{"post":{"description":"Entity-level quick action: the Trust's dated override of its standing distribution split (`/v1/entities` `trust.cashDistribution.owner1..5Percent`, PERSONAL!J1350:J1354). One event = one Trust entity + one financial year + five owner percentages. `date` may be any day; it is stored snapped to that FY's 30 June because the distribution fires in the June column only (PERSONAL!M590). Cells: PERSONAL!M1350:M1354 for the first related entity (workbook slot 3), +63 rows per further slot; 0 / omitted = keep the entity default. Percents must sum to ≤ 100 (else 400); the entity must be a Trust (else 400) in this strategy (else 404). Appears on GET /v1/timeline/personal as `trust_distribution`. Not read by the model until the adapter emits Inputs_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).","operationId":"TrustDistributionController_add_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrustDistributionDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrustDistributionResponseDto"}}}}},"summary":"Add a trust distribution override for a financial year","tags":["Timeline"]}}}}
```

## Get one trust distribution override

> Entity-level quick action — one Trust's dated override of its distribution split, by id; 404 unless it belongs to this strategy. \`date\` is the snapped 30 June. Cells PERSONAL!M1350:M1354 (slot 3; +63 rows per slot). Appears on GET /v1/timeline/personal as \`trust\_distribution\`. Not read by the model until the adapter emits Inputs\_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TrustDistributionResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Trust entity the override applies to."},"date":{"type":"string","format":"date","description":"The 30 June the event was snapped to (YYYY-06-30) — the PERSONAL column in which the percents apply."},"owner1Percent":{"type":"number","description":"PERSONAL!M1350 (slot 3), 0–100."},"owner2Percent":{"type":"number","description":"PERSONAL!M1351 (slot 3), 0–100."},"owner3Percent":{"type":"number","description":"PERSONAL!M1352 (slot 3), 0–100."},"owner4Percent":{"type":"number","description":"PERSONAL!M1353 (slot 3), 0–100."},"owner5Percent":{"type":"number","description":"PERSONAL!M1354 (slot 3), 0–100."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Percent","owner2Percent","owner3Percent","owner4Percent","owner5Percent","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/trust-distribution/{id}":{"get":{"description":"Entity-level quick action — one Trust's dated override of its distribution split, by id; 404 unless it belongs to this strategy. `date` is the snapped 30 June. Cells PERSONAL!M1350:M1354 (slot 3; +63 rows per slot). Appears on GET /v1/timeline/personal as `trust_distribution`. Not read by the model until the adapter emits Inputs_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).","operationId":"TrustDistributionController_get_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrustDistributionResponseDto"}}}}},"summary":"Get one trust distribution override","tags":["Timeline"]}}}}
```

## Update a trust distribution override (partial)

> Entity-level quick action — any subset of the POST fields. A new \`date\` is re-snapped to its FY's 30 June; the resulting percents must still sum to ≤ 100; a new \`entityId\` must be a Trust in this strategy. Cells PERSONAL!M1350:M1354 (slot 3; +63 rows per slot). Appears on GET /v1/timeline/personal as \`trust\_distribution\`. Not read by the model until the adapter emits Inputs\_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UpdateTrustDistributionDto":{"type":"object","properties":{"entityId":{"type":"string","description":"The Trust entity (from `/v1/entities`) whose distribution split this overrides. Must be in the request's strategy (else 404) and `entityType = Trust` (else 400)."},"date":{"type":"string","format":"date","description":"Any day in the financial year the override is for, YYYY-MM-DD. Stored and returned snapped to that FY's 30 June (Australian FY: July–December → 30 June of the next calendar year; January–June → 30 June of the same year), because the distribution only fires in the June column (PERSONAL!M590 = MONTH(M$4)=6). PUT with a new `date` re-snaps."},"owner1Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 1 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner1Percent`). Workbook PERSONAL!M1350 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1350, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."},"owner2Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 2 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner2Percent`). Workbook PERSONAL!M1351 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1351, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."},"owner3Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 3 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner3Percent`). Workbook PERSONAL!M1352 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1352, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."},"owner4Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 4 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner4Percent`). Workbook PERSONAL!M1353 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1353, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."},"owner5Percent":{"type":"number","default":0,"minimum":0,"maximum":100,"description":"Distribution % to owner slot 5 for the financial year, 0–100 (same unit as `/v1/entities` `trust.cashDistribution.owner5Percent`). Workbook PERSONAL!M1354 for the first related entity (workbook slot 3); +63 rows per further entity slot. 0 / omitted = keep the entity default (PERSONAL!J1354, the standing APPLIED %). The five percents may sum to less than 100 (the sheet charges 47% penalty tax on the gap, 1330) but not more."}}},"TrustDistributionResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Trust entity the override applies to."},"date":{"type":"string","format":"date","description":"The 30 June the event was snapped to (YYYY-06-30) — the PERSONAL column in which the percents apply."},"owner1Percent":{"type":"number","description":"PERSONAL!M1350 (slot 3), 0–100."},"owner2Percent":{"type":"number","description":"PERSONAL!M1351 (slot 3), 0–100."},"owner3Percent":{"type":"number","description":"PERSONAL!M1352 (slot 3), 0–100."},"owner4Percent":{"type":"number","description":"PERSONAL!M1353 (slot 3), 0–100."},"owner5Percent":{"type":"number","description":"PERSONAL!M1354 (slot 3), 0–100."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Percent","owner2Percent","owner3Percent","owner4Percent","owner5Percent","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/trust-distribution/{id}":{"put":{"description":"Entity-level quick action — any subset of the POST fields. A new `date` is re-snapped to its FY's 30 June; the resulting percents must still sum to ≤ 100; a new `entityId` must be a Trust in this strategy. Cells PERSONAL!M1350:M1354 (slot 3; +63 rows per slot). Appears on GET /v1/timeline/personal as `trust_distribution`. Not read by the model until the adapter emits Inputs_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).","operationId":"TrustDistributionController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTrustDistributionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrustDistributionResponseDto"}}}}},"summary":"Update a trust distribution override (partial)","tags":["Timeline"]}}}}
```

## Delete a trust distribution override

> Entity-level quick action — removes the Trust's dated override for that FY, so the June goes back to the entity default (PERSONAL!J1350:J1354). Returns the deleted row. Cells PERSONAL!M1350:M1354 (slot 3; +63 rows per slot). The \`trust\_distribution\` dot leaves GET /v1/timeline/personal. Not read by the model until the adapter emits Inputs\_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TrustDistributionResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The Trust entity the override applies to."},"date":{"type":"string","format":"date","description":"The 30 June the event was snapped to (YYYY-06-30) — the PERSONAL column in which the percents apply."},"owner1Percent":{"type":"number","description":"PERSONAL!M1350 (slot 3), 0–100."},"owner2Percent":{"type":"number","description":"PERSONAL!M1351 (slot 3), 0–100."},"owner3Percent":{"type":"number","description":"PERSONAL!M1352 (slot 3), 0–100."},"owner4Percent":{"type":"number","description":"PERSONAL!M1353 (slot 3), 0–100."},"owner5Percent":{"type":"number","description":"PERSONAL!M1354 (slot 3), 0–100."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","date","owner1Percent","owner2Percent","owner3Percent","owner4Percent","owner5Percent","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/trust-distribution/{id}":{"delete":{"description":"Entity-level quick action — removes the Trust's dated override for that FY, so the June goes back to the entity default (PERSONAL!J1350:J1354). Returns the deleted row. Cells PERSONAL!M1350:M1354 (slot 3; +63 rows per slot). The `trust_distribution` dot leaves GET /v1/timeline/personal. Not read by the model until the adapter emits Inputs_EntityDefinitions and the port reads M1350:M1354 per period (personalTrustBeneficiaryPct currently ignores date).","operationId":"TrustDistributionController_remove_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrustDistributionResponseDto"}}}}},"summary":"Delete a trust distribution override","tags":["Timeline"]}}}}
```

## List entity cash contributions and withdrawals for a strategy

> Entity-level quick action — every cash contribution / withdrawal on this strategy's entities, ordered by date then creation. Filter one entity with \`?entityId=\` and one direction with \`?direction=\`. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. \`ownerSlot\` picks the row. Each row also Appears on GET /v1/timeline/personal as \`entity\_cash\_flow\` with \`actionType\` ADD (CONTRIBUTION) / WITHDRAW (WITHDRAWAL). Not read by the model until the adapter emits Inputs\_EntityDefinitions and PERSONAL\_M1312 / M1313 are ported.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"EntityCashFlowResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The related entity the cash moves into or out of."},"entityName":{"type":"string","description":"The entity's name (`/v1/entities` `entityName`, INPUTS!199). Read-only."},"ownerSlot":{"type":"number","minimum":1,"maximum":5,"description":"Which owner (1–5) the cash comes from (CONTRIBUTION) or goes to (WITHDRAWAL) — the dropdown is the entity's `owners[]` from `/v1/entities` (INPUTS!243–247). Picks the row in the block: first related entity (workbook slot 3) contribution owner 1 → PERSONAL!1872 … owner 5 → 1876 (total 1877); withdrawal owner 1 → 1930 … owner 5 → 1934 (total 1935); +7 rows per further entity slot. The slot must be a non-empty owner on that entity (else 400)."},"ownerName":{"type":"string","description":"The owner's name for that slot (`/v1/entities` `owners[].ownerName`, INPUTS!243–247) — the label on the owner row (slot 3: 1872–1876 / 1930–1934). Read-only."},"ownerUserId":{"type":"string","nullable":true,"description":"The user this owner is when the slot is linked to a ScaleApp account (`owners[].userId`, INPUTS!262–266 Linked ID — typically owner 1 / 2 = the client / partner); `null` when the owner is another entity or unlinked. Read-only."},"date":{"type":"string","format":"date","description":"The stored day, YYYY-MM-DD — the PERSONAL month column the $ lands in."},"amount":{"type":"number","description":"$ moved. Owner-row cell of PERSONAL!1870 (CONTRIBUTION; slot 3 rows 1872–1876) or 1928 (WITHDRAWAL; slot 3 rows 1930–1934) for that month."},"direction":{"type":"string","enum":["CONTRIBUTION","WITHDRAWAL"],"description":"`CONTRIBUTION` = owner → entity, lands in the PERSONAL!1870 CASH CONTRIBUTIONS block and is summed by entity slot into the entity's `1312 + Cash contributions / injections`. `WITHDRAWAL` = entity → owner, lands in the PERSONAL!1928 CASH WITHDRAWALS block and is summed into `1313 − Cash withdrawals`."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","entityName","ownerSlot","ownerName","ownerUserId","date","amount","direction","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/entity-cash-flow":{"get":{"description":"Entity-level quick action — every cash contribution / withdrawal on this strategy's entities, ordered by date then creation. Filter one entity with `?entityId=` and one direction with `?direction=`. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. `ownerSlot` picks the row. Each row also Appears on GET /v1/timeline/personal as `entity_cash_flow` with `actionType` ADD (CONTRIBUTION) / WITHDRAW (WITHDRAWAL). Not read by the model until the adapter emits Inputs_EntityDefinitions and PERSONAL_M1312 / M1313 are ported.","operationId":"EntityCashFlowController_list_v1","parameters":[{"name":"entityId","required":false,"in":"query","description":"Only events for this entity.","schema":{"type":"string"}},{"name":"direction","required":false,"in":"query","description":"Only `CONTRIBUTION` (1870 block) or only `WITHDRAWAL` (1928 block) events.","schema":{"enum":["CONTRIBUTION","WITHDRAWAL"],"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityCashFlowResponseDto"}}}}}},"summary":"List entity cash contributions and withdrawals for a strategy","tags":["Timeline"]}}}}
```

## Add an entity cash contribution or withdrawal

> Entity-level quick action: one $ in one month from a chosen owner into the entity (\`direction = CONTRIBUTION\`, PERSONAL!1870 block) or back out to that owner (\`direction = WITHDRAWAL\`, PERSONAL!1928 block). One event = one entity + one owner slot + one month + one amount. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. \`ownerSlot\` picks the row. \`entityId\` must be an active entity of this strategy (else 404), any type; \`ownerSlot\` (1–5, the entity's \`owners\[]\` dropdown) must be a non-empty owner on it (else 400). Appears on GET /v1/timeline/personal as \`entity\_cash\_flow\` with \`actionType\` ADD (CONTRIBUTION) / WITHDRAW (WITHDRAWAL). Not read by the model until the adapter emits Inputs\_EntityDefinitions and PERSONAL\_M1312 / M1313 are ported.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"EntityCashFlowDto":{"type":"object","properties":{"entityId":{"type":"string","description":"The related entity (from `/v1/entities`; Company / Trust / SMSF — any type) the cash moves into or out of. Must be an active entity of the request's strategy (else 404). Decides which 1870 / 1928 block (its workbook slot) and which `1310 CASH ACCOUNT` (1312 / 1313) the $ reaches."},"ownerSlot":{"type":"number","minimum":1,"maximum":5,"description":"Which owner (1–5) the cash comes from (CONTRIBUTION) or goes to (WITHDRAWAL) — the dropdown is the entity's `owners[]` from `/v1/entities` (INPUTS!243–247). Picks the row in the block: first related entity (workbook slot 3) contribution owner 1 → PERSONAL!1872 … owner 5 → 1876 (total 1877); withdrawal owner 1 → 1930 … owner 5 → 1934 (total 1935); +7 rows per further entity slot. The slot must be a non-empty owner on that entity (else 400)."},"date":{"type":"string","format":"date","description":"Any day in the month the $ lands in, YYYY-MM-DD. The value sits in the PERSONAL period column whose M$4..M$5 bounds contain it; several events in one month for the same entity sum on the entity side (1312 / 1313 are SUMIFs)."},"amount":{"type":"number","minimum":0,"description":"$ moved, ≥ 0. The owner-row cell of the 1870 block (CONTRIBUTION; slot 3 rows 1872–1876) or the 1928 block (WITHDRAWAL; slot 3 rows 1930–1934) for that month."},"direction":{"type":"string","enum":["CONTRIBUTION","WITHDRAWAL"],"description":"`CONTRIBUTION` = owner → entity, lands in the PERSONAL!1870 CASH CONTRIBUTIONS block and is summed by entity slot into the entity's `1312 + Cash contributions / injections`. `WITHDRAWAL` = entity → owner, lands in the PERSONAL!1928 CASH WITHDRAWALS block and is summed into `1313 − Cash withdrawals`."}},"required":["entityId","ownerSlot","date","amount","direction"]},"EntityCashFlowResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The related entity the cash moves into or out of."},"entityName":{"type":"string","description":"The entity's name (`/v1/entities` `entityName`, INPUTS!199). Read-only."},"ownerSlot":{"type":"number","minimum":1,"maximum":5,"description":"Which owner (1–5) the cash comes from (CONTRIBUTION) or goes to (WITHDRAWAL) — the dropdown is the entity's `owners[]` from `/v1/entities` (INPUTS!243–247). Picks the row in the block: first related entity (workbook slot 3) contribution owner 1 → PERSONAL!1872 … owner 5 → 1876 (total 1877); withdrawal owner 1 → 1930 … owner 5 → 1934 (total 1935); +7 rows per further entity slot. The slot must be a non-empty owner on that entity (else 400)."},"ownerName":{"type":"string","description":"The owner's name for that slot (`/v1/entities` `owners[].ownerName`, INPUTS!243–247) — the label on the owner row (slot 3: 1872–1876 / 1930–1934). Read-only."},"ownerUserId":{"type":"string","nullable":true,"description":"The user this owner is when the slot is linked to a ScaleApp account (`owners[].userId`, INPUTS!262–266 Linked ID — typically owner 1 / 2 = the client / partner); `null` when the owner is another entity or unlinked. Read-only."},"date":{"type":"string","format":"date","description":"The stored day, YYYY-MM-DD — the PERSONAL month column the $ lands in."},"amount":{"type":"number","description":"$ moved. Owner-row cell of PERSONAL!1870 (CONTRIBUTION; slot 3 rows 1872–1876) or 1928 (WITHDRAWAL; slot 3 rows 1930–1934) for that month."},"direction":{"type":"string","enum":["CONTRIBUTION","WITHDRAWAL"],"description":"`CONTRIBUTION` = owner → entity, lands in the PERSONAL!1870 CASH CONTRIBUTIONS block and is summed by entity slot into the entity's `1312 + Cash contributions / injections`. `WITHDRAWAL` = entity → owner, lands in the PERSONAL!1928 CASH WITHDRAWALS block and is summed into `1313 − Cash withdrawals`."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","entityName","ownerSlot","ownerName","ownerUserId","date","amount","direction","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/entity-cash-flow":{"post":{"description":"Entity-level quick action: one $ in one month from a chosen owner into the entity (`direction = CONTRIBUTION`, PERSONAL!1870 block) or back out to that owner (`direction = WITHDRAWAL`, PERSONAL!1928 block). One event = one entity + one owner slot + one month + one amount. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. `ownerSlot` picks the row. `entityId` must be an active entity of this strategy (else 404), any type; `ownerSlot` (1–5, the entity's `owners[]` dropdown) must be a non-empty owner on it (else 400). Appears on GET /v1/timeline/personal as `entity_cash_flow` with `actionType` ADD (CONTRIBUTION) / WITHDRAW (WITHDRAWAL). Not read by the model until the adapter emits Inputs_EntityDefinitions and PERSONAL_M1312 / M1313 are ported.","operationId":"EntityCashFlowController_add_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityCashFlowDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityCashFlowResponseDto"}}}}},"summary":"Add an entity cash contribution or withdrawal","tags":["Timeline"]}}}}
```

## Get one entity cash contribution or withdrawal

> Entity-level quick action — one cash contribution / withdrawal by id; 404 unless it belongs to this strategy. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. \`ownerSlot\` picks the row. Appears on GET /v1/timeline/personal as \`entity\_cash\_flow\` with \`actionType\` ADD (CONTRIBUTION) / WITHDRAW (WITHDRAWAL). Not read by the model until the adapter emits Inputs\_EntityDefinitions and PERSONAL\_M1312 / M1313 are ported.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"EntityCashFlowResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The related entity the cash moves into or out of."},"entityName":{"type":"string","description":"The entity's name (`/v1/entities` `entityName`, INPUTS!199). Read-only."},"ownerSlot":{"type":"number","minimum":1,"maximum":5,"description":"Which owner (1–5) the cash comes from (CONTRIBUTION) or goes to (WITHDRAWAL) — the dropdown is the entity's `owners[]` from `/v1/entities` (INPUTS!243–247). Picks the row in the block: first related entity (workbook slot 3) contribution owner 1 → PERSONAL!1872 … owner 5 → 1876 (total 1877); withdrawal owner 1 → 1930 … owner 5 → 1934 (total 1935); +7 rows per further entity slot. The slot must be a non-empty owner on that entity (else 400)."},"ownerName":{"type":"string","description":"The owner's name for that slot (`/v1/entities` `owners[].ownerName`, INPUTS!243–247) — the label on the owner row (slot 3: 1872–1876 / 1930–1934). Read-only."},"ownerUserId":{"type":"string","nullable":true,"description":"The user this owner is when the slot is linked to a ScaleApp account (`owners[].userId`, INPUTS!262–266 Linked ID — typically owner 1 / 2 = the client / partner); `null` when the owner is another entity or unlinked. Read-only."},"date":{"type":"string","format":"date","description":"The stored day, YYYY-MM-DD — the PERSONAL month column the $ lands in."},"amount":{"type":"number","description":"$ moved. Owner-row cell of PERSONAL!1870 (CONTRIBUTION; slot 3 rows 1872–1876) or 1928 (WITHDRAWAL; slot 3 rows 1930–1934) for that month."},"direction":{"type":"string","enum":["CONTRIBUTION","WITHDRAWAL"],"description":"`CONTRIBUTION` = owner → entity, lands in the PERSONAL!1870 CASH CONTRIBUTIONS block and is summed by entity slot into the entity's `1312 + Cash contributions / injections`. `WITHDRAWAL` = entity → owner, lands in the PERSONAL!1928 CASH WITHDRAWALS block and is summed into `1313 − Cash withdrawals`."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","entityName","ownerSlot","ownerName","ownerUserId","date","amount","direction","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/entity-cash-flow/{id}":{"get":{"description":"Entity-level quick action — one cash contribution / withdrawal by id; 404 unless it belongs to this strategy. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. `ownerSlot` picks the row. Appears on GET /v1/timeline/personal as `entity_cash_flow` with `actionType` ADD (CONTRIBUTION) / WITHDRAW (WITHDRAWAL). Not read by the model until the adapter emits Inputs_EntityDefinitions and PERSONAL_M1312 / M1313 are ported.","operationId":"EntityCashFlowController_get_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityCashFlowResponseDto"}}}}},"summary":"Get one entity cash contribution or withdrawal","tags":["Timeline"]}}}}
```

## Update an entity cash contribution or withdrawal (partial)

> Entity-level quick action — any subset of the POST fields (\`entityId\`, \`ownerSlot\`, \`date\`, \`amount\`, \`direction\`). A new \`entityId\` must be an active entity of this strategy (else 404); the resulting \`ownerSlot\` must still be a non-empty owner on the resulting entity (else 400). Changing \`direction\` moves the $ between the 1870 and 1928 blocks. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. \`ownerSlot\` picks the row. Appears on GET /v1/timeline/personal as \`entity\_cash\_flow\` with \`actionType\` ADD (CONTRIBUTION) / WITHDRAW (WITHDRAWAL). Not read by the model until the adapter emits Inputs\_EntityDefinitions and PERSONAL\_M1312 / M1313 are ported.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UpdateEntityCashFlowDto":{"type":"object","properties":{"entityId":{"type":"string","description":"The related entity (from `/v1/entities`; Company / Trust / SMSF — any type) the cash moves into or out of. Must be an active entity of the request's strategy (else 404). Decides which 1870 / 1928 block (its workbook slot) and which `1310 CASH ACCOUNT` (1312 / 1313) the $ reaches."},"ownerSlot":{"type":"number","minimum":1,"maximum":5,"description":"Which owner (1–5) the cash comes from (CONTRIBUTION) or goes to (WITHDRAWAL) — the dropdown is the entity's `owners[]` from `/v1/entities` (INPUTS!243–247). Picks the row in the block: first related entity (workbook slot 3) contribution owner 1 → PERSONAL!1872 … owner 5 → 1876 (total 1877); withdrawal owner 1 → 1930 … owner 5 → 1934 (total 1935); +7 rows per further entity slot. The slot must be a non-empty owner on that entity (else 400)."},"date":{"type":"string","format":"date","description":"Any day in the month the $ lands in, YYYY-MM-DD. The value sits in the PERSONAL period column whose M$4..M$5 bounds contain it; several events in one month for the same entity sum on the entity side (1312 / 1313 are SUMIFs)."},"amount":{"type":"number","minimum":0,"description":"$ moved, ≥ 0. The owner-row cell of the 1870 block (CONTRIBUTION; slot 3 rows 1872–1876) or the 1928 block (WITHDRAWAL; slot 3 rows 1930–1934) for that month."},"direction":{"type":"string","enum":["CONTRIBUTION","WITHDRAWAL"],"description":"`CONTRIBUTION` = owner → entity, lands in the PERSONAL!1870 CASH CONTRIBUTIONS block and is summed by entity slot into the entity's `1312 + Cash contributions / injections`. `WITHDRAWAL` = entity → owner, lands in the PERSONAL!1928 CASH WITHDRAWALS block and is summed into `1313 − Cash withdrawals`."}}},"EntityCashFlowResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The related entity the cash moves into or out of."},"entityName":{"type":"string","description":"The entity's name (`/v1/entities` `entityName`, INPUTS!199). Read-only."},"ownerSlot":{"type":"number","minimum":1,"maximum":5,"description":"Which owner (1–5) the cash comes from (CONTRIBUTION) or goes to (WITHDRAWAL) — the dropdown is the entity's `owners[]` from `/v1/entities` (INPUTS!243–247). Picks the row in the block: first related entity (workbook slot 3) contribution owner 1 → PERSONAL!1872 … owner 5 → 1876 (total 1877); withdrawal owner 1 → 1930 … owner 5 → 1934 (total 1935); +7 rows per further entity slot. The slot must be a non-empty owner on that entity (else 400)."},"ownerName":{"type":"string","description":"The owner's name for that slot (`/v1/entities` `owners[].ownerName`, INPUTS!243–247) — the label on the owner row (slot 3: 1872–1876 / 1930–1934). Read-only."},"ownerUserId":{"type":"string","nullable":true,"description":"The user this owner is when the slot is linked to a ScaleApp account (`owners[].userId`, INPUTS!262–266 Linked ID — typically owner 1 / 2 = the client / partner); `null` when the owner is another entity or unlinked. Read-only."},"date":{"type":"string","format":"date","description":"The stored day, YYYY-MM-DD — the PERSONAL month column the $ lands in."},"amount":{"type":"number","description":"$ moved. Owner-row cell of PERSONAL!1870 (CONTRIBUTION; slot 3 rows 1872–1876) or 1928 (WITHDRAWAL; slot 3 rows 1930–1934) for that month."},"direction":{"type":"string","enum":["CONTRIBUTION","WITHDRAWAL"],"description":"`CONTRIBUTION` = owner → entity, lands in the PERSONAL!1870 CASH CONTRIBUTIONS block and is summed by entity slot into the entity's `1312 + Cash contributions / injections`. `WITHDRAWAL` = entity → owner, lands in the PERSONAL!1928 CASH WITHDRAWALS block and is summed into `1313 − Cash withdrawals`."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","entityName","ownerSlot","ownerName","ownerUserId","date","amount","direction","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/entity-cash-flow/{id}":{"put":{"description":"Entity-level quick action — any subset of the POST fields (`entityId`, `ownerSlot`, `date`, `amount`, `direction`). A new `entityId` must be an active entity of this strategy (else 404); the resulting `ownerSlot` must still be a non-empty owner on the resulting entity (else 400). Changing `direction` moves the $ between the 1870 and 1928 blocks. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. `ownerSlot` picks the row. Appears on GET /v1/timeline/personal as `entity_cash_flow` with `actionType` ADD (CONTRIBUTION) / WITHDRAW (WITHDRAWAL). Not read by the model until the adapter emits Inputs_EntityDefinitions and PERSONAL_M1312 / M1313 are ported.","operationId":"EntityCashFlowController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEntityCashFlowDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityCashFlowResponseDto"}}}}},"summary":"Update an entity cash contribution or withdrawal (partial)","tags":["Timeline"]}}}}
```

## Delete an entity cash contribution or withdrawal

> Entity-level quick action — removes the $ from its owner row in the 1870 (CONTRIBUTION) or 1928 (WITHDRAWAL) block for that month, so the entity's 1312 / 1313 no longer count it. Returns the deleted row. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. \`ownerSlot\` picks the row. The \`entity\_cash\_flow\` dot leaves GET /v1/timeline/personal. Not read by the model until the adapter emits Inputs\_EntityDefinitions and PERSONAL\_M1312 / M1313 are ported.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"EntityCashFlowResponseDto":{"type":"object","properties":{"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"entityId":{"type":"string","description":"The related entity the cash moves into or out of."},"entityName":{"type":"string","description":"The entity's name (`/v1/entities` `entityName`, INPUTS!199). Read-only."},"ownerSlot":{"type":"number","minimum":1,"maximum":5,"description":"Which owner (1–5) the cash comes from (CONTRIBUTION) or goes to (WITHDRAWAL) — the dropdown is the entity's `owners[]` from `/v1/entities` (INPUTS!243–247). Picks the row in the block: first related entity (workbook slot 3) contribution owner 1 → PERSONAL!1872 … owner 5 → 1876 (total 1877); withdrawal owner 1 → 1930 … owner 5 → 1934 (total 1935); +7 rows per further entity slot. The slot must be a non-empty owner on that entity (else 400)."},"ownerName":{"type":"string","description":"The owner's name for that slot (`/v1/entities` `owners[].ownerName`, INPUTS!243–247) — the label on the owner row (slot 3: 1872–1876 / 1930–1934). Read-only."},"ownerUserId":{"type":"string","nullable":true,"description":"The user this owner is when the slot is linked to a ScaleApp account (`owners[].userId`, INPUTS!262–266 Linked ID — typically owner 1 / 2 = the client / partner); `null` when the owner is another entity or unlinked. Read-only."},"date":{"type":"string","format":"date","description":"The stored day, YYYY-MM-DD — the PERSONAL month column the $ lands in."},"amount":{"type":"number","description":"$ moved. Owner-row cell of PERSONAL!1870 (CONTRIBUTION; slot 3 rows 1872–1876) or 1928 (WITHDRAWAL; slot 3 rows 1930–1934) for that month."},"direction":{"type":"string","enum":["CONTRIBUTION","WITHDRAWAL"],"description":"`CONTRIBUTION` = owner → entity, lands in the PERSONAL!1870 CASH CONTRIBUTIONS block and is summed by entity slot into the entity's `1312 + Cash contributions / injections`. `WITHDRAWAL` = entity → owner, lands in the PERSONAL!1928 CASH WITHDRAWALS block and is summed into `1313 − Cash withdrawals`."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","strategyId","entityId","entityName","ownerSlot","ownerName","ownerUserId","date","amount","direction","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/entity-cash-flow/{id}":{"delete":{"description":"Entity-level quick action — removes the $ from its owner row in the 1870 (CONTRIBUTION) or 1928 (WITHDRAWAL) block for that month, so the entity's 1312 / 1313 no longer count it. Returns the deleted row. Cells: CONTRIBUTION → PERSONAL!1870 CASH CONTRIBUTIONS block (first related entity, workbook slot 3: owner rows 1872–1876, total 1877; +7 rows per further slot), summed by slot into the entity's 1312; WITHDRAWAL → PERSONAL!1928 CASH WITHDRAWALS block (slot 3: owner rows 1930–1934, total 1935; +7 rows per slot), summed into 1313. `ownerSlot` picks the row. The `entity_cash_flow` dot leaves GET /v1/timeline/personal. Not read by the model until the adapter emits Inputs_EntityDefinitions and PERSONAL_M1312 / M1313 are ported.","operationId":"EntityCashFlowController_remove_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy. Resolved exactly as on `/v1/entities`.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Client user ID (brokers acting for a client). Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that client. The event hangs off the strategy, not the person, so this only selects whose strategy.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityCashFlowResponseDto"}}}}},"summary":"Delete an entity cash contribution or withdrawal","tags":["Timeline"]}}}}
```

## GET /v1/timeline/salary-sacrifice

> List salary sacrifice events for a strategy

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SalarySacrificeResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Salary sacrificed in that month, $ (≥ 0). Workbook PERSONAL!2044 (User 1) / 2045 (User 2) \"Salary sacrifice\" in the 2041 CONTRIBUTIONS block; flows to 2108/2109 Salary Sacrifice deduction (= −input) → 436/437 Gross Salary (Excl. Super) and 2180/2188 Reportable Super Contributions. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2044 vs 2045."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/salary-sacrifice":{"get":{"operationId":"SalarySacrificeController_list_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2044); partner's id → User 2 (PERSONAL!2045), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SalarySacrificeResponseDto"}}}}}},"summary":"List salary sacrifice events for a strategy","tags":["Timeline"]}}}}
```

## Add salary sacrifice for a month

> Person-level quick action, same pattern as reportable-fringe-benefit. One $ for one person in one month → workbook PERSONAL!2044 (User 1) / 2045 (User 2) "Salary sacrifice" in the 2041 CONTRIBUTIONS block; flows to 2108/2109 Salary Sacrifice deduction (= −input) → 436/437 Gross Salary (Excl. Super) and 2180/2188 Reportable Super Contributions. The person is \`?userId=\` (client = User 1, partner = User 2). Several events in a month sum. Appears on GET /v1/timeline/personal as type SALARY\_SACRIFICE. Not read by the model until an Inputs\_\* key for 2044/2045 exists in the adapter and PERSONAL\_M2108/M2109 are ported.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SalarySacrificeDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Salary sacrificed in that month, $ (≥ 0). Workbook PERSONAL!2044 (User 1) / 2045 (User 2) \"Salary sacrifice\" in the 2041 CONTRIBUTIONS block; flows to 2108/2109 Salary Sacrifice deduction (= −input) → 436/437 Gross Salary (Excl. Super) and 2180/2188 Reportable Super Contributions. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."}},"required":["date","amount"]},"SalarySacrificeResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Salary sacrificed in that month, $ (≥ 0). Workbook PERSONAL!2044 (User 1) / 2045 (User 2) \"Salary sacrifice\" in the 2041 CONTRIBUTIONS block; flows to 2108/2109 Salary Sacrifice deduction (= −input) → 436/437 Gross Salary (Excl. Super) and 2180/2188 Reportable Super Contributions. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2044 vs 2045."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/salary-sacrifice":{"post":{"description":"Person-level quick action, same pattern as reportable-fringe-benefit. One $ for one person in one month → workbook PERSONAL!2044 (User 1) / 2045 (User 2) \"Salary sacrifice\" in the 2041 CONTRIBUTIONS block; flows to 2108/2109 Salary Sacrifice deduction (= −input) → 436/437 Gross Salary (Excl. Super) and 2180/2188 Reportable Super Contributions. The person is `?userId=` (client = User 1, partner = User 2). Several events in a month sum. Appears on GET /v1/timeline/personal as type SALARY_SACRIFICE. Not read by the model until an Inputs_* key for 2044/2045 exists in the adapter and PERSONAL_M2108/M2109 are ported.","operationId":"SalarySacrificeController_add_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2044); partner's id → User 2 (PERSONAL!2045), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalarySacrificeDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalarySacrificeResponseDto"}}}}},"summary":"Add salary sacrifice for a month","tags":["Timeline"]}}}}
```

## GET /v1/timeline/salary-sacrifice/{id}

> Get one salary sacrifice event

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SalarySacrificeResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Salary sacrificed in that month, $ (≥ 0). Workbook PERSONAL!2044 (User 1) / 2045 (User 2) \"Salary sacrifice\" in the 2041 CONTRIBUTIONS block; flows to 2108/2109 Salary Sacrifice deduction (= −input) → 436/437 Gross Salary (Excl. Super) and 2180/2188 Reportable Super Contributions. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2044 vs 2045."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/salary-sacrifice/{id}":{"get":{"operationId":"SalarySacrificeController_get_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2044); partner's id → User 2 (PERSONAL!2045), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalarySacrificeResponseDto"}}}}},"summary":"Get one salary sacrifice event","tags":["Timeline"]}}}}
```

## PUT /v1/timeline/salary-sacrifice/{id}

> Update a salary sacrifice event (partial)

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UpdateSalarySacrificeDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Salary sacrificed in that month, $ (≥ 0). Workbook PERSONAL!2044 (User 1) / 2045 (User 2) \"Salary sacrifice\" in the 2041 CONTRIBUTIONS block; flows to 2108/2109 Salary Sacrifice deduction (= −input) → 436/437 Gross Salary (Excl. Super) and 2180/2188 Reportable Super Contributions. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."}}},"SalarySacrificeResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Salary sacrificed in that month, $ (≥ 0). Workbook PERSONAL!2044 (User 1) / 2045 (User 2) \"Salary sacrifice\" in the 2041 CONTRIBUTIONS block; flows to 2108/2109 Salary Sacrifice deduction (= −input) → 436/437 Gross Salary (Excl. Super) and 2180/2188 Reportable Super Contributions. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2044 vs 2045."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/salary-sacrifice/{id}":{"put":{"operationId":"SalarySacrificeController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2044); partner's id → User 2 (PERSONAL!2045), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSalarySacrificeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalarySacrificeResponseDto"}}}}},"summary":"Update a salary sacrifice event (partial)","tags":["Timeline"]}}}}
```

## DELETE /v1/timeline/salary-sacrifice/{id}

> Delete a salary sacrifice event

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SalarySacrificeResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Salary sacrificed in that month, $ (≥ 0). Workbook PERSONAL!2044 (User 1) / 2045 (User 2) \"Salary sacrifice\" in the 2041 CONTRIBUTIONS block; flows to 2108/2109 Salary Sacrifice deduction (= −input) → 436/437 Gross Salary (Excl. Super) and 2180/2188 Reportable Super Contributions. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!2044 vs 2045."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/salary-sacrifice/{id}":{"delete":{"operationId":"SalarySacrificeController_remove_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!2044); partner's id → User 2 (PERSONAL!2045), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalarySacrificeResponseDto"}}}}},"summary":"Delete a salary sacrifice event","tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-deduction

> List personal deduction events for a strategy

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalDeductionResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Personal deductions claimed in that month, $ in today's dollars (≥ 0) — the sheet indexes it. Workbook PERSONAL!406 (User 1) / 407 (User 2) \"Personal Deductions\" (405 block); 408/409 Applied = input × M160 × G160 → 694/789 Personal Deductions (−SUMIF by financial year) → 697/792 Taxable Income. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!406 vs 407."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/personal-deduction":{"get":{"operationId":"PersonalDeductionController_list_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!406); partner's id → User 2 (PERSONAL!407), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PersonalDeductionResponseDto"}}}}}},"summary":"List personal deduction events for a strategy","tags":["Timeline"]}}}}
```

## Add personal deductions for a month

> Person-level quick action, same pattern as reportable-fringe-benefit. One $ for one person in one month → workbook PERSONAL!406 (User 1) / 407 (User 2) "Personal Deductions" (405 block); 408/409 Applied = input × M160 × G160 (indexed) → 694/789 Personal Deductions (−SUMIF by financial year) → 697/792 Taxable Income. Amount is in today's dollars; the sheet indexes it. The person is \`?userId=\` (client = User 1, partner = User 2). Several events in a month sum. Appears on GET /v1/timeline/personal as type PERSONAL\_DEDUCTION. Fully ported; read by the model through Inputs key Personal\_Personaldeductions\_PersonalDeductionsOwner1 / Owner2.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalDeductionDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Personal deductions claimed in that month, $ in today's dollars (≥ 0) — the sheet indexes it. Workbook PERSONAL!406 (User 1) / 407 (User 2) \"Personal Deductions\" (405 block); 408/409 Applied = input × M160 × G160 → 694/789 Personal Deductions (−SUMIF by financial year) → 697/792 Taxable Income. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."}},"required":["date","amount"]},"PersonalDeductionResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Personal deductions claimed in that month, $ in today's dollars (≥ 0) — the sheet indexes it. Workbook PERSONAL!406 (User 1) / 407 (User 2) \"Personal Deductions\" (405 block); 408/409 Applied = input × M160 × G160 → 694/789 Personal Deductions (−SUMIF by financial year) → 697/792 Taxable Income. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!406 vs 407."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/personal-deduction":{"post":{"description":"Person-level quick action, same pattern as reportable-fringe-benefit. One $ for one person in one month → workbook PERSONAL!406 (User 1) / 407 (User 2) \"Personal Deductions\" (405 block); 408/409 Applied = input × M160 × G160 (indexed) → 694/789 Personal Deductions (−SUMIF by financial year) → 697/792 Taxable Income. Amount is in today's dollars; the sheet indexes it. The person is `?userId=` (client = User 1, partner = User 2). Several events in a month sum. Appears on GET /v1/timeline/personal as type PERSONAL_DEDUCTION. Fully ported; read by the model through Inputs key Personal_Personaldeductions_PersonalDeductionsOwner1 / Owner2.","operationId":"PersonalDeductionController_add_v1","parameters":[{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!406); partner's id → User 2 (PERSONAL!407), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalDeductionDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalDeductionResponseDto"}}}}},"summary":"Add personal deductions for a month","tags":["Timeline"]}}}}
```

## GET /v1/timeline/personal-deduction/{id}

> Get one personal deduction event

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalDeductionResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Personal deductions claimed in that month, $ in today's dollars (≥ 0) — the sheet indexes it. Workbook PERSONAL!406 (User 1) / 407 (User 2) \"Personal Deductions\" (405 block); 408/409 Applied = input × M160 × G160 → 694/789 Personal Deductions (−SUMIF by financial year) → 697/792 Taxable Income. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!406 vs 407."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/personal-deduction/{id}":{"get":{"operationId":"PersonalDeductionController_get_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!406); partner's id → User 2 (PERSONAL!407), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalDeductionResponseDto"}}}}},"summary":"Get one personal deduction event","tags":["Timeline"]}}}}
```

## PUT /v1/timeline/personal-deduction/{id}

> Update a personal deduction event (partial)

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UpdatePersonalDeductionDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Personal deductions claimed in that month, $ in today's dollars (≥ 0) — the sheet indexes it. Workbook PERSONAL!406 (User 1) / 407 (User 2) \"Personal Deductions\" (405 block); 408/409 Applied = input × M160 × G160 → 694/789 Personal Deductions (−SUMIF by financial year) → 697/792 Taxable Income. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."}}},"PersonalDeductionResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Personal deductions claimed in that month, $ in today's dollars (≥ 0) — the sheet indexes it. Workbook PERSONAL!406 (User 1) / 407 (User 2) \"Personal Deductions\" (405 block); 408/409 Applied = input × M160 × G160 → 694/789 Personal Deductions (−SUMIF by financial year) → 697/792 Taxable Income. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!406 vs 407."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/personal-deduction/{id}":{"put":{"operationId":"PersonalDeductionController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!406); partner's id → User 2 (PERSONAL!407), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePersonalDeductionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalDeductionResponseDto"}}}}},"summary":"Update a personal deduction event (partial)","tags":["Timeline"]}}}}
```

## DELETE /v1/timeline/personal-deduction/{id}

> Delete a personal deduction event

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Timeline","description":"Financial timeline, events, and projections (60+ endpoints)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PersonalDeductionResponseDto":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"The month the value applies to, YYYY-MM-DD (any day in the month). Lands in the PERSONAL period column whose M$4..M$5 bounds contain it."},"amount":{"type":"number","description":"Personal deductions claimed in that month, $ in today's dollars (≥ 0) — the sheet indexes it. Workbook PERSONAL!406 (User 1) / 407 (User 2) \"Personal Deductions\" (405 block); 408/409 Applied = input × M160 × G160 → 694/789 Personal Deductions (−SUMIF by financial year) → 697/792 Taxable Income. Which row: the person the event belongs to — `?userId=` the client for User 1, the partner for User 2, like every other personal event."},"id":{"type":"string"},"strategyId":{"type":"string","description":"The control centre / strategy the event belongs to."},"userId":{"type":"string","description":"The person the event belongs to (User 1 = the client, User 2 = the partner). Decides PERSONAL!406 vs 407."},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["date","amount","id","strategyId","userId","createdAt","updatedAt"]}}},"paths":{"/v1/timeline/personal-deduction/{id}":{"delete":{"operationId":"PersonalDeductionController_remove_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"strategyId","required":false,"in":"query","description":"A control centre/strategy ID. Optional; defaults to the selected user's default strategy.","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"The person the event belongs to. Client → User 1 (PERSONAL!406); partner's id → User 2 (PERSONAL!407), exactly as the simulator does for personal-income / personal-loan. Optional; defaults to the authenticated user. Resolved by the auth guard, so the caller must have access to that user.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalDeductionResponseDto"}}}}},"summary":"Delete a personal deduction event","tags":["Timeline"]}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.scaleconnect.com.au/api/rest-api/scaleapp-rest-api/timeline.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
