Webhook Integrations

Send real-time event data to external systems when actions happen in CE Pro.

IntermediateUpdated 2026-03-08

Webhook Integrations

Webhooks let you push real-time event data from CE Pro to external systems whenever something meaningful happens -- a proposal is accepted, a job is completed, or a new estimate is created. Use webhooks to connect CE Pro to your CRM, project management tool, accounting software, or any system that can receive HTTP requests. Go to Settings --> Integrations --> Webhooks to get started.

Screenshot placeholder
Webhooks page showing the list of configured webhook endpoints with status indicators and Add Webhook button

How Webhooks Work

A webhook is an HTTP POST request that CE Pro sends to a URL you provide whenever a specific event occurs. Instead of polling CE Pro for changes, your system receives a push notification with the relevant data the moment something happens.

For example, when a customer accepts a proposal, CE Pro sends a POST request containing the proposal details to your configured endpoint. Your server processes the data and takes action -- creating a project in your PM tool, adding a row to a spreadsheet, or triggering a downstream workflow.

Webhooks are a developer-oriented feature. You need a server or service capable of receiving HTTP POST requests. No-code platforms like Zapier, Make, and n8n can receive webhooks without custom code.


Available Events

CE Pro supports webhooks for the following event types:

EventDescription
estimate_createdA new estimate is created in the system.
estimate_sentAn estimate is sent to the customer via email or SMS.
proposal_createdA new proposal is generated.
proposal_sentA proposal is delivered to the customer.
proposal_acceptedA customer accepts a proposal.
proposal_declinedA customer declines a proposal.
job_createdA new job is added to the schedule.
job_completedA scheduled job is marked as complete.
invoice_paidA customer pays an invoice.
client_createdA new client record is added.

Each event includes a JSON payload with the relevant data. You can subscribe a single endpoint to multiple events, or create separate endpoints for different events.


Setting Up a Webhook

  1. Go to Settings --> Integrations --> Webhooks.
  2. Click the Add Webhook button.
  3. Fill in the configuration fields:
  • URL -- The full HTTPS endpoint that will receive the webhook POST requests. HTTP URLs are not accepted.
  • Events -- Check one or more event types you want to listen for.
  • Active -- Toggle on to enable the webhook immediately.
  1. Click Save.
Screenshot placeholder
Add Webhook form with fields for URL, event type checkboxes, active toggle, and Save button

CE Pro sends a test ping to your URL when you save. Your endpoint must respond with a 200 status code for the webhook to be saved successfully. If the ping fails, check your URL and try again.


Payload Format

Every webhook request includes a JSON body with a consistent structure:

{
  "event": "proposal_accepted",
  "timestamp": "2026-03-08T14:30:00Z",
  "webhook_id": "wh_abc123",
  "data": {
    "id": "prop_xyz789",
    "client_name": "Jane Smith",
    "client_email": "jane@example.com",
    "total": 2500.00,
    "status": "accepted",
    "accepted_at": "2026-03-08T14:29:45Z"
  }
}

Top-Level Fields

  • event -- The event type string (matches the values in the table above).
  • timestamp -- ISO 8601 timestamp of when the event occurred.
  • webhook_id -- A unique identifier for this webhook delivery, useful for deduplication.
  • data -- An object containing the event-specific details. The fields inside data vary by event type.

Request Headers

Each webhook request includes the following headers:

  • Content-Type: application/json
  • X-CEPro-Signature -- The HMAC-SHA256 signature for verification (see below).
  • X-CEPro-Event -- The event type.
  • X-CEPro-Delivery -- A unique delivery ID.

Testing Webhooks

Before configuring a webhook in CE Pro, verify that your endpoint works correctly.

Using a Request Inspector

  1. Go to a service like Webhook.site or RequestBin.
  2. Copy the generated URL.
  3. Paste it into the CE Pro webhook URL field.
  4. Save the webhook. CE Pro sends a test ping.
  5. Check the request inspector to see the payload.

Testing in Development

