# Delete (https://v2.s3.dimah.dev/docs/react/custom-backend/delete)

Deleting is a request to your backend, not a presigned transfer. Delete is
idempotent: a key that does not exist still succeeds.

## Delete one [#delete-one]

`delete` receives a `route` and one object `key`.

<AutoTypeTable
  path="packages/core/src/types/requests.ts"
  name="DeletePayload"
/>

<AutoTypeTable
  path="packages/core/src/types/responses.ts"
  name="DeleteResponse"
/>

## Delete many [#delete-many]

`deleteMany` receives one route and between 1 and 100 keys
(`DELETE_MANY_MAX_KEYS`). `useDelete` splits larger calls into batches of that
size.

<AutoTypeTable
  path="packages/core/src/types/requests.ts"
  name="DeleteManyPayload"
/>

Delete each key on its own. Put it in `deleted`, or in `failed` with an error
body `{ code, message, params? }`. A key you leave out of both fails with
`UNKNOWN_ERROR`.

<AutoTypeTable
  path="packages/core/src/types/responses.ts"
  name="DeleteManyResponse"
/>

## Example [#example]

[`@dimah-s3/server`](https://v2.s3.dimah.dev/docs/server) uses `DELETE /api/s3/delete?route=…&key=…`
and `POST /api/s3/delete/batch`.

```ts title="lib/s3-api/delete.ts"
import type {
  DeleteManyPayload,
  DeleteManyResponse,
  DeletePayload,
  DeleteResponse,
  S3RequestOptions,
} from "@dimah-s3/core";
import { $fetch, call } from "./fetch";

export const deleteObject = (
  payload: DeletePayload,
  options?: S3RequestOptions,
) =>
  $fetch<DeleteResponse>("/delete", {
    method: "DELETE",
    query: payload,
    ...call(options),
  });

export const deleteMany = (
  payload: DeleteManyPayload,
  options?: S3RequestOptions,
) =>
  $fetch<DeleteManyResponse>("/delete/batch", {
    method: "POST",
    body: payload,
    ...call(options),
  });
```

`$fetch` and `call` come from the
[skeleton](https://v2.s3.dimah.dev/docs/react/custom-backend#skeleton).
