← Val TownCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Val Town
Snapshot Sep 30, 2026 · 22:50 UTC · version 3.0.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "email",
"description": "Use when a val sends email, receives email, or is triggered by an incoming email. Covers email-type vals (the Email handler shape, attachment limits, the assigned val email address) and sending mail via std/email.",
"included_files": [],
"skill_md_contents": "---\nname: email\ndescription: Use when a val sends email, receives email, or is triggered by an incoming email. Covers email-type vals (the Email handler shape, attachment limits, the assigned val email address) and sending mail via std/email.\n---\n\n# Email\n\nVal Town supports both directions: vals can be **triggered by** incoming mail (email-type vals) and can **send** mail via `std/email`.\n\n## Receiving email — email-type vals\n\nEmail vals (`fileType: \"email\"`) run when a message is delivered to the val's assigned address.\n\n```ts\n// Learn more: https://docs.val.town/vals/email/\n// Email type: {\n// from: string,\n// to: string[],\n// subject?: string,\n// text?: string,\n// html?: string,\n// attachments: File[],\n// headers: Record<string, string>\n// }\nexport default async function (e: Email) {\n console.log(e.from, e.subject, e.text);\n}\n```\n\nThe file must have an `export` — `export default` for the handler.\n\n**Maximum 30MB per message**, including attachments. Larger messages will be rejected.\n\n### Reading the assigned address\n\nWhen you list files or create an email-type file, the response includes `links.email` — the address that triggers this val. **Always read this from the API response. Never construct an email address yourself** — the format is owned by the platform and may change.\n\n## Sending email — `std/email`\n\nFor outgoing mail, import from `std/email`:\n\n```ts\nimport { email } from \"https://esm.town/v/std/email\";\n\nawait email({\n to: \"user@example.com\",\n subject: \"Hello\",\n text: \"Message body\",\n});\n```\n\n`std/email` exports `email` as the send function itself — call it directly (`email({ ... })`); there is no `email.send` method. It accepts the shape you'd expect: `to`, `subject`, `text`, `html`, plus `from`, `cc`, `bcc`, `replyTo`, `attachments`, and `headers`. If no `to` field is specified, it defaults to sending mail to the val owner's address.\n\n## Replying to an incoming message\n\nCombine the two — read the inbound `from` in an email-type handler, then call `email` to reply:\n\n```ts\nimport { email } from \"https://esm.town/v/std/email\";\n\nexport default async function (e: Email) {\n await email({\n to: e.from,\n subject: `Re: ${e.subject ?? \"\"}`,\n text: \"Got it, thanks!\",\n });\n}\n```\n\n## Verifying changes\n\nAfter editing an email-type val, use `run_file` with a sample `Email` payload to invoke the handler manually instead of waiting for a real incoming message. For send-only vals, run the script the same way and check `get_logs` for delivery errors.\n"
}SHA-256: 52e3fc9dd25d28477efa8321fd50e915e26f0a237a95489e3b06d79e8408a235