Skip to content

Example: hosted endpoints document

Doc gen writes docs/application/hosted-endpoints.md for a web front end that hosts requests for its own screens: named page handlers that return JSON, a partial view or a file, grid reads and updates, and any API controller or minimal API the application serves to itself. These are not a published API, so there is no docs/apis/ set; each endpoint is listed once on this page and the screens link to it. The example is for an ASP.NET Core Razor Pages front end; the document for a .NET Framework 4 MVC front end has the same shape (see the checks below).

What reviewers should check

  • The page exists only when there is something to list. The default OnGet or OnPost handler that renders a screen is the screen, not an endpoint. A page with no hosted endpoints should not have this document.
  • Every H3 is a plain-text anchor. ### GET /Policy/Summary?handler=Declaration has no backticks, so the anchor is #get-policysummaryhandlerdeclaration. The AJAX and grid actions tables on the screen pages link to exactly these anchors.
  • Both directions reconcile. Each row in a screen's ## AJAX and grid actions table has an entry here, and each entry's Called from links back to a screen page. An endpoint that no screen reaches is marked unattributed ** rather than dropped. The Summary counts add up to the number of entries.
  • Requests use the Core form. The H3 and URL row use VERB /<Page>?handler=<Name>, and the Handler row names the page model method (SummaryModel.OnGetDeclarationAsync). A Controller.Action here means the MVC vocabulary leaked in.
  • Anti-forgery is stated per endpoint. POST handlers say whether the token is validated and why; GET handlers say it does not apply.
  • Access is the declared requirement. Authorization names the attribute and the type that declares it, and a requirement contributed by a package base class carries †.
  • The same page applies to .NET Framework 4 MVC apps. The net4-app-hosted-endpoints.md template uses ### <VERB> <Controller>/<Action> headings, a Controller.Action row instead of Handler, a [SaifAuthorize(Roles = "...")] authorization row, and no anti-forgery row. Its kinds are Web API, grid, AJAX, and remote validator.

Example

The document below is a complete, correct hosted-endpoints.md for the same fictional SAIF.Policy.Portal application as the Razor Pages screen example.

View rendered example — the same document as a real page, so you can compare rendering as well as source.

---
title: Hosted endpoints
summary: Named page handlers, partial fetches and API actions the application exposes to its own screens.
status: draft
owner: Policy Services Team
last_reviewed: 2026-09-09
---

# Hosted endpoints

These endpoints serve this application's own screens and are not a published API. They are listed here once so that each screen page can link to the request it makes.

## Endpoint catalog

### POST /Payroll/Reports?handler=Read

| Field | Value |
| --- | --- |
| Handler | `ReportsModel.OnPostReadAsync` |
| Kind | grid read |
| URL | `/Payroll/Reports?handler=Read` |
| Request | Form fields of the Kendo `DataSourceRequest` (`page`, `pageSize`, `sort`, `filter`) and the `policyNumber` route value |
| Response | `JsonResult` wrapping a `DataSourceResult` of `PayrollReportRow` |
| Anti-forgery | Validated by default; the grid `data` function sends the request verification token |
| Authorization | `[SecurityApiAuthorize("PolicyServices.Read,PolicyServices.Underwriting")]` declared on `BolPolicyModel`† |
| Called from | [Payroll Reports](../screens/payroll-reports.md) |

### GET /Policy/Search?handler=Employers

| Field | Value |
| --- | --- |
| Handler | `SearchModel.OnGetEmployersAsync` |
| Kind | named handler JSON |
| URL | `/Policy/Search?handler=Employers` |
| Request | Query string `term` (`string`, at least three characters) |
| Response | `JsonResult` array of `{ employerId, employerName, policyNumber }`; an empty array when `term` is shorter than three characters |
| Anti-forgery | Not applicable; GET handlers are not validated |
| Authorization | `[SecurityApiAuthorize("PolicyServices.Read,PolicyServices.Underwriting")]` declared on `SearchModel` |
| Called from | [Policy Search](../screens/policy-search.md) |

### GET /Policy/Summary?handler=Declaration

| Field | Value |
| --- | --- |
| Handler | `SummaryModel.OnGetDeclarationAsync` |
| Kind | file download |
| URL | `/Policy/Summary?handler=Declaration` |
| Request | Optional route value `policyNumber`; the policy number in `WebContext` is used when it is absent |
| Response | `FileStreamResult`, `application/pdf` |
| Anti-forgery | Not applicable; GET handlers are not validated |
| Authorization | `[SecurityApiAuthorize("PolicyServices.Read,PolicyServices.Underwriting")]` declared on `BolPolicyModel`† |
| Called from | [Policy Summary](../screens/policy-summary.md) |

### GET /Policy/Summary?handler=PayrollHistory

| Field | Value |
| --- | --- |
| Handler | `SummaryModel.OnGetPayrollHistoryAsync` |
| Kind | partial fetch |
| URL | `/Policy/Summary?handler=PayrollHistory` |
| Request | Query string `reportYear` (`int`, bound to `ReportYear`) |
| Response | `PartialViewResult` for `_PayrollHistory`; `400 Bad Request` when `reportYear` is not a year in the policy history |
| Anti-forgery | Not applicable; GET handlers are not validated |
| Authorization | `[SecurityApiAuthorize("PolicyServices.Read,PolicyServices.Underwriting")]` declared on `BolPolicyModel`† |
| Called from | [Policy Summary](../screens/policy-summary.md) |

## Summary

| Kind | Count |
| --- | --- |
| Named handler (JSON) | 1 |
| Named handler (partial) | 1 |
| File download | 1 |
| API controller / minimal API | 0 |
| Grid | 1 |
| Unattributed | 0 |

---

> [!NOTE]
> Statements marked with `*` are inferred from code patterns. Statements marked with `**` could not be verified from available source. Statements marked with `†` are sourced from package documentation retrieved with the Legends CLI.

## Related documentation
- [Application index](index.md)
- [Architecture](architecture.md)
- [Security and authorization](security-authorization.md)
- [Screen catalog](../screens/index.md)

## Sources
- src/SAIF.Policy.Portal/Pages/Payroll/Reports.cshtml.cs
- src/SAIF.Policy.Portal/Pages/Policy/Search.cshtml.cs
- src/SAIF.Policy.Portal/Pages/Policy/Summary.cshtml.cs