Definition
2xx Success status codes indicate that the client’s HTTP request was successfully received, understood, and accepted by the server. These codes confirm that the operation completed as expected.
The most common 2xx status codes are:
- 200 OK - Request succeeded, response contains requested data
- 201 Created - New resource successfully created
- 202 Accepted - Request accepted for processing (async operations)
- 204 No Content - Request succeeded but no content to return (e.g., DELETE operations)
- 206 Partial Content - Server is returning only part of the resource (range requests)
2xx codes are defined in RFC 7231 and are fundamental to RESTful API design, indicating successful CRUD operations.
Example
200 OK - Successful GET:
GET /api/users/123 HTTP/1.1
Host: api.example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 142
{
"id": 123,
"name": "Alice Smith",
"email": "[email protected]",
"role": "developer"
}
201 Created - Successful POST:
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "Bob Johnson",
"email": "[email protected]"
}
HTTP/1.1 201 Created
Location: /api/users/124
Content-Type: application/json
Content-Length: 168
{
"id": 124,
"name": "Bob Johnson",
"email": "[email protected]",
"createdAt": "2026-01-09T10:30:00Z"
}
204 No Content - Successful DELETE:
DELETE /api/users/123 HTTP/1.1
Host: api.example.com
Authorization: Bearer YOUR_TOKEN
HTTP/1.1 204 No Content
Date: Thu, 09 Jan 2026 10:30:00 GMT
202 Accepted - Async Processing:
POST /api/reports/generate HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"reportType": "sales",
"dateRange": "2025-12-01/2025-12-31"
}
HTTP/1.1 202 Accepted
Location: /api/reports/status/abc-123
Content-Type: application/json
{
"status": "processing",
"statusUrl": "/api/reports/status/abc-123",
"estimatedCompletion": "2026-01-09T10:35:00Z"
}
Code Example
JavaScript (Fetch API):
// Handle 200 OK
const getUser = async (userId) => {
const response = await fetch(`https://api.example.com/users/${userId}`, {
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN'
}
});
if (response.status === 200) {
return await response.json();
}
throw new Error(`Unexpected status: ${response.status}`);
};
// Handle 201 Created
const createUser = async (userData) => {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN'
},
body: JSON.stringify(userData)
});
if (response.status === 201) {
const location = response.headers.get('Location');
console.log('Created resource at:', location);
return await response.json();
}
throw new Error(`Failed to create: ${response.status}`);
};
// Handle 204 No Content
const deleteUser = async (userId) => {
const response = await fetch(`https://api.example.com/users/${userId}`, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_TOKEN'
}
});
if (response.status === 204) {
console.log('User deleted successfully');
return; // No content to parse
}
throw new Error(`Failed to delete: ${response.status}`);
};
// Handle 202 Accepted (async operations)
const generateReport = async (reportData) => {
const response = await fetch('https://api.example.com/reports/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN'
},
body: JSON.stringify(reportData)
});
if (response.status === 202) {
const data = await response.json();
console.log('Report generation started:', data.statusUrl);
// Poll status URL until complete
return await pollStatus(data.statusUrl);
}
throw new Error(`Failed to start report: ${response.status}`);
};
const pollStatus = async (statusUrl) => {
const maxAttempts = 60;
const delay = 2000; // 2 seconds
for (let i = 0; i < maxAttempts; i++) {
const response = await fetch(statusUrl, {
headers: { 'Authorization': 'Bearer YOUR_TOKEN' }
});
const data = await response.json();
if (data.status === 'completed') {
return data.result;
} else if (data.status === 'failed') {
throw new Error('Report generation failed');
}
await new Promise(resolve => setTimeout(resolve, delay));
}
throw new Error('Report generation timeout');
};
Python (requests library):
import requests
import time
# Handle 200 OK
def get_user(user_id):
response = requests.get(
f'https://api.example.com/users/{user_id}',
headers={
'Accept': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN'
}
)
if response.status_code == 200:
return response.json()
raise Exception(f'Unexpected status: {response.status_code}')
# Handle 201 Created
def create_user(user_data):
response = requests.post(
'https://api.example.com/users',
json=user_data,
headers={'Authorization': 'Bearer YOUR_TOKEN'}
)
if response.status_code == 201:
location = response.headers.get('Location')
print(f'Created resource at: {location}')
return response.json()
raise Exception(f'Failed to create: {response.status_code}')
# Handle 204 No Content
def delete_user(user_id):
response = requests.delete(
f'https://api.example.com/users/{user_id}',
headers={'Authorization': 'Bearer YOUR_TOKEN'}
)
if response.status_code == 204:
print('User deleted successfully')
return # No content to parse
raise Exception(f'Failed to delete: {response.status_code}')
# Handle 202 Accepted (async operations)
def generate_report(report_data):
response = requests.post(
'https://api.example.com/reports/generate',
json=report_data,
headers={'Authorization': 'Bearer YOUR_TOKEN'}
)
if response.status_code == 202:
data = response.json()
print(f"Report generation started: {data['statusUrl']}")
# Poll status URL until complete
return poll_status(data['statusUrl'])
raise Exception(f'Failed to start report: {response.status_code}')
def poll_status(status_url):
max_attempts = 60
delay = 2 # 2 seconds
for i in range(max_attempts):
response = requests.get(
status_url,
headers={'Authorization': 'Bearer YOUR_TOKEN'}
)
data = response.json()
if data['status'] == 'completed':
return data['result']
elif data['status'] == 'failed':
raise Exception('Report generation failed')
time.sleep(delay)
raise Exception('Report generation timeout')
Diagram
graph TB
subgraph "2xx Success Codes"
S200[200 OK
Standard success]
S201201 Created
[Resource created]
S202[202 Accepted
Async processing]
S204[204 No Content
Success, no body]
S206[206 Partial Content
Range request]
end
subgraph "Use Cases"
UC1[GET request]
UC2[POST create]
UC3[Async job]
UC4[DELETE request]
UC5[Video streaming]
end
UC1 --> S200
UC2 --> S201
UC3 --> S202
UC4 --> S204
UC5 --> S206
S200 --> BODY1[Response includes body]
S201 --> BODY2[Response includes body
+ Location header]
S202 --> BODY3[Response includes status URL]
S204 --> NOBODY[No response body]
S206 --> PARTIAL[Partial response body
+ Content-Range header]
Analogy
Think of 2xx status codes like different types of success confirmations:
- 200 OK β “Here’s what you asked for” (cashier hands you your change)
- 201 Created β “Created! Here’s your receipt” (got a new account number)
- 202 Accepted β “We’re working on it, check back later” (order being prepared)
- 204 No Content β “Done! Nothing more to say” (subscription canceled, no receipt needed)
Best Practices
- Use Correct 2xx Code - Don’t use 200 for everything; use 201 for creates, 204 for deletes
- Include Location Header - Always add
Locationheader with 201 Created - Return Created Resource - Include the new resource in 201 response body
- Use 202 for Async - Long-running operations should return 202 with status URL
- No Body for 204 - Never include a response body with 204 No Content
- Consistent 200 Structure - Use the same response format across endpoints
- Include Metadata - Add timestamps, versions, or ETags in successful responses
Common Mistakes
- 200 for Everything - Using 200 OK for creates/deletes instead of 201/204
- 201 Without Location - Not including
Locationheader when creating resources - 204 With Body - Including response body with 204 No Content (violates spec)
- Sync 202 - Using 202 for operations that complete immediately
- No Status URL - Returning 202 without providing a way to check status
- Inconsistent Format - Changing response structure between similar endpoints
- Missing Timestamps - Not including
createdAtorupdatedAtin responses
Standards & RFCs
Standards & RFCs