Skip to main content

Service Webhooks

Service Webhooks are server-to-server integration callbacks. When a certificate issuance finishes with SUCCESS, bbserver will POST a signed JSON payload to your endpoint.

This is meant for automation (e.g., trigger a deploy job). The webhook payload is a notification; your service can fetch the certificate via the existing export APIs.

When it fires

  • Event key: certificate.issued
  • Trigger condition: every issuance success (including renewals)
  • It does not fire for PENDING/PROCESSING/FAILED/CANCELLED.

Managing webhooks

You can manage service webhooks in the web console at /service-webhooks, or via the HTTP API:

  • GET /apiv1/users/:user_id/service_webhooks?offset=0&limit=50
  • GET /apiv1/users/:user_id/service_webhooks/:webhook_id
  • POST /apiv1/users/:user_id/service_webhooks
  • PUT /apiv1/users/:user_id/service_webhooks/:webhook_id
  • DELETE /apiv1/users/:user_id/service_webhooks/:webhook_id

Notes:

  • secret is required on create/update and is never returned by the server.
  • event_key is currently expected to be certificate.issued.

Scope filtering

Each webhook has a scope JSON object. Supported forms:

  • All certificates (default):
    • { "type": "all" }
  • A single certificate:
    • { "type": "cert_id", "cert_id": 123 }
  • A single domain:
    • { "type": "domain", "domain": "example.com" }

If the scope JSON is invalid, the server treats it as {type: all}.

Request format

bbserver sends an HTTP POST with a JSON body.

Headers

  • User-Agent: bbserver-service-webhook/1
  • X-BB-Event: certificate.issued
  • X-BB-Webhook-Id: <webhook_id>
  • X-BB-Delivery-Id: <outbox_row_id>
  • X-BB-Cert-Id: <cert_id>
  • X-BB-Issue-History-Id: <issue_history_id>
  • X-BB-Timestamp: <unix_ms>
  • X-BB-Signature: sha256=<hex>

Body

Example:

{
"event": "certificate.issued",
"cert_id": 123,
"issue_history_id": 456,
"user_id": 789,
"ts_ms": 1700000000000,
"domain_name": "example.com"
}

Notes:

  • domain_name may be omitted.
  • ts_ms in the body is the enqueue time; the signature uses X-BB-Timestamp.

Signature verification

To verify authenticity:

  1. Read the raw request body bytes exactly as received.
  2. Build the signing string:
<timestamp_ms>.<raw_body>

Where <timestamp_ms> is the value of X-BB-Timestamp.

  1. Compute HMAC-SHA256 using your webhook secret as the key.
  2. Hex-encode the digest, and compare with X-BB-Signature (after the sha256= prefix).

Important:

  • Do not JSON-parse and re-serialize before verifying; that changes bytes and breaks the signature.
  • Enforce a freshness window (e.g., reject if X-BB-Timestamp differs from now by more than 5 minutes).

Delivery semantics & retries

  • Success is any HTTP status 2xx.
  • Retryable statuses: 408, 429, and 5xx.
  • Non-retryable statuses (e.g., 400, 401, 403) are treated as permanent failures.
  • Retries use exponential backoff starting at ~5 seconds (capped), with a max attempt budget.

Recommended receiver behavior:

  • Return 204 quickly once the payload is accepted.
  • Process asynchronously (queue a job) rather than blocking the request.

Downloading the certificate

The webhook does not contain private key material. After receiving cert_id, fetch the certificate via the certificate APIs (e.g., export/download endpoints) using your existing automation credentials.