ASP.NET Minimal API with OpenAPI
Create well-structured ASP.NET Minimal API endpoints by grouping routes, modeling request and response DTOs, returning typed results, and documenting operations so generated OpenAPI describes real behavior.
Use it for OpenAPI/Swagger documentation and strongly-typed endpoint design.
Treat endpoint filters as the cross-cutting extension point.
When to invoke
- "Create an ASP.NET Minimal API endpoint with OpenAPI docs."
- "Add Swagger documentation for this Minimal API."
- "Use typed results for these endpoints."
- "Group these Minimal API routes."
- "Document request and response models in .NET 9 OpenAPI."
API organization
| Concern |
Recommended approach |
Why it matters |
| Related endpoints |
Group related endpoints using MapGroup() extension. |
Keeps shared route prefixes, tags, authorization, filters, and metadata consistent. |
| Cross-cutting behavior |
Use endpoint filters for validation, logging, authorization checks, or other concerns that do not belong in handlers. |
Prevents duplicated handler boilerplate. |
| Large APIs |
Structure larger APIs with separate endpoint classes or extension methods. |
Keeps Program.cs small and discoverable. |
| Complex domains |
Consider feature-based folders. |
Collocates endpoint mapping, DTOs, validation, and tests by capability. |
Keep handlers thin: parse typed input, call application services, map domain outcomes to HTTP results, and attach metadata.
Request and response types
| Topic |
Rule |
| DTOs |
Define explicit request and response DTOs/models instead of accepting anonymous shapes. |
| Immutability |
Use record types for immutable request/response objects when mutation is unnecessary. |
| Names |
Use meaningful property names that align with API design standards and the public contract. |
| Validation |
Create clear model classes with [Required] and other validation attributes to enforce constraints. |
| Nullability |
Leverage nullable annotations and init-only properties so required and optional data are visible in C# and OpenAPI. |
| Errors |
Use ProblemDetailsService and StatusCodePages to get standard error responses. |
Do not leak EF entities or internal domain models as public API contracts unless the project explicitly treats them as contracts.
Typed result handling
| Need |
API |
Guidance |
| Multiple outcomes |
Results<T1, T2> |
Represent success, validation, not-found, and error outcomes in the method signature. |
| Strong response metadata |
TypedResults |
Prefer TypedResults instead of Results so response types flow into OpenAPI. |
| Route parameters |
Strongly-typed route parameters |
Use explicit type binding such as int id, Guid id, or custom binders where supported. |
| Standard errors |
TypedResults.Problem, TypedResults.ValidationProblem, TypedResults.NotFound |
Align runtime behavior with documented OpenAPI responses. |
OpenAPI documentation
| Documentation item |
How to express it |
| Operation name |
Add operationIds using WithName. |
| Summary and description |
Define operation summary and description on the endpoint metadata supported by the target .NET version. |
| Request/response content types |
Set proper content types for requests and responses. |
| Property and parameter descriptions |
Add descriptions to properties and parameters with [Description()]. |
| Document-wide metadata |
Use document transformers to add servers, tags, security schemes, and other document-level elements. |
| Schema customization |
Use schema transformers to apply customizations to OpenAPI schemas. |
| Built-in support |
Use the built-in OpenAPI document support added in .NET 9 when the project targets it. |
Output template
## ASP.NET Minimal API result
**Status:** created | reviewed | blocked
**Endpoint group:** `<route group or feature>`
| Endpoint | Request type | Response types | OpenAPI metadata |
| --- | --- | --- | --- |
| `<METHOD /route>` | `<DTO or none>` | `Results<T1, T2>` | `WithName`, summary, description, content types |
### Implementation notes
- Grouping: `<MapGroup decision>`
- Validation: `<attributes/filter/service>`
- Error shape: `<ProblemDetails/StatusCodePages behavior>`
### Validation
- `<build/test/openapi command>`: pass | fail | not run
Quality gate
1---2name: aspnet-minimal-api-openapi3description: Create or review ASP.NET Minimal API endpoints with typed results, DTO validation, endpoint groups, filters, ProblemDetails, and OpenAPI documentation. Use this skill when asked to add Minimal APIs, document endpoints with Swagger/OpenAPI, use .NET 9 built-in OpenAPI, or design request and response types.4---56<!-- Generated from harness/github-copilot/skills/aspnet-minimal-api-openapi/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->78# ASP.NET Minimal API with OpenAPI910Create well-structured ASP.NET Minimal API endpoints by grouping routes, modeling request and response DTOs, returning typed results, and documenting operations so generated OpenAPI describes real behavior.1112Use it for OpenAPI/Swagger documentation and strongly-typed endpoint design.13Treat endpoint filters as the cross-cutting extension point.1415## When to invoke1617- "Create an ASP.NET Minimal API endpoint with OpenAPI docs."18- "Add Swagger documentation for this Minimal API."19- "Use typed results for these endpoints."20- "Group these Minimal API routes."21- "Document request and response models in .NET 9 OpenAPI."2223## API organization2425| Concern | Recommended approach | Why it matters |26| --- | --- | --- |27| Related endpoints | Group related endpoints using `MapGroup()` extension. | Keeps shared route prefixes, tags, authorization, filters, and metadata consistent. |28| Cross-cutting behavior | Use endpoint filters for validation, logging, authorization checks, or other concerns that do not belong in handlers. | Prevents duplicated handler boilerplate. |29| Large APIs | Structure larger APIs with separate endpoint classes or extension methods. | Keeps `Program.cs` small and discoverable. |30| Complex domains | Consider feature-based folders. | Collocates endpoint mapping, DTOs, validation, and tests by capability. |3132Keep handlers thin: parse typed input, call application services, map domain outcomes to HTTP results, and attach metadata.3334## Request and response types3536| Topic | Rule |37| --- | --- |38| DTOs | Define explicit request and response DTOs/models instead of accepting anonymous shapes. |39| Immutability | Use record types for immutable request/response objects when mutation is unnecessary. |40| Names | Use meaningful property names that align with API design standards and the public contract. |41| Validation | Create clear model classes with `[Required]` and other validation attributes to enforce constraints. |42| Nullability | Leverage nullable annotations and init-only properties so required and optional data are visible in C# and OpenAPI. |43| Errors | Use `ProblemDetailsService` and StatusCodePages to get standard error responses. |4445Do not leak EF entities or internal domain models as public API contracts unless the project explicitly treats them as contracts.4647## Typed result handling4849| Need | API | Guidance |50| --- | --- | --- |51| Multiple outcomes | `Results<T1, T2>` | Represent success, validation, not-found, and error outcomes in the method signature. |52| Strong response metadata | `TypedResults` | Prefer `TypedResults` instead of `Results` so response types flow into OpenAPI. |53| Route parameters | Strongly-typed route parameters | Use explicit type binding such as `int id`, `Guid id`, or custom binders where supported. |54| Standard errors | `TypedResults.Problem`, `TypedResults.ValidationProblem`, `TypedResults.NotFound` | Align runtime behavior with documented OpenAPI responses. |5556## OpenAPI documentation5758| Documentation item | How to express it |59| --- | --- |60| Operation name | Add operationIds using `WithName`. |61| Summary and description | Define operation summary and description on the endpoint metadata supported by the target .NET version. |62| Request/response content types | Set proper content types for requests and responses. |63| Property and parameter descriptions | Add descriptions to properties and parameters with `[Description()]`. |64| Document-wide metadata | Use document transformers to add servers, tags, security schemes, and other document-level elements. |65| Schema customization | Use schema transformers to apply customizations to OpenAPI schemas. |66| Built-in support | Use the built-in OpenAPI document support added in .NET 9 when the project targets it. |6768## Output template6970```markdown71## ASP.NET Minimal API result7273**Status:** created | reviewed | blocked74**Endpoint group:** `<route group or feature>`7576| Endpoint | Request type | Response types | OpenAPI metadata |77| --- | --- | --- | --- |78| `<METHOD /route>` | `<DTO or none>` | `Results<T1, T2>` | `WithName`, summary, description, content types |7980### Implementation notes81- Grouping: `<MapGroup decision>`82- Validation: `<attributes/filter/service>`83- Error shape: `<ProblemDetails/StatusCodePages behavior>`8485### Validation86- `<build/test/openapi command>`: pass | fail | not run87```8889## Quality gate9091- [ ] Related endpoints are grouped with `MapGroup()` or the absence of grouping is justified.92- [ ] Request and response contracts use explicit DTOs/models with meaningful names.93- [ ] Validation attributes such as `[Required]` are applied where the public contract requires them.94- [ ] Handlers return `TypedResults` and `Results<T1, T2>` where multiple response types are possible.95- [ ] Standard errors use `ProblemDetailsService`, StatusCodePages, or typed problem results.96- [ ] OpenAPI includes operationIds through `WithName`, summaries/descriptions, content types, and useful schema metadata.97- [ ] Document transformers or schema transformers are used only when endpoint-level metadata is insufficient.