Coachful
CoachfulHelp

Sending Coachful events to Webhooks

By Coachful10 min readUpdated Apr 20, 2026

Learn how to send Coachful events to webhooks — configure endpoints, verify signatures, handle retries, and automate your coaching workflows with real-time data.

What's covered
  • What are Coachful webhooks and why do they matter?
  • TL;DR
  • Supported webhook events
  • How to add a webhook endpoint in Coachful
  • Understanding the webhook payload structure
  • Verifying webhook signatures

What are Coachful webhooks and why do they matter?

If you've ever wanted your coaching platform to automatically talk to your CRM, fire a Slack notification when a client books a session, or trigger a Zapier workflow the moment someone enrolls in your program — webhooks are how you make that happen. Sending Coachful events to webhooks lets you push real-time data from your Coachful workspace to any external system that can receive an HTTP POST request.

Unlike polling (where an external app repeatedly asks "anything new?"), webhooks are event-driven. Coachful sends a payload the moment an event occurs — a new booking, a completed task, a payment — so your automations stay in sync without delay and without wasted API calls.

TL;DR

  • Webhooks are configured in Coach Dashboard → Settings → Integrations → Webhooks.
  • You provide a public HTTPS endpoint URL; Coachful sends a signed JSON POST to that URL when subscribed events fire.
  • Each payload includes an event type, a timestamp, and a data object with the relevant resource.
  • Verify the X-Coachful-Signature header on every incoming request to prevent spoofed events.
  • Retry logic is built in — failed deliveries are retried up to 5 times with exponential backoff.

Supported webhook events

Coachful emits webhooks across all major platform areas. Below is the current catalogue of event types you can subscribe to. Each event name follows a resource.action convention so they're easy to filter programmatically.

Booking & scheduling events

  • booking.created — a client books a 1:1, group call, or intake session.
  • booking.cancelled — a booking is cancelled by the coach or client.
  • booking.rescheduled — a booking is moved to a new time slot.
  • booking.completed — a session is marked as completed.

Program & enrollment events

  • enrollment.created — a client enrolls in a program (paid or free).
  • enrollment.completed — a client completes all tasks in a program.
  • task.completed — a client checks off a task inside a program week/day.
  • goal.achieved — a tracked goal is marked as achieved.
  • habit.checked_in — a client logs a habit check-in.

Billing & payment events

  • payment.succeeded — a charge succeeds (one-time or recurring).
  • payment.failed — a charge attempt fails.
  • subscription.created — a client starts a recurring subscription offer.
  • subscription.cancelled — a subscription is cancelled.
  • coupon.redeemed — a client applies a coupon at checkout.

Client & squad events

  • client.created — a new client record is created in your workspace.
  • client.updated — a client's profile information changes.
  • squad.member_joined — a member joins a cohort or community squad.
  • squad.member_left — a member leaves or is removed from a squad.
  • message.sent — a message is sent in a squad channel (use sparingly — high volume).

How to add a webhook endpoint in Coachful

