Groups

Hosted travel groups: create a group, attach trips, manage members, publish a public booking page that auto-creates trips from sign-ups.

By System Generated · Updated Jul 1, 2026

Download PDF

Groups model a hosted trip — a group cruise, escorted tour, themed travel cohort — where one container holds many individual traveler trips, a shared roster, communication channels, and an optional public booking page that captures sign-ups directly into your CRM.

This article covers the foundation (Phase 1) through to the public booking page (Phase 3). Messages and the live chat room ship in Phase 4 — see the bottom of this article for what is coming.

When to use a Group

A Group is the right primitive when you are hosting one travel experience that multiple separately-paying parties join. Examples:

A Group is NOT the right primitive for a single party traveling together — that is just a Trip with multiple travelers.

Create a group

  1. Click Groups in the sidebar (currently labeled BETA while we finish building)

  2. Click "New group"

  3. Enter a name (e.g. "Smith Family Cruise"), an optional default destination, optional default start/end dates, and a brand color

  4. Submit — you land on the new group's page

The default destination and dates pre-fill onto every trip created inside the group, so your travelers do not have to re-type them.

Add members

The Members tab manages who is in the group. Two ways to add members:

Promote a member to Leader by changing their role from the inline dropdown. Leaders get send-message permissions when Phase 4 ships.

Attach trips

Two ways to populate the group with trips:

A trip can belong to multiple groups (e.g. main group cruise + pre-cruise side excursion). Detaching from one group does not affect the other.

The public booking page

Every group can have one public booking page at /g/{slug}. Open Booking page tab → click "Create booking page" if none exists, or "Edit page" if you have one.

Editor sections

Publishing

Click "Publish" in the header to make the page live. Click "Unpublish" to take it down without deleting. The agent-side editor stays accessible regardless.

How sign-ups become trips automatically

Every public submission goes through this pipeline immediately on submit (no manual "convert" step):

  1. Terms text is snapshotted onto the submission row with the IP, user agent, and timestamp

  2. A Core contact is created (or matched on existing email / name+DOB)

  3. A local Trips contact is created bound to that Core UUID

  4. The primary submitter is added to the group's member roster

  5. A Trip is created named "{Last name} party — {Group name}" with the group's default dates

  6. Every traveler row on the submission becomes a Trip traveler (the primary is row 0 / is_primary=true)

  7. The Trip is attached to the group via the trip-group pivot

  8. The submission row gets status=converted with converted_to_trip_id pointing at the new Trip

If Core is unreachable during conversion the submission is still saved with status=new; the rest gets caught up on the next agent action.

Booking submissions tab

Lists every public sign-up, newest first. Columns: submitted date, primary contact, party size, selected option, status, converted Trip link. Click through to the Trip for full editing.

Broadcast messages

The Messages tab on a group sends one email to every group member who is on at least one trip in the group. Each email also lands on the recipient's trip Messages tab, so when a client replies the conversation threads back into their specific trip.

Composing

Past broadcasts

The right column of the Messages tab lists every broadcast in order — subject, sent date, sender, recipient count, and how many were skipped (no email on file). Click "View message" to expand the full body inline.

Why some members get skipped

Two reasons a member won't receive a broadcast:

Group attachments

Files uploaded to a group live in trip_group_attachments and can be attached to any broadcast email from the composer. They're encrypted at rest on R2 with the same tenant-scoped AES-256-GCM cipher trip attachments use — so if you ever need to hand-recover a blob, the same tooling works.

Chat room (Phase 4b.1 — agent side)

The Community Chat tab on a group is a live in-app shared thread between everyone in the agency team. Polling-based delivery every 3 seconds — good enough for a booking-thread cadence, and websockets can slot in later without changing the UI contract.

How it works today

Data model

Each message is a trip_group_chat_messages row with either author_user_id (agents) OR author_contact_id (portal members, when Phase 4b.2 lands) — never both. Per-(group, member) last-read pointers in trip_group_chat_reads drive unread counts without scanning every message.

Coming in Phase 4b.2

Common questions

Can a contact be in multiple groups?

Yes — the trip_group_members table is a pivot, so the same contact can be a member of many groups.

Can a trip be in multiple groups?

Yes — same M:N pattern. Most won't be, but the schema supports it.

What happens to attached trips if I archive a group?

Trips stay intact. Archiving only hides the group from the index; the trip-group pivot rows remain, so unarchiving restores the full state.

Who can access the public booking page?

Anyone with the URL — there is no auth required to sign up. Spam-control is via the IP rate limit (5 submissions/minute per IP). Add a terms_required checkbox to slow drive-by submissions further.

Back to resources Published by UrTravelPro