Skip to content

Email (Resend)

All transactional email in the system flows through one Netlify function: send-email.js, which lives in studio-website. The admin has no email function of its own — it calls this endpoint. Email is sent via Resend from hello@sitecrate.ca.

netlify/functions/send-email.js:

  • Accepts a small request body: { type, token } (plus any type-specific flags).
  • Resolves the project from the DB by token using the service-role key.
  • Builds all recipients and content server-side — never from the request body. A forged body cannot redirect the email or inject content.
  • Locks CORS to SiteCrate origins.
  • Sends through Resend.

It requires SUPABASE_SERVICE_ROLE_KEY and the Supabase URL in the function env. See Environments.

TypeFired byTrigger
intakestudio-website intake formNew intake submitted (non-blocking)
reviewsitecrate-adminStage → review (requires preview_url)
launchsitecrate-adminStage → live
feedbackstudio-website status pageClient submits feedback
approvedstudio-website status pageClient approves their site
CallerTypesNotes
studio-website intakeintakeFired after create_intake returns the token; non-blocking
studio-website status pagefeedback, approvedFired after the matching RPC write
sitecrate-admin Detail panelreview, launchFired on stage transition; calls https://sitecrate.ca/.netlify/functions/send-email

The admin’s email-log.js function reads the last 20 Resend emails matching a subject query. It exposes client email metadata, so it’s gated — any active team member can call it, but only with a valid Bearer JWT verified against user_roles. See sitecrate-admin.