---
title: DeleteObjects · S3 API
description: Deletes up to 1,000 objects in one request.
doc_version: 0.1.0-preview
last_updated: 2026-09-14
---

# DeleteObjects

`POST /{bucket}?delete`

Deletes up to 1,000 objects in one request.

Each key gets its own result. A key that fails does not stop the others. An Object with a VersionId removes that version for good. Without a VersionId, storage removes the object. In a bucket with versioning on, it adds a delete marker and keeps the versions.

- Role: Editor or higher.
- Support: supported.
- Auth: AWS Signature Version 4 with your API key. See [S3 API](/api/s3.md).
- Up to 1,000 keys. Each key gets its own result. A VersionId removes that version. Quiet mode works.
- A key with no object comes back as an Error with the code `NoSuchKey`.
- Storage does not need Content-MD5.

## Example request

```http
POST /support-tickets?delete HTTP/1.1
Host: wspq7ws2np5l8z4.storage.beta.graphon.sh
x-amz-date: 20261007T093000Z
x-amz-content-sha256: c7c851ceb4359b2eff263321acec9a3b9804f1cd80750006d5d348989187998e
Authorization: AWS4-HMAC-SHA256 Credential=<ACCESS_KEY_ID>/20261007/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=<SIGNATURE>
Content-Length: 156

<Delete xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Object>
    <Key>a.json</Key>
  </Object>
  <Object>
    <Key>b.json</Key>
  </Object>
</Delete>
```

## Path parameters

- `bucket` (string, required): The bucket name.

## Query parameters

- `delete` (flag, required): Selects this operation. Send it with no value.

## Headers

- `x-amz-expected-bucket-owner` (string, optional): The workspace ID that must own the bucket. Another owner returns `403 AccessDenied`.

## Request body

- `Delete` (object, required): The root element.
  - `Quiet` (boolean, optional): Send `true` to return only the errors. Default: `false`.
  - `Object` (array, required): One element for each key, up to 1,000.
    - `Key` (string, required): The key to delete.
    - `VersionId` (string, optional): Remove this version for good.

## Responses

### 200 · OK

The result for each key. Check the Error elements, because the status is 200 even when keys fail.

Response body:

- `DeleteResult` (object, required): The root element.
  - `Deleted` (array, optional): One element for each deleted key. Quiet mode leaves it out.
    - `Key` (string, optional): The deleted key.
    - `VersionId` (string, optional): The VersionId of the Object, when it has one.
    - `DeleteMarker` (boolean, optional): `true` when the delete added a delete marker or removed one.
    - `DeleteMarkerVersionId` (string, optional): The version ID of that delete marker.
  - `Error` (array, optional): One element for each key that failed.
    - `Key` (string, optional): The key.
    - `VersionId` (string, optional): The VersionId of the Object, when it has one.
    - `Code` (string, optional): The error code, such as `NoSuchKey`.
    - `Message` (string, optional): What went wrong.

```http
HTTP/1.1 200 OK
Content-Type: application/xml
x-amz-request-id: 4F8A2C7D1E6B4093A5C2D8E1F7B3A960

<?xml version="1.0" encoding="UTF-8"?>
<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Deleted>
    <Key>a.json</Key>
  </Deleted>
  <Error>
    <Key>b.json</Key>
    <Code>NoSuchKey</Code>
    <Message>The specified key does not exist.</Message>
  </Error>
</DeleteResult>
```

## Errors

Any request can also get the common errors on [S3 API](/api/s3.md).

### 404 · `NoSuchBucket`

No bucket has this name, or the bucket was deleted.

Check the bucket name. ListBuckets shows the buckets of the workspace.

### 403 · `AccessDenied`

The key does not have the role for this operation, or the bucket is in another workspace.

Use a key of the workspace that owns the bucket, with the role above.

## Other request languages

### aws CLI

```bash
# The graphon profile from the S3 API overview.
export AWS_PROFILE=graphon

aws s3api delete-objects \
  --bucket support-tickets \
  --delete '{"Objects":[{"Key":"a.json"},{"Key":"b.json"}]}'
```

### Python (boto3)

```python
# Replace wspq7ws2np5l8z4 with your workspace ID.
import os

import boto3
from botocore.config import Config

api_key = os.environ["GRAPHON_API_KEY"]
access_key_id = api_key.split("_", 1)[1].split(".")[0]

s3 = boto3.client(
    "s3",
    endpoint_url="https://wspq7ws2np5l8z4.storage.beta.graphon.sh",
    region_name="us-east-1",
    aws_access_key_id=access_key_id,
    aws_secret_access_key=api_key,
    config=Config(signature_version="s3v4", s3={"addressing_style": "path"}),
)

response = s3.delete_objects(
    Bucket="support-tickets",
    Delete={
        "Objects": [
            {
                "Key": "a.json",
            },
            {
                "Key": "b.json",
            },
        ],
    },
)
print(response.get("Deleted"), response.get("Errors"))
```

### JavaScript (AWS SDK)

```javascript
// Replace wspq7ws2np5l8z4 with your workspace ID.
import { S3Client, DeleteObjectsCommand } from '@aws-sdk/client-s3';

const apiKey = process.env.GRAPHON_API_KEY;
if (!apiKey) throw new Error('Set GRAPHON_API_KEY.');
const accessKeyId = apiKey.split('_')[1].split('.')[0];

const s3 = new S3Client({
  endpoint: 'https://wspq7ws2np5l8z4.storage.beta.graphon.sh',
  region: 'us-east-1',
  forcePathStyle: true,
  credentials: { accessKeyId, secretAccessKey: apiKey },
});

const response = await s3.send(new DeleteObjectsCommand({
  Bucket: 'support-tickets',
  Delete: {
    Objects: [
      {
        Key: 'a.json',
      },
      {
        Key: 'b.json',
      },
    ],
  },
}));
console.log(response.Deleted, response.Errors);
```

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
