1. Library
  2. Computer Networks
  3. Http and the Web
  4. Methods

Updated 9 hours ago

DELETE does exactly what it says: it asks the server to remove a resource. But that simplicity hides a deeper question that every implementation must answer—what does it mean to destroy something?

The Request

DELETE requests are minimal. The URL identifies what to destroy. Headers handle authentication. There's typically no body.

DELETE /articles/12345 HTTP/1.1
Host: api.example.com
Authorization: Bearer token123

After a successful DELETE, GET requests to that URL should return 404 Not Found. The resource is gone.

The Response

204 No Content is the most common success response—the resource is deleted, there's nothing more to say:

HTTP/1.1 204 No Content

200 OK works when you want to return information about what was deleted:

{
  "id": 12345,
  "deleted_at": "2024-05-15T10:30:00Z"
}

202 Accepted signals that deletion is queued but not complete—useful when deleting large amounts of data that takes time to process.

404 Not Found means the resource doesn't exist. But this raises an interesting question we'll get to shortly.

409 Conflict indicates the resource can't be deleted—perhaps it has dependencies, or business rules prevent removal.

The Philosophical Divide

DELETE is idempotent: calling it multiple times should have the same effect as calling it once. After the first successful DELETE, the resource is gone. But what happens when you DELETE something that's already gone?

Camp One—Return 404: "The resource doesn't exist. I can't delete what isn't there."

DELETE /articles/12345
→ First request: 204 No Content
→ Second request: 404 Not Found

Camp Two—Return 204: "You asked me to ensure this resource doesn't exist. Mission accomplished."

DELETE /articles/12345
→ First request: 204 No Content  
→ Second request: 204 No Content

Both positions have merit. The 404 approach provides more information—did my request actually do anything? The 204 approach emphasizes the end state—the resource is gone, which is what you wanted.

Most modern APIs use 404, but the debate reveals something real about how we think about destruction. Is deletion an action ("remove this thing") or an outcome ("ensure this thing is absent")?

Soft Deletes: Having It Both Ways

Many applications never actually delete data. They mark it as deleted:

UPDATE articles SET deleted_at = NOW() WHERE id = 12345;

From the API's perspective, the resource is gone—GET returns 404, it disappears from lists. But the data remains in the database, recoverable if needed.

This provides:

  • Recovery from accidental deletions
  • Audit trails showing what was deleted and when
  • Compliance with regulations requiring data retention
  • Referential integrity for resources that reference deleted items

Some APIs expose this explicitly:

GET /articles?include_deleted=true
POST /articles/12345/restore

Conditional Deletes

DELETE is the only HTTP method that makes you ask: "Are you sure?" That hesitation isn't a bug in human psychology—it's appropriate respect for irreversibility.

Conditional requests provide a technical version of that safety check. The If-Match header ensures you're deleting what you think you're deleting:

DELETE /articles/12345 HTTP/1.1
If-Match: "etag-abc123"

If the article has been modified since you last read it—if someone else edited it while you were deciding to delete—the ETags won't match and the server returns:

HTTP/1.1 412 Precondition Failed

This prevents a specific kind of tragedy: deleting a resource that contains changes you've never seen.

Bulk Deletions

Deleting multiple resources at once is powerful and dangerous. Several patterns exist:

Individual requests: Simple, safe, chatty.

DELETE /articles/1
DELETE /articles/2
DELETE /articles/3

Query parameters: Powerful, terrifying.

DELETE /articles?status=draft&created_before=2024-01-01

A misconfigured filter could delete everything.

Explicit bulk endpoint: Not RESTful, but safe.

POST /articles/bulk-delete
{"ids": [1, 2, 3, 4, 5]}

For bulk operations, favor explicitness over elegance. The extra verbosity is a feature.

Security

DELETE requires careful protection:

Authentication: Never allow anonymous deletions.

Authorization: Verify the user can delete this specific resource. Owning a resource doesn't mean owning all resources.

CSRF protection: Prevent malicious sites from tricking browsers into sending DELETE requests.

Rate limiting: Prevent abuse—a compromised account with unlimited DELETE access is catastrophic.

Audit logging: Log every deletion with timestamp, user, and what was deleted. When something goes wrong, you'll need this.

Cascading behavior: Decide what happens to dependent resources. Delete them too? Return an error? The answer affects data integrity.

Asynchronous Deletion

Deleting large amounts of data takes time. Rather than making clients wait, acknowledge the request and process it in the background:

DELETE /users/12345 HTTP/1.1
→
HTTP/1.1 202 Accepted
{
  "status": "pending",
  "job_id": "delete-job-789",
  "status_url": "/jobs/delete-job-789"
}

Clients poll the status URL until the job completes. This pattern works for any operation that might take longer than a reasonable request timeout.

The Recycle Bin Pattern

User-facing applications often combine soft deletes with a grace period:

  1. DELETE request → soft delete immediately
  2. Resource appears "deleted" to users
  3. 30-day grace period for recovery
  4. Background job permanently deletes after grace period

This provides the UX of immediate deletion with the safety net of reversibility. Users get fast feedback; operations teams get time to fix mistakes.

Frequently Asked Questions About the HTTP DELETE Method

Was this page helpful?

😔
🤨
😃