> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mynth.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Reference for webhook events, headers, signature format, and payloads.

## Delivery model

Mynth supports:

* dashboard-managed webhooks
* task-level custom webhook endpoints

Dashboard-managed webhooks are signed. Task-level custom endpoints are not signed.

## Headers

Signed deliveries include:

| Header              | Meaning                                        |
| ------------------- | ---------------------------------------------- |
| `X-Mynth-Event`     | The event name                                 |
| `X-Mynth-Signature` | HMAC-SHA256 signature in `t=...,v1=...` format |

## Events

Payloads sent by the worker are image-task payloads:

* `task.image.generate.completed`
* `task.image.generate.failed`
* `task.image.rate.completed`
* `task.image.rate.failed`
* `task.image.alt.completed`
* `task.image.alt.failed`

Dashboard event subscriptions also support hierarchical matching through:

* `task.completed`
* `task.failed`
* `all`

For example, a `task.image.generate.completed` delivery can satisfy a webhook subscribed to `task.completed`.

## Signature verification

The signature is calculated from:

```text theme={"theme":"kanagawa-dragon"}
{timestamp}.{raw_request_body}
```

using the webhook secret and HMAC-SHA256.

The `X-Mynth-Signature` header format is:

```text theme={"theme":"kanagawa-dragon"}
t={timestamp},v1={signature}
```

Parse the timestamp and signature from the header, then recompute the HMAC over `{timestamp}.{raw_request_body}` using your webhook secret. Compare the result to the `v1` value.

See [Use Webhooks](/guides/use-webhooks#verify-webhook-signatures) for a complete code example.

## `task.image.generate.completed` payload

```json theme={"theme":"kanagawa-dragon"}
{
  "event": "task.image.generate.completed",
  "task": { "id": "tsk_123" },
  "request": {
    "prompt": "A campaign image for a summer travel brand"
  },
  "result": {
    "model": "google/gemini-3.1-flash-image",
    "images": [
      {
        "status": "success",
        "id": "img_123",
        "url": "https://...",
        "mynth_url": "https://...",
        "size": "1024x1024",
        "cost": "0.01250000"
      }
    ]
  }
}
```

## `task.image.generate.failed` payload

Failed tasks do not include a `result` object because generation did not produce images.

```json theme={"theme":"kanagawa-dragon"}
{
  "event": "task.image.generate.failed",
  "task": { "id": "tsk_123" },
  "request": {
    "prompt": "A campaign image for a summer travel brand"
  }
}
```

## `task.image.rate.completed` payload

```json theme={"theme":"kanagawa-dragon"}
{
  "event": "task.image.rate.completed",
  "task": { "id": "tsk_456" },
  "request": {
    "urls": ["https://example.com/image.png"],
    "mode": "nsfw_sfw"
  },
  "result": {
    "results": [
      {
        "status": "success",
        "url": "https://example.com/image.png",
        "level": "sfw"
      }
    ]
  }
}
```

## `task.image.rate.failed` payload

```json theme={"theme":"kanagawa-dragon"}
{
  "event": "task.image.rate.failed",
  "task": { "id": "tsk_456" },
  "request": {
    "urls": ["https://example.com/image.png"],
    "mode": "nsfw_sfw"
  }
}
```

## `task.image.alt.completed` payload

```json theme={"theme":"kanagawa-dragon"}
{
  "event": "task.image.alt.completed",
  "task": { "id": "tsk_789" },
  "request": {
    "urls": ["https://example.com/image.png"]
  },
  "result": {
    "results": [
      {
        "status": "success",
        "url": "https://example.com/image.png",
        "alt": "A ceramic mug on a wooden table beside a window."
      }
    ]
  }
}
```

## `task.image.alt.failed` payload

```json theme={"theme":"kanagawa-dragon"}
{
  "event": "task.image.alt.failed",
  "task": { "id": "tsk_789" },
  "request": {
    "urls": ["https://example.com/image.png"]
  }
}
```
