RCIC App by Investatech

RCIC App manual

An online manual covering every module, kept in sync with the platform.

Up to date as of v1.30.0

Personal Invites

One-off named booking links for a specific person, locked to a single service, with an expiry date, an optional fixed-amount discount or full-free gift, an optional personal note, and a self-serve booking flow that runs entirely from the invitee's side. Covers prerequisites (services, Stripe Connect, calendar, off days), the send form, the discount block, the invitee email and landing page, the invites list, every row action, and the interactions with Bookings, Stripe, your calendar, and Service Agreements.

Download PDF

Overview

Personal Invites is a Bookings-adjacent module that lets you send a named, one-time booking link to a specific person. The link is locked to a single service that you choose, expires on a date that you choose (up to a year out), and burns the moment the invitee books their slot. It bypasses your public booking page entirely: the invitee never sees your other services, never sees a service picker, never has to type their name and email, and gets a clean, single-purpose page that simply offers them slot times and a confirm button. Use it for VIP clients, post-consultation follow-ups, second-meeting bookings after a successful intake, gifted sessions, sponsor-paid sessions, partner-network introductions, or any case where the prospect is named and the relationship is already established.

The module is open to every tenant on every tier (Basic and Premium). There is no gate on the feature itself. Some adjacent features (the AI document summary at booking time, runtime translation of the invitee page into the eight non-EN-FR languages) inherit their Premium gating from the underlying Bookings module, but the Personal Invites surface itself works the same on both tiers.

What a personal invite is NOT

  • It is not a discount code. Discount codes (in the Discounts sidebar entry) are typed by the prospect on the public booking page and can be reused by anyone with the code. A personal invite is one specific person, one specific link, one use, then gone.

  • It is not a calendar invite. The invitee has not yet picked a time when you send the link. They pick the time on their landing page, and only then does the platform create the booking, send the calendar invite, and burn the token.

  • It is not a recurring link. One invite equals one booking. If a client needs to book multiple sessions, send multiple invites (each one independently expires and tracks separately).

  • It is not a team invitation. Inviting a teammate to join your tenant happens under Settings, Team. Personal invites are strictly client-outreach.

  • It is not a payment link. Stripe handles the payment for paid services at the moment the invitee picks their slot. If you want to send a one-off bill instead of a session, use Single Bills (a separate module).

Where the module sits in your workflow

The typical sequence is: a prospect contacts you outside the platform (email, phone, referral, in-person introduction); you decide they should book a specific service (a 30-minute consultation, a 60-minute second meeting, a paid follow-up); you open Personal Invites in the dashboard sidebar; you send them a named invite locked to that service; they receive an email, click through, pick a time that suits them, and the booking lands on your dashboard and your calendar exactly as if they had used the public booking page. The difference is that you control the relationship: only people you have personally invited can use the link, the link works once, and you can rescind or extend it at any time before they book.

Prerequisites before sending your first invite

Personal Invites is downstream of four other platform surfaces. Before you send your first invite, make sure these are in place. The next four sections walk through each one briefly; full documentation lives in the Bookings chapter.

  1. Services. You MUST have at least one active service before the Send-an-invite form is usable. If you have no services, the form shows a friendly empty state telling you to create one in Services first. This is the most common reason a brand-new tenant hits Personal Invites and gets stuck.

  2. Stripe Connect. Required ONLY for paid invites (a paid service with no discount, or a discounted service whose net price is still above zero). Free services and free-flipped invites (Make this session free) work without Stripe. If you try to send a paid invite without Stripe connected, the platform refuses creation with a clear error pointing you to Settings, Payments.

  3. A connected calendar (Google or Microsoft 365). Strongly recommended. Without a connected calendar, the slot picker on the invitee's landing page only avoids conflicts with existing platform-side bookings; it does NOT know about meetings on your personal calendar, court dates, lunch with a colleague, or anything else outside the platform. Connect a calendar so the invitee never picks a slot that collides with something you already have scheduled.

  4. Off Days, if relevant. Specific dates you want blocked (a holiday, a vacation week, a personal day) belong in Off Days. The invitee slot picker respects them automatically. You do not need to set Off Days to send an invite, but they prevent invitees from picking a date you cannot actually honour.

Note: If you have just signed up and only want to walk through the platform, you can create a single free service (price set to $0), set a one-line weekly availability, and use Personal Invites to send yourself a test invite. The Stripe and calendar requirements only bite when you start charging real money or coordinating around real-world conflicts.

Set up services first

A personal invite is locked to ONE service. The service must exist before you can pick it from the form dropdown. If you have not created any services yet, open Services from the dashboard sidebar (under the Bookings module) and create at least one. The Bookings chapter has a comprehensive Services section walking through every field: name, duration, price, currency, meeting modes (online and in-person), the optional CICC consultation agreement attachment, the per-member assignment in Team Mode, and the active or archived flag.

Which services appear in the invite picker

  • Active services only (the green Active badge on the Services list). Archived services do not appear.

  • Non-deleted services only. Services soft-deleted through the Services page are excluded.

  • Public services only. Internal-only services (those auto-seeded for Service Agreement negotiation flows, for example) are hidden from the invite picker. They are managed exclusively by the Service Agreements module.

  • All formats are eligible: live appointments (the default), written consultations (where applicable), and Q&A sessions all support personal invites.

  • In Team Mode, every service appears regardless of which member owns it. The booking that results lands on the owning member's calendar (and on the per-member dashboard view if you have one filtered).

Important: If you archive or delete a service AFTER sending an invite for it, the invite stops working. The invitee sees a friendly 'service is no longer available' card and cannot book. The platform does NOT auto-cancel the invite or auto-notify the invitee. If you must archive a service that has outstanding invites, send those invitees a courteous email and either create a replacement service plus a new invite, or refund any expected gesture.

