Every dashboard action is an MCP tool your agent can call.Read the docs
SvelteKit email

Send SvelteKit email from the server file, not the component. Private env in, accepted ID out.

Queue transactional mail behind a form action or server route, return the accepted message ID, and handle the delivery result on a separate signed webhook path.

Import the key from $env/dynamic/private, never $env/public.

Server quickstart
Sveltekit

One request, complete trace

Request

POST /api/v1/emails

Authorization: Bearer aem_…

Idempotency-Key: welcome-8f21

{ "to": "[email protected]", "template": "welcome" }

202 Accepted

{ "id": "msg_7ca31", "status": "queued" }

RuntimeServer process
RequestPOST /api/v1/emails
Result202 · queued
Credentials stay server-side

[ 01 / 03 ]Integration shape

Let SvelteKit's file boundary protect the integration.

Use server routes and form actions

Use a form action for a page mutation or +server.ts for a focused API boundary; both can read private environment values.

Publish product events

Publish events after the server-side mutation succeeds, so flows follow trusted state instead of client activity.

Verify the webhook

A +server.ts route reading await request.text() before parsing.

[ 02 / 03 ]Server quickstart

Queue one email from SvelteKit +server.ts.

The server route protects the key and returns an accepted message ID while delivery continues independently.

Use a server route so private environment values never enter the client build.

src/routes/api/welcome/+server.ts
export const POST: RequestHandler = async ({ request }) => {
  const input = await request.json();
  return fetch(EMAIL_URL, { method: "POST",
    headers: authHeaders(`welcome-${input.userId}`),
    body: JSON.stringify({ to: input.email, template: "welcome" }) });
};

Accepted response

{ "id": "msg_7ca31", "status": "queued" }

Questions people ask us

Give SvelteKit email a private, traceable path.

Queue the message from a server file and verify the event that reports delivery.