Skip to main content

Webhooks: Send Cademy Events to Other Systems

Create and manage Cademy webhooks, choose events, verify signed requests, review deliveries, and troubleshoot retries.

Written by Artur Binzaru

Webhooks automatically send information from Cademy to another system when selected events happen. For example, Cademy can notify your CRM when a registration is created or notify your reporting system when an order is updated.

Webhooks are useful for custom integrations because the other system does not need to keep checking Cademy for changes.

Important: A webhook is a developer tool. If you do not already have an endpoint URL, ask your developer or integration provider to create one. Your normal website address is usually not a webhook endpoint.


Before You Start

You need:

  • A Teams or Custom plan.

  • System Admin access. Only System Admins can open and manage Settings > Webhooks.

  • A public HTTPS endpoint that can accept JSON POST requests.

  • Access to the system receiving the requests so you can store the secret and verify each request.

What Should I Enter in Endpoint URL?

Endpoint URL is the web address where Cademy will send webhook messages. It is mandatory and cannot be left blank.

Your developer or integration provider should give you this address. For example:

https://example.com/webhooks/cademy

Do not enter your normal website homepage unless it has been specifically built to receive Cademy webhook requests.

The URL must:

  • Start with https://.

  • Be available publicly on the internet.

  • Not use localhost, a .local address, or a private or reserved IP address.

  • Return a successful 2xx response within 10 seconds.


Create a Webhook

  1. From the admin dashboard, go to Settings > Webhooks.

  2. Click Add Webhook.

  3. Enter the address provided by your developer or integration provider in Endpoint URL.

  4. Use Description (optional) to explain what the webhook connects to. You can leave this blank.

  5. Under Events, select every event you want Cademy to send.

  6. Click Create.

Copy the Webhook Secret

After you click Create, Webhook Secret opens.

  1. Click Copy secret to clipboard.

  2. Store the secret securely in the system that receives the webhook.

  3. Click Done.

The receiving system uses this secret to confirm that requests came from Cademy. Do not publish or share it. You can open the webhook menu and use Reveal Secret… if you need to copy it again later.


Choose Which Events to Send

You can select one event, several events, or every event. You can change the selection later with Edit….

Group

Event shown in Cademy

Event code sent

Courses

Course created

course.created

Courses

Course updated

course.updated

Courses

Course deleted

course.deleted

Course Dates

Course date created

course_date.created

Course Dates

Course date updated

course_date.updated

Course Dates

Course date deleted

course_date.deleted

Contacts

Contact created

contact.created

Contacts

Contact updated

contact.updated

Contacts

Contact deleted

contact.deleted

Registrations

Registration created

registration.created

Registrations

Registration cancelled

registration.cancelled

Orders

Order created

order.created

Orders

Order updated

order.updated

Course updated can be sent for published, private, and draft courses, including when a course's visibility changes.


What Cademy Sends

Cademy sends a signed HTTPS POST request shortly after a selected event happens.

JSON Body

Every request uses the same top-level structure:

{
  "id": "evt_1234567890abcdef",
  "type": "registration.created",
  "created": "2026-07-17T10:00:00.000Z",
  "data": {
    "id": "registration-id"
  }
}

Field

Meaning

id

The event ID. Use this to identify and ignore duplicate events.

type

The event code, such as registration.created.

created

The date and time the event happened, in ISO 8601 format.

data

Information about the course, course date, contact, registration, or order.

Deletion events contain identifiers instead of the full deleted record. course.deleted and contact.deleted contain the record ID. course_date.deleted contains the course date ID and course ID.

Request Headers

Header

Meaning

X-Cademy-Event

The event code.

X-Cademy-Delivery

A unique ID for that delivery attempt.

X-Cademy-Timestamp

The Unix timestamp used to sign the request.

X-Cademy-Signature

The HMAC SHA-256 signature.

Verify the Signature

Verify every request before using its data:

  1. Read the raw request body exactly as Cademy sent it. Do this before parsing or reformatting the JSON.

  2. Read X-Cademy-Timestamp.

  3. Join the timestamp, a full stop, and the raw body: {timestamp}.{rawBody}.

  4. Create an HMAC SHA-256 digest using the webhook secret.

  5. Add the sha256= prefix and compare the result with X-Cademy-Signature using a timing-safe comparison.

Node.js example:

import { createHmac, timingSafeEqual } from 'node:crypto';const expected = `sha256=${createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')}`;const isValid =
    signature.length === expected.length &&
    timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

