Skip to content

Delete

In REST APIs, it is customary to make a DELETE request to a resource’s URI (for example, /v1/publishers/{publisherId}/books/{bookId}) in order to delete that resource.

Resource-oriented design (AEP-121) honors this pattern through the Delete action. This action accepts the URI representing that resource and usually returns an empty response.

APIs should generally provide a delete action for resources unless it is not valuable for users to do so.

The Delete action should succeed even if nothing was deleted. If the resource did not exist, the action should not return 404 Not Found. See idempotency.

The action must have strong consistency: the completion of a delete action must mean that the existence of the resource has reached a steady-state and reading resource state returns a consistent 404 Not Found response.

Delete actions are specified using the following pattern:

  • The action must be used to remove a resource at a known URI.
  • Some resources take longer to delete than is reasonable for a regular API request. In this situation, the API should use a long-running operation.

Delete operations must be made by sending a DELETE request to the resource’s canonical URI path:

DELETE /v1/publishers/{publisherId}/books/{bookId}

Delete actions implement a common request pattern:

  • The HTTP method must be DELETE, and must follow the DELETE method guidelines in AEP-69.
  • If a delete request contains a body, the body must be ignored and must not cause an error (this is required by RFC 9110)
  • The request must not require any query parameters.
    • Optional query parameters may be included for additional options (e.g., cascade=true), but the core deletion operation must be determined by the URI alone.
paths:
/publishers/{publisherId}/books/{bookId}:
delete:
parameters:
- in: path
name: publisherId
required: true
schema:
type: string
- in: path
name: bookId
required: true
schema:
type: string
- in: query
name: cascade
schema:
type: boolean
  • Delete actions should return 204 No Content with no response body if the delete was successful.
paths:
/publishers/{publisherId}/books/{bookId}:
delete:
responses:
'204':
content:
application/json:
schema: {}
description: Successful response

A Delete action must return appropriate error responses. For additional guidance, see Errors and HTTP status codes.

Most common error scenarios:

  • 409 Conflict should be returned if the cascade field is false (or unset) and child resources are present.
  • See authorization checks for details on responses based on permissions.

See the full Soft delete AEP-164 for guidance.

Sometimes, it may be necessary for users to be able to delete a resource as well as all applicable child resources. However, since deletion is usually permanent, it is also important that users do not do so accidentally, as reconstructing wiped-out child resources may be quite difficult.

If an API allows deletion of a resource that may have child resources, the API should provide a bool cascade field on the request, which the user sets to explicitly opt in to a cascading delete.

The API should fail with a 409 Conflict error if the cascade field is false (or unset) and child resources are present.

paths:
/publishers/{publisherId}:
parameters:
- $ref: '#/components/parameters/PublisherId'
delete:
operationId: deletePublisher
description: Delete a publisher.
parameters:
- in: query
name: cascade
description: >
If set to true, any books from this publisher will also be deleted.
(Otherwise, the request will only work if the publisher has no
books.)
schema:
type: boolean
default: false
responses:
'204':
description: Publisher was deleted
'409':
description: |
Delete request failed because publisher has child resource and the
`cascade` parameter was set or defaulted to `false`.

Delete operations must be idempotent. When a client attempts to delete a resource that has already been deleted or does not exist, the API must treat the operation as successful and return the same response as if the resource was just deleted.

This treats deletion as “ensure this resource does not exist” rather than “remove this specific resource.” The approach simplifies client retry logic and aligns with idempotency principles: repeated identical requests produce the same result.

APIs must not return 404 Not Found for deletion attempts on non-existent resources, as this breaks idempotency guarantees.

# First delete removes the resource
DELETE /books/123
204 No Content
# Subsequent deletes return the same response
DELETE /books/123
204 No Content

Delete actions should return 204 No Content with no response body. However, APIs may return 200 OK with a response body when additional information is useful:

200 OK
Content-Type: application/json
{
"id": "123",
"deletedTime": "2024-12-02T10:30:00Z",
"cascadeDeleted": [
{"type": "review", "id": "review-1"},
{"type": "review", "id": "review-2"}
]
}

This approach is useful when:

  • Providing confirmation details about what was deleted
  • Returning information about cascade-deleted child resources
  • Including metadata like deletion timestamps or audit information
paths:
/publishers/{publisherId}/books/{bookId}:
delete:
description: Delete method for book
operationId: deleteBook
parameters:
- in: path
name: publisherId
required: true
schema:
type: string
- in: path
name: bookId
required: true
schema:
type: string
- in: query
name: cascade
schema:
type: boolean
responses:
'204':
content:
application/json:
schema: {}
description: Successful response
  • For soft delete and undelete, see AEP-164.
  • For bulk deleting large numbers of resources based on a filter, see AEP-165.

Not Found vs No Content Response

Idempotency is crucial for DELETE because it allows clients to safely retry deletion operations without fear of unintended consequences. Network failures, timeouts, and other transient issues are common in distributed systems, and idempotent operations enable automatic retry logic. The debate between returning 404 Not Found versus 204 No Content for already-deleted resources centers on the definition of “idempotent.” Both approaches achieve the same end state (resource doesn’t exist), but differ in how they signal completion. Returning 204 for all deletions (permissive idempotency) is recommended because it treats the operation as “ensure this resource is deleted” rather than “delete this specific resource,” which better matches client expectations and simplifies error handling.