---
title: "Register Imagery Webhook"
method: POST
path: "/wine_labels/webhooks"
tags: ["Imagery"]
---

# Register Imagery Webhook

`POST /wine_labels/webhooks`

## Request

- Base URL: `https://external-api.wine-labs.com`
- URL: `https://external-api.wine-labs.com/wine_labels/webhooks`
- Auth: none declared

Register an HTTPS endpoint that receives a signed POST whenever one of your imagery requests reaches a terminal status. The signing secret is returned once, in this response only.

## Request body

- object
  - `user_id` string, uuid: Account identifier. Optional when the request uses an authorized `Authorization` header.
  - `url` string, required: Public HTTPS URL. Private, loopback, and link-local destinations are rejected. Redirects are not followed.
  - `description` string: Free-text label for your own reference (max 200 characters).
  - `events` string[]: Subset of `wine_label.fulfilled`, `wine_label.unavailable`, `wine_label.failed`. Defaults to all three.

## Response `200`

Response highlights:
- `endpoint`: the registered endpoint (`id`, `url`, `events`, `active`, `secret_hint`, delivery health timestamps).
- `secret`: the `whsec_…` signing secret. Store it now; it is never returned again.
- `signing`: how the signature header is computed.
- Delivery body: `{ "id", "event", "created_at", "attempt", "data": { "request": { … } } }` where `data.request` is exactly the `request` object from `GET /wine_labels/{request_id}`, with an absolute `status_url`.
- Delivery headers: `X-WineLabs-Event`, `X-WineLabs-Delivery-Id`, `X-WineLabs-Timestamp`, `X-WineLabs-Signature`.

Notes:
- Verify the signature: split `X-WineLabs-Signature` into `t` and `v1`, compute HMAC-SHA256 over `"<t>.<raw body>"` with the secret, compare in constant time to `v1`, and reject timestamps older than 5 minutes.
- Respond with any 2xx within 10 seconds; queue heavy work. Non-2xx, redirects, and timeouts are retried with backoff (1m, 5m, 15m, 1h, 3h, 6h, 12h, 24h) and abandoned after 8 attempts.
- A request that is re-queued and re-delivered later (for example after an asset is withdrawn and replaced) sends a new `wine_label.fulfilled` event with the new `asset_url`. Use `data.request.id` and `data.request.client_request_id` to correlate.
- An endpoint that fails 30 deliveries in a row is switched off (`active: false`); fix it and register the URL again.
- Returns 409 when the URL is already registered or the account already has 5 active endpoints.

- object

---

[API](https://skmtc.dev/winelabs/apis/wine-labs-api.md) · [All operations](https://skmtc.dev/winelabs/apis/wine-labs-api/llms.txt) · [OpenAPI document](https://skmtc.dev/winelabs/apis/wine-labs-api/revisions/f8898ca9974e?raw)