Briefly: connecting Stripe (for paid invites)

Paid personal invites (a paid service with no discount, or a paid service with a Fixed-amount discount whose net is still above zero) need Stripe Connect to be set up on your tenant. Free services and free-flipped invites (Make this session free) skip Stripe entirely. The Bookings chapter has the full Stripe Connect walkthrough; here is the short version.

  1. Open Settings from the top-right gear icon. Find the Payments card.

  2. Click 'Connect Stripe'. You are redirected to Stripe's hosted onboarding to either sign in to an existing Stripe account or create a new one. Funds settle directly to YOUR bank account; the platform never holds your money.

  3. When Stripe finishes its onboarding, you land back on the Settings page with a green Connected badge plus a Manage on Stripe link.

  4. From this point on, paid personal invites work. Until Stripe is connected, the Send form will refuse a paid invite with a clear error message that links to the Payments settings.

Note: Per-tenant platform commission is the same whether the booking arrives through the public page or through a personal invite. On Basic tier the platform takes a tiered 1% on the first $5,000 CAD of monthly Stripe-processed volume and 0% above the cap. On Premium tier the platform fee is always 0%. The booking-page surcharge and the personal-invites surcharge (configured separately in Settings, Payments) are tenant-charged, independent of platform commission, and applied to the discounted price for invite-driven bookings.

Briefly: connecting your calendar (Google or Microsoft 365)

Connecting at least one calendar transforms the invitee's slot picker from naive (only knowing about platform-side bookings) to honest (knowing about everything on your calendar). Without a connected calendar, an invitee can pick a slot that collides with a meeting outside the platform, leaving you double-booked. With a connected calendar, the platform reads your busy intervals in real time and hides the colliding slots before the invitee ever sees them.

Google Calendar

Open Profile (top-right popover, your headshot). Find the Calendars card. Click 'Connect Google Calendar'. You are redirected to Google's OAuth consent screen. Approve the permissions (read busy times, create and update events on your behalf). On return, the card shows your connected Google account email plus a green status dot. From this point on, every booking and personal invite redemption creates a real calendar event on your Google calendar (with Google Meet auto-created on online bookings), and the platform reads busy intervals from your Google calendar when computing slot availability.

Microsoft 365 Outlook Calendar

Same place in Profile. Click 'Connect Outlook Calendar'. You are redirected to Microsoft's OAuth consent. The platform supports both personal Microsoft accounts and Microsoft 365 work or school accounts. On return, the card shows your connected Microsoft account email plus a green status dot. From this point on, bookings on Microsoft-primary calendars get Teams meetings auto-created (when the underlying account has a Teams Business license) and the platform reads busy intervals via Microsoft Graph.

Note: Each member can connect up to two calendars (a primary plus a secondary, cross-provider or same-provider). Bookings write to the primary; busy intervals are merged from both. If you have separate work and personal calendars, connect both so the invitee never picks a slot that conflicts with either.

Important: If your calendar connection ever shows a 'Reconnect required' banner (yellow background, with a Reconnect button), click it promptly. A disconnected calendar means the platform falls back to naive slot computation and the next invitee may double-book you.

Briefly: Off Days

Off Days is the second sidebar entry inside the Personal Invites module (the actual feature lives at the Bookings level and applies to everything that consumes your availability). It lets you mark specific dates as not bookable, regardless of your weekly availability pattern. Use it for statutory holidays (Canada Day, Christmas Day, Family Day, etc.), vacation weeks, sick days, professional development days, court dates that take a full day, or any other date you do not want any invitee or public visitor to be able to pick.

How to add an Off Day

  1. Open Off Days from the Personal Invites sidebar (or from the Bookings sidebar; same page).

  2. Click 'Add an off day'. Pick a date with the date picker. Add an optional reason note (visible only to you; useful for remembering why you blocked it).

  3. Click Save. The date is added to the list, sorted chronologically with the soonest at the top. Past dates auto-hide after a few days.

  4. To remove an Off Day before it occurs (you changed your mind, the holiday was rescheduled), click the trash icon on its row. Past Off Days can be removed too; the platform just hides them from the default view after they pass.

Note: Off Days apply to ALL services and ALL invites. There is no per-service Off Day. If you want to block a date only for one service, the workaround is to remove that service's day-of-week from your weekly availability for that one date by setting an Off Day, then re-add the service to a different date.

Note: In Team Mode, each member has their own Off Days (the Viewing dropdown at the top of the page selects whose Off Days you are editing). An Off Day for one member does not block other members; the platform applies the right per-member Off Days when computing each member's availability.

Opening the Personal Invites module

Personal Invites lives in the dashboard sidebar with its own module section. The sidebar entry is labelled 'Personal Invites' and uses a paper-plane icon. Click it to land on the module's home page, which contains the Send form at the top and the list of all invites you have ever sent below.

Who can open the module

The Personal Invites module is available to Owner and Admin roles. Staff cannot see or manage invites, because this is a client-outreach surface (sending a named invite is a relationship action, not a calendar-keeping action). This matches the visibility model of the main Bookings list. If you are a staff member who needs to send an invite, ask your Owner or Admin to send it on the client's behalf, or to promote you to Admin in Settings, Team.

What you see on the module page

  • A page title 'Personal invites' with a one-line description of what the module does.

  • A 'Send a personal invite' card containing the form (Service, Invitee name, Invitee email, Expires on, Discount block, Personal note, Send button).

  • An 'Invites' list card below the form, with a count in the title (Invites (12), Invites (0), etc.) and one row per invite you have ever created.

  • The list shows every invite regardless of status (pending, booked, expired, cancelled). Filters and search are not yet provided; the list is intended to stay short because most tenants send a handful at a time, not bulk batches.

