TypedResults vs Results in ASP.NET Core Minimal APIs
Results.Ok(x) and TypedResults.Ok(x) put the same response on the wire. The difference is what the rest of your app can see before the request happens. With TypedResults and a declared return type, the OpenAPI document knows every status and body your endpoint can return, without any extra code. Here are both versions of one endpoint, and the documents they produce.
Prerequisites
- An ASP.NET Core minimal API with an OpenAPI document, from
AddOpenApiandMapOpenApi. The examples use .NET 10.
The Same Endpoint, Twice
Both endpoints return a category, or 404. This one uses Results, in a lambda:
d.MapGet("/results-style/{id:int}", async (int id, InventoryDbContext db) =>
{
var category = await db.Categories.FindAsync(id);
return category is null ? Results.NotFound() : Results.Ok(new CategoryResponse(category.Id, category.Name, category.CreatedAtUtc));
});
This one uses TypedResults, in a method whose return type lists both results:
private static async Task<Results<Ok<CategoryResponse>, NotFound>> TypedStyleAsync(int id, InventoryDbContext db)
{
var category = await db.Categories.FindAsync(id);
return category is null
? TypedResults.NotFound()
: TypedResults.Ok(new CategoryResponse(category.Id, category.Name, category.CreatedAtUtc));
}
Compare the OpenAPI Documents
Here's what each one looks like in /openapi/v1.json:
"responses": {
"200": {
"description": "OK"
}
}
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CategoryResponse"
}
}
}
},
"404": {
"description": "Not Found"
}
}

The Results version says nothing about its body, and doesn't mention 404, though it can return one. Anything built from that document, such as a documentation page or a generated client, inherits the gap. ASP.NET Core's responses page names the advantages: "TypedResults helpers return strongly typed objects, which can improve code readability, unit testing, and reduce the chance of runtime errors", and "The implementation type automatically provides the response type metadata for OpenAPI to describe the endpoint."
How to Write It
One kind of result needs no declaration:
private static async Task<Ok<List<CategoryResponse>>> ListAsync(
InventoryDbContext db,
CancellationToken cancellationToken)
{
var categories = await db.Categories
.OrderBy(c => c.Name)
.Select(c => new CategoryResponse(c.Id, c.Name, c.CreatedAtUtc))
.ToListAsync(cancellationToken);
return TypedResults.Ok(categories);
}
Several kinds use Results<…>, which comes from using Microsoft.AspNetCore.Http.HttpResults;. The types in it add their responses to the document, and the compiler checks your code against them. The page says: "Attempting to return a type that isn't declared as one of the generic arguments to Results<> results in a compilation error."
private static async Task<Results<Created<CategoryResponse>, ProblemHttpResult>> CreateAsync(
The page explains why you must write it out: "To use TypedResults, the return type must be fully declared; when the method is asynchronous, the declaration requires wrapping the return type in a Task<>." In a lambda with no declared type, two different results don't compile. A named method is the simplest place for the type.
If You Keep Results
Results is fine when you don't need the metadata, or when you need to return something decided at runtime. Then add it yourself, as the page shows, with .Produces<CategoryResponse>() on the route. That's one more thing to keep in step with the code by hand.
Common Mistakes
| Mistake | What happens | Do this instead |
|---|---|---|
Using TypedResults but returning IResult | The document loses the metadata again | Declare the concrete type |
| Mixing results in a lambda with no return type | CS1593 | Use a method with Results<…> |
Forgetting using Microsoft.AspNetCore.Http.HttpResults; | Ok<T> and NotFound aren't found | Add it |
Trusting the document with Results | It leaves out your 404s | Use TypedResults, or add Produces |
FAQ
What does each one return?
The page says: "the Results helpers' return type is IResult, while each TypedResults helper's return type is one of the IResult implementation types." Ok<CategoryResponse> is one of those types.
Does the document list every response then?
Not quite. In this API, POST /api/v1/categories is declared as Results<Created<CategoryResponse>, ProblemHttpResult>, and its document lists only 201. ProblemHttpResult doesn't say which status it carries, and AddValidation answers before the handler runs. How to Add Summaries and Tags to an OpenAPI Document adds those two.
Conclusion
The response is the same. TypedResults with a declared Results<…> type also gives you a complete OpenAPI document and a compiler check on every return, for no extra code. Use Results where you don't need those.
Additional Resources
- Responses in Minimal API apps —
TypedResultsandResults<…>. - Include OpenAPI metadata — describing responses.
