
## Delete object

`DELETE /v1/storage/objects/:key`

Marks the object as deleted (soft delete). The object's `deletedAt` field is filled with the deletion date; the physical bytes remain in storage for up to 30 days, then are removed automatically. Restoring the object via the API is not available.

## Parameters

| Parameter | Type | Req. | Description |
|----------|-----|:-----:|---------|
| `key` (path) | string | yes | Logical object key, URL-encoded. For keys with `/` (e.g. `users/42/avatar.png`) pass as `users%2F42%2Favatar.png` |

## Examples

### curl — personal key

```bash
curl -s -X DELETE "https://vibecode.bitrix24.com/v1/storage/objects/docs-test%2Fverify.txt" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth app

```bash
curl -s -X DELETE "https://vibecode.bitrix24.com/v1/storage/objects/docs-test%2Fverify.txt" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

### JavaScript — personal key

```javascript
const key = encodeURIComponent('docs-test/verify.txt')
const res = await fetch(`https://vibecode.bitrix24.com/v1/storage/objects/${key}`, {
  method: 'DELETE',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
  },
})
const body = await res.json()
if (body.object?.deletedAt) {
  console.log('Object deleted:', body.object.deletedAt)
}
```

### JavaScript — OAuth app

```javascript
const key = encodeURIComponent('docs-test/verify.txt')
const res = await fetch(`https://vibecode.bitrix24.com/v1/storage/objects/${key}`, {
  method: 'DELETE',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})
const body = await res.json()
if (body.object?.deletedAt) {
  console.log('Object deleted:', body.object.deletedAt)
}
```

## Response fields

| Field | Type | Description |
|------|-----|---------|
| `object.id` | string (CUID) | Internal object identifier |
| `object.key` | string | Logical key |
| `object.contentType` | string | Content MIME type |
| `object.sizeBytes` | string | Size in bytes (a string due to JSON limits on large numbers) |
| `object.sha256` | string \| null | SHA-256 of the content, if it was passed at upload |
| `object.visibility` | string | `PRIVATE` or `PUBLIC` |
| `object.uploadStatus` | string | Upload status (`COMPLETED`) |
| `object.createdAt` | string (ISO 8601) | Creation date |
| `object.deletedAt` | string (ISO 8601) | Deletion date — filled after a successful deletion |

## Response example

```json
{
  "object": {
    "id": "cmpfkc57v0akio510qclwfn7t",
    "key": "docs-test/verify.txt",
    "contentType": "text/plain",
    "sizeBytes": "40",
    "sha256": null,
    "visibility": "PRIVATE",
    "uploadStatus": "COMPLETED",
    "createdAt": "2026-05-21T14:05:20.092Z",
    "deletedAt": "2026-05-21T14:05:36.880Z"
  }
}
```

## Error response example

410 — object already deleted (repeated call):

```json
{
  "success": false,
  "error": {
    "code": "STORAGE_OBJECT_DELETED",
    "message": "Object docs-test/verify.txt was deleted"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `STORAGE_INVALID_KEY` | The key contains invalid characters, starts with `/` or `.`, contains `..`, or exceeds 1024 characters |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is not passed |
| 403 | `STORAGE_SCOPE_REQUIRED` | API key does not have the `vibe:storage` scope |
| 404 | `STORAGE_OBJECT_NOT_FOUND` | No object with this key exists, or it belongs to another owner |
| 409 | `STORAGE_MULTIPART_IN_PROGRESS` | The object is in an unfinished multipart-upload state — first call [`/multipart/abort`](/docs/storage/upload/multipart-abort) |
| 410 | `STORAGE_OBJECT_DELETED` | The object was already deleted earlier |
| 503 | `STORAGE_STS_UNAVAILABLE` | The storage credentials service is temporarily unavailable — retry the request |
| 503 | `STORAGE_FEATURE_DISABLED` | Storage is temporarily unavailable on the platform |

The full list of general API errors — [Errors](/docs/errors).

## Known specifics

- **Keys with `/` in the path.** A slash in the key is not a route separator — pass it URL-encoded. In JavaScript use `encodeURIComponent(key)`.
- **A deleted object is immediately unavailable.** GET and HEAD by key return `410 STORAGE_OBJECT_DELETED` until the 30-day physical-deletion period expires. The object-list request does not include deleted objects.

## See also

- [Download object](/docs/storage/objects/get) — `GET /v1/storage/objects/:key`
- [List objects](/docs/storage/objects/list) — `GET /v1/storage/objects`
- [Abort multipart upload](/docs/storage/upload/multipart-abort) — `POST /v1/storage/objects/multipart/abort`
- [Public access GET](/docs/storage/objects/public-get) — `GET /v1/public-storage/:portalId/:objectId`
