These hooks follow a sign-up from the RSVP form to the door. Use them to add fields to the form, refuse or limit a registration and add columns to the Attendees screen. Others react when someone registers, cancels, changes date or is deleted.
For the site owner’s side, see setting up an RSVP form and managing attendees. New to hooks? Start with Extending HappenBoard with hooks.
Dates, seats and translations
A sign-up for a recurring event is for one date. The attendee row stores that date’s sequence number in the series (occurrence_seq, 0 for the first date); it is null for a one-off event.
The event’s capacity applies to each date. Only going attendees hold seats: waitlist, declined and cancelled hold none.
With WPML or Polylang, the translations of an event share their seats. Every translation’s registrations count against the capacity of the default language’s translation, and one email registers only once. Each row keeps the translation it was made on, which sets the language of the attendee’s emails.
Which hook fires when
| What happens | Hook |
|---|---|
| Someone registers (RSVP form, ticket order, import) | happenboard_rsvp_submitted |
| The attendee cancels with their link, or a refund cancels the ticket | happenboard_rsvp_cancelled |
| An operator changes the status, Cancel included | happenboard_attendee_status_changed |
| An operator edits the name, email or seats | happenboard_attendee_updated |
| An operator moves the attendee to another date | happenboard_attendee_date_changed |
| The attendee is deleted for good, alone or with their event | happenboard_attendee_deleted |
| A ticket is scanned at the door (Pro) | happenboard_pro_attendee_checked_in |
happenboard_rsvp_form_fields
Adds your own inputs to the RSVP Form, after the email field and before the number of seats. HappenBoard Pro’s Ticket Picker prints the same fields, so ticket buyers are asked them too.
Signature
apply_filters( 'happenboard_rsvp_form_fields', string $html, int $post_id )
Parameters
-
$htmlstring - HTML to print. Empty by default.
-
$post_idint - The event.
Return value
string
HTML printed as is: escape everything you build.
Example
add_filter(
'happenboard_rsvp_form_fields',
function ( string $html, int $post_id ): string {
// The form sends only inputs named happenboard_cf_<key>.
$html .= sprintf(
'<label class="wp-block-happenboard-rsvp-form__field"><span>%s</span><input type="text" name="happenboard_cf_diet" maxlength="190"></label>',
esc_html__( 'Dietary requirements', 'my-plugin' )
);
return $html;
},
10,
2
);
Notes
- Two arguments: register with
10, 2. - Append to
$html: HappenBoard Pro prints its custom fields through this filter too. - Name each input
happenboard_cf_<key>. The form sends only those, keyed<key>, and skips disabled ones. A value is stored only ifhappenboard_rsvp_custom_fieldskeeps it. - It runs only when the form is shown: not for an event that is cancelled, postponed, over, undated, full or locked by a password. HappenBoard Pro replaces the form with the Ticket Picker on an event that has tickets.
happenboard_rsvp_custom_fields
Checks the extra answers sent with a sign-up and returns the ones to store on the attendee. It is the other half of happenboard_rsvp_form_fields: that filter prints the input, this one keeps the value.
Signature
apply_filters( 'happenboard_rsvp_custom_fields', array<string,mixed> $fields, array<string,string|array<int,string>> $raw, int $event_id )
Parameters
-
$fieldsarray<string,mixed> - Answers kept so far. Empty by default.
-
$rawarray<string,string|array<int,string>> - What was sent, keyed by field key (the input name without
happenboard_cf_). Keys went throughsanitize_key()and values throughsanitize_text_field(), which is not validation. -
$event_idint - The event.
Return value
array<string,mixed>|WP_Error
The answers to store, or a WP_Error to refuse the sign-up with its message. Any other value stores nothing.
Example
add_filter(
'happenboard_rsvp_custom_fields',
function ( $fields, array $raw, int $event_id ) {
$fields = is_array( $fields ) ? $fields : array();
$diet = sanitize_text_field( (string) ( $raw['diet'] ?? '' ) );
if ( '' === $diet ) {
// The RSVP Form shows this message to the visitor.
return new WP_Error( 'my_diet_required', __( 'Please tell us about your dietary requirements.', 'my-plugin' ), array( 'status' => 400 ) );
}
$fields['diet'] = $diet;
return $fields;
},
20,
3
);
Notes
- Three arguments: register with
10, 3, at priority 20 or later when HappenBoard Pro is active. Pro checks its own fields at 10 and, when the event has some, returns only those. - Merge into
$fieldsrather than replacing it. The result is stored as JSON, so keep to strings and arrays of strings. - It runs for every sign-up through HappenBoard’s RSVP service (the form, the
create-rsvpability, Pro’s CSV import and its dry runs), after the date, duplicate and capacity checks. Pro’s Ticket Picker checkout applies it too; WooCommerce orders do not.
happenboard_rsvp_allowed
Decides whether an event takes free sign-ups at all. Return a WP_Error to refuse the sign-up with your own code, message and HTTP status.
Signature
apply_filters( 'happenboard_rsvp_allowed', true|WP_Error $allowed, int $event_id, array<string,mixed> $input )
Parameters
-
$allowedtrue|WP_Error true, or theWP_Errorof an earlier callback.-
$event_idint - The event, already known to be published and still taking sign-ups.
-
$inputarray<string,mixed> - The registration:
event_id,email,display_name,quantity,occurrence(the date asked for),raw_fields, and from operator toolsuser_id,status,bypass_capacity,validate_onlyor Pro’scomp.
Return value
true|WP_Error
true to go on, or a WP_Error returned to the caller as is. Any other value refuses with happenboard_rsvp_not_allowed (HTTP 403).
Example
add_filter(
'happenboard_rsvp_allowed',
function ( $allowed, int $event_id, array $input ) {
if ( is_wp_error( $allowed ) ) {
return $allowed;
}
// Staff-only events take staff addresses only.
$staff = str_ends_with( strtolower( (string) ( $input['email'] ?? '' ) ), '@example.com' );
if ( has_term( 'staff-only', 'happenboard_category', $event_id ) && ! $staff ) {
return new WP_Error( 'my_staff_only', __( 'This event is open to staff only.', 'my-plugin' ), array( 'status' => 403 ) );
}
return $allowed;
},
20,
3
);
Notes
- Three arguments: register with
10, 3. - Pass an incoming
WP_Erroron untouched. The check is strict:1or'yes'refuses. - It runs for every caller of HappenBoard’s RSVP service, after the event checks (published, not cancelled, postponed or over) and before the date, duplicate, capacity and field checks.
- HappenBoard Pro uses it at priority 10 to refuse plain sign-ups on any event that has tickets, free or paid (
happenboard_pro_ticket_required), unless its CSV import marks the rowcomp.
happenboard_rsvp_max_quantity
Filters the most seats one sign-up may ask for through the public RSVP route. HappenBoard reads it from the RSVP Form blocks on the event’s page, so a request cannot ask for more than the form offers.
Signature
apply_filters( 'happenboard_rsvp_max_quantity', int $limit, int $event_id )
Parameters
-
$limitint - The largest limit among the RSVP Form blocks in the event’s content and single-event template. A form allows 1 seat without Allow multi-seat RSVP, else its Maximum seats per RSVP (4 by default). 20 when no form is found.
-
$event_idint - The event.
Return value
int
The limit, kept between 1 and 20 after the filter.
Example
add_filter(
'happenboard_rsvp_max_quantity',
function ( int $limit, int $event_id ): int {
// Workshop forms sit in a synced pattern HappenBoard cannot see: they allow 6 seats.
if ( has_term( 'workshops', 'happenboard_category', $event_id ) ) {
return 6;
}
return $limit;
},
10,
2
);
Notes
- Two arguments: register with
10, 2. - Forms inside a synced pattern or a template part are not seen. On a classic theme, the form HappenBoard adds after the content counts as a one-seat form.
- It limits the public
POST /happenboard/v1/rsvproute only: a larger request is refused withhappenboard_quantity_too_high(HTTP 400). It does not change the number the form offers, and operator tools (thecreate-rsvpability, the CSV import) ignore it.
happenboard_rsvp_client_ip
Filters the visitor address the sign-up throttle counts on (5 sign-ups per address per minute). HappenBoard reads REMOTE_ADDR and ignores X-Forwarded-For, so behind a proxy or CDN every visitor shares one address until you filter it.
Signature
apply_filters( 'happenboard_rsvp_client_ip', string $ip )
Parameters
-
$ipstring REMOTE_ADDRif it is a valid IP, else an empty string.
Return value
string
The address to count on. Return $ip when you cannot do better.
Example
// Behind Cloudflare: count each visitor's real address.
add_filter(
'happenboard_rsvp_client_ip',
fn( $ip ) => filter_var( $_SERVER['HTTP_CF_CONNECTING_IP'] ?? '', FILTER_VALIDATE_IP ) ?: $ip
);
// Booking forms have their own filter: add the same there.
add_filter(
'happenboard_booking_client_ip',
fn( $ip ) => filter_var( $_SERVER['HTTP_CF_CONNECTING_IP'] ?? '', FILTER_VALIDATE_IP ) ?: $ip
);
Notes
- One argument.
- Trust only a header your own proxy sets, and only if the site cannot be reached without the proxy: otherwise anyone can send the header and change it at will. With
X-Forwarded-For, take the address your proxy added, not the first one, which the visitor controls. - HappenBoard Pro’s throttles use the same filter: free Ticket Picker carts (in the RSVP budget), paid checkouts (see
happenboard_pro_checkout_limits) and event submissions (3 per address every 10 minutes). - The address is also sent to Turnstile and Akismet. An empty string turns the per-address limit off; the per-email limit (3 per hour), the honeypot and the minimum fill time still apply.
happenboard_rsvp_submitted
Fires right after an attendee row is created, for a free sign-up or a ticket order. Use it for anything that must happen when someone registers.
Signature
do_action( 'happenboard_rsvp_submitted', int $attendee_id, array{event_id:int,occurrence_seq:?int,email:string,display_name:string,quantity:int,cancel_token:string} $data )
Parameters
-
$attendee_idint - The new attendee.
-
$dataarray<string,mixed> event_id,occurrence_seq(the date of a recurring event, elsenull),email,display_name,quantityandcancel_token. Pro’s ticket paths addpaid,source(stripe,woocommerceorfree_ticket) andsession_idororder_id.
Example
add_action(
'happenboard_rsvp_submitted',
function ( int $attendee_id, array $data ): void {
// Log every new registration.
error_log( sprintf(
'Attendee %d registered for event %d with %d seat(s).',
$attendee_id,
(int) $data['event_id'],
(int) $data['quantity']
) );
},
10,
2
);
Notes
- Two arguments: register with
10, 2. - It fires from HappenBoard’s RSVP service: the form, the
create-rsvpability, Pro’s CSV import (not its dry runs). Pro also fires it from its Stripe webhook, WooCommerce orders and free ticket carts, once per ticket line, so one order can fire it several times. $datahas no status: read the row when you need it, since an import can record waitlisted or declined rows. HappenBoard sends its confirmation email at priority 10, togoingattendees only.cancel_tokenis the secret behind the attendee’s cancel link. Never log it, show it or send it to a third party.
happenboard_rsvp_cancelled
Fires when a sign-up is cancelled by the attendee (the cancel link in their emails, or DELETE /happenboard/v1/rsvp/{token}) or by a refund in HappenBoard Pro. The row is kept with the status cancelled and its seats are free again.
Signature
do_action( 'happenboard_rsvp_cancelled', int $attendee_id )
Parameters
-
$attendee_idint - The attendee whose sign-up was cancelled.
Example
add_action(
'happenboard_rsvp_cancelled',
function ( int $attendee_id ): void {
// The row still exists, with the status cancelled.
$attendee = ( new \HappenBoard\Service\Attendees\Repository() )->find_by_id( $attendee_id );
if ( null !== $attendee ) {
error_log( 'Seat released for ' . $attendee['email'] );
}
}
);
Notes
- One argument.
- HappenBoard Pro fires it for each line a Stripe refund cancels (from the Orders screen or the
charge.refundedwebhook) and for a WooCommerce order that is refunded, cancelled or failed. Your callback may then run in a webhook request with no user signed in. - A partial Stripe refund cancels only the lines it pays back in full or the operator chose. A repeated cancellation fires nothing.
- An operator’s cancellation (Attendees screen,
cancel-rsvpability) fireshappenboard_attendee_status_changedinstead. HappenBoard sends the cancellation email in both cases.
happenboard_attendee_status_changed
Fires when an operator changes an attendee’s status: on the Attendees screen (its Cancel action included), through PATCH /happenboard/v1/attendees/{id}, or with the update-attendee-status and cancel-rsvp abilities.
Signature
do_action( 'happenboard_attendee_status_changed', int $attendee_id, string $new_status, string $old_status )
Parameters
-
$attendee_idint - The attendee.
-
$new_statusstring - The new status:
going,waitlist,cancelledordeclined. -
$old_statusstring - The status before. Empty string when the row had none.
Example
add_action(
'happenboard_attendee_status_changed',
function ( int $attendee_id, string $new_status, string $old_status ): void {
// Someone got a seat from the waitlist.
if ( 'going' === $new_status && 'waitlist' === $old_status ) {
error_log( sprintf( 'Attendee %d promoted from the waitlist.', $attendee_id ) );
}
},
10,
3
);
Notes
- Three arguments: register with
10, 3. The new status comes before the old one. - It fires after a successful write, and only when the status really changes. A move to
goingwhose seats do not fit in the capacity is refused before anything is written, unless the operator confirms it over capacity, so it does not fire. - HappenBoard emails the attendee from it: the confirmation when they come off the waitlist, the cancellation when they are cancelled. HappenBoard Pro gives back or takes ticket seats here, since only
goingholds seats.
happenboard_attendee_updated
Fires when an operator edits an attendee’s name, email or number of seats through PATCH /happenboard/v1/attendees/{id} (the Attendees screen). It receives the before and after of each field that changed.
Signature
do_action( 'happenboard_attendee_updated', int $attendee_id, array<string,array{from:mixed,to:mixed}> $changes )
Parameters
-
$attendee_idint - The attendee.
-
$changesarray<string,array{from:mixed,to:mixed}> - Keyed by column (
display_name,email,quantity), each withfromandto.
Example
add_action(
'happenboard_attendee_updated',
function ( int $attendee_id, array $changes ): void {
if ( ! isset( $changes['email'] ) ) {
return;
}
// Keep our mailing list in step with the new address.
my_plugin_sync_contact( (string) $changes['email']['from'], (string) $changes['email']['to'] );
},
10,
2
);
Notes
- Two arguments: register with
10, 2. - The keys are column names, not the camelCase names of the request. A request that changes nothing still fires it with an empty array: return early.
- A status change in the same request fires
happenboard_attendee_status_changedafter this one. Raising the seats of agoingattendee is checked first (happenboard_attendee_seats_left); a refused request fires nothing.
happenboard_attendee_seats_left
Filters how many seats an attendee may hold when an operator raises their number of seats or moves them to going: on the Attendees screen (Mark as Going included) or with the update-attendee-status ability. HappenBoard allows the event’s capacity (the date’s, on a recurring event) less the seats the other going attendees hold.
Signature
apply_filters( 'happenboard_attendee_seats_left', int|null $left, array<string,mixed> $attendee )
Parameters
-
$leftint|null - Seats the attendee may hold, or
nullwhen the event has no capacity. -
$attendeearray<string,mixed> - The attendee row before the change (
attendee_id,event_id,occurrence_seq,status,quantity…).
Return value
int|null
The most seats allowed, or null for no limit. A larger request is refused with happenboard_capacity_full (HTTP 409).
Example
add_filter(
'happenboard_attendee_seats_left',
function ( $left, array $attendee ) {
// No more than 6 seats per attendee, even on events without a capacity.
return null === $left ? 6 : min( 6, (int) $left );
},
20,
2
);
Notes
- Two arguments: register with
10, 2. Return an integer ornull: other values are cast to an integer, sofalsemeans 0 seats and refuses the change. - It runs only when an attendee who is, or becomes,
goingwould hold more seats than now: more seats, or a move togoingfrom another status. Not when the operator confirms the change over capacity. Fewer seats always fit. - On a translated event, the capacity is the default language translation’s and every translation’s attendees count. Moving an attendee to another date uses
happenboard_attendee_date_seats_leftinstead. - HappenBoard Pro answers at priority 10 for ticket holders: what their ticket has left on their date, plus the seats they already hold. Use a later priority to change its answer, as the example does.
happenboard_attendee_date_changed
Fires after an operator moved an attendee of a recurring event to another date: with Change date on the Attendees screen, through POST /happenboard/v1/attendees/{id}/date, or with the reschedule-rsvp ability. The row is already on the new date.
Signature
do_action( 'happenboard_attendee_date_changed', int $attendee_id, int $sequence, ?int $from, array<string,mixed> $context )
Parameters
-
$attendee_idint - The attendee moved.
-
$sequenceint - Sequence of the new date.
-
$from?int - Sequence of the old date,
nullwhen the row had none. -
$contextarray<string,mixed> event_id;from_start_utcandfrom_label(the date left);to_start_utcandto_label;quantity;status;over_capacity;notify. Starts are UTCY-m-d H:i:s, labels use the site’s date and time formats.
Example
add_action(
'happenboard_attendee_date_changed',
function ( int $attendee_id, int $sequence, ?int $from, array $context ): void {
// Keep a trace of every move.
error_log( sprintf(
'Attendee %d moved from "%s" to "%s".',
$attendee_id,
(string) $context['from_label'],
(string) $context['to_label']
) );
},
10,
4
);
Notes
- Four arguments: register with
10, 4. - It does not fire when the attendee is already on that date or the move is refused. A move is refused for a date skipped, over or not in the series, or one the same email is already registered on. A date without room for a
goingattendee is refused unless the operator confirms (over_capacityis then true). notifyis true when the attendee isgoingand the operator left the email on. HappenBoard then emails the new date with a calendar file at priority 20 and moves the reminder.- HappenBoard Pro moves the ticket seats to the new date at priority 5, before other callbacks read them.
happenboard_attendee_date_seats_left
Filters the seats left for one attendee on the dates of a recurring event they could be moved to. HappenBoard counts the event’s capacity against the seats going attendees hold on each date.
Signature
apply_filters( 'happenboard_attendee_date_seats_left', array<int,?int> $left, array<string,mixed> $attendee, array<int,int> $sequences )
Parameters
-
$leftarray<int,?int> - Seats left, keyed by sequence;
nullwhere nothing limits them. -
$attendeearray<string,mixed> - The attendee row.
-
$sequencesarray<int,int> - The dates asked about.
Return value
array<int,?int>
Seats left by sequence, null for no limit. A return that is not an array is ignored.
Example
add_filter(
'happenboard_attendee_date_seats_left',
function ( $left, array $attendee, array $sequences ) {
// Keep two seats in reserve on every limited date.
foreach ( (array) $left as $sequence => $seats ) {
if ( null !== $seats ) {
$left[ $sequence ] = max( 0, $seats - 2 );
}
}
return $left;
},
20,
3
);
Notes
- Three arguments: register with
10, 3. - It runs once for the whole list of dates (up to 200 upcoming dates), then again for the chosen date when a
goingattendee is moved. Read what you need for all the dates in one query. - A move is refused when the attendee’s seats exceed the figure for the date, unless the operator confirms. Return
nullfor a date to lift the limit. - HappenBoard Pro answers at priority 10 for ticket holders: the ticket’s capacity on each date less what is sold and held there.
happenboard_attendee_dates_assigned
Fires after attendees of a recurring event who had no date were given one. Each gets the date that was current when they registered: the first not over at that time, else the last.
Signature
do_action( 'happenboard_attendee_dates_assigned', int $event_id, array<int,int> $attendee_ids )
Parameters
-
$event_idint - The recurring event.
-
$attendee_idsarray<int,int> - The attendees who were given a date.
Example
add_action(
'happenboard_attendee_dates_assigned',
function ( int $event_id, array $attendee_ids ): void {
// Forget the dates we cached for these attendees.
foreach ( $attendee_ids as $attendee_id ) {
delete_transient( 'my_attendee_date_' . $attendee_id );
}
},
10,
2
);
Notes
- Two arguments: register with
10, 2. - Undated rows are sign-ups made before HappenBoard 0.2.0, rows of an event that has since become recurring, and rows inserted with a
nulldate. Placing runs once when the attendees table is upgraded, then on everyhappenboard_occurrences_changed(priority 20). - It fires once per event, only when at least one row was placed. A row older than the first date a long series still stores keeps no date.
- HappenBoard arms a reminder for the placed attendees whose date is ahead. HappenBoard Pro moves their ticket sales to the same dates.
happenboard_attendee_deleted
Fires after an attendee was deleted for good: with Delete permanently on the Attendees screen (DELETE /happenboard/v1/attendees/{id}), or with their event when it is deleted for good. Use it to drop what you store about the attendee.
Signature
do_action( 'happenboard_attendee_deleted', int $attendee_id )
Parameters
-
$attendee_idint - ID of the row that was deleted.
Example
add_action(
'happenboard_attendee_deleted',
function ( int $attendee_id ): void {
global $wpdb;
// Delete the badges we printed for this attendee.
$wpdb->delete( $wpdb->prefix . 'my_badges', array( 'attendee_id' => $attendee_id ), array( '%d' ) );
}
);
Notes
- One argument. The row is already gone: capture what you need earlier, for example on
happenboard_event_deleting, which still sees the rows. - When the event is being deleted, its post and meta can still be read. Cancelling a sign-up deletes nothing and does not fire it.
- HappenBoard clears the attendee’s pending reminder here. HappenBoard Pro releases the ticket seats, deletes the sale and the attendee’s journal, and sends the
attendee.deletedwebhook.
happenboard_rest_attendees_prefetch
Fires once with all the attendee rows a list or export response is about to send, before happenboard_rest_attendee_response runs on each row. Load your data for the whole set here, in one query.
Signature
do_action( 'happenboard_rest_attendees_prefetch', array<int,array<string,mixed>> $rows, WP_REST_Request $request )
Parameters
-
$rowsarray<int,array<string,mixed>> - Raw rows in response order (snake_case columns,
custom_fieldsstill JSON). An event’s list includes the attendees of its translations. -
$requestWP_REST_Request - The list (
GET /happenboard/v1/attendees) or an export (GET /happenboard/v1/attendees/export).
Example
$my_tiers = array();
add_action(
'happenboard_rest_attendees_prefetch',
function ( array $rows ) use ( &$my_tiers ): void {
// One query for the whole page, keyed by attendee ID.
$my_tiers = my_plugin_tiers_for( array_map( 'intval', array_column( $rows, 'attendee_id' ) ) );
}
);
add_filter(
'happenboard_rest_attendee_response',
function ( array $serialized, array $row ) use ( &$my_tiers ): array {
$id = (int) $row['attendee_id'];
// Single-row responses are not announced: fall back to one query.
$serialized['myTier'] = $my_tiers[ $id ] ?? ( my_plugin_tiers_for( array( $id ) )[ $id ] ?? '' );
return $serialized;
},
10,
2
);
Notes
- Two arguments. A callback that needs only the rows can keep the default of one.
- A list page holds up to 200 rows and an export up to 10,000: a query in the per-row filter would run that many times.
- Single-row responses (
GETandPATCH /attendees/{id},POST /attendees/{id}/date) do not fire it, so the filter still needs a fallback. Keep only the current response’s data.
happenboard_rest_attendee_response
Filters one attendee as the REST API sends it to the Attendees screen and its exports. Use it to add your own columns.
Signature
apply_filters( 'happenboard_rest_attendee_response', array<string,mixed> $serialized, array<string,mixed> $row )
Parameters
-
$serializedarray<string,mixed> id,eventId,eventTitle,language,occurrenceId,occurrenceSeq,occurrenceStartUtc,occurrenceLabel,occurrenceStatus,bookedStartUtc,userId,email,displayName,status,quantity,customFields,createdUtc,updatedUtc.-
$rowarray<string,mixed> - The raw database row, so you do not have to query it again.
Return value
array<string,mixed>
The attendee with your keys added. It is cast with (array): always return the array.
Example
add_filter(
'happenboard_rest_attendee_response',
function ( array $serialized, array $row ): array {
// Add the event's tier to each attendee.
$serialized['myTier'] = (string) get_post_meta( (int) $row['event_id'], '_my_tier', true );
return $serialized;
},
10,
2
);
Notes
- Two arguments: register with
10, 2. - Add keys; do not rebuild the array, or you drop HappenBoard’s fields and those of earlier callbacks (HappenBoard Pro adds
checkinCountandlastCheckinUtc). - A key you add reaches the JSON export. The CSV export keeps its own columns (plus one
cf:column per custom field) and the vCard export ignores extra keys. - It runs once per row: load your data on
happenboard_rest_attendees_prefetch.
happenboard_pro_attendee_checked_in
Fires after a check-in is recorded at the door: a scan on the check-in screen (POST /happenboard/v1/pro/checkin/mark) or Pro’s check-in-attendee ability. Use it to print a badge, notify a team or refresh a live list.
Signature
do_action( 'happenboard_pro_attendee_checked_in', int $checkin_id, int $attendee_id, int $event_id )
Parameters
-
$checkin_idint - ID of the check-in row just recorded (not the attendee ID).
-
$attendee_idint - The attendee who was scanned.
-
$event_idint - The event of the attendee’s registration (on a translated event, the translation they registered on).
Example
add_action(
'happenboard_pro_attendee_checked_in',
function ( int $checkin_id, int $attendee_id, int $event_id ): void {
// Log every entry at the door.
error_log( sprintf( 'Scan %d: attendee %d entered event %d.', $checkin_id, $attendee_id, $event_id ) );
},
10,
3
);
Notes
- Three arguments: register with
10, 3. - It fires for every recorded scan, re-scans included, each with a new check-in ID. Deduplicate if you want only the first entry.
- A ticket turned away (no seat, another date or another event) fires
happenboard_pro_attendee_checkin_refused, and an undone scan fireshappenboard_pro_attendee_checkin_undone. Both are documented with the check-in hooks.
Next steps
- Notification and email hooks: change the confirmation, reminder and cancellation emails.
- Calendar sync, webhook and check-in hooks: refused and undone check-ins, and the attendee webhooks.
- Ticketing and payment hooks: tickets, checkouts and refunds in HappenBoard Pro.