# TanStack Start

> Receive signed Mynth webhooks in a TanStack Start server route, generate from a server function, and use the TanStack AI image adapter.

`@mynthio/sdk/tanstack-start` exports `mynthWebhookHandler` for a Start server
route. Generation from a server function uses the normal SDK. If the app
already uses TanStack AI's `generateImage()`, the separate
`@mynthio/tanstack-ai-adapter` package plugs Mynth into it.

## Receive the webhook

```bash
npm install @mynthio/sdk
```

Put `MYNTH_WEBHOOK_SECRET`, the `wbs_` secret from registering the endpoint,
in the server environment.

```ts
// src/routes/api/mynth-webhook.ts
import { createFileRoute } from "@tanstack/react-router";
import { mynthWebhookHandler } from "@mynthio/sdk/tanstack-start";

export const Route = createFileRoute("/api/mynth-webhook")({
  server: {
    handlers: {
      POST: mynthWebhookHandler({
        imageTaskCompleted: async (payload, { request }) => {
          console.log(payload.task.id, payload.result.images, request.url);
        },
        imageTaskFailed: async (payload) => {
          console.error(payload.task.id, payload.errors);
        },
      }),
    },
  },
});
```

The handler verifies `X-Mynth-Signature` against the raw body, requires
`X-Mynth-Event` to match the body's `event` and `X-Mynth-Delivery` to be
present, and rejects a timestamp more than five minutes off, all with `400`. An event with no handler, or one it does not
know, answers `200`. It reads the secret on each request, from
`MYNTH_WEBHOOK_SECRET` or from `{ webhookSecret }` as the second argument, and
throws if neither is set.

It reads a clone of the request, so the route's `request` stays unread. Each
callback receives the payload and the route context: `request`, `params`, and
middleware `context`, plus `deliveryId`, the `X-Mynth-Delivery` value. The handler names are the same as in every SDK helper.
See the [table on webhooks](https://mynth.io/docs/concepts/webhooks.md#receive-events).
Unsigned per-request `webhook.custom` deliveries are rejected.

## Generate on the server

Keep `MYNTH_API_KEY` on the server and call the SDK from a server function:

```ts
import Mynth from "@mynthio/sdk";

const mynth = new Mynth();

const pending = await mynth.image.generateAsync({
  model: "black-forest-labs/flux.2-pro",
  prompt: "A lighthouse at dusk, film grain",
});

return { taskId: pending.id, token: pending.access.publicAccessToken };
```

`generate()` waits for the task. `generateAsync()` returns the id and a
browser token right away, for when the caller cannot wait.
[Tasks and polling](https://mynth.io/docs/sdks/typescript/tasks.md) covers both.

## TanStack AI

`@mynthio/tanstack-ai-adapter` is for apps that already call `generateImage()`
from `@tanstack/ai`. It depends on `@mynthio/sdk` and needs `@tanstack/ai`
0.34.0 or newer as a peer. It does not verify webhooks. The route above still
does that.

```bash
npm install @mynthio/tanstack-ai-adapter @tanstack/ai
```

```ts
import { generateImage } from "@tanstack/ai";
import { mynthImage } from "@mynthio/tanstack-ai-adapter";

const result = await generateImage({
  adapter: mynthImage("black-forest-labs/flux.2-pro"),
  prompt: "A lighthouse at dusk, film grain",
});

console.log(result.images[0]?.url);
```

- `mynthImage(model, config?)` binds one model. The key comes from
  `MYNTH_API_KEY` or `config.apiKey`.
- `createMynthImage({ apiKey, baseUrl, destination })` returns a function that
  takes a model, for several adapters sharing one config.
- Image content parts become Mynth `inputs` on models listed in
  `MYNTH_IMAGE_INPUT_MODELS`. Other Mynth fields go in `modelOptions`.
- `MYNTH_IMAGE_MODELS` is the id list built into the package version, and it
  includes `auto`. Pass an explicit id. The live list is
  `GET https://api.mynth.io/models`.

The adapter calls the SDK's `generate()` and returns the finished images.
[tanstack-start-ai-mynth-adapter](https://github.com/mynthio/oss/tree/main/examples/tanstack-start-ai-mynth-adapter)
is a complete Start app that streams the TanStack call.

## Next steps

- [Webhooks](https://mynth.io/docs/concepts/webhooks.md): registering the endpoint, events, sources, and retries.
- [Generate images](https://mynth.io/docs/guides/generate-images.md): the request fields.