Important: Webhooks use at-least-once delivery and events are not guaranteed to arrive in order. Your system must safely handle duplicates by storing the JSON body's id and ignoring any event ID it has already processed.


Check Deliveries and Retries

View Recent Deliveries

  1. Go to Settings > Webhooks.

  2. Open the menu beside the webhook.

  3. Click View Deliveries….

Recent Deliveries shows the event, result, time, attempt number, response status, duration, and any error. Delivery records are kept for 30 days. The JSON payload is not stored in this delivery history.

What Happens When a Delivery Fails?

Any 2xx response counts as successful. A non-2xx response, network error, unsafe redirect, or request that takes longer than 10 seconds counts as failed.

Cademy makes up to 5 attempts over about 30 minutes. The first attempt happens immediately, followed by up to 4 retries.

Why Was My Webhook Auto-disabled?

If 10 consecutive events each use all 5 attempts without succeeding, Cademy changes the webhook's status to Auto-disabled. This prevents repeated requests to an endpoint that is not working.

Fix the endpoint, then go to Settings > Webhooks and click Re-enable. A successful delivery resets the consecutive failure count.


Manage a Webhook

Go to Settings > Webhooks and open the menu beside a webhook.

Option

What it does

Edit…

Change the Endpoint URL, Description (optional), or Events.

View Deliveries…

Open the delivery history from the last 30 days.

Reveal Secret…

Show and copy the current webhook secret.

Regenerate Secret…

Create a new secret. The current secret stops working immediately, so update your receiving system straight away.

Disable

Stop new deliveries and queued retries immediately without deleting the webhook.

Enable

Start sending selected events again.

Delete…

Permanently remove the webhook and stop deliveries immediately.


Troubleshooting

Cademy Will Not Accept the Endpoint URL

Check the message shown under Endpoint URL:

  • Endpoint URL must use HTTPS: Replace http:// with a working https:// endpoint.

  • Endpoint URL cannot target localhost: Use a public endpoint instead of localhost or a .local address.

  • Endpoint URL cannot target a private or reserved address: Use a public internet address instead of a private or internal IP address.

The Webhook Is Enabled but Nothing Arrives

  1. Open Edit… and confirm the correct event is selected.

  2. Confirm the event happened after the webhook was enabled. Cademy does not send historical events.

  3. Open View Deliveries… and look for the event.

  4. Confirm the endpoint accepts HTTPS POST requests and returns a 2xx response within 10 seconds.

  5. Check that your endpoint is not redirecting requests to a different host.

The Signature Does Not Match

  • Use the raw request body before JSON parsing or reformatting.

  • Use the value from X-Cademy-Timestamp in the signed content.

  • Confirm your receiving system uses the current secret. If you used Regenerate Secret…, the previous secret stopped working immediately.

  • Confirm the expected value includes the sha256= prefix.


Frequently Asked Questions

Do I need a developer to use webhooks?

Usually, yes. You can create and manage the webhook in Cademy, but the receiving endpoint must be built or provided by a developer or integration service.

Can I leave Endpoint URL blank?

No. Cademy needs a public HTTPS endpoint before it can create the webhook.

Can I use my website homepage as Endpoint URL?

Usually not. Use it only if a developer has specifically configured that address to receive Cademy webhook POST requests.

Can I leave Description (optional) blank?

Yes. It is only a label to help System Admins understand what the webhook connects to.

Can I send a test webhook?

There is no separate test button. Create the webhook, then perform one of its selected events in Cademy and check View Deliveries….

Will Cademy send an event exactly once?

No. Cademy uses at-least-once delivery, so the same event can arrive more than once. Use the JSON body's id to ignore duplicates.

Will events arrive in the same order they happened?

Not always. Your receiving system should use the event's created value and must not rely on delivery order.

How many times will Cademy retry a failed delivery?

Cademy makes up to 5 attempts over about 30 minutes.

How long is delivery history kept?

Recent Deliveries keeps delivery records for 30 days. It does not store the JSON payload.

Can I see the secret again?

Yes. Open the webhook menu and click Reveal Secret….

What happens if I regenerate the secret?

The previous secret stops working immediately. Copy the new secret to your receiving system straight away.

Can I pause a webhook without deleting it?

Yes. Use Disable. This stops new deliveries and queued retries immediately. Use Enable when you are ready to start again.

Did this answer your question?