Guests
Invite guests by email and give them a temporary member account for 12, 24 or 48 hours.
Club administrators and members can invite a guest by email. When the guest accepts, Champagne creates a temporary member account in the inviter's club that stays active for the duration the inviter chose: 12, 24 or 48 hours.
- The host calls
inviteGuest(clubId, email, durationHours). - Champagne emails the guest a
/guest-invitation?token=…link on the member site. - The guest previews it with
guestInvitation(token)and accepts withacceptGuestInvitation. - Acceptance creates a
guest_accessgrant and signs the guest in until that grant expires.
Invite a guest
mutation InviteGuest($clubId: ID!, $email: String!, $durationHours: Int!) {
inviteGuest(clubId: $clubId, email: $email, durationHours: $durationHours)
}{
"clubId": "51000000-0000-4000-8000-000000000051",
"email": "guest@example.com",
"durationHours": 24
}| Argument | Type | Description |
|---|---|---|
clubId | ID! | Club the guest joins. Must be the inviter's club. |
email | String! | Guest email. Trimmed and compared case-insensitively. |
durationHours | Int! | Guest access granted on acceptance: exactly 12, 24 or 48. |
Callers must be either a staff account with members_manage in clubId (club
administrators hold every permission; see staff permissions) or a signed-in member of that club
whose effective status is active. Staff without that permission, guests, anonymous
callers and other clubs receive UNAUTHENTICATED. Other durations, invalid emails
and emails that already belong to a regular person of the club fail with
BAD_USER_INPUT. An email belonging to a current or former guest can be invited again.
The mutation returns true only after the email was delivered. The email contains a
single-use link to CONSUMER_ORIGIN/guest-invitation?token=…, valid for 7 days. The
guest access duration only starts when the guest accepts. Inviting the same email again
from the same inviter replaces their unaccepted invitation. If delivery fails, the new
invitation is removed and a retryable error is returned. No token is returned to the caller.
List invitations
query GuestInvitations($clubId: ID!) {
guestInvitations(clubId: $clubId) {
id
email
durationHours
status
invitedBy
guestName
createdAt
expiresAt
accessExpiresAt
}
}Administrators see every invitation of the club; members see only the invitations they sent. Results are ordered newest first and limited to 100.
| Field | Type | Description |
|---|---|---|
status | GuestInvitationStatus! | pending, expired (link unused and elapsed), active or ended. |
invitedBy | String! | Member full name or staff name of the inviter. |
guestName | String | Guest full name once accepted. |
expiresAt | String! | ISO timestamp after which the link can no longer be accepted. |
accessExpiresAt | String | ISO end of the temporary account granted by this invitation. |
An accepted invitation is active while its access grant is neither expired nor revoked,
and ended afterwards.
Accept an invitation
The public guestInvitation query previews a link before acceptance. It returns null
for unknown tokens; expired is true once the link was used or has elapsed.
query GuestInvitationPreview($token: String!) {
guestInvitation(token: $token) {
email
clubName
invitedBy
durationHours
expired
}
}
mutation AcceptGuestInvitation(
$token: String!
$firstName: String!
$lastName: String!
$password: String!
) {
acceptGuestInvitation(
token: $token
firstName: $firstName
lastName: $lastName
password: $password
) {
token
personId
clubId
}
}Names need 1–100 characters and the password follows the member password policy. Acceptance
atomically creates the guest person and login (or renews a former guest with the same email),
creates a guest_access row ending at now plus durationHours, consumes the link, revokes the
guest's older sessions and returns a member session. Used, expired or unknown links fail with
BAD_USER_INPUT, as does an email that became a regular member of the club in the meantime.
Guest accounts
Guests are ordinary people whose latest guest_access grant determines their temporary access.
The derived guestExpiresAt field remains exposed on Person, PersonDetail and memberViewer;
PersonDetail.guestAccess also exposes the latest grant and its structured inviter. Until expiry,
a guest can sign in with
loginMember, read their own profile and see the reservations they are invited to. Guests do
not book themselves: the member site offers them no club schedule. They cannot start
membership, add-on or credit Checkout and cannot invite other guests. The member site shows
them only Overview, Reservations (the reservations they were invited to) and
Notifications. Once guestExpiresAt has
passed, existing sessions stop resolving and sign-in fails with
Your guest access has ended. The person and access records are kept for history. If an inviter
account is deleted, the access record retains its inviter kind while the inviter ID and name become
null; clients should display a deleted-user label.
Reservation invitations requiring accounts
Clubs can require accounts for reservation guests in admin Settings. See
Reservation guest accounts for the policy queries
and invitation arguments. These invitations appear in guestInvitations and use the same
guestInvitation preview and acceptGuestInvitation registration contract. Acceptance also links
the person to the reservation and marks their invitation accepted in the same transaction.
A reservation invitation can complete an existing person record that has no login credentials;
it never overwrites an existing member password. Invalidated reservation links cannot register.
Sending a regular Guests-tab invitation does not invalidate invitations tied to reservations.