# HTTP Status Codes: an overview

Every response starts with a status code that says how the request went. By default an ASP.NET Core API answers 200 when an action returns, and 500 when it throws, so an action has to choose a better code, such as 404, on purpose.

Apprentice · REST API · ASP.NET Core · Updated November 3, 2026

## After this lesson you can

- Explain what an API's status code tells the client, and why a missing item should answer 404, not 200 or 204

## Key takeaways

- A status code's first digit gives its family: 2xx means success, 4xx the client's mistake and 5xx the server's.
- By default ASP.NET Core answers `200 OK` when an action returns, and `500 Internal Server Error` when it throws an exception nobody catches.
- An action that returns `null` answers `204 No Content`, which tells the client everything went fine.
- A missing item should answer `404 Not Found`, not `200` or `204`, and your action has to choose that code on purpose.
- Clients decide what to do from the status code alone, so it has to be right.

Every response starts with a **status code**: a three-digit number that tells the client how its request went, before it reads a single byte of the body.

```http
HTTP/1.1 200 OK
```

The first digit gives the family:

| Codes | Mean | Whose problem |
|---|---|---|
| **2xx** | Success | Nobody's: it worked |
| **4xx** | Client error | The client's: a bad request, a wrong address, not signed in |
| **5xx** | Server error | The server's: something broke on our side |

The client's code decides what to do from the status code alone: show the data, show *"not found"*, ask the user to fix the form, or say *"try again later"*. So the code has to be right.

## What ASP.NET Core does by default

When an API action returns, ASP.NET Core answers **`200 OK`** with what it returned as the body. When an action throws an exception that nobody catches, it answers **`500 Internal Server Error`**. That's a sensible start, but look what happens with a category that doesn't exist:

```csharp
[HttpGet("{id}")]
public Category? GetById(int id)
{
    return categoryDao.GetById(id);
}
```

```http
GET {{HostAddress}}/api/categories/300
```

```http
HTTP/1.1 204 No Content
```

There's no category 300, so the DAO returned `null`, and ASP.NET Core answered **`204 No Content`**: *"it worked, and there's nothing to send."* But it didn't work. The client asked for something that isn't there, and the honest answer is **`404 Not Found`**.

A client reading `204` would think everything is fine, and show an empty page. One reading `404` knows to say *"there's no such category"*.

## Choosing the code on purpose

So an action has to decide its own status code whenever *"it returned"* isn't the whole story:

| The request | The right answer |
|---|---|
| Get a category that exists | `200 OK`, with the category |
| Get a category that doesn't exist | `404 Not Found` |
| Add a category | `201 Created`, with the new category and its address |
| Add a category with no name | `400 Bad Request`, saying what's wrong |
| Update a category | `200 OK`, with the category as it's now saved |
| Delete a category | `204 No Content` |
| The database is down | `500 Internal Server Error`, without the details |

The next lesson lists the common codes, and *Web APIs with Controllers* shows how an action returns each one.

## Check yourself

1 question to try on the lesson page.

## So what

The status code is the first thing a client reads, and often the only thing it checks. ASP.NET Core picks 200 or 500 for you; every other answer, such as 404 for something that isn't there, is a choice you make in the action.

## Key terms

- [Status Code](https://www.ask-codey.com/glossary/status-code)
- [200 OK](https://www.ask-codey.com/glossary/200-ok)
- [204 No Content](https://www.ask-codey.com/glossary/204-no-content)
- [404 Not Found](https://www.ask-codey.com/glossary/404-not-found)
- [500 Internal Server Error](https://www.ask-codey.com/glossary/500-internal-server-error)

## Cheat sheets

- [HTTP Status Codes: an overview](https://www.ask-codey.com/cheat-sheets/http-status-codes-in-aspnet-core-an-overview-cheat-sheet)

Source: https://www.ask-codey.com/lessons/http-status-codes-in-aspnet-core-an-overview