Setting up your first webhook takes about two minutes. Before you start, make sure your receiving server is publicly accessible over HTTPS — Coachful will not deliver events to plain HTTP or localhost URLs in production. For local testing, use a tunnel tool like ngrok or Smee.io to expose a local port.

  1. Open your Coach Dashboard and navigate to Settings → Integrations → Webhooks.
  2. Click Add endpoint.
  3. Paste your endpoint URL (must be https://). Example: https://yourdomain.com/coachful/webhook.
  4. Under Events to send, choose specific events or select All events. For high-traffic workspaces, we recommend subscribing only to the events you need — this reduces noise and processing overhead on your server.
  5. Optionally add a Description to remind yourself what this endpoint does (e.g., "Syncs new enrollments to HubSpot").
  6. Click Save endpoint. Coachful immediately generates a unique signing secret for this endpoint — copy it now and store it securely (you won't be able to see it again).
  7. Click Send test event to fire a sample payload to your endpoint and confirm delivery.

You can register up to 10 webhook endpoints per workspace on the Scale plan, and up to 3 on the Growth plan. Each endpoint can subscribe to a different subset of events, so you can route booking events to one system and payment events to another.

Pro tip: If you're building automations with no-code tools, Coachful webhooks pair perfectly with Zapier, Make (formerly Integromat), or n8n. Create a "Webhooks by Zapier" trigger, paste that URL into Coachful, and you can push enrollment data into Google Sheets, add clients to Mailchimp, or send a Slack DM — all without writing a single line of code.

Understanding the webhook payload structure

Every Coachful webhook POST request shares the same envelope structure. Here's an annotated example for a booking.created event:

{
  "id": "wh_01HZ9XMPQ4EFGR7KYBVD3N",
  "event": "booking.created",
  "timestamp": "2025-01-15T14:32:00Z",
  "workspace_id": "ws_abc123",
  "data": {
    "booking": {
      "id": "bk_99XYZABC",
      "type": "one_on_one",
      "status": "confirmed",
      "start_at": "2025-01-20T10:00:00Z",
      "end_at": "2025-01-20T11:00:00Z",
      "client": {
        "id": "usr_clientid",
        "name": "Jane Smith",
        "email": "jane@example.com"
      },
      "coach": {
        "id": "usr_coachid",
        "name": "Alex Rivera"
      }
    }
  }
}

Key fields to know:

  • id — a unique identifier for this specific delivery attempt. Use this to deduplicate events if your server receives a retry.
  • event — the event type string. Filter on this first in your handler.
  • timestamp — ISO 8601 UTC time the event was generated on Coachful's servers.
  • workspace_id — useful when a single endpoint receives events from multiple Coachful workspaces.
  • data — the resource object relevant to the event. The shape varies by event type; see the full schema reference in Webhook event schemas.

Verifying webhook signatures

Anyone who knows your endpoint URL could theoretically POST fake events to it. To prevent this, Coachful signs every delivery with a X-Coachful-Signature header. Always verify this signature before processing the payload — it's a one-minute implementation that protects your automations from spoofed data.

How the signature works

Coachful computes an HMAC-SHA256 hash of the raw request body using your endpoint's signing secret as the key. The result is hex-encoded and sent in the X-Coachful-Signature header as sha256=<hash>.

Verification example (Node.js)

const crypto = require('crypto');

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

Use the raw request body (before any JSON parsing) and crypto.timingSafeEqual (or its equivalent in your language) to avoid timing attacks. If the signature doesn't match, return a 401 and discard the payload.

Need help setting this up? Ask Michelle, Coachful's built-in AI assistant, to walk you through webhook configuration directly inside your dashboard. Just type "help me set up a webhook" in the Michelle panel and she'll guide you step by step — or even pre-fill the settings form for you.

Retry behavior and delivery guarantees

Coachful delivers webhooks with an at-least-once guarantee. If your endpoint returns anything other than a 2xx HTTP status code within 10 seconds, Coachful treats the delivery as failed and schedules a retry.

The retry schedule uses exponential backoff:

  1. Retry 1 — 30 seconds after the first failure
  2. Retry 2 — 5 minutes later
  3. Retry 3 — 30 minutes later
  4. Retry 4 — 2 hours later
  5. Retry 5 — 8 hours later

After 5 failed retries, the delivery is marked as permanently failed and will not be retried again. You can view failed deliveries and manually re-send them from Settings → Integrations → Webhooks → [Endpoint] → Delivery logs.

Because retries can cause the same event to be delivered more than once, your handler should be idempotent — use the id field to detect and skip duplicate events you've already processed.

Pro tips for production webhook integrations

Respond fast, process async

Your endpoint should return a 200 OK response immediately — ideally in under 500 ms — and then process the payload asynchronously (e.g., push it onto a queue). If your handler does database writes, external API calls, or email sends synchronously, you risk hitting the 10-second timeout and generating unnecessary retries.

Log everything at first

During initial setup, log every incoming payload to a database table or logging service before you do anything else. This gives you a complete audit trail and makes debugging far easier when an automation behaves unexpectedly.

Subscribe narrowly

It's tempting to subscribe to "All events" for convenience, but high-frequency events like message.sent or habit.checked_in can generate thousands of requests per day for an active workspace. Subscribe only to the events your integration actually needs.

Use separate endpoints per integration

Rather than routing all events to one URL and branching by event type in your handler, consider registering separate Coachful endpoints for each downstream system. This makes delivery logs cleaner and lets you disable one integration without affecting others.

Troubleshooting common webhook problems

My endpoint is receiving events but the signature check fails

The most common cause is computing the HMAC over a parsed-then-re-serialized body instead of the raw bytes. Make sure you read the raw request body before any JSON parsing middleware touches it. In Express.js, for example, use express.raw({ type: 'application/json' }) on the webhook route instead of express.json().

Events are showing as "Delivered" in Coachful but my system isn't updating

Check whether your handler is returning a 2xx status before it finishes processing (see "Respond fast, process async" above). If Coachful gets a 200, it marks the delivery as successful regardless of what your code does next. Check your async processing queue for errors.

I'm not receiving any events at all

First, confirm your endpoint URL is publicly reachable — Coachful cannot deliver to private IPs, localhost, or non-HTTPS URLs. Use the Send test event button in the webhook settings; if that fails, you'll see an error response code in the delivery log. Also verify you've subscribed to the correct event types and that the events you're expecting are actually being triggered in your workspace.

I'm getting duplicate events

This is expected behavior with at-least-once delivery. Implement idempotency in your handler: store processed webhook id values in a fast key-value store (Redis works well) and skip any payload whose id you've seen before.

My endpoint went down for a few hours — did I lose events?

Events that failed delivery will have been retried up to 5 times over approximately 10 hours. If your endpoint was down for longer, some events may have been permanently failed. Go to Settings → Integrations → Webhooks → [Endpoint] → Delivery logs, filter by "Failed", and use the Resend button to replay them manually.

Webhook deliveries are timing out intermittently

Coachful enforces a strict 10-second response timeout. Move any slow processing (database writes, third-party API calls) out of the synchronous request handler. If you're on a serverless platform like AWS Lambda or Vercel Functions, watch for cold-start latency — pre-warming strategies or keeping a persistent worker can help.

Ready to automate your coaching workflows?

Webhooks unlock a whole layer of automation that removes repetitive admin work and keeps your tools in sync — so you spend more time coaching and less time copying data between apps. Whether you're syncing enrollments to a CRM, sending welcome emails on payment success, or updating a project board when a client completes a program milestone, Coachful's webhook system gives you the real-time data you need.

Log in to your workspace and configure your first endpoint today, or explore the rest of the Integrations section for more ways to connect Coachful to your tech stack. Not on Coachful yet? Start your free trial and see how much faster your business runs when everything talks to everything. Need more help? Browse all guides in the Coachful Help Center.

Frequently asked questions

What events can Coachful send to a webhook?
Coachful supports webhooks for bookings (created, cancelled, rescheduled, completed), program enrollments and task completions, billing events (payment succeeded/failed, subscription changes), and client and squad membership changes. You can subscribe to individual events or all events when configuring an endpoint.
How do I verify that a webhook request is really from Coachful?
Coachful includes an X-Coachful-Signature header on every request, containing an HMAC-SHA256 hash of the raw request body signed with your endpoint's unique signing secret. Compute the same hash server-side and compare it using a timing-safe comparison function. If the values don't match, reject the request.
What happens if my webhook endpoint is down or returns an error?
Coachful retries failed deliveries up to 5 times using exponential backoff, with the final retry attempt occurring roughly 8 hours after the first failure. After 5 retries, the delivery is marked permanently failed. You can manually resend failed deliveries from the Delivery logs section in your webhook settings.
Can I use Coachful webhooks with Zapier or Make?
Yes. Create a 'Webhooks by Zapier' or 'Custom webhook' trigger in Make, copy the generated URL, and paste it as your Coachful webhook endpoint. This lets you build no-code automations that react to Coachful events — such as adding new clients to a CRM or sending a welcome email when someone enrolls in your program.
How many webhook endpoints can I register?
Growth plan workspaces can register up to 3 webhook endpoints, while Scale plan workspaces can register up to 10. Each endpoint can subscribe to a different set of events, so you can route different event types to different downstream systems.
Why am I receiving the same webhook event more than once?
Coachful uses at-least-once delivery semantics, meaning a successful retry after a transient failure can result in duplicate deliveries. To handle this, implement idempotency in your webhook handler by storing the unique id field from each payload and skipping any event whose id you've already processed.
Can I test my webhook endpoint before going live?
Yes. After saving an endpoint in Settings → Integrations → Webhooks, click the Send test event button to fire a sample payload immediately. For local development, use a tunneling tool like ngrok or Smee.io to expose your local server to a public HTTPS URL that Coachful can reach.
Was this article helpful?