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

# Webhooks

> Receive an HTTP POST when a training or evaluation run finishes

Webhooks notify your systems when runs finish. Osmosis sends a `POST` request with a JSON payload to a URL you configure, once per completed run.

## Setup

Open **Workspace Settings → Webhooks** (owners and admins only):

1. Enter your **Webhook URL**. It must use HTTPS on port 443 and resolve to a public address. URLs that point at private or internal networks are rejected.
2. Turn on **Deliver events** and click **Save**.
3. Click **Send test payload** to confirm your receiver gets a `webhook.test` event.

Turn off **Deliver events** to pause deliveries without losing the URL. To remove the webhook entirely, clear the **Webhook URL** and click **Save**.

## Events

| Event                    | Sent when                       |
| ------------------------ | ------------------------------- |
| `training_run.completed` | A training run finishes         |
| `eval_run.completed`     | An evaluation run finishes      |
| `webhook.test`           | You click **Send test payload** |

## Payload

Every request is a `POST` with `Content-Type: application/json` and this envelope:

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/cli.json"]}}
{
  "event": "training_run.completed",
  "timestamp": "2026-07-15T22:14:05.123456+00:00",
  "data": {}
}
```

### `training_run.completed` and `eval_run.completed`

The `data` object has the same shape for both events:

| Field              | Description                                                                                                                                                                                    |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`               | The run ID                                                                                                                                                                                     |
| `name`             | The run name                                                                                                                                                                                   |
| `status`           | Final status of the run: `finished`, `failed`, or `stopped`                                                                                                                                    |
| `started_at`       | When the run started, ISO 8601                                                                                                                                                                 |
| `completed_at`     | When the run finished, ISO 8601                                                                                                                                                                |
| `duration_seconds` | Total run duration in seconds                                                                                                                                                                  |
| `model_name`       | Name of the model used by the run                                                                                                                                                              |
| `dataset`          | `{ "id", "name" }` of the dataset, or `null`                                                                                                                                                   |
| `rollout`          | `{ "id", "name" }` of the rollout, or `null`                                                                                                                                                   |
| `platform_url`     | Link to the run detail page in the platform                                                                                                                                                    |
| `latest_metrics`   | For training runs, the latest logged value of each run metric keyed by metric name. For evaluation runs, the run's final aggregate results, including the reward distribution (`reward_stats`) |

Training run example:

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/cli.json"]}}
{
  "event": "training_run.completed",
  "timestamp": "2026-07-15T22:14:05.123456+00:00",
  "data": {
    "id": "a1b2c3d4-0000-0000-0000-000000000000",
    "name": "my-training-run",
    "status": "finished",
    "started_at": "2026-07-15T20:01:12+00:00",
    "completed_at": "2026-07-15T22:14:03+00:00",
    "duration_seconds": 7971,
    "model_name": "Qwen3-8B",
    "dataset": { "id": "d1e2f3a4-0000-0000-0000-000000000000", "name": "my-dataset" },
    "rollout": { "id": "r1s2t3u4-0000-0000-0000-000000000000", "name": "my-rollout" },
    "platform_url": "https://platform.osmosis.ai/my-workspace/training/a1b2c3d4-0000-0000-0000-000000000000",
    "latest_metrics": {
      "rollout/raw_reward": 0.82,
      "eval/validation/reward": 0.79,
      "train/entropy_loss": 1.24,
      "rollout/response_lengths": 512,
      "rollout/total_lengths": 1930,
      "rollout/truncated_ratio": 0.03
    }
  }
}
```

For evaluation runs, `latest_metrics` contains the final aggregate results instead:

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/cli.json"]}}
"latest_metrics": {
  "total_runs": 200,
  "graded": 198,
  "passed": 154,
  "failed": 44,
  "skipped": 2,
  "pass_rate": 0.78,
  "pass_threshold": 0.5,
  "score": 0.71,
  "reward_stats": {
    "mean": 0.71,
    "median": 0.74,
    "std": 0.18,
    "min": 0.05,
    "max": 0.98,
    "pass_at_k": { "1": 0.78, "4": 0.91 }
  },
  "total_tokens": 1834520,
  "total_duration_ms": 5421000
}
```

### `webhook.test`

| Field       | Description            |
| ----------- | ---------------------- |
| `workspace` | The workspace name     |
| `message`   | A confirmation message |

## Delivery

* Each attempt times out after 5 seconds. Failed deliveries are retried up to 2 times with backoff.
* Any 2xx response counts as delivered. Redirects are not followed.
* Delivery is best effort: a webhook failure never affects the run itself.