If you are building a custom integration:

  1. Use a tunneling tool like ngrok to expose your local server to the internet.
  2. Start your local server.
  3. Copy the ngrok HTTPS URL and add your webhook path (for example, https://abc123.ngrok.io/webhooks/cepro).
  4. Configure the webhook in CE Pro with this URL.
  5. Trigger an event (create a test estimate, for example) and check your server logs.

Test Ping Payload

The test ping sent on save uses this format:

{
  "event": "ping",
  "timestamp": "2026-03-08T14:30:00Z",
  "webhook_id": "wh_test_001",
  "data": {
    "message": "Webhook configured successfully"
  }
}

Security and Signature Verification

CE Pro signs every webhook request using HMAC-SHA256. This lets you verify that the request genuinely came from CE Pro and was not tampered with in transit.

How Signing Works

  1. When you create a webhook, CE Pro generates a signing secret. Copy it immediately and store it securely. It is shown only once.
  2. For each webhook delivery, CE Pro computes an HMAC-SHA256 hash of the raw request body using your signing secret.
  3. The hash is sent in the X-CEPro-Signature header.

Verifying the Signature on Your Server

Compute the HMAC-SHA256 hash of the raw request body using your stored signing secret. Compare the result to the value in the X-CEPro-Signature header. If they match, the request is authentic.

Node.js example:

const crypto = require('crypto');

function verifyWebhookSignature(rawBody, signatureHeader, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature),
    Buffer.from(signatureHeader)
  );
}

Python example:

import hmac
import hashlib

def verify_webhook_signature(raw_body, signature_header, secret):
    expected = hmac.new(
        secret.encode(),
        raw_body.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Warning: Always verify webhook signatures in production. Without verification, anyone who discovers your endpoint URL can send fake events to your system.

Best Practices for Signing Secrets

  • Store the signing secret in an environment variable, not in your source code.
  • Rotate your signing secret periodically by deleting and re-creating the webhook.
  • Use constant-time comparison functions (like timingSafeEqual in Node.js or compare_digest in Python) to prevent timing attacks.

Retry Logic

If your endpoint returns an error (any HTTP status code other than 2xx) or does not respond within 10 seconds, CE Pro retries the delivery automatically. Retries follow an exponential backoff schedule:

AttemptDelay After Previous Failure
First retry1 minute
Second retry5 minutes
Third retry30 minutes
Final retry2 hours

After four failed attempts, the delivery is marked as permanently failed. Failed deliveries remain visible in the delivery log, and you can manually retry them at any time.

Tip: If your endpoint is consistently failing, CE Pro may automatically disable the webhook after a sustained period of failures. Check the delivery log and fix the issue, then re-enable the webhook.


Delivery Logging

CE Pro logs every webhook delivery attempt. View the log by clicking on a webhook endpoint in the list. The log shows:

  • Event Type -- The event that triggered the delivery.
  • Timestamp -- When the delivery was attempted.
  • Status Code -- The HTTP response code your endpoint returned.
  • Response Time -- How long your endpoint took to respond (in milliseconds).
  • Outcome -- Success, Failed, or Retrying.
  • Attempt -- Which attempt number (1 through 5).
Screenshot placeholder
Webhook delivery log showing recent deliveries with status codes, response times, and outcomes

Click on any delivery entry to see the full request payload and response body. Use this to debug issues with your integration.

Manual Retry

For any failed delivery, click the Retry button to resend the webhook immediately. This is useful when your endpoint was temporarily down and you need to replay missed events.

Screenshot placeholder
Failed delivery entry in the log with a Retry button

Managing Webhooks

Edit a Webhook

  1. Go to Settings --> Integrations --> Webhooks.
  2. Click on the webhook you want to modify.
  3. Update the URL, subscribed events, or active status.
  4. Click Save.

Disable a Webhook

Toggle the Active switch off to stop deliveries without deleting the webhook. This preserves your configuration and delivery history.

Delete a Webhook

  1. Click on the webhook.
  2. Click Delete.
  3. Confirm the deletion.

Deleting a webhook removes the endpoint and all delivery history permanently.


Tips

  • Test your webhook endpoint with a request inspector before configuring it in CE Pro.
  • Keep your endpoint response time under 5 seconds. CE Pro waits for a response before continuing.
  • Use the delivery log to debug integration issues. A string of 500 errors means your endpoint is crashing.
  • Store your signing secret in an environment variable, never in source code.
  • If you use Zapier or Make, use their "Webhooks" trigger to receive CE Pro events without writing any code.
  • Subscribe only to the events you need. Unnecessary events create noise and consume processing resources on your server.
  • Implement idempotency on your server using the webhook_id field. Network issues can occasionally cause duplicate deliveries.

Was this article helpful?

Still need help? Contact support