---
title: "RegisterWebhook"
method: POST
path: "/api/v2/shipping/webhooks"
tags: ["ShippingV2Service"]
---

# RegisterWebhook

`POST /api/v2/shipping/webhooks`

## Request

- Base URL: `https://api.worldmonitor.app`
- URL: `https://api.worldmonitor.app/api/v2/shipping/webhooks`
- Auth: one of:
  - API key in header `X-WorldMonitor-Key`
  - API key in header `X-Api-Key`
  - HTTP bearer

RegisterWebhook subscribes a callback URL to one event type. Returns the subscriberId and the raw HMAC secret — the secret is never returned again except via rotate-secret. PRO-gated. Requires an active Pro subscription.

## Headers

- `Idempotency-Key` string

## Request body

- WorldmonitorShippingV2RegisterWebhookRequest: RegisterWebhookRequest subscribes to one eventType (default chokepoint.disruption). Wire shape is byte-compatible with the legacy POST body.
  - `callbackUrl` string, required: HTTPS callback URL. Must not resolve to a private/loopback address at registration time (SSRF guard). The delivery worker re-validates the resolved IP before each send to mitigate DNS rebinding.
  - `chokepointIds` string[]
  - `alertThreshold` integer: Disruption-score threshold for delivery, 0-100. Default 50; an explicit 0 delivers every alert.
  - `eventType` string: A shared/event-triggers.json key; `chokepoint.disruption` when omitted.
  - `countries` string[]
  - `minLiveSignal` integer: `chokepoint.disruption` live-signal floor; 0 = score only.
  - `scope` WorldmonitorShippingV2WebhookScope: Per-event filters for occurrence events. Each key applies to the events named in its comment; the handler validates against shared/event-triggers.json and stores the defaults.
    - `keywords` string[]
    - `categories` string[]
    - `importanceFloor` integer: news.breaking: importanceScore floor, 0-100 (default 69).
    - `severityFloor` string: news.breaking: `critical` or `high` (default high).
    - `countries` string[]
    - `hazardTypes` string[]
    - `minMagnitude` number, double: natural.hazard: earthquake magnitude floor, 4.5-9.5 (default 5.5).
    - `minAlertLevel` string: natural.hazard: GDACS `Orange` or `Red` (default Orange).
    - `assetClasses` string[]
    - `symbols` string[]
    - `minAbsPct` number, double: market.move: |changePct| floor, 5-100 (default 10).
    - `direction` string: market.move: `up`, `down` or `any` (default any).

## Response `200`

OK

- WorldmonitorShippingV2RegisterWebhookResponse: RegisterWebhookResponse wire shape preserved exactly — partners persist the `secret` because the server never returns it again except via rotate-secret.
  - `subscriberId` string: `wh_` prefix + 24 lowercase hex chars (12 random bytes).
  - `secret` string: Raw 64-char lowercase hex secret (32 random bytes). No `whsec_` prefix.

## Other responses

- `400`: Validation error, invalid Idempotency-Key header, or malformed JSON request body
- `401`: Missing or invalid API key.
- `403`: Pro subscription required.
- `409`: A request with this Idempotency-Key is still being processed
- `422`: The Idempotency-Key was already used with a different request body
- `429`: Rate limit exceeded.
- `503`: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape.
- `default`: Gateway or handler error response.

---

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