Browse docs
Actions, filters and integration surfaces
The stable hooks to build on, the theme-support flags, and the REST surfaces to know about.
The curated integration surface: the hooks that are stable and intended for third-party use. (The full internal hook list is larger; building on undocumented internals is at your own risk across updates.)
Domain actions
Fired by the plugin's services after the database transaction commits, so a listener can safely read the state the event describes, send external notifications, or sync a CRM without racing the write:
| Action | Fires after |
|---|---|
dsb_order_bookings_confirmed | an order's bookings confirm |
dsb_order_failed | a failed order releases its holds |
dsb_order_bookings_ended | a refund, cancellation or late failure cancels an order's bookings |
dsb_booking_cancelled | any booking cancellation (member or club path) |
dsb_booking_refunded | staff record a refund |
dsb_absence_reported / dsb_absence_reversed | an expected absence is set or undone |
dsb_credit_issued / dsb_credit_redeemed / dsb_credit_adjusted / dsb_credit_expired | the corresponding credit ledger event |
dsb_manual_booking_created | a staff-built booking is saved |
dsb_session_change_recorded | a session change affecting booked members is flagged (note: when flagged, not when the notice is sent) |
dsb_account_converted / dsb_conversion_requested / dsb_conversion_request_completed / dsb_conversion_request_declined | the account-conversion lifecycle |
dsb_member_registered | public registration succeeds |
Filters
| Filter | Adjusts |
|---|---|
dsb_manual_hold_minutes | how long pending manual bookings hold places (default 48 hours, floor 1 hour) |
dsb_class_durations | the durations offered on the timetable form (defaults to the setting) |
dsb_register_profile_cards | the protected-profile popup's cards: add cards or remap fields per site |
dsb_wizard_takes_over_page | return false to render the first-login wizard inside the theme layout instead of full-window |
dsb_bypass_front_page_template | return false if your theme handles the booking-page-as-front-page case itself |
dsb_notice_channel | route a notice to inline, toast or popup presentation |
dsb_root_align_class | the alignment class on the booking flow's root element (default 'alignwide', the block theme's wide width); return 'alignfull' for edge-to-edge or an empty string for a classic layout |
dsb_booking_add_veto | lets an extension refuse an add-to-basket with its own customer-facing message: return a WP_Error (default null allows). Runs on the single add path shared by the JS and no-JS flows, before the capacity hold, so a refused add never occupies a place |
dsb_checkout_credit_allowed | whether account credit may be applied to the current cart at all (default true). Returning false zeroes the applied amount, stops auto-apply and hides the checkout credit box together |
dsb_credit_issue_scope | the scope stamped on compensation credit (default '', ordinary club credit). Returning a payout recipient name makes the lot spendable only on that recipient's classes |
dsb_checkout_credit_scope | the scope of the current basket (default ''). Checkout, auto-apply and redemption only ever see lots of the matching scope, and the scope is stamped on the order so later refunds restore credit into the right pot |
dsb_credit_admin_scopes | the recipient pots staff may issue credit into on the admin Credit screen (default none, so no selector is shown) |
The last four exist for site-specific payment-routing addons (classes whose payments go directly to a recipient, with credit kept honest per pot); without such an addon they never change anything. The club-owner view is in How booking credit works.
Theme support flags
Some branding settings only make sense when the theme renders the relevant chrome, so themes opt in rather than the plugin hard-coding theme names:
add_theme_support( 'dsb-header-background' );
add_theme_support( 'dsb-body-background' );
add_theme_support( 'dsb-login-panel-image' );
add_theme_support( 'dsb-student-profile' );
Each unlocks its Branding & vocabulary field and its helper (dsb_header_background_colour(), dsb_body_background_colour(), dsb_login_panel_image_url()); the last enables the My Account student-profile tab for themes that define the profile fields. Helpers return an empty string when the flag is absent. Any theme, fork or rebrand unlocks them the same way.
The public timetable feed (the one REST route meant for you)
GET /wp-json/dsbook/v1/timetable is the exception to the build-on-hooks-not-routes advice below: an unauthenticated, read-only route designed for external consumption, typically a club's separate marketing site rendering the current timetable. The club-owner view is Publishing your timetable on another website; the contract:
- Opt-in and off by default, gated on the Public timetable feed setting (Tempo → Settings → Timetable). While off, the route stays registered and answers 403 with error code
dsb_timetable_feed_disablednaming the setting, deliberately not a 404 that would read as a broken install. Unlicensed sites answer 402 like the rest of the namespace. - Optional
termparameter;0(the default) resolves to the current term, or the next to start between terms. - The payload carries the resolved term's dates, half-term break and exclusions, the current-and-upcoming term list, and every active schedule for the term: day, time, class name, age group, location, and teacher display names. Entries closed to online booking are included with
online_open: false, so your front end can badge invitation-only classes instead of hiding them. - Never in the payload: pricing, capacity or remaining places, staff notes, or any teacher data beyond display names. Nothing about students exists anywhere near this route.
- Extra sessions (staff-created dated one-offs) are deliberately excluded; the feed's shape is weekly slots.
- Responses send
Cache-Control: public, max-age=300, so a plain fetch on the consuming site inherits five-minute caching; there's no need to hammer it per page view.
REST, for awareness
The plugin also runs authenticated REST routes for its own front ends: customer flow routes, register routes (capability-gated, with protected-profile fetches PIN-window-checked and audited), wizard routes, and the admin calendar's session feed (admin-only, capability-gated). Those exist to serve the plugin's own screens, and their contracts can evolve with it; build integrations on the domain actions and template functions above in preference to calling them directly. On locked (unlicensed) sites the namespace answers 402 across the board.
Two WooCommerce notes
- Checkout Block only: classic
woocommerce_checkout_*hooks don't fire; usewoocommerce_store_api_*and read state from the order. - Booking metadata rides on order line items with hidden machine keys and visible Student / Package / Sessions rows, so order-based integrations (accounting exports, CRM sync) can read what a line was for without touching Tempo's tables.
Thanks. That helps us improve these guides.
Thanks for letting us know. Ask us on the Support page and we'll help directly.