> Part of [WHCC Developer Documentation](https://www.whcc.com/developer/llms.txt)

**Legacy** This page is reference for integrations already built on the Order Submit API. It remains supported. New integrations use the [WHCC API](https://www.whcc.com/developer/docs/quick-start/index.html.md).

# Webhook Registration

Version 1.0 &middot; Updated 2026-10-07

## Requirements

You need to register and verify the endpoint you'd like to receive webhooks. The Order Submit API will POST to this endpoint as events occur, retrying if your endpoint does not return a valid response in time.

This registration is for integrations that already have Order Submit API credentials, and it keeps working for them. New integrations are set up on the WHCC API in place of new Order Submit API credentials, so start new work on the [WHCC API](https://www.whcc.com/developer/docs/api/index.html.md). For help with an existing integration, contact WHCC support.

> Before you register an endpoint, read [Delivery, Retries & Idempotency](https://www.whcc.com/developer/docs/legacy/order-submit-api/webhook-delivery/index.html.md). It covers the response timeout, the full retry schedule (currently up to ~39 days), and why your endpoint needs to handle repeat notifications.

## Before you register

Registration is not a reservation. The moment you call `/api/callback/create`, we POST to your endpoint and expect it to answer. Deploy the endpoint first, then register it.

Your endpoint must already:

- be deployed and serving traffic on a public HTTPS URL,
- answer `POST` with a `2xx` status, and
- accept the verification POST, which arrives as `application/x-www-form-urlencoded` with a single `verifier` field.

> **Registering again resets you to unverified.** Calling `/api/callback/create` clears the verified status on your existing callback before it POSTs to the new URI. If that POST fails, webhooks stop until you register and verify successfully. Do not re-register a working endpoint to "refresh" it.

## POST `/api/callback/create`

Content-type: application/json

> Each set of API credentials can only have a single webhook address enabled at one time.

### Example Request

```shell
curl https://apps.whcc.com/api/callback/create  \
	-H "Authorization: Bearer 726670514499" \
	-F callbackUri=https://path.to.your/webhook/endpoint \
	-X POST
```

We will immediately POST to `callbackUri` with a parameter `verifier` with a unique verification code. Use the endpoint below to submit this verification code to prove you control the endpoint and enable webhooks to be sent to that address.

## POST `/api/callback/verify`

Content-type: application/json

### Example Request

```shell
curl https://apps.whcc.com/api/callback/verify  \
	-H "Authorization: Bearer 726670514499" \
	-F verifier=a53ae191-00f3-44f4-810c-19d88a5b4c16 \
	-X POST
```

Your webhook endpoint is now setup and ready to go.

## Troubleshooting `400.05`

`400.05` &mdash; *Unable to post a unique verification code to provided URI* &mdash; means our verification POST did not get a successful response from your endpoint. It is a single error covering several unrelated causes.

Start by checking your own access log for our POST. That one observation splits the causes in half.

### If your log shows the POST arriving

1. **Your endpoint returned a 4xx or 5xx status.** Only a 2xx completes the registration. A 3xx is a separate case &mdash; see the redirect warning below.
2. **Your endpoint rejected the request body.** The verification POST is `application/x-www-form-urlencoded` with a single `verifier` field. It is not JSON. An endpoint written to parse only JSON may answer 400 or 415 here and then handle every real webhook correctly.
3. **Your endpoint answered, but took too long.** We give up after 100 seconds. Answer the verification POST straight away and do any real work afterwards &mdash; the same rule that applies to webhook deliveries.

### If your log shows nothing

1. **Your server must accept TLS 1.2.** We negotiate TLS 1.2 specifically. An endpoint configured to require TLS 1.3 and refuse 1.2 fails the handshake, and nothing reaches your application.
2. **Your certificate must be valid and trusted.** We validate it. An expired, self-signed or hostname-mismatched certificate fails the handshake &mdash; including the case where you clicked through the warning in a browser and assumed it was fine.
3. **The endpoint must be reachable from the public internet.** Check it from a network that is not your own &mdash; not from the machine running it, and not from your office. A firewall rule, an IP allowlist or geo-blocking produces this symptom.
4. **The endpoint must already be deployed.** We POST during the `create` call itself, not later.

> **Do not register a URI that redirects.** A redirect is followed, but replayed as a `GET` with no body. If that `GET` answers 2xx, registration *succeeds* while your handler never sees the verifier, so this appears as a confusing success rather than a 400.05. Register the final destination directly &mdash; including where you would rely on `http://` being upgraded to `https://`. See [Delivery, Retries & Idempotency](https://www.whcc.com/developer/docs/legacy/order-submit-api/webhook-delivery/index.html.md).

Retrying is safe. Because each `create` mints a fresh verifier and leaves your callback unverified, always finish by calling `/api/callback/verify` with the verifier from the **most recent** POST you received. An earlier verifier is no longer valid.

> ## What's Next
>
> [Event Types](https://www.whcc.com/developer/docs/legacy/order-submit-api/webhook-types/index.html.md) describes the different types of messages to expect.