# Bring your own backend (https://s3.dimah.dev/docs/react/custom-backend)



Implement `S3Api` with [`defineApi`](https://s3.dimah.dev/docs/react/setup). Routes, transport, and
server framework are up to you. They do not need to match
[`@dimah-s3/server`](https://s3.dimah.dev/docs/server).

Each `S3Api` method must accept the documented input and return JSON with
**every field** in the response tables. Missing fields break the hooks.
Every request includes a required `route` name. Upload and multipart init
do **not** send `key` — your backend generates it and returns it.

Input types: `Parameters<S3Api["upload"]>`. Response types are exported from
`@dimah-s3/core`.

## Flows [#flows]

| Flow          | Methods                                                             | Doc                                               |
| ------------- | ------------------------------------------------------------------- | ------------------------------------------------- |
| Simple upload | `upload` → browser uploads to S3 → `confirm`                        | [Upload](https://s3.dimah.dev/docs/react/custom-backend/upload)       |
| Download      | `download`                                                          | [Download](https://s3.dimah.dev/docs/react/custom-backend/download)   |
| Delete        | `delete`                                                            | [Delete](https://s3.dimah.dev/docs/react/custom-backend/delete)       |
| Multipart     | `init` → `signPart` → `complete` or `abort` · `listParts` to resume | [Multipart](https://s3.dimah.dev/docs/react/custom-backend/multipart) |

## Skeleton [#skeleton]

Merge the methods from each page into one `defineApi` call:

```ts title="lib/s3-api.ts"
import { defineApi } from "@dimah-s3/react";

export const api = defineApi({
  async upload(payload) {
    /* see Upload */
  },
  async confirm(payload) {
    /* see Upload */
  },
  async download(payload) {
    /* see Download */
  },
  async delete(payload) {
    /* see Delete */
  },
  multipart: {
    async init(payload) {
      /* see Multipart */
    },
    async signPart(payload) {
      /* see Multipart */
    },
    async listParts(payload) {
      /* see Multipart */
    },
    async complete(payload) {
      /* see Multipart */
    },
    async abort(payload) {
      /* see Multipart */
    },
  },
});
```
