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

# Troubleshooting: webhook endpoint creation errors

> Resolve the three creation-time rejections — endpoint cap reached, DNS-invalid hostname, and blocked URL — that POST /webhooks answers with 422 before it persists anything.

# Troubleshooting: webhook endpoint creation errors

`POST /api/v1/webhooks` validates your request before it persists anything.
When it rejects, it answers **422** with one of three error codes, and no
endpoint is created. Match the code below, apply its fix, then verify with
the `GET /api/v1/webhooks` count check at the bottom of this page.

If creation succeeds and deliveries fail instead, switch to
[Troubleshooting: failed webhook deliveries](/troubleshooting/webhook-deliveries).

## Symptom map

| Error code                     | HTTP | Actionable cause                                                                                                                        |
| ------------------------------ | ---- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `WEBHOOK_ENDPOINT_CAP_REACHED` | 422  | The tenant already holds the maximum of 10 webhook endpoints                                                                            |
| `WEBHOOK_DNS_INVALID`          | 422  | The URL's hostname did not resolve — most often a typo (`.com` vs `.io`) or an unprovisioned host                                       |
| `INVALID_WEBHOOK_URL`          | 422  | The URL failed safety validation — non-HTTPS scheme, or a hostname/IP on the blocked list (loopback, private ranges, internal suffixes) |

```json theme={null}
{
  "error": {
    "code": "WEBHOOK_ENDPOINT_CAP_REACHED",
    "status": 422,
    "details": { "limit": 10, "current": 10 }
  }
}
```

## `WEBHOOK_ENDPOINT_CAP_REACHED` — you are at 10 endpoints

Each tenant can register up to **10** webhook endpoints. The cap exists so a
runaway integration cannot fan out thousands of delivery jobs per event.

Fix one of two ways:

1. **Delete a stale endpoint.** List your endpoints, find one that no longer
   receives traffic, and remove it:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/webhooks" \
  -H "X-API-Key: dv_live_sk_..."
```

```bash theme={null}
curl -X DELETE "https://api.orbit.devotel.io/api/v1/webhooks/{id}" \
  -H "X-API-Key: dv_live_sk_..."
```

2. **Ask support to raise the cap.** If ten endpoints are genuinely in use
   (one per integration), write in with your **tenant id** (Settings →
   Organization) and the integrations each endpoint serves. A raise is an
   out-of-band operation, not self-serve.

## `WEBHOOK_DNS_INVALID` — the hostname does not resolve

Orbit resolves the URL's hostname before persisting it. An NXDOMAIN answer
means no inbound request would ever reach your endpoint, so creation stops. The
usual causes, in order of frequency:

* **A typo in the domain** — swapping a TLD (`.com` for `.io`) or a dropped
  character. Re-check the hostname character by character.
* **A host that is not yet provisioned** — the record was not created in DNS,
  or it lives behind an internal resolver that public DNS cannot answer.
* **DNS still propagating** — if you just cut the record, wait for your
  provider's TTL, then retry the create call.

From a shell, confirm what public resolvers see:

```bash theme={null}
dig +short your-endpoint.example.com
```

An empty answer is NXDOMAIN — fix the record (or the typo) and re-submit
`POST /api/v1/webhooks`.

## `INVALID_WEBHOOK_URL` — the URL fails safety validation

When DNS resolves but validation still rejects, the URL itself is the
problem. Webhook endpoint URLs must be **publicly routable HTTPS**. Check
your URL against this list:

* **Use `https://`.** Plain `http://` is rejected. If you front the endpoint
  with a CDN, point the URL at the CDN's HTTPS hostname.
* **No loopback or literal IPs from private ranges.** `localhost`,
  `127.0.0.1`, `10.x`, `172.16–31.x`, `192.168.x`, and the cloud-metadata
  address are rejected by design — Orbit must never deliver your events into
  its own network or your workstation.
* **No internal suffixes.** Hostnames ending in `.internal`, `.local`,
  or `.svc` are rejected even when they resolve publicly.
* **Every resolved IP must be public.** A hostname whose A/AAAA records
  include even one private address fails validation, so multi-homed DNS
  needs all-public answers.

Move the receiver behind a public hostname — or put a CDN / load balancer in
front — and re-submit with the routable HTTPS URL.

## Verify: the endpoint-count check

Confirm the create succeeded with the endpoint list. The response carries a
`total` count that reflects every endpoint under the cap:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/webhooks" \
  -H "X-API-Key: dv_live_sk_..."
```

```json theme={null}
{
  "rows": [
    { "id": "webhook_...", "url": "https://your-endpoint.example.com/hook", "active": true }
  ],
  "total": 3
}
```

`total < 10` means you have headroom; the new endpoint appearing in `rows`
closes the loop.

## Once creation succeeds

Delivery-level failures — retries, the dead-letter queue, replay — are a
different page: [Troubleshooting: failed webhook deliveries](/troubleshooting/webhook-deliveries).
Signature rejections are covered in
[Troubleshooting: signature failures](/webhooks/troubleshooting-signature-failures),
and the full delivery contract (signatures, retry semantics, security
cadence) is on [Webhook security](/webhooks/security).

## See also

* [Error codes reference](/reference/error-codes) — the raw code table this
  page expands on.
* [Manage webhook endpoints](/api-reference/endpoints/webhooks) — request
  shapes for create, list, and delete.
