Webhooks

Webhooks are a way to receive real-time updates from SaaS Custom Domains. When an event happens in SaaS Custom Domains, we'll send a POST request to the URL you specify with additional data about the event. You can use webhooks to trigger anything from a simple email notification to a complex workflow.

Getting Started

To start using webhooks, navigate to the webhooks section in the application. Here, you can create a new webhook. You'll have to specify the endpoint URL to receive webhook notifications and select the events you wish to be notified about.

Security

We recommend that you secure your webhook endpoint to prevent unauthorized access. Every webhook sent by SaaS Custom Domains includes a security token in the token query parameter. This token will look something like 19ca846829efbcafd41af16e04f123.

It is important to verify this token before processing the webhook. You can find the token in the webhook view in the SaaS Custom Domains application. Each webhook has its own unique token.

Available Events

Our webhook service provides real-time notifications for a range of domain and upstream events. Below you'll find the events you can subscribe to, along with a brief description of each.

All datetimes are in UTC and ISO 8601 format, e.g. 2024-02-27T15:23:54Z.

Domain Events

Domain Created - A new domain has been created.

{
   "event": "domain_created",
   "domain": {
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "domain_12345",
      "host": "subdomain.apple.com",
      "challenge_type": "http01",
      "instructions_recipient": "steve@apple.com",
      "last_dns_check_at": "2024-02-27T15:31:27Z"
   }
}

Domain Deleted - A domain has been deleted.

{
   "event": "domain_deleted",
   "domain": {
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "domain_12345",
      "host": "subdomain.apple.com",
      "challenge_type": "http01",
      "instructions_recipient": "steve@apple.com",
      "last_dns_check_at": "2024-02-27T15:31:27Z UTC"
   }
}

Domain DNS Proxy Record Valid - This event is fired when a CNAME record successfully points your custom domain to in.saascustomdomains.com, or A records are correctly set to our static IP addresses. Relevant only for non-wildcard custom domains.

{
   "event": "domain_dns_proxy_record_valid",
   "domain": {
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "domain_12345",
      "host": "subdomain.apple.com",
      "challenge_type": "http01",
      "instructions_recipient": "steve@apple.com",
      "last_dns_check_at": "2024-02-27T15:31:27Z UTC"
   }
}

Domain DNS Proxy Record Invalid - Alerts you when we can't find CNAME that points your custom domain to in.saascustomdomains.com, or A records pointing to our static IP addresses. Relevant only for non-wildcard custom domains.

{
   "event": "domain_dns_proxy_record_invalid",
   "domain": {
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "domain_12345",
      "host": "subdomain.apple.com",
      "challenge_type": "http01",
      "instructions_recipient": "steve@apple.com",
      "last_dns_check_at": "2024-02-27T15:31:27Z UTC"
   }
}

Domain DNS Challenge Record Valid - Notifies you when the DNS challenge records for your domain are correctly configured. Relevant only for custom domains using the DNS-01 challenge for verification.

{
   "event": "domain_dns_challenge_record_valid",
   "domain": {
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "domain_12345",
      "host": "subdomain.apple.com",
      "challenge_type": "http01",
      "instructions_recipient": "steve@apple.com",
      "last_dns_check_at": "2024-02-27T15:31:27Z UTC"
   }
}

Domain DNS Challenge Record Invalid - Triggered when we can't find domain's DNS challenge records. Relevant only for custom domains using the DNS-01 challenge for verification.

{
   "event": "domain_dns_challenge_record_invalid",
   "domain": {
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "domain_12345",
      "host": "subdomain.apple.com",
      "challenge_type": "http01",
      "instructions_recipient": "steve@apple.com",
      "last_dns_check_at": "2024-02-27T15:31:27Z UTC"
   }
}

TLS/SSL Certificate Issued - Indicates that a TLS/SSL certificate has been successfully issued for your domain.

{
   "event": "tls_certificate_issued",
   "domain": {
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "domain_12345",
      "host": "subdomain.apple.com",
      "challenge_type": "http01",
      "instructions_recipient": "steve@apple.com",
      "last_dns_check_at": "2024-02-27T15:31:27Z UTC"
   }
}

TLS/SSL Certificate Revoked - Occurs when a TLS/SSL certificate for your domain is revoked.

{
   "event": "tls_certificate_revoked",
   "domain": {
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "domain_12345",
      "host": "subdomain.apple.com",
      "challenge_type": "http01",
      "instructions_recipient": "steve@apple.com",
      "last_dns_check_at": "2024-02-27T15:31:27Z UTC"
   }
}

Upstream Events

Upstream Created - Triggered when a new upstream is created.

{
   "event": "upstream_created",
   "upstream":{
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "upstream_12345",
      "host": "app.domain.com",
      "port": "443",
      "tls": true,
      "bubble_io": false
  }
}

Upstream Deleted - Triggered when an upstream is deleted.

{
   "event": "upstream_deleted",
   "upstream":{
      "created_at": "2024-02-27T15:23:54Z",
      "uuid": "upstream_12345",
      "host": "app.domain.com",
      "port": "443",
      "tls": true,
      "bubble_io": false
  }
}

Timeouts and Retries

We have a 5-second timeout for webhooks. Successful responses are those with a status code in the 2xx range. If we don't receive a successful response within 5 seconds we will consider the webhook delivery failed and queue the retry.

We will retry sending the webhook up to 10 times. We use exponential backoff to determine the time between retries. The retries will be spaced out as follows:

RetryNext Retry BackoffTotal Waiting Time
10d 0h 0m 20s0d 0h 0m 20s
20d 0h 0m 26s0d 0h 0m 46s
30d 0h 0m 46s0d 0h 1m 32s
40d 0h 1m 56s0d 0h 3m 28s
50d 0h 4m 56s0d 0h 8m 24s
60d 0h 11m 10s0d 0h 19m 34s
70d 0h 22m 26s0d 0h 42m 0s
80d 0h 40m 56s0d 1h 22m 56s
90d 1h 9m 16s0d 2h 32m 12s
100d 1h 50m 26s0d 4h 22m 38s

If we still don't receive a successful response, we will stop retrying and log the failure.