# Multipart Hooks (https://v1.s3.dimah.dev/docs/server/hooks/multipart)

Enable multipart support on large-file routes by setting `upload.multipart: true` or passing a `MultipartConfig` object.

```ts title="lib/s3.ts"
import { S3Client } from "@aws-sdk/client-s3";
import { dimahS3, route } from "@dimah-s3/server";

export const awsS3 = new S3Client({/* env */});

export const s3 = dimahS3({
  client: awsS3,
  bucket: process.env.S3_BUCKET!,
  routes: {
    video: route({
      upload: {
        fileTypes: ["video/*"],
        maxFileSize: 500 * 1024 * 1024, // 500MB
        multipart: true, // [!code ++]
        onConfirmed: async ({ key, contentLength }) => {
          // Triggered on successful multipart completion
        },
      },
    }),
  },
});
```

---

## Multipart lifecycle flow [#multipart-lifecycle-flow]

<Flow
  label="Multipart upload flow"
  steps={[
    { name: "upload.guard", kind: "hook", note: "Init validation" },
    { name: "CreateMultipartUpload", kind: "s3" },
    { name: "multipart.guard", kind: "hook", note: "Authorizes each part" },
    { name: "CompleteMultipartUpload", kind: "s3" },
    { name: "HeadObject", kind: "server" },
    { name: "onConfirmed", kind: "hook", note: "Final metadata" },
  ]}
/>

---

## Type reference [#type-reference]

```ts
import type {
  MultipartConfig,
  MultipartOnInitContext,
  MultipartGuardContext,
  MultipartOnAbortContext,
  MultipartOnListContext,
} from "@dimah-s3/server";
```

### MultipartConfig [#multipartconfig]

<AutoTypeTable
  path="packages/server/src/types/config.ts"
  name="MultipartConfig"
/>

---

### MultipartOnInitContext [#multipartoninitcontext]

<AutoTypeTable
  path="packages/server/src/types/hook-contexts.ts"
  name="MultipartOnInitContext"
/>

---

### MultipartGuardContext [#multipartguardcontext]

<AutoTypeTable
  path="packages/server/src/types/hook-contexts.ts"
  name="MultipartGuardContext"
/>

---

### MultipartOnAbortContext [#multipartonabortcontext]

<AutoTypeTable
  path="packages/server/src/types/hook-contexts.ts"
  name="MultipartOnAbortContext"
/>

---

### MultipartOnListContext [#multipartonlistcontext]

<AutoTypeTable
  path="packages/server/src/types/hook-contexts.ts"
  name="MultipartOnListContext"
/>

## Frequently asked questions [#frequently-asked-questions]

<Accordions>

<Accordion title="Does multipart upload require a second confirm call?">

No. The final assembly step (`multipart.complete`) internally runs `upload.confirmGuard`, queries `HeadObject`, and calls `upload.onConfirmed`.

</Accordion>

<Accordion title="How do I enforce part size and total size bounds?">

Set `upload.maxFileSize`; the server checks each signed part against the
remaining allowance and sums uploaded part sizes before
`CompleteMultipartUpload`. If the total size exceeds the limit, the server
aborts the multipart upload and returns `PAYLOAD_TOO_LARGE`.

</Accordion>

</Accordions>
