# tr-forms — Add a Form Source: [tr-forms — Add a Form](https://typeroll.com/docs/skills/tr-forms/) > Create contact, booking or signup forms — server-backed, HMAC-protected, with inline JS feedback. **Triggers on:** “contact form”, “add a form”, “let visitors message us”, “booking form”, “formulär” ## What it does [Section titled “What it does”](https://typeroll.com/docs/skills/tr-forms/#what-it-does) Forms in Typeroll are server-backed — submissions go to `/api/forms/submit` and are stored in Firestore. No third-party service needed. The portal’s Submissions inbox shows all received messages. The AI agent: 1. Creates the form definition (`create_form`) 2. Fetches the signed embed token (`read_form`) 3. Generates the embed HTML with the token, honeypot and optional JS feedback 4. Embeds it on the target page (`update_page`) 5. Deploys ## Field types [Section titled “Field types”](https://typeroll.com/docs/skills/tr-forms/#field-types) | Type | Use for | | ---------- | ----------------------------------- | | `text` | Short text, name, company | | `email` | Email addresses (validated) | | `tel` | Phone numbers | | `url` | Website URLs | | `number` | Quantities, ages | | `textarea` | Long messages | | `select` | Dropdown — provide `options: [...]` | | `radio` | Single choice from a list | | `checkbox` | Boolean yes/no | ## Example prompts [Section titled “Example prompts”](https://typeroll.com/docs/skills/tr-forms/#example-prompts) ```plaintext Add a contact form to the Contact page. Fields: name, email, phone (optional), message. Send submissions to hej@acme.se. ``` ```plaintext Add a booking form to the Services page. Fields: name, email, desired date, time slot (09:00/10:00/11:00/14:00/15:00), optional notes. ``` ```plaintext Add a newsletter signup with just an email field at the bottom of the homepage. ``` ## Field name rules [Section titled “Field name rules”](https://typeroll.com/docs/skills/tr-forms/#field-name-rules) Field names must be lowercase ASCII — no Swedish characters: | Wrong | Right | | ------------ | ----------------------------------------------------------- | | `förnamn` | `fornamn` | | `företag` | `foretag` | | `meddelände` | `meddelande` (this one is actually fine — no special chars) | | `ämne` | `amne` | The `label` (what the user sees) can be any text. ## Token expiry [Section titled “Token expiry”](https://typeroll.com/docs/skills/tr-forms/#token-expiry) Caution The `submit_token` in the embedded form HTML is short-lived (24 hours by default). For forms on long-cached static pages, fetch a fresh token and redeploy periodically. On the hosted plan, token refresh is handled automatically. ## Viewing submissions [Section titled “Viewing submissions”](https://typeroll.com/docs/skills/tr-forms/#viewing-submissions) Submissions appear in the portal at `/app/sites/{siteId}/forms/{formId}/submissions`. The portal stores all submissions regardless of the `recipient_email` setting. Email delivery to `recipient_email` depends on email configuration in your portal deployment. On the hosted plan (app.typeroll.com) email delivery is included. ## Protection layers [Section titled “Protection layers”](https://typeroll.com/docs/skills/tr-forms/#protection-layers) Every form submission goes through three protection layers: 1. **Rate limiting** — 30 submissions per 5 minutes per IP 2. **HMAC token** — proves the form was generated by the platform 3. **Honeypot** — hidden `_hp` field that bots fill but humans don’t; filled = rejected