# Multipart (https://v1.s3.dimah.dev/docs/react/custom-backend/multipart)

Split a large file into parts. Each part is a presigned PUT; your backend
orchestrates init, signing, complete, and abort.

**Flow:** `init` → `signPart` (per part) → `complete` or `abort` · `listParts`
to resume.

## Init [#init]

Same payload shape as [simple upload](https://v1.s3.dimah.dev/docs/react/custom-backend/upload).

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

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

## Sign part [#sign-part]

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

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

## List parts [#list-parts]

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

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

## Complete [#complete]

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

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

## Abort [#abort]

Same payload shape as list-parts.

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

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

```ts
import type {
  MultipartInitPayload,
  MultipartInitResponse,
  MultipartSignPartPayload,
  MultipartPartResponse,
  MultipartListPartsPayload,
  MultipartListPartsResponse,
  MultipartCompletePayload,
  MultipartCompleteResponse,
  MultipartAbortPayload,
  MultipartAbortResponse,
} from "@dimah-s3/core";
```

## Example [#example]

Add this to the [`defineApi`](https://v1.s3.dimah.dev/docs/react/custom-backend) skeleton.
[`@dimah-s3/server`](https://v1.s3.dimah.dev/docs/server) mounts these under
`/api/s3/presign/multipart/*`.

```ts
const base = "/api/files/presign/multipart";

async function post<T>(url: string, body: unknown): Promise<T> {
  const res = await fetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  if (!res.ok) throw new Error(await res.text());
  return res.json();
}

multipart: {
  init: (payload) => post(`${base}/init`, payload),
  signPart: (payload) => post(`${base}/part`, payload),
  async listParts(payload) {
    const params = new URLSearchParams({
      route: payload.route,
      key: payload.key,
      uploadId: payload.uploadId,
    });
    const res = await fetch(`${base}/parts?${params}`);
    if (!res.ok) throw new Error(await res.text());
    return res.json();
  },
  complete: (payload) => post(`${base}/complete`, payload),
  abort: (payload) => post(`${base}/abort`, payload),
}
```