The Send-an-invite form, field by field

The Send form is a single-column layout with five labelled inputs plus a conditional Discount card. Each field is required unless the label explicitly says (optional). The Send button at the bottom validates client-side first, then submits to the server. Both sides validate identically; the server is the authority.

Field summary

  1. Service: a dropdown of your active, non-internal services. The first one is pre-selected.

  2. Invitee name: free text, required.

  3. Invitee email: email format check (a@b.c), required.

  4. Expires on: a date picker, defaults to 30 days from today, minimum 1 day in the future, maximum 365 days.

  5. Discount (optional): three radio choices (None, Fixed amount off, Make this session free). Hidden entirely when the picked service has a zero price.

  6. Personal note (optional): a free-text textarea, up to 2000 characters.

Note: After a successful send, the form clears the invitee name, email, personal note, expiry date (back to default), and discount block. The service selection is preserved on purpose: administrators frequently send a batch of invites for the same service (a group of referrals all booking the same 30-minute consultation, for example) and clearing the service every time would slow them down.

Picking the service

The Service dropdown lists each eligible service with three pieces of information separated by middle dots: name, duration, and price. For example, '15-Min Triage, 15 min, $99.00' tells you the service is named '15-Min Triage', lasts 15 minutes, and costs $99 (the currency code from the service row). Free services show only the name and duration (no price line).

Changing the service mid-form resets the Discount block to None and clears any typed discount amount. This is intentional: a fixed-amount discount valid for one service may exceed another's price, and silently carrying the discount across a service swap would be a confusing source of bugs.

Note: If you do not see the service you expect in the dropdown, check three things: is the service Active (not Archived) on the Services page; is the service public (Internal-only services are hidden); has the service been soft-deleted. Open Services from the Bookings sidebar to fix any of these.

Invitee name and email

The invitee name is the friendly name used in the email greeting and on the landing page hero card (the line that reads 'Hi <name>, ...'). It is also the name the platform will pre-fill into the booking form on the invitee's side, so the invitee never has to type their own name. Use the name the invitee would expect to see addressed to themselves (first name, full name, or honorific plus surname; your call).

The invitee email is where the invitation is sent. It also becomes the locked email on the booking form (the invitee cannot change it). Make sure it is the address the invitee actually reads. The platform normalises it to lowercase before storing; case-insensitive duplicates are allowed (you can send a fresh invite to the same address; each invite is independent and tracks its own status).

Important: The platform does NOT verify deliverability before sending. If you typo the email (jhon@example.com instead of john@example.com), the email goes to the wrong address and the invitee never sees it. The send is reported as successful as long as SMTP accepted the handoff. Double-check the address before clicking Send.

Expires on

Every invite has an expiry date. Once the date passes (in UTC, end-of-day), the link stops working and the invitee sees a friendly 'Invitation expired' card. The default is 30 days from today, which balances the typical 'book within a couple of weeks' expectation with a buffer for travel or holidays. You can pick anything from tomorrow (minimum 1 day in the future) up to one year from today (maximum 365 days, to prevent a typo of '2099-01-01' from creating a functionally-immortal link).

Picking the right expiry

  • Short (7-14 days) for hot leads who said they would book that week. Creates gentle urgency without being pushy.

  • Medium (30 days, the default) for most warm referrals. The invitee has a month to find a slot that fits their calendar.

  • Long (60-180 days) for second-meeting invitations after a successful first consultation, or for sponsored sessions where the invitee may want to coordinate with a third party before booking.

  • Very long (one year) only when you want the invite to function as a perpetual 'whenever you are ready' offer. Rare but legitimate (a graduating client thanking you for help, with an open invitation for a renewal consultation).

Note: If the invitee misses the deadline, you can extend the expiry from the invite's row in the list (Extend button), pushing it forward by any number of days up to the same 365-day cap. The original link continues to work; no fresh email is sent automatically, but you can pair the extension with a Resend if you want the invitee notified.

The Discount block (introduction)

The Discount block is a per-invite optional offer that lets you adjust the price the invitee will pay, without changing your underlying service price. It is hidden entirely when the picked service is free (no Discount block appears for $0 services because there is nothing to discount). For paid services, the block shows three radio choices in a bordered card titled 'Discount (optional)'.

The three modes

  1. No discount: the invitee pays the full service price (the default).

  2. Fixed amount off: you type a dollar amount; the invitee pays the service price minus that amount.

  3. Make this session free: a complete gift; the invitee pays nothing, and Stripe is bypassed entirely at booking time (no Stripe Checkout step).

The chosen mode is snapshotted on the invite row at send time. This means the price the invitee sees stays stable even if you change the underlying service price afterwards. The snapshot is also what governs the price at booking time, what shows on the email, and what shows on the landing page. There is only one source of truth (the invite row) so the three surfaces cannot drift.

Note: Discounts apply only to the service price. The tenant-charged surcharge (Settings, Payments, Personal Invites admin fee, if you set one) is computed AFTER the discount, on the reduced price. The platform commission (Investatech's piece, taken via Stripe's application fee) is also computed on the reduced price. Free-flipped invites skip both the surcharge and the platform commission because no money changes hands.

Fixed-amount discount in detail

When you pick 'Fixed amount off', a dollar input appears immediately below the radio. Type the amount you want subtracted from the service price (for example, 50 to give $50 off a $99 service). The input accepts up to two decimal places (50 or 50.00 or 49.75 are all valid). Below the input, a live helper line shows the math: 'Service price: $99.00. Invitee will pay $49.00.' so you can sanity-check the numbers before sending.

Rules and limits

  • The amount must be greater than zero. Typing 0 leaves you in No-discount territory; the form rejects the send.

  • The amount must be strictly less than the service price. Equal-to-price or above-price is rejected with a clear message: 'Discount can't equal or exceed the service price. Use "Make this session free" instead.' This is enforced both in the form (client-side) and on the server.

  • Fractional cents are rejected (the input itself blocks more than two decimal places). Negative numbers are rejected. Non-numeric input is rejected.

  • The dollar amount is stored in integer cents on the invite row, so $49.75 is stored as 4975. There is no rounding loss.

What if the service price changes after sending

If the service price drops below the promised discount after the invite is already in flight, the invitee gets the better deal. For example: you sent an invite for a $99 service with $50 off (invitee was promised $49). You later lower the service to $40. The invitee redeems. The platform honours the absolute $50 promise (clamped to zero, since the service is now cheaper than the discount), and the invitee gets a free session. The absolute discount the tenant promised always wins.

If the service price rises above the original after the invite is in flight, the invitee still gets the originally-promised price (gross minus discount at the snapshot moment). For example: you sent an invite for a $99 service with $50 off (invitee was promised $49). You later raise the service to $150. The invitee redeems. The platform applies the snapshotted $50 off to the now-$150 price, so the invitee pays $100. They get a worse deal than the original promise of $49 because the platform locks the absolute discount, not the absolute net. If you want net-stable promises across price changes, send a fresh invite after the price change.

Make this session free (the gift mode)

The third radio choice flips the entire session to a free gift. The invitee pays nothing. The discount amount input disappears (it cannot be combined with the free flag; the radios are mutually exclusive). The behaviour at booking time is special: Stripe Checkout is bypassed entirely. The invitee picks a slot, fills the form, clicks Confirm, and the booking is created immediately with no payment step. No payment intent is created, no commission is paid to the platform, no surcharge applies.

When to use it

  • A complimentary follow-up after a paid consultation that uncovered a question the original session did not have time for.

  • A VIP introduction (a referral from a network partner, a journalist, a community organisation) where you want the relationship to start without a transaction.

  • A gifted session as part of a marketing campaign, a charity donation, or a continuing-education obligation.

  • A goodwill gesture after a service failure (a missed appointment on your side, a delayed file transfer, etc.).

What the invitee sees

On the invitation email, the price line is replaced with 'Free (gift from <your business name>)' in green. On the landing page, the hero card shows the same emerald block instead of the original-price line. There is no strikethrough, no math, no 'minus $X' line, no 'you pay $0' line; just the friendly Free label and the gift attribution. The invitee picks a slot, fills the form, and lands on the success page immediately with no payment step.

Important: A free-flipped invite still produces a real booking on your calendar, a real entry in the dashboard list, real meeting reminders, and (if the service is set to require an agreement) a real CICC consultation agreement signature. The only thing skipped is the payment flow. Treat the gifted session as a full appointment with full preparation; the invitee experiences it as one.

Personal note (optional)

The Personal note is a free-text message that gets shown TWICE: once on the invitation email (as a quoted block under the service details) and once on the invitee's landing page hero card (in a coloured side-stripe styled like a sticky note). It is the place to say why you are extending the invite, what you discussed when you spoke, what to prepare for the meeting, or anything else specific to that one invitee. It is bilingual-neutral; whatever you type is shown verbatim.

Rules and rendering

  • Maximum 2000 characters (roughly two paragraphs of prose).

  • Line breaks are preserved (the renderer respects whitespace and emits a paragraph break for each blank line you type).

  • HTML is NOT rendered. If you type a URL, the invitee sees the URL as plain text (no clickable link). Links inside the note are intentional; the invite's primary call-to-action is the Book button, and competing links would dilute that.

  • Leave it blank if you have nothing specific to say. The hero card just hides the note section in that case (it does not show an empty box).

Note: The note is shown to the invitee only. It is NOT stored on the resulting booking row (after redemption, the note is preserved on the personal_invites row but is not surfaced on the booking detail page). If you want the note to follow the relationship past the redemption, paste a copy into the Meeting Notes module after the meeting.

Sending the invite

Click 'Send invite'. The button shows a loading spinner while the platform validates the form, creates the invite row in the database (with a 32-byte random URL-safe token), and sends the email. The whole round-trip is typically under two seconds on a warm function and under five on a cold start.

What happens on success

  • A green success pill appears under the form: 'Invite sent to <email>.'

  • The new invite is prepended to the Invites list below (sorted newest-first), with the right status badge (Pending) and the snapshotted discount pill if applicable (a green 'Free (gift)' for free invites, or 'minus $X' for fixed-amount discounts).

  • The form clears (except for the service selection, which stays for batch sends).

  • The invitee should receive the email within a couple of minutes. If they do not, see the Troubleshooting section.

What happens on failure

A red error pill appears under the form with the specific error: validation failure (missing field, bad email format, discount overrun), Stripe not connected when a paid invite is required, the picked service is no longer available, or a server error. The form retains the values you typed so you can correct the problem and click Send again.

Partial success: invite created but email failed

If the database write succeeded but the SMTP send failed (rare; typically a transient Siteground outage or a recipient mail server that rejected the message), the success pill is amber instead of green and reads: 'Invite created for <email>, but the email didn't send. You can share the link manually from the list below.' The invite IS valid; you can grab the link from the new row's Copy button and send it through another channel (text message, WhatsApp, your own email client).

What the invitation email looks like

The email comes from 'noreply@rcicapp.ca' with a from-name of '<your business name> via RCIC App'. The reply-to is set to your business email so the invitee can hit Reply and reach you directly (the noreply mailbox does not accept incoming mail). The subject line reads: '<your business name> has invited you to book, <service name>'. The body is a clean, brand-themed HTML email that mobile and desktop email clients both render correctly.

Body anatomy

  1. Branded header: your business logo (if you uploaded one in Settings, Branding) or your business name in your brand colour. The header links to your website if you have one configured.

  2. Greeting: 'Hi <invitee name>,'

  3. Introduction line: '<Your business name> has invited you to book an appointment:'

  4. Service summary card: service name, duration in minutes, and the price block (the price block branches based on the discount snapshot; see the section below).

  5. Personal note (if you typed one): in a coloured sticky-note style block, labelled 'A PERSONAL NOTE' in small uppercase.

  6. Call-to-action button: 'Book your appointment' in your brand colour, large, centered. This is the link the invitee clicks.

  7. Expiry reminder: 'This invitation expires on <weekday>, <month> <day>, <year>. The link is for you only and can be used once.'

  8. Fallback URL: a plain-text version of the link in case the button does not render (some corporate email gateways strip HTML buttons).

  9. Footer: a small 'Powered by Investatech' line linking back to investatech.com, plus the platform unsubscribe disclaimer.

Price block: the three branches

  • No discount, paid service: a single line, 'Price: $99.00' (using the service's currency).

  • Fixed-amount discount: three lines, 'Original price: $99.00' (with the original strike-through), 'Discount: minus $50.00' (in green), and 'You pay: $49.00' (in bold). The math is shown explicitly so the invitee can see how the discount was calculated.

  • Make this session free: a single line, 'Price: Free (gift from <your business name>)' in green. No price math is shown because no price math applies.

  • Free service (the underlying service is $0): a single line, 'Price: Free' (no gift attribution because the service itself is free, not a discounted offer).

Note: The email is English-only on the body (the platform-side template does not currently translate per-invite). The branded chrome (your business name, your logo, your service name, the personal note) is shown verbatim regardless of locale, so if you typed a French note it renders in French inside the English-templated email. Translation of the email body to French is a follow-up that will ship in a future release.

The invitee landing page

When the invitee clicks the email button, they land on a public URL of the form 'https://rcicapp.ca/invite/<token>'. The token is the 32-byte random string the platform generated at send time; it functions as both the identifier and the access credential. No login is required. The page is fully self-serve.

Page anatomy

  1. Branded header (your logo or name, in your brand colour) with an optional language picker on the right (Premium tenants with multilingual booking enabled get a picker for up to ten languages; Basic tenants get English and Quebec French).

  2. Hero card with greeting ('Hi <invitee name>,'), the introduction ('<Your business name> has invited you to book:'), the service card (name, duration, price block), the personal note (if you typed one, in a sticky-note styled block), and the expiry reminder ('This link expires on <date>').

  3. Booking card below the hero. This is where the invitee picks a slot and confirms the booking. The booking flow takes over from here and is identical to the public booking page.

  4. Below the booking card, a small ghost-style link offering 'Need a different service? Visit the public booking page' as an escape hatch for invitees who realise they want a different service than the one you sent them.

Locale handling

The page respects your tenant's default client-page language (set in Settings, Booking page languages). If you have Premium plus additional languages enabled, the language picker in the top-right appears and the invitee can switch. The page chrome translates immediately; the service description, your personal note, and the email body itself remain in the language you typed them in.

Note: The landing page is publicly accessible to anyone with the token URL. Treat the URL as a one-time-use bearer token: do not paste it into public-facing documents, social media, or chat rooms. If the URL leaks, the first person to use it burns the invite (each invite is single-use). For a leaked invite, cancel the original from the list and send a fresh one to the right invitee.

The invitee's booking flow

Once the invitee is on the landing page, the booking flow takes over. It is identical to the public booking page experience, with three small differences: the service is locked (the invitee cannot pick another), the invitee's name and email are pre-filled and locked (matching what you typed when sending), and the price block reflects the discount snapshot (so the invitee never sees the gross price as a surprise).

Step 1: pick a slot

The slot picker shows a calendar view with available dates (greyed out for off days, weekends if you do not work weekends, and days where every slot is taken). The invitee picks a date, sees the available time slots for that date (computed in real time from your weekly availability minus Off Days minus existing bookings minus your connected-calendar busy intervals), and picks a slot. Slot lengths are determined by the service's duration; a 15-minute service offers slots in 15-minute increments within your availability windows, with a 15-minute buffer enforced before and after every existing booking.

Step 2: fill the form (or just confirm)

After picking a slot, the invitee sees the booking form with name and email pre-filled and locked. The remaining fields are: phone (optional, but recommended for follow-up), notes (optional; what the invitee wants to discuss), meeting mode (if the service supports multiple, like online or in-person), and the CICC consultation agreement acceptance (if the service requires one). For paid bookings, Stripe Checkout opens on submit. For free or free-flipped bookings, the booking is created immediately.

Step 3: success

On success, the invitee lands on a confirmation card showing the booking reference, the scheduled time in their browser timezone, your business name, and what to expect next (an email confirmation plus a calendar invite if their calendar provider auto-accepts). For paid bookings, the receipt is available in Stripe Checkout's own confirmation flow. The invite token is burned at this point; the invitee cannot re-use the link, even if they try to navigate back.

What happens behind the scenes on redemption

When the invitee successfully confirms their slot, the platform runs a sequence of side effects. Understanding the sequence helps you debug edge cases (a missing calendar event, a missing reminder, a missing email) and also helps you understand why a failed redemption leaves a specific kind of residue.

Free or free-flipped booking sequence

  1. Server validates the slot is still available (someone else may have booked it during the picker step).

  2. Server creates the booking row with status=confirmed and payment_status=free.

  3. Server burns the personal_invites row (sets redeemed_at to the current timestamp, sets redeemed_booking_id to the new booking's id). From this moment, the invite link returns 'Invitation already used'.

  4. Server creates a calendar event on your connected calendar (Google or Microsoft), with the invitee as attendee. For online bookings, a Google Meet or Microsoft Teams link is auto-created and stored on the booking row.

  5. Server sends a confirmation email to the invitee (with the meeting link if applicable, the calendar attachment, and the CICC consultation agreement PDF if the service required one).

  6. Server sends a notification email to you (the same details, plus any notes the invitee typed on the booking form).

Paid booking sequence

  1. Server validates the slot is still available.

  2. Server creates a Stripe Checkout Session with the discounted price (line_item.unit_amount equals service_price minus discount; admin fee added as a separate line if you configured one).

  3. Server creates the booking row with status=pending_payment, awaits Stripe webhook confirmation.

  4. The invitee is redirected to Stripe Checkout, pays, and is redirected back to the success page. Stripe fires the checkout.session.completed webhook to the platform.

  5. Server processes the webhook: flips status to confirmed, stamps payment intent details on the booking row, then runs steps 4 to 6 from the free sequence above (burn the invite, create the calendar event, send the two emails).

  6. If the invitee abandons Stripe Checkout (closes the tab, never pays), the booking row stays at pending_payment until the Stripe session expires (30 minutes by default). The invite is also burned at the moment Checkout opens, so an abandoned payment does NOT release the invite back to pending. The tenant can re-create a fresh invite if needed.

Important: The invite-burn-on-Checkout-open (not on payment) is a deliberate design choice. It prevents the same invitee from opening Stripe Checkout in five tabs and racing to pay, which would create five booking rows. If your invitee abandons payment by mistake, you can create a fresh invite from your dashboard within seconds.

The Invites list

Below the Send form, the Invites list shows every invite you have ever sent, newest first. Each row carries enough information to identify the invitee, the service, the current status, and the relevant action buttons for the row's state. The list title shows a count (Invites (12)) so you can see at a glance how many invites you have on file.

Per-row layout

  • Top line: invitee name (in bold), invitee email, status badge (Pending in amber, Booked in green, Expired in grey, Cancelled in red).

  • Second line: service name, optional discount pill (green 'Free (gift)' for free-flipped invites, green 'minus $X' for fixed-amount discounts; no pill on no-discount invites), and a status detail (expires on <date> for Pending, expired on <date> for Expired, booked on <date> for Booked).

  • Right side: action buttons appropriate to the row's status (see Row actions below).

Sort and search

The list is sorted by creation date, newest first. There is no manual sort, no per-column sort, and no search box. The list is intended to stay short because most tenants send a few invites at a time, not bulk batches. If your list grows large enough to be inconvenient, the right pattern is to start cancelling old Pending invites (an unbooked invite that has not been redeemed in 60 days is probably not coming back) so the active list stays manageable.

Invite status lifecycle

Every invite is in exactly one of four states at any time. The state is computed from a small set of timestamp columns on the row (cancelled_at, redeemed_at, expires_at). Understanding the state machine helps you interpret the list and decide what to do next.

Pending (amber badge)

The invite has been sent but the invitee has not yet booked. The expiry has not yet passed. The invite is still valid. The row offers four actions: Copy link (grab the URL for manual sharing), Resend (re-fire the email), Extend (push the expiry out), Cancel (kill the invite immediately).

Booked (green badge)

The invitee has redeemed the link and the booking has landed. The row shows the booking date and offers a single action: a 'View in bookings' link that jumps you to the Bookings list (filtered or scrolled to the resulting booking). The invite itself is immutable from this point on; you cannot extend, resend, or cancel a Booked invite (the booking that resulted is the audit trail).

Expired (grey badge)

The expiry date has passed without redemption. The link no longer works (the invitee sees an 'Invitation expired' card). The row offers a single action: Extend (push the expiry out to a new date, reviving the invite). Extending an Expired invite does NOT auto-notify the invitee; the original email link continues to work after extension, and the platform leaves it to you to decide whether to also Resend a fresh notification.

Cancelled (red badge)

You cancelled the invite from its row. The link no longer works (the invitee sees an 'Invitation cancelled' card). There is no Uncancel action; once cancelled, the invite stays cancelled forever. If you cancelled by mistake, send a fresh invite.

Row actions in detail

Pending rows have four actions; Expired rows have one (Extend); Booked rows have one (View in bookings); Cancelled rows have none. Here is what each action does and when to use it.

Copy link

Copies the invite URL to your clipboard. A small 'Copied!' badge briefly replaces the button label so you know it worked. Use this when you want to share the link through a different channel (text message, WhatsApp, your own email client, a private direct message on a referral platform) rather than relying on the platform-sent email. If your browser denies clipboard permission, a fallback prompt opens with the URL pre-selected so you can copy it manually.

Resend

Re-sends the invitation email to the same address using the same token. Use this when the invitee reports they did not receive the original email (check spam folder first), or when you have just extended the expiry and want the invitee notified of the new deadline. The resent email contains the snapshotted discount block (so a discounted invite resent stays discounted). A small 'Email resent.' confirmation appears under the row on success, or a red error if SMTP rejected the send.

Extend

Pushes the expiry date out to a new date you pick. Clicking Extend reveals an inline date picker below the row, pre-filled with the current expiry. Pick a new date (minimum 1 day in the future, maximum 365 days from today), click Save, and the platform updates the invite's expiry. The original link continues to work; no email is sent automatically. Pair with a Resend if you want the invitee notified. Extend works on both Pending and Expired invites (effectively reviving an Expired one).

Cancel

Kills the invite immediately. A confirm dialog asks 'Cancel this invite? The recipient will no longer be able to book with this link.' On confirm, the platform stamps cancelled_at on the row, the row flips to the Cancelled state, and the invite link starts returning 'Invitation cancelled' to anyone who clicks it. There is no Uncancel; if you cancelled by mistake, the right move is to send a fresh invite (which will have a fresh token, a fresh expiry, and a fresh email).

View in bookings (Booked rows only)

A maroon link on Booked rows that jumps you to the Bookings list. The booking that resulted from the invite carries the same client name and email; you can find it by searching or by sorting bookings by date.

Note: Resend and Cancel are deliberately separate actions, not a single 'Re-send or cancel' confirmation. If you want to cancel and immediately send a fresh invite (because the original email had a typo in the discount amount, for example), Cancel the old one first, then submit the Send form again with the corrected values.

Admin fees and platform commission on invite bookings

When an invite is redeemed for a paid booking, three layers of fee math apply, in this order: the discount, your admin fee (if you set one), and the platform commission. Understanding the order helps you sanity-check your Stripe payouts and your reports.

Worked example

  1. Service price (gross): $99.00.

  2. Personal invite discount (Fixed amount off): minus $50.00.

  3. Discounted base: $49.00. This is what the invitee sees on the landing page and the email.

  4. Admin fee (if you set one in Settings, Payments, Personal Invites admin fee, percentage type, 5%): $49.00 times 5% equals $2.45. Admin fee applies to the DISCOUNTED base, not the gross.

  5. Total Stripe charge: $49.00 plus $2.45 equals $51.45.

  6. Platform commission (Basic tier, tiered 1% on the first $5,000 monthly): $51.45 times 1% equals $0.51 (rounded). Premium tier pays $0.00.

  7. Your net (Basic): $51.45 minus $0.51 equals $50.94. Stripe also charges its own processing fee (typically 2.9% plus $0.30 in Canada); that comes out of your $50.94 on the Stripe side, separate from the platform's piece.

Free-flipped invites

When the invite is free-flipped (Make this session free), all three layers go to zero: no discount math (there is no discount; the whole price is gifted), no admin fee (the surcharge is computed on the charge, and there is no charge), and no platform commission (the platform takes nothing on a gift). The booking lands with payment_status set to free and amount_cents set to zero. Your Stripe dashboard never sees the transaction.

Configuring the personal-invites admin fee

The personal-invites admin fee is configured separately from the booking-page admin fee. You can set a VIP-style no-surcharge on named invites while still charging the booking admin fee on public booking page traffic, or the reverse. Open Settings, Payments, find the 'Personal Invites' card, pick percentage or flat, type the value, save. The fee applies from the next invite redemption forward; in-flight invites do not retroactively recompute.

Interactions with other modules

Personal Invites does not live in isolation. Several other modules either depend on it, interact with it, or are deliberately partitioned from it. Here is the map.

Bookings

A successful invite redemption produces a regular booking row in the Bookings module. The booking is indistinguishable from a public-page booking except that its row carries a back-reference to the invite (so the audit trail is complete). The booking shows up in every booking-side surface: the dashboard list, the per-day calendar view, the Meeting Notes editor after the meeting, the reschedule and cancel flows, every booking-related cron and email.

Services

Services are upstream. Every invite locks to one service. If you delete or archive a service after sending invites for it, those invites stop working. The platform does not auto-clean those invites; you are responsible for cancelling them and offering replacements if appropriate.

Service Agreements (Premium)

The Service Agreements module uses the Personal Invites mechanism internally for one specific flow: the negotiation-meeting invitation that happens when a Service Agreement is in the decline-negotiation state. Those internal invites are tagged on the row (sa_party_id is set), hidden from the regular Personal Invites list, and managed exclusively by the Service Agreements module. You will never see them in your Invites list and you cannot manually create one through the Send form (the picker filters out the internal-only Negotiation services that those invites use). This is a deliberate partition: Service Agreement pricing is a different beast based on Global and Local templates with tenant overrides, and the personal-invite discount feature does NOT flow into agreement pricing.

Stripe Connect

Stripe is required for paid invites (a paid service whose discount does not zero out the price). Free services and free-flipped invites skip Stripe entirely. Connect Stripe once from Settings, Payments; the platform reuses the connection across Bookings, Personal Invites, Events, and Single Bills.

Calendars (Google, Microsoft 365)

Connecting a calendar is recommended but not strictly required. Without a connected calendar, the invitee's slot picker only avoids platform-side booking conflicts; with a connected calendar, the picker reads your real busy intervals and hides conflicting slots before the invitee sees them. The connection is per-member in Team Mode; each member's invites use their own calendar.

Off Days

Off Days you set in the Off Days sidebar entry (or the equivalent under Bookings) are respected by the invitee's slot picker automatically. You do not need to do anything else; setting an Off Day immediately removes that date from every Pending invite's slot list.

Discounts (booking-side promo codes)

Booking-side discount codes (the Discounts sidebar entry; typed by the prospect on the public booking page) and personal-invite discounts (the Discount block on the Send form) are independent. A personal-invite redemption can ALSO carry a discount code if the invitee types one on the booking form during redemption; both reductions are applied in order (booking-side code first, personal-invite discount second). In practice it is rare for an invited client to also have a promo code, but the platform handles the combination correctly if it happens.

Troubleshooting

The invitee says they did not receive the email

  1. Ask them to check their spam, junk, and promotions folders. The email comes from noreply@rcicapp.ca which is sometimes flagged by aggressive spam filters on the first delivery to a new recipient.

  2. Verify the address on the invite row matches what the invitee actually uses. A typo (jhon vs john) is the most common cause.

  3. Click Resend on the invite row. The platform re-fires the same email. A successful resend pops a green confirmation; a failure pops a red error with the SMTP message.

  4. If multiple resends fail, use Copy link to grab the URL and share it through a different channel (text message, WhatsApp, your own email client).

The invitee clicks the link and sees an error card

  • 'Invitation not found' means the URL is malformed (the invitee mistyped it) or the invite was never actually created. Re-check the row in your list.

  • 'Invitation expired' means the expiry date passed. Click Extend on the row to push it out, then click Resend to notify the invitee of the new deadline.

  • 'Invitation already used' means the invite has been redeemed (someone clicked the link and completed a booking). Open the row's 'View in bookings' link to find the resulting booking.

  • 'Invitation cancelled' means you (or another admin) cancelled the invite from its row. Send a fresh invite to restore the offer.

  • 'Invitation unavailable, the service is no longer offered' means the service was archived or deleted after the invite was sent. Restore the service from the Services page, OR create a replacement service plus a fresh invite.

  • 'This invitation is temporarily unavailable' on a paid invite means Stripe is not connected on your tenant. Open Settings, Payments and connect Stripe; the next time the invitee clicks the link, the booking flow will work.

The invitee picked a slot but no booking landed on my dashboard

If the invite is for a paid service, the booking might be stuck at 'pending_payment' status because the invitee opened Stripe Checkout but did not complete payment. The Bookings list filter for 'Pending payment' will reveal it. Stripe holds the session open for 30 minutes; if the invitee comes back and pays within that window, the booking flips to confirmed automatically. If they abandon entirely, the session expires and the row stays at pending_payment indefinitely (you can leave it or manually cancel from the booking detail page). The invite itself is burned the moment Stripe Checkout opened, so the invitee cannot retry with the same link.

The discount on the email looks wrong

The discount block on the email and the landing page is locked to the snapshot taken at send time. If you sent the invite when the service was $99 with $50 off (showing You pay $49), and you later changed the service to $150, the invitee still sees You pay $100 (gross $150 minus snapshotted $50). To honour an updated promise, cancel the original invite and send a fresh one with the right discount on the current price.

The Discount card does not appear on the Send form

The Discount card is hidden when the picked service has a zero price. A free service has nothing to discount, so the card is suppressed to avoid confusion. If you want to offer a free session for a service that you also offer paid, the cleanest path is to set the underlying service to paid and then use 'Make this session free' on the invite (which records that this particular invitee is being gifted the session, distinct from a service that is always free for everyone).

The slot picker shows no available dates

  • Check your weekly availability under Bookings, Availability. You may have no active rules at all, or only rules on days that are entirely covered by upcoming Off Days.

  • Check the next 30 days of Off Days. If you have a vacation block that spans every weekday of the next month, the picker will rightly show no available dates.

  • Check that your calendar is not so full of external events that every slot is being filtered out. If you connected a calendar with a heavy meeting load, the platform respects every busy interval. Disconnect the calendar temporarily if you want to see what the picker would show without it.

  • Check the service's duration. A 90-minute service requires 90-minute uninterrupted gaps (plus the 15-minute buffer before and after every existing booking); long-duration services find fewer slots than short ones.

Tips and best practices

Make the invite feel personal

The Personal note is your single biggest lever for making the invite feel like a hand-extended invitation rather than a system-generated link. Take 30 seconds to type a one-paragraph note referencing the conversation you had, the referral source, or the specific question the invitee mentioned. The difference in redemption rate (the percentage of invites that actually result in bookings) between a no-note invite and a 50-word personal-note invite is significant.

Use the discount block strategically

  • Round dollar amounts (minus $25, minus $50, minus $100) feel more intentional than odd amounts (minus $23.47) and read cleaner on the email.

  • Reserve 'Make this session free' for high-trust, high-relationship cases. A free session is a memorable gift; offering it too freely dilutes its meaning.

  • Pair a discount with a personal note that references it. 'Looking forward to chatting on Tuesday. I have applied a discount on this so the consultation is on me.' converts noticeably better than a discount with no narrative around it.

  • Avoid the temptation to discount every invite. The Personal Invite mechanism by itself signals 'you matter enough to be named individually'; adding a discount on top of that is a separate compliment that should be reserved for cases where it earns its keep.

Pick the right expiry for the context

Default 30 days works for most warm referrals. Tighten to 7-14 days for hot leads where you want gentle urgency. Stretch to 60-90 days for second-meeting invitations after a longer file (your client may want to chase down government processing before booking the follow-up). Avoid one-year expiries except for true 'whenever you are ready' goodwill gestures; a one-year unbooked invite is almost always an invite the relationship lost momentum on, and the long expiry just keeps the unrequited offer in your list.

Keep the list tidy

Periodically scan your Pending list and cancel invites that are clearly not coming back (the prospect went silent, the referral fell through, the discussion took a different direction). A clean list helps you see at a glance who is genuinely in flight versus who is a stale data point. Cancelled invites stay visible in the list for audit purposes, but they no longer represent active offers.

Pair invites with Meeting Notes

After the invitee redeems and the meeting happens, click into the resulting booking from the Bookings list and capture Meeting Notes. The Meeting Notes module is a structured editor designed for capturing client identity, family members, matter context, RCIC advice, and next steps. From a Meeting Note you can hand off to Send the Intake Form (which seeds an intake submission with the client identity pre-filled) or to Make a Proposal (which seeds a Service Proposal with the same identity). The Personal Invite is the entry point of a relationship; Meeting Notes is the place where it becomes a file.

Note: If you find yourself sending personal invites to the same prospect repeatedly without redemption, the issue is usually outside the platform (the prospect is genuinely not ready to book, or the consultation does not match what they need). The platform is happy to keep sending invites, but at some point the answer is a phone call or an honest 'let me know when the time is right' email rather than another invite.