API reference › Webhooks › Create endpoint
Create a webhook endpoint
POST
/v1/webhooksRegisters a URL to receive events. For the event payloads and how to verify a signature, see Webhooks.
No CLI command yet — webhooks are managed over the API only.
| Field | Type | Description |
|---|---|---|
| url* | string | https only, and not a loopback or private address — the signature protects the body, not the connection, so plain http would sign a request that travels unprotected anyway. |
| events | array | Which events to send. Omitted or empty means all of them: domain.degraded, domain.failed, domain.recovered, domain.verified. |
curl -s -X POST https://api.propgate.dev/v1/webhooks \
-H "authorization: Bearer pg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H 'content-type: application/json' \
-d '{"url":"https://example.com/hooks/propgate","events":["domain.failed","domain.recovered"]}'{
"data": {
"createdAt": "2026-08-03T12:00:00.000Z",
"disabled": false,
"events": [
"domain.failed",
"domain.recovered"
],
"id": "019fcf9a-3c4d-7e5f-a06b-7c8d9e0f1a2b",
"object": "webhook",
"secret": "whsec_...",
"url": "https://example.com/hooks/propgate"
},
"error": null,
"meta": {
"created": true
}
}Creating is idempotent on (account, url) — posting the same URL again
returns the existing endpoint rather than a second one, and meta.created
tells the two apart. secret is only ever present in this response: on a
retry that matched an existing endpoint, the stored secret is not this call's
to hand back, since it exists to sign with, not to be read. To replace a
secret you have lost, rotate it.
A URL that fails the https-and-not-private check is a 422:
{
"data": null,
"error": {
"message": "10.0.0.5 is a private or loopback address, which this service will not send to"
},
"meta": null
}