Swapcard ↔ ZenSpace Bridge
The swapcard-zencore repo is a small Fastify+SQLite service that maps Swapcard event Locations to ZenSpace meeting spaces and syncs Swapcard meetings into ZenSpace bookings via webhooks.
What it does
- Mapping UI — paste credentials, see your Swapcard event's Locations, map each to a ZenSpace meeting space UUID
- Webhook sync — when a Swapcard meeting is created/updated, the bridge receives the webhook and creates the matching ZenSpace booking
- Cancel UI — see all synced bookings, cancel any with one click
Stack
- Node.js 20+, Fastify, EJS server-side rendering
- SQLite via
better-sqlite3 - No React, no build step, no Redis
Deploy
The bridge runs as a single Fly.io app:
fly volumes create data --size 1
fly deploy
Or run locally:
npm install
cp .env.example .env
npm run migrate
npm run dev
Open http://localhost:3000 and configure mappings.
Configure Swapcard webhooks
After saving a mapping, the secret is shown once. Add it in Swapcard Studio:
- Studio → Integrations → Webhooks → Create
- Subscribe to Meetings: Created + Updated
- URL:
https://<your-bridge>.fly.dev/webhooks/swapcard - HMAC hex digest secret: paste from the bridge UI
Flow
Cancel from the bridge
The Cancel UI lists all synced bookings with one-click cancel. Cancellations propagate to ZenCore (POST /api/v1/bookings/:id/cancel).
Limitations
- One-way sync only (Swapcard → ZenSpace). ZenSpace-side cancellations don't push back to Swapcard.
- Per-event mapping: spin up one bridge instance per event or share a database with namespacing.