Use when staff need to connect a Luma calendar to BreatheCode for real-time guest registration and check-in via webhooks; do NOT use for Eventbrite sync, manual event check-in APIs only, or learner self-service join flows.
Installation
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Use when staff need to connect a Luma calendar to BreatheCode for real-time guest registration and check-in via webhooks; do NOT use for Eventbrite sync, manual event check-in APIs only, or learner self-service join flows.
requires
["bc-events-create-and-edit-event"]
Skill: Configure Luma Webhooks for Academy Events
When to Use
Use this skill when you must:
register a Luma webhook that posts to BreatheCode,
store Luma calendar credentials on an academy organization,
link a Luma event (evt-…) to a BreatheCode event (luma_id),
verify guest registration/check-in webhooks are flowing.
Do NOT use for Eventbrite (/v1/events/eventbrite/webhook/...), creating/editing events without Luma (bc-events-create-and-edit-event only), or attendee join/check-in APIs that do not involve Luma webhooks.
Luma calendar: every Luma API key and webhook belongs to one calendar. Webhooks require Luma Plus.
Organization: each academy has one events.Organization record. Store luma_calendar_id and luma_webhook_secret (whsec_…) on it via the academy organization API.
Event linking: set luma_id on the BreatheCode event to the Luma event.id (evt-…). Webhooks match guests using that field.
Webhook types (v1): subscribe to guest.registered and guest.updated only.
Workflow
Confirm prerequisites: Luma Plus on the calendar, calendar manage access for target events, and BreatheCode Luma processing enabled (default; set LUMA_EVENT_PROCESSING=0 only to disable globally).
Resolve the academy organization in BreatheCode.
Call GET /v1/events/academy/organization with Authorization and Academy: <academy_id>.
If missing, create it with POST /v1/events/academy/organization (requires crud_organization).
Create the BreatheCode event (or load an existing one) and note its internal id.
Use bc-events-create-and-edit-event if the event does not exist yet.
Create the event on Luma (outside BreatheCode) and copy its Luma event id (evt-…).
Link the events in BreatheCode.
Call PUT /v1/events/academy/event/<event_id> with luma_id set to the Luma evt-… value (and optional luma_url such as https://lu.ma/your-event).
Register the webhook in Luma (Luma API, not BreatheCode).
Call POST https://api.lu.ma/v1/webhooks/create with header x-luma-api-key: <calendar_api_key>.
Set url to https://<api-host>/v1/events/luma/webhook/<organization_id> where <organization_id> is the BreatheCode organization primary key from Step 2.
Set event_types to ["guest.registered", "guest.updated"].
Save the returned webhook.secret (whsec_…).
Persist Luma credentials on the organization.
Call PUT /v1/events/academy/organization with luma_calendar_id and luma_webhook_secret from Steps 2 and 6.
Send a test registration on Luma and confirm ingestion.
Luma sends POST /v1/events/luma/webhook/<organization_id> with signed body.
BreatheCode creates/updates EventCheckin and runs the same marketing automations as Eventbrite registrations when approval_status is approved.
guest.updated with checked_in_at marks the check-in DONE.
If deliveries fail, list webhooks in Luma (GET /v1/webhooks/list) and re-create or update the endpoint URL/event types as needed.