Send invite emails.
Send invites (N).
The cohort panel header has three buttons. The leftmost is Send invites (N) — N is the count of pending students. The button is disabled when N is zero (no pending students to invite).
Click it. The studio sends an HTML email to every pending student in one server call. A status banner appears below the header: “X sent · Y skipped (sent <60s ago) · Z failed.”
Friendly, HTML, single CTA.
Subject line: You’re invited to [Course Title] (§Section). The body text:
[Your name] (your.email@school.edu) has invited you to join “[Course Title]” on ij8.
Use this email address (their.email@school.edu) to sign in — your access has been pre-approved.
[Sign in to start] — a button that opens
https://ij8.ai/login?email=their.email@school.eduOn the sign-in page, click Email me a sign-in link to receive a one-click magic link.
That’s it. The student clicks the button, lands on the login page with their email pre-filled, clicks Email me a sign-in link, gets the actual magic-link email from Auth.js, clicks the magic link, and they’re in the studio with the cohort role applied.
Two clicks in two emails. Could it be one click? Yes, but only if we generated and embedded an Auth.js verification token directly. We don’t do that — it would couple us to Auth.js internals and break silently on the next provider upgrade. Two clicks is the price of a stable contract.
60-second per-recipient guard.
Each recipient has a 60-second cooldown. If you click Send invites twice within a minute, the second click skips anyone who was sent to in the last 60 seconds. The status banner reports them in the “skipped” count and lists the addresses (up to 5).
Reason: prevent accidental double-clicks from spamming students. The cooldown is server-side and per-email, so it can’t be bypassed by clicking multiple buttons fast.
If you genuinely need to resend within 60 seconds (e.g. an email bounced and you fixed it), wait the cooldown out — there’s no override.
Send icon next to a single pending row.
Each pending row has a small paper-airplane icon between the Pending sign-up chip and the trash. Click it to send (or resend) only that one student’s invitation. Same email content, same cooldown rule.
Once a student has been sent at least one invitation, the row’s subtitle changes from “Will be added on first sign-in” to “Invited 12m ago · pending sign-up.” The relative timestamp updates on every render.
Resend a single student when:
- They tell you they didn’t get it (check spam first).
- It’s been a few days and you want to nudge them.
- They mistyped their email originally and you’ve fixed it (remove the wrong row, add the right one, send).
What can go wrong, and what it means.
“Email invites are not configured.”
The studio’s SMTP credentials aren’t set on the server. Contact your admin — they need to set SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, and AUTH_EMAIL_FROM in the production environment.
Status banner shows non-zero “failed”.
The studio attempted the send, but the SMTP server rejected it. The most common cause is a malformed email — the parser shouldn’t accept those, but if a malformed address slipped through, you’ll see it in the failures list. Remove that row and try again.
Status banner shows non-zero “skipped (sent <60s ago)”.
You clicked too soon after a previous send. Wait, then click again.
Student says they got the invite but the link sends them to a “Server Not Found” page.
This is a DNS / network issue on their end, not a Studio issue. The deep link is just https://ij8.ai/login?email=… — if their DNS can resolve ij8.ai they should land on the login page fine. Have them try a different network or browser.
What students do next.
From the student’s side, the path after they receive the invite is identical to 01 / Getting started — they click the link, land on the login page, click Email me a sign-in link, click the magic link, and they’re in. The cohort role is applied automatically the moment Auth.js consumes their allowed_emails row.