Skip to content

Restful Status Codes

DodaTech 3 min read

title: "RESTful Status Codes — Choosing the Right HTTP Status Codes" description: "RESTful HTTP status codes communicate operation results clearly with 2xx for success, 4xx for client errors, and 5xx for server errors following REST conventions." date: 2026-06-28 lastmod: 2026-06-28 weight: 12 tags: [apis, restful] }

RESTful status codes use HTTP status codes to communicate operation results: 200 OK for success, 201 Created for new resources, 204 No Content for deletions.

What You'll Learn

  • Common RESTful status codes
  • Status code categories
  • Choosing the right code

Why It Matters

Correct status codes enable standard HTTP client behavior. Wrong codes confuse clients and break error handling.

Status Code Reference

Code Name When to Use
200 OK Successful GET, PUT, PATCH
201 Created Successful POST (new resource)
204 No Content Successful DELETE, PUT (no body)
301 Moved Permanently Resource relocated
400 Bad Request Invalid input, malformed request
401 Unauthorized Missing or invalid authentication
403 Forbidden Authenticated but not authorized
404 Not Found Resource doesn't exist
405 Method Not Allowed Wrong HTTP method
409 Conflict Resource state conflict
422 Unprocessable Entity Validation errors
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Unexpected server error

Code Examples

@app.route('/users', methods=['POST'])
def create_user():
    data = request.json
    if not data or 'name' not in data:
        return jsonify({"error": "Name is required"}), 400

    try:
        user = db.create_user(data)
        # 201 Created with location header
        response = jsonify(user.to_dict())
        response.status_code = 201
        response.headers['Location'] = f'/users/{user.id}'
        return response
    except IntegrityError:
        return jsonify({"error": "User already exists"}), 409

@app.route('/users/<int:id>', methods=['DELETE'])
def delete_user(id):
    user = db.get_user(id)
    if not user:
        return jsonify({"error": "User not found"}), 404
    db.delete_user(id)
    return '', 204  # No Content
app.get('/orders/:id', (req, res) => {
  const order = db.findOrder(req.params.id);

  if (!order) {
    return res.status(404).json({ error: 'Order not found' });
  }

  if (order.visibility === 'private' && req.user.id !== order.userId) {
    return res.status(403).json({ error: 'Access denied' });
  }

  res.status(200).json(order);
});

Common Mistakes

1. Always Returning 200

Every request gets 200 OK with error in body. Don't do this.

2. Using 400 for Auth Errors

Use 401 for auth issues, not 400.

3. No 201 with Location Header

POST responses should include Location header pointing to new resource.

4. 500 for Expected Errors

Client errors (validation, not found) should be 4xx, not 500.

5. 204 with Body

204 No Content means no body. Don't include one.

Practice Questions

  1. What status code for successful POST?
  2. What status code for successful DELETE?
  3. What is the difference between 401 and 403?
  4. What status code for rate limiting?
  5. What header should 201 include?

Answers:

  1. 201 Created.
  2. 204 No Content.
  3. 401 is unauthenticated; 403 is authenticated but not authorized.
  4. 429 Too Many Requests.
  5. Location header with the URL of the new resource.

Challenge: Audit your API endpoints. Ensure every endpoint returns the correct status code for each outcome (success, error, not found, conflict).

FAQ

Should I return 200 or 201 for updates?

: 200 OK for updates (PUT, PATCH). 201 for creates (POST).

What status code for validation errors?

: 400 Bad Request or 422 Unprocessable Entity.

Can I return 200 with an error message in the body?

: No. Use the correct 4xx status code and put details in the body.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro