An invitation creates a single-use token tied to a role and optionally a crew, mails and/or texts a branded invite, and hands back a copyable link. Accepting the link stamps the invitee's role and crew onto their account, marks the invitation accepted, and syncs them into the crew.
Also called: add a user · invite crew · send an invite · invite link · onboard an employee
- 1Add Member takes full name, email, phone and role, plus a Send Via choice of SMS / Email / Both / Link Only.
- 2POST /api/invite mints a URL-safe token, stores the invitation with a 48-hour expiry, and sends on the chosen channels.
- 3The invite URL is built from the ORIGIN of the request, so an invite sent from a tenant subdomain returns to that subdomain.
- 4The new person signs up at /sign-up?invite=<token>; /api/invite/accept verifies the session matches the claimed user, writes role + crew into their account metadata, marks the row accepted, and upserts crew_members_sync when the invite was crew-scoped.
- 5Crew leaders can invite too, but their invite is locked to worker role and their own crew — enforced server-side, not just in the UI.
Field crews often have a phone and no work email, so an email-only invite excludes exactly the people who need the app in their hand — hence SMS, both, and a raw link. The origin logic carries its own bug story in the code: invite links used to point at the platform apex, so middleware blocked the accept call with 'No organization — visit /onboarding', and even when it didn't the user landed on the apex instead of their own dashboard.
- Email-only invitations excluded field crews.
- Invite links pointed at the wrong host and failed to attach the user to the tenant.
- Every new person had to go through the owner.
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →