Definition
DELETE is an HTTP method that removes a resource from the server. When a client sends a DELETE request to a resource URI, the server should remove that resource or mark it as deleted. DELETE is idempotent - if you delete a resource that’s already deleted, the result is the same: the resource doesn’t exist.
The key characteristic of DELETE is irreversibility: once executed successfully, subsequent GET requests to the same URI should return 404 Not Found (or 410 Gone if you want to indicate the resource existed previously). However, many production systems implement “soft deletes” where resources are marked as deleted rather than physically removed.
DELETE is fundamental to RESTful CRUD operations, representing the “D” (Delete/Destroy). Unlike unsafe methods like POST, DELETE should be implemented carefully with proper authorization checks to prevent accidental or malicious data loss.
Example
User Account - Hard Delete:
DELETE /api/users/123 HTTP/1.1
// Response: 204 No Content (deleted successfully)
Blog Post - Remove Content:
DELETE /api/posts/456 HTTP/1.1
// Response: 200 OK with deletion confirmation
{
"message": "Post deleted successfully",
"deletedAt": "2026-01-09T12:00:00Z"
}
Shopping Cart - Clear All Items:
DELETE /api/cart HTTP/1.1
// Response: 204 No Content
File Storage - Remove Document:
DELETE /api/files/report-2024.pdf HTTP/1.1
Authorization: Bearer token...
// Response: 200 OK
{
"deleted": true,
"filename": "report-2024.pdf",
"size": 2048576
}
Collection - Remove Specific Item:
DELETE /api/playlists/789/songs/101 HTTP/1.1
// Response: 204 No Content
Analogy
Erasing a Whiteboard: DELETE is like erasing something from a whiteboard. Once you wipe it clean, it’s gone. If you try to erase the same spot again, nothing happens - it’s already empty. The action is idempotent.
Canceling a Reservation: When you DELETE a hotel reservation, it’s removed from the system. If you try to cancel the same reservation again, the system tells you it doesn’t exist anymore - but the end result is the same: no reservation.
Removing Books from Library: Think of checking a book out permanently (removing it from circulation). Whether you remove it once or try to remove it ten times, the result is identical - the book is no longer available.
Code Example
// DELETE - Remove user resource
DELETE /api/users/789 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
// Response - 204 No Content (standard response)
HTTP/1.1 204 No Content
Date: Thu, 09 Jan 2026 12:00:00 GMT
// DELETE - With confirmation body (less common)
DELETE /api/posts/456 HTTP/1.1
Authorization: Bearer token...
// Response - 200 OK with body
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "deleted",
"id": 456,
"title": "My Blog Post",
"deletedAt": "2026-01-09T12:00:00Z"
}
// DELETE - Idempotent behavior (already deleted)
DELETE /api/users/789 HTTP/1.1
// Response - 404 Not Found (already deleted)
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "not_found",
"message": "User not found"
}
// Alternative - 410 Gone (indicates it existed before)
HTTP/1.1 410 Gone
Content-Type: application/json
{
"error": "resource_deleted",
"message": "User was deleted",
"deletedAt": "2026-01-09T12:00:00Z"
}
// DELETE - Conditional delete with ETag
DELETE /api/documents/123 HTTP/1.1
If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
// Response - 204 No Content (matched, deleted)
HTTP/1.1 204 No Content
// DELETE - Failed precondition
DELETE /api/documents/123 HTTP/1.1
If-Match: "wrong-etag"
// Response - 412 Precondition Failed
HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
"error": "precondition_failed",
"message": "Resource has been modified since last fetch"
}
// DELETE - Authorization error
DELETE /api/users/999 HTTP/1.1
Authorization: Bearer invalid-token
// Response - 403 Forbidden
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"error": "forbidden",
"message": "You don't have permission to delete this resource"
}
// DELETE - Soft delete (resource marked inactive)
DELETE /api/accounts/555 HTTP/1.1
// Response - 200 OK
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 555,
"status": "deleted",
"deletedAt": "2026-01-09T12:00:00Z",
"restorable": true,
"restoreUntil": "2026-02-09T12:00:00Z"
}
Diagram
sequenceDiagram
participant Client
participant Server
participant Database
Client->>Server: DELETE /api/users/123
Note over Client,Server: Authorization header
Server->>Server: Verify authorization
Note over Server: Check permissions
Server->>Database: Check if resource exists
Database-->>Server: Resource found
Server->>Database: DELETE from users WHERE id=123
Database-->>Server: Deleted successfully
Server-->>Client: 204 No Content
Note over Server,Client: Resource deleted
Client->>Server: DELETE /api/users/123 (again)
Note over Client,Server: Idempotent - same request
Server->>Database: Check if resource exists
Database-->>Server: Not found
Server-->>Client: 404 Not Found
Note over Server,Client: Already deleted (idempotent)
Security Notes
CRITICAL - Implement strict authorization checks before deleting. Deletion is irreversible.
Authorization & Verification:
- Permission checks: Verify user has permission to delete
- Ownership validation: Confirm user owns or can delete resource
- Admin review: Require review for critical deletions
- Soft delete: Consider soft delete (mark as deleted) for important data
- Recovery window: Allow recovery within time window
Idempotency & Safety:
- Idempotent behavior: Multiple DELETE calls should succeed
- Return 404 for deleted: Subsequent requests return 404 Not Found
- Conditional deletes: Use ETags to prevent accidental deletes
- If-Match headers: Validate resource hasn’t changed
Logging & Audit:
- Audit trail: Log all deletions with user, timestamp, resource
- Data preservation: Back up deleted data before removal
- Immutable logs: Ensure logs cannot be tampered with
- Compliance: Meet regulatory requirements for deletion
Cascade & Dependencies:
- Warn on cascade: Alert user if deletion cascades
- Atomic operations: All-or-nothing cascade deletes
- Constraints: Use database constraints to prevent orphaned data
- User confirmation: Require explicit confirmation for cascades
Rate Limiting & Abuse:
- Rate limit: Limit deletions per user/IP
- Bulk limits: More aggressive limits on bulk operations
- Anomaly detection: Alert on unusual deletion patterns
- Block abuse: Block users attempting to delete others’ data
Best Practices
- Return 204 No Content: Standard successful response (no body needed)
- Use 200 OK if returning data: Include deletion details in response body
- Implement authorization: Verify user has permission to delete
- Make it idempotent: Deleting already-deleted resource should succeed
- Return 404 Not Found: After successful delete, GET should return 404
- Consider soft deletes: Mark as deleted instead of physical removal
- Support ETags: Use If-Match for conditional deletes
- Log deletions: Audit trail for compliance and recovery
- Handle cascades carefully: Document what else gets deleted
- Provide undo/restore: For critical resources, allow recovery period
Common Mistakes
Returning 200 OK with empty body instead of 204 No Content. Not implementing proper authorization, allowing users to delete others’ resources. Making DELETE non-idempotent - returning 500 error when resource already deleted instead of 404/410. Including request body in DELETE (some servers ignore it). Not logging deletion events for audit purposes. Implementing hard deletes for critical data without backup/restore mechanism. Forgetting cascade delete implications - removing parent without handling orphaned children. Not supporting conditional deletes with ETags, risking deletion of modified resources. Allowing DELETE without authentication for sensitive resources. Returning 204 but not actually deleting the resource (soft delete without documentation).