Dokumentace SimplyForms

Kompletní průvodce prací se SimplyForms API

Co je SimplyForms?

SimplyForms je Form Backend as a Service (FBaaS). Umožňuje zpracovávat odeslání z libovolného HTML formuláře bez psaní a provozu backendového kódu: atribut action formuláře nasměrujete na endpoint SimplyForms a každé odeslání se ověří, volitelně zkontroluje na spam a přepošle do e-mailové schránky vlastníka formuláře. Odeslání se nikdy nezapisují do databáze — SimplyForms je bezstavový e-mailový relay, takže neexistují žádná uložená data formuláře k exportu, úniku ani vydání a soulad s GDPR vyplývá ze samotné architektury, ne jen z pravidel. Integrace je změna jediného řádku ve stávajícím formuláři, plán zdarma nevyžaduje platební kartu a veškerá infrastruktura běží v EU na vlastních mailových serverech SimplyForms.

Rychlý start

Začněte používat SimplyForms během 2 minut — stačí změnit atribut action vašeho formuláře.

1

Zaregistrujte se

Vytvořte si účet a získejte svůj jedinečný Form ID

2

Změňte action URL

Nahraďte atribut action ve vašem formuláři

3

Hotovo!

Váš formulář nyní funguje a odesílá e-maily

html
<form action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
  <input type="email" name="email" required />
  <button type="submit">Odeslat</button>
</form>

Napojení přes Claude Code

Pokud používáte Claude Code (oficiální CLI od Anthropicu), můžete formulář napojit jedním promptem. Náš oficiální open-source skill Claude provede celým procesem — najde existující formulář ve vašem projektu, přesměruje odeslání na SimplyForms API, vloží anti-spam widget a otestuje to s vámi. Funguje s HTML, React, Vue/Nuxt a dalšími framework formuláři.

Instalace skillu (jednorázově)

bash
git clone https://github.com/simplyforms/public-claude-skill ~/.claude/skills/simplyforms

Příklad promptu

text
Here's my contact form at ./about.html. Wire it up to SimplyForms.
My form_id is YOUR_FORM_ID, I'm on the FREE plan.
Show me an inline thank-you message on success.
Zdrojový kód skillu

MIT licence, otevřený kód, semver verze. Issues a pull requesty vítány. Aktualizace přes `cd ~/.claude/skills/simplyforms && git pull`.

github.com/simplyforms/public-claude-skill

Základní formulář

Jednoduchý kontaktní formulář se jménem, e-mailem a zprávou.

html
<form action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
  <label for="name">Jmeno:</label>
  <input type="text" id="name" name="name" required />

  <label for="email">Email:</label>
  <input type="email" id="email" name="email" required />

  <label for="message">Zprava:</label>
  <textarea id="message" name="message" rows="5" required></textarea>

  <button type="submit">Odeslat zpravu</button>
</form>
Tip
Atribut name určuje název pole v přijatém e-mailu.

Vícestupňový formulář

Rozložte dlouhý formulář do více kroků pro lepší UX.

html
<form id="multi-step-form" action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
  <!-- Krok 1: Osobni udaje -->
  <div class="step step-1 active">
    <h3>Krok 1: Osobni udaje</h3>
    <input type="text" name="firstName" placeholder="Jmeno" required />
    <input type="text" name="lastName" placeholder="Prijmeni" required />
    <button type="button" onclick="nextStep()">Dalsi</button>
  </div>

  <!-- Krok 2: Kontakt -->
  <div class="step step-2">
    <h3>Krok 2: Kontaktni udaje</h3>
    <input type="email" name="email" placeholder="Email" required />
    <input type="tel" name="phone" placeholder="Telefon" />
    <button type="button" onclick="prevStep()">Zpet</button>
    <button type="button" onclick="nextStep()">Dalsi</button>
  </div>

  <!-- Krok 3: Zprava -->
  <div class="step step-3">
    <h3>Krok 3: Vase zprava</h3>
    <textarea name="message" placeholder="Zprava" rows="5" required></textarea>
    <button type="button" onclick="prevStep()">Zpet</button>
    <button type="submit">Odeslat</button>
  </div>
</form>

<script>
let currentStep = 1;
const totalSteps = 3;

function nextStep() {
  if (currentStep < totalSteps) {
    document.querySelector(`.step-${currentStep}`).classList.remove('active');
    currentStep++;
    document.querySelector(`.step-${currentStep}`).classList.add('active');
  }
}

function prevStep() {
  if (currentStep > 1) {
    document.querySelector(`.step-${currentStep}`).classList.remove('active');
    currentStep--;
    document.querySelector(`.step-${currentStep}`).classList.add('active');
  }
}
</script>

<style>
.step { display: none; }
.step.active { display: block; }
</style>

Nahrávání souborů

Přidejte možnost nahrávat soubory až do 50MB (Extend plán).

html
<form
  action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID"
  method="POST"
  enctype="multipart/form-data">

  <label for="name">Jmeno:</label>
  <input type="text" id="name" name="name" required />

  <label for="email">Email:</label>
  <input type="email" id="email" name="email" required />

  <label for="file">Nahrat soubor:</label>
  <input
    type="file"
    id="file"
    name="attachment"
    accept=".pdf,.doc,.docx,.jpg,.png"
    required />

  <p class="file-info">
    Podporovane formaty: PDF, DOC, DOCX, JPG, PNG<br>
    Maximalni velikost: 50MB (Extend plan)
  </p>

  <button type="submit">Odeslat s prilohou</button>
</form>
Důležité
Pro nahrávání souborů musíte použít enctype="multipart/form-data".

Speciální pole formuláře

Některé názvy polí mají pro doručený e-mail zvláštní význam. Funguje to pro každý plán bez konfigurace v dashboardu — stačí pole přidat do formuláře. Pole subject se použije jako předmět e-mailu, ccemail přidá kopie na další adresy (max 5, oddělené ;), a pole začínající podtržítkem (_*) se do těla e-mailu nevypisují.

html
<form action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">

  <!-- subject -> Subject: header of the delivered e-mail -->
  <input type="text" name="subject" placeholder="Email subject" required />

  <!-- ccemail -> extra recipients, max 5, semicolon-separated -->
  <input type="hidden" name="ccemail" value="manager@company.com; hr@company.com" />

  <!-- Regular fields (appear in the e-mail body) -->
  <input type="text" name="name" placeholder="Your name" required />
  <input type="email" name="email" placeholder="Your e-mail" required />
  <textarea name="message" placeholder="Your message" required></textarea>

  <!-- _-prefixed -> kept out of the e-mail body (use for hidden context) -->
  <input type="hidden" name="_source" value="homepage-hero" />

  <button type="submit">Send</button>
</form>
Důležité

EXTEND plán umí v Email Template Studiu nastavit vlastní šablonu předmětu pomocí Jinja proti polím formuláře. Tahle hodnota např. použije odeslaný subject, a v jeho nepřítomnosti fallbackne na statický text:

{{ subject or "Lead received" }}

CAPTCHA ochrana

Chraňte svůj formulář proti spamu pomocí Cloudflare Turnstile nebo Google reCAPTCHA (Extend plán). Free plán spoléhá na rate-limiting; SimplyForms ochrana je dostupná od plánu Standard výše.

Cloudflare Turnstile (Extend plán)

html
<form action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
  <input type="text" name="name" placeholder="Jmeno" required />
  <input type="email" name="email" placeholder="Email" required />
  <textarea name="message" placeholder="Zprava" required></textarea>

  <!-- Cloudflare Turnstile -->
  <div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>

  <button type="submit">Odeslat</button>
</form>

<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>

Google reCAPTCHA v3 (Extend plán)

html
<form action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
  <input type="text" name="name" placeholder="Jmeno" required />
  <input type="email" name="email" placeholder="Email" required />

  <!-- reCAPTCHA v3 token -->
  <input type="hidden" name="g-recaptcha-response" id="recaptchaResponse" />

  <button type="submit">Odeslat</button>
</form>

<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY"></script>
<script>
grecaptcha.ready(function() {
  document.querySelector('form').addEventListener('submit', function(e) {
    e.preventDefault();
    grecaptcha.execute('YOUR_SITE_KEY', {action: 'submit'}).then(function(token) {
      document.getElementById('recaptchaResponse').value = token;
      e.target.submit();
    });
  });
});
</script>

SimplyForms ochrana (privacy-first, bez registrace)

Chraňte formulář před spamem pomocí SimplyForms ochrany — privacy-first, self-hosted proof-of-work výzva dostupná od plánu Standard výše. Není potřeba žádný účet třetí strany. SimplyForms ochrana je postavena na open-source knihovně ALTCHA (licence MIT, © 2023 Daniel Regeci).

Ochrana soukromí
Zdarma, bez účtu třetí strany, privacy-first: ověření probíhá 100% lokálně — žádná data uživatele neopouštějí náš server.

Self-hosted widget (primární)

JavaScript widgetu je servírován přímo z API SimplyForms — z prohlížečů návštěvníků tedy nevzniká žádný požadavek na externí CDN.

html
<form action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
  <input type="text" name="name" placeholder="Jmeno" required />
  <input type="email" name="email" placeholder="Email" required />
  <textarea name="message" placeholder="Zprava" required></textarea>

  <!-- SimplyForms Protection widget — loads JS from the SimplyForms API (self-hosted) -->
  <script type="module" src="https://api.simplyforms.app/sf/widget.js"></script>
  <sf-captcha challengeurl="https://api.simplyforms.app/sf/challenge?form_id=YOUR_FORM_ID"></sf-captcha>

  <button type="submit">Odeslat</button>
</form>
Produkční nasazení
API musí běžet přes HTTPS, jinak prohlížeč zablokuje mixed-content. Pokud má váš web přísné CSP, povolte origin API v direktivách script-src a connect-src. Widget skript se musí načíst — bez něj se formulář neodešle.

Vícenásobné odeslání formuláře

Každý vygenerovaný token je single-use — server ho po prvním přijetí zneplatní. Stejné chování má Cloudflare Turnstile i Google reCAPTCHA. Pokud váš formulář může být odeslán víckrát během jedné stránky (komentáře, opakovaný odeslání po chybě validace), musíte widget mezi odesláními resetovat — jinak druhé odeslání skončí chybou 400 ALTCHA_REPLAY.

Možnost A — automatický reset (atribut autoreset)

Nejjednodušší cesta: přidejte k sf-captcha tagu atribut autoreset. Po každém ověření widget sám naplánuje reset (200 ms po dispatchnutém submit), takže další klik na Odeslat spustí nový proof-of-work. Vstupy uživatele zůstanou ve formuláři.

html
<form action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>

  <script type="module" src="https://api.simplyforms.app/sf/widget.js"></script>
  <!-- auto="onsubmit" defers PoW until the user clicks Send;
       autoreset clears the verified payload after every submit. -->
  <sf-captcha
    challengeurl="https://api.simplyforms.app/sf/challenge?form_id=YOUR_FORM_ID"
    auto="onsubmit"
    autoreset
  ></sf-captcha>

  <button type="submit">Send</button>
</form>

Možnost B — manuální reset z vašeho kódu

Pokud chcete řídit lifecycle widgetu sami (vlastní fetch, vlastní error UI), vyvolejte na rodičovském form synthetický 'reset' event. Resetujte vždy (v finally), protože server token spotřeboval bez ohledu na to, jestli žádost přijal nebo odmítl — bez resetu druhý pokus skončí chybou ALTCHA_REPLAY. Synthetický event zasáhne jen widget; vstupy formuláře nemažeme.

html
<form id="contactForm" action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>

  <script type="module" src="https://api.simplyforms.app/sf/widget.js"></script>
  <sf-captcha
    challengeurl="https://api.simplyforms.app/sf/challenge?form_id=YOUR_FORM_ID"
    auto="onsubmit"
  ></sf-captcha>

  <button type="submit">Send</button>
</form>

<script>
  const form = document.getElementById('contactForm');
  form.addEventListener('submit', async (e) => {
    e.preventDefault();
    try {
      const res = await fetch(form.action, { method: 'POST', body: new FormData(form) });
      if (res.ok) {
        // ...show your own success UI here
      } else {
        // ...show your own error UI here
      }
    } finally {
      // Always reset — the server consumed the token whether it accepted
      // or rejected the submission, so a re-submit would hit ALTCHA_REPLAY
      // without a fresh challenge. Dispatching the event resets ONLY the
      // captcha widget; form fields stay intact (form.reset() would wipe
      // them).
      form.dispatchEvent(new Event('reset'));
    }
  });
</script>

Kompletní kontaktní formulář

Profesionální kontaktní formulář s validací a pokročilými funkcemi.

html
<form
  id="contact-form"
  action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID"
  method="POST"
  class="contact-form">

  <div class="form-group">
    <label for="fullName">Cele jmeno *</label>
    <input
      type="text"
      id="fullName"
      name="fullName"
      required
      minlength="2" />
  </div>

  <div class="form-row">
    <div class="form-group">
      <label for="email">Email *</label>
      <input type="email" id="email" name="email" required />
    </div>

    <div class="form-group">
      <label for="phone">Telefon</label>
      <input type="tel" id="phone" name="phone" pattern="[0-9]{9,}" />
    </div>
  </div>

  <div class="form-group">
    <label for="subject">Predmet *</label>
    <select id="subject" name="subject" required>
      <option value="">Vyberte predmet</option>
      <option value="general">Obecny dotaz</option>
      <option value="support">Technicka podpora</option>
      <option value="sales">Obchodni dotaz</option>
      <option value="other">Jine</option>
    </select>
  </div>

  <div class="form-group">
    <label for="message">Zprava *</label>
    <textarea
      id="message"
      name="message"
      rows="6"
      required
      minlength="10"></textarea>
  </div>

  <div class="form-group">
    <label class="checkbox-label">
      <input type="checkbox" name="newsletter" value="yes" />
      Chci odebirat newsletter
    </label>
  </div>

  <div class="form-group">
    <label class="checkbox-label">
      <input type="checkbox" name="gdpr" required />
      Souhlasim se zpracovanim osobnich udaju *
    </label>
  </div>

  <button type="submit" class="btn-submit">
    Odeslat zpravu
  </button>

  <div class="form-success" style="display: none;">
    Zprava byla uspesne odeslana!
  </div>
</form>

<script>
document.getElementById('contact-form').addEventListener('submit', function(e) {
  e.preventDefault();
  const form = this;
  const formData = new FormData(form);

  fetch(form.action, {
    method: 'POST',
    body: formData
  })
  .then(response => response.json())
  .then(data => {
    form.style.display = 'none';
    document.querySelector('.form-success').style.display = 'block';
  })
  .catch(error => {
    alert('Chyba pri odesilani formulare. Zkuste to prosim znovu.');
  });
});
</script>

Newsletter signup

Jednoduchý formulář pro přihlášení k odběru newsletteru.

html
<form
  action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID"
  method="POST"
  class="newsletter-form">

  <h3>Prihlaste se k odberu</h3>
  <p>Ziskejte nejnovejsi tipy a triky primo do emailu</p>

  <div class="newsletter-input">
    <input
      type="email"
      name="email"
      placeholder="vas@email.cz"
      required />
    <button type="submit">Odeslat</button>
  </div>

  <p class="newsletter-note">
    Zadny spam. Odhlasit se muzete kdykoli.
  </p>
</form>

<style>
.newsletter-form {
  max-width: 500px;
  margin: 0 auto;
  padding: 30px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 16px;
  text-align: center;
}

.newsletter-input {
  display: flex;
  gap: 10px;
  margin: 20px 0;
}

.newsletter-input input {
  flex: 1;
  padding: 12px;
  border: none;
  border-radius: 8px;
  font-size: 16px;
}

.newsletter-input button {
  padding: 12px 24px;
  background: white;
  color: #667eea;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 600;
}

.newsletter-note {
  font-size: 14px;
  opacity: 0.9;
}
</style>

Webhooky

Posílejte data z formulářů do vlastních endpointů v reálném čase. Ideální pro integraci s vlastními systémy, CRM nebo automatizačními nástroji. Dostupné na Extend plánu a vyšším.

Jak fungují webhooky

Při každém odeslání formuláře SimplyForms pošle POST request na vámi zadanou URL s daty formuláře ve formátu JSON, podepsaný HMAC-SHA256 signaturou.

Ano
Webhooky jsou dostupné na Extend plánu a vyšším.

Konfigurace webhooku

V dashboardu SimplyForms otevřete Integrace a nastavte svůj webhook:

text
1. Sign in to the SimplyForms dashboard
2. Open "Integrations" in the sidebar
3. In the "Webhook" section, enable it and enter your URL
4. (Optional) toggle "Include metadata" — off by default
5. Save — a signing secret is generated automatically

Příklad webhook payloadu

json
{
  "formId": "YOUR_FORM_ID",
  "timestamp": 1736519400,
  "data": {
    "name": "Jan Novak",
    "email": "jan.novak@example.com",
    "message": "Dobry den, mam zajem o vas produkt."
  }
  // "metadata": { ipAddress, userAgent, referrer }
  // is ONLY included if you explicitly opt in per form.
}

Zpracování webhooku (Node.js)

javascript
// Express.js priklad
const express = require('express');
const app = express();

app.use(express.json());

app.post('/api/webhook', async (req, res) => {
  try {
    const { formId, submissionId, data, metadata } = req.body;

    // Validace signature (doporuceno)
    const signature = req.headers['x-simplyforms-signature'];
    if (!verifySignature(signature, req.body)) {
      return res.status(401).json({ error: 'Invalid signature' });
    }

    // Zpracovani dat
    console.log('Novy formular od:', data.email);

    // Ulozeni do databaze
    await db.submissions.create({
      formId,
      submissionId,
      email: data.email,
      name: data.name,
      message: data.message,
      receivedAt: new Date()
    });

    // Notifikace do Slacku, CRM, etc.
    await sendToSlack(data);

    // Vzdy odpovezte status 200
    res.status(200).json({ received: true });

  } catch (error) {
    console.error('Webhook error:', error);
    res.status(500).json({ error: 'Internal error' });
  }
});

function verifySignature(signature, body) {
  const crypto = require('crypto');
  const secret = process.env.SIMPLYFORMS_WEBHOOK_SECRET;
  const hash = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(body))
    .digest('hex');
  return signature === hash;
}

app.listen(3000);

Testování webhooku

Pro lokální vývoj použijte nástroj jako ngrok pro zpřístupnění localhost URL:

bash
# Instalace ngrok
npm install -g ngrok

# Spusteni tunelu
ngrok http 3000

# Pouzijte vygenerovanou URL (napr. https://abc123.ngrok.io)
# jako webhook URL v Simply Forms dashboardu
Důležité
Vždy ověřujte hlavičku x-simplyforms-signature pro zabezpečení proti neautorizovaným requestům.

Retry logika

Pokud váš endpoint neodpoví status 200, SimplyForms se pokusí o opětovné odeslání:

  • 1. pokus: okamžitě
  • 2. pokus: za 5 minut
  • 3. pokus: za 30 minut
  • 4. pokus: za 2 hodiny

Vlastní validace

Přidejte pokročilou validaci formuláře na straně klienta i serveru pro maximální kontrolu nad přijímanými daty.

Client-side validace (JavaScript)

HTML5 validační atributy jsou skvělé, ale někdy potřebujete více kontroly:

html
<form id="validated-form" action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
  <div class="form-group">
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required />
    <span class="error-message" id="email-error"></span>
  </div>

  <div class="form-group">
    <label for="phone">Telefon (CZ format):</label>
    <input type="tel" id="phone" name="phone" required />
    <span class="error-message" id="phone-error"></span>
  </div>

  <div class="form-group">
    <label for="age">Vek (18+):</label>
    <input type="number" id="age" name="age" required />
    <span class="error-message" id="age-error"></span>
  </div>

  <button type="submit">Odeslat</button>
</form>

<script>
const form = document.getElementById('validated-form');

const validators = {
  email: (value) => {
    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!regex.test(value)) {
      return 'Zadejte platnou emailovou adresu';
    }
    const blocked = ['tempmail.com', 'throwaway.email'];
    const domain = value.split('@')[1];
    if (blocked.includes(domain)) {
      return 'Pouzijte prosim trvalou emailovou adresu';
    }
    return null;
  },

  phone: (value) => {
    const regex = /^(\+420)?[0-9]{9}$/;
    if (!regex.test(value.replace(/\s/g, ''))) {
      return 'Zadejte platne ceske telefonni cislo';
    }
    return null;
  },

  age: (value) => {
    const age = parseInt(value);
    if (isNaN(age) || age < 18) {
      return 'Musite byt starsi 18 let';
    }
    if (age > 120) {
      return 'Zadejte prosim realny vek';
    }
    return null;
  }
};

Object.keys(validators).forEach(fieldName => {
  const field = document.getElementById(fieldName);
  const errorSpan = document.getElementById(`${fieldName}-error`);

  field.addEventListener('blur', () => {
    const error = validators[fieldName](field.value);
    if (error) {
      errorSpan.textContent = error;
      field.classList.add('invalid');
    } else {
      errorSpan.textContent = '';
      field.classList.remove('invalid');
    }
  });
});

form.addEventListener('submit', (e) => {
  e.preventDefault();
  let isValid = true;

  Object.keys(validators).forEach(fieldName => {
    const field = document.getElementById(fieldName);
    const errorSpan = document.getElementById(`${fieldName}-error`);
    const error = validators[fieldName](field.value);

    if (error) {
      errorSpan.textContent = error;
      field.classList.add('invalid');
      isValid = false;
    }
  });

  if (isValid) {
    form.submit();
  } else {
    alert('Opravte prosim chyby ve formulari');
  }
});
</script>

<style>
.error-message {
  color: #e53e3e;
  font-size: 14px;
  display: block;
  margin-top: 5px;
}

input.invalid {
  border-color: #e53e3e;
  background-color: #fff5f5;
}
</style>

Server-side validace (SimplyForms dashboard)

V SimplyForms dashboardu můžete nastavit validační pravidla, která se vyhodnotí před přijetím formuláře:

Enterprise funkce
Server-side validační pravidla jsou dostupná na Enterprise plánu.
json
{
  "validationRules": {
    "email": {
      "required": true,
      "type": "email",
      "blockedDomains": ["tempmail.com", "guerrillamail.com"]
    },
    "age": {
      "required": true,
      "type": "number",
      "min": 18,
      "max": 120
    },
    "phone": {
      "required": false,
      "pattern": "^(\\+420)?[0-9]{9}$"
    },
    "message": {
      "required": true,
      "minLength": 10,
      "maxLength": 1000
    }
  }
}

Async validace (kontrola duplicit)

Zkontrolujte, zda e-mail již není v databázi před odesláním formuláře:

javascript
const emailInput = document.getElementById('email');
const emailError = document.getElementById('email-error');

emailInput.addEventListener('blur', async () => {
  const email = emailInput.value;

  clearTimeout(emailInput.debounceTimer);
  emailInput.debounceTimer = setTimeout(async () => {

    try {
      const response = await fetch('/api/check-email', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email })
      });

      const data = await response.json();

      if (data.exists) {
        emailError.textContent = 'Tento email je jiz zaregistrovan';
        emailInput.classList.add('invalid');
      } else {
        emailError.textContent = '';
        emailInput.classList.remove('invalid');
      }
    } catch (error) {
      console.error('Validation error:', error);
    }

  }, 500);
});

Šablony emailů

Přizpůsobte design a obsah notifikačních emailů svému brandu.

Výchozí šablona

SimplyForms používá profesionální výchozí šablonu, která obsahuje všechna odeslaná pole.

text
Predmet: Novy formular z example.com

Dobry den,

obdrzeli jste novy formular od:

Jmeno: Jan Novak
Email: jan.novak@example.com
Telefon: +420777123456

Zprava:
Dobry den, mam zajem o vas produkt.

---
Odeslano pres Simply Forms
ID: sub_xyz789
Cas: 10.1.2025 14:30

Připravené šablony (galerie)

V dashboardu na stránce Šablony emailů je k dispozici šest vestavěných šablon. Stačí kliknout a vybrat — živý náhled se zobrazí ještě před uložením.

  • minimal — Minimal — simple left-aligned title, no color band
  • clean-card — Clean Card — light bg, purple top accent bar
  • bold-header — Bold Header — full-width dark header with white title
  • notification — Notification — inline NEW badge, compact padding
  • editorial — Editorial — serif fonts, warm paper tones
  • dark-first — Dark First — dark-mode-first with light media query
Živý náhled
Dashboard zobrazuje živý náhled každé šablony i vlastního HTML vykreslený backendem s ukázkovými daty, takže přesnou podobu emailu vidíte před uložením.

Živý náhled

Stránka Šablony emailů v dashboardu zobrazuje sandboxovaný živý náhled vykreslený backendem s ukázkovými daty. Dostupné pro všechny přihlášené uživatele — bez omezení plánem.

Vlastní HTML šablona (pouze EXTEND)

Na plánu EXTEND lze v dashboardu napsat plně vlastní HTML tělo. Vlastní šablona je odeslána jako kompletní email — není obalena výchozím obalem SimplyForms.

Celý email
Když je mode nastaven na custom, vaše šablona JE celý HTML dokument emailu. Obal SimplyForms (záhlaví s předmětem, branding v zápatí) se nepřidává. Při mode=default se standardní obal vždy použije.
Dostupnost
Vlastní šablony emailů (mode=custom) jsou dostupné pouze na plánu EXTEND. Výběr šablony z galerie a živý náhled jsou dostupné všem přihlášeným uživatelům.
html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
           background: #f3f4f6; margin: 0; padding: 32px 12px; }
    .card { background: #fff; border-radius: 12px; max-width: 600px;
            margin: 0 auto; overflow: hidden; }
    .header { background: #111827; color: #fff; padding: 28px 32px; }
    .header h1 { margin: 0; font-size: 20px; }
    .body { padding: 28px 32px; }
    .field-label { font-size: 11px; font-weight: 600; text-transform: uppercase;
                   letter-spacing: .05em; color: #6b7280; padding-top: 12px; }
    .field-value { font-size: 15px; color: #111827; padding-bottom: 12px;
                   border-bottom: 1px solid #f3f4f6; }
    .footer { background: #fafafa; padding: 16px 32px; font-size: 12px;
              color: #9ca3af; text-align: center; }
  </style>
</head>
<body>
  <div class="card">
    <div class="header">
      <h1>New form submission</h1>
    </div>
    <div class="body">
      <!-- Reference individual fields by name attribute -->
      <div class="field-label">Name</div>
      <div class="field-value">{{ name }}</div>

      <div class="field-label">Email</div>
      <div class="field-value">{{ email }}</div>

      <div class="field-label">Message</div>
      <div class="field-value">{{ message }}</div>
    </div>
    <div class="footer">Sent via SimplyForms</div>
  </div>
</body>
</html>

Dostupné proměnné šablony

ProměnnáPopisPříklad
{{ fieldName }}Hodnota odeslaného pole formuláře — použijte přesný atribut name daného pole. Pole začínající _ a soubory jsou vyloučeny.{{ email }}, {{ name }}, {{ message }}
fieldsSlovník všech odeslaných polí (název na hodnotu). Použijte s cyklem for pro automatické vykreslení každého pole bez ohledu na jejich názvy.{% for label, value in fields.items() %}

Iterace přes všechna pole

Proměnná fields je slovník mapující název každého odeslaného pole na jeho hodnotu. Použijte Jinja2 cyklus for pro automatické vykreslení každého pole — užitečné v šablonách galerie a pro formuláře s dynamickými poli.

html
<!-- Loop over all submitted fields (any form) -->
{% for label, value in fields.items() %}
  <div class="field-label">{{ label }}</div>
  <div class="field-value">{{ value }}</div>
{% endfor %}

Autoresponder

Pošlete automatickou potvrzovací zprávu odesílateli formuláře.

HTML autoresponder šablona

html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>
<body style="font-family: sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
  <h2>Dekujeme za Vasi zpravu!</h2>

  <p>Mily/a {{name}},</p>

  <p>Dekujeme za vyplneni formulare. Vasi zpravu jsme obdrzeli a odpovime Vam do 24 hodin.</p>

  <div style="background: #f7fafc; padding: 20px; border-radius: 8px; margin: 20px 0;">
    <p><strong>Shrnuti Vasi zpravy:</strong></p>
    <p>{{message}}</p>
  </div>

  <p>Pokud mate nalehavou otazku, kontaktujte nas na <a href="tel:+420777123456">+420 777 123 456</a>.</p>

  <p>S pozdravem,<br>
  Vas tym</p>

  <hr style="border: none; border-top: 1px solid #e2e8f0; margin: 30px 0;">

  <p style="color: #718096; font-size: 14px;">
    Tento email byl odeslan automaticky. Neodpovidejte na nej.
  </p>
</body>
</html>
Důležité
Pro aktivaci autoresponderu musí formulář obsahovat pole s name="email" — na tuto adresu bude automatická odpověď odeslána.

Plain text fallback

Vždy přidejte plain text verzi pro e-mailové klienty, které nepodporují HTML:

text
Dekujeme za Vasi zpravu!

Mily/a {{name}},

Dekujeme za vyplneni formulare. Vasi zpravu jsme obdrzeli a odpovime Vam do 24 hodin.

Shrnuti Vasi zpravy:
{{message}}

Pokud mate nalehavou otazku, kontaktujte nas na +420 777 123 456.

S pozdravem,
Vas tym

---
Tento email byl odeslan automaticky. Neodpovidejte na nej.

API Reference

Kompletní dokumentace SimplyForms API.

Endpoint

bash
POST https://api.simplyforms.app/v1/forms/{FORM_ID}

Kanonická routa je /v1/forms/. Původní cesta /submit/ funguje dál jako trvalý alias.

Hlavičky

HlavičkaHodnotaPovinné
Content-Typeapplication/x-www-form-urlencoded, multipart/form-data, application/jsonAno

Response

json
{
  "success": true
}
// Submissions are relayed, never stored — there is no submissionId.
// If the monthly email limit is reached you also get:
//   "warning": "...", "email_limit": { "used", "limit", "reset_date" }

Chybová odpověď

json
{
  "ok": false,
  "code": "INVALID_FORM_ID",
  "message": "Invalid or inactive form ID"
}

Časté dotazy

Ukládá SimplyForms odeslání mých formulářů?

Ne. SimplyForms je bezstavový e-mailový relay: každé odeslání se ověří, volitelně zkontroluje na spam, přepošle do vaší schránky a poté zahodí. Obsah formuláře ani IP adresa návštěvníka se nikdy nezapisují do databáze, takže neexistují žádná uložená data odeslání k exportu, úniku ani povinnému vydání.

Je SimplyForms v souladu s GDPR?

Ano. Protože se odeslání nikdy neukládají, je rozsah zpracování osobních údajů ze své podstaty minimální. Veškerá infrastruktura je hostována v EU na vlastních mailových serverech SimplyForms — žádný externí e-mailový zpracovatel typu SendGrid nebo Mailgun. Zpracovatelská smlouva (DPA), zásady ochrany soukromí a seznam sub-zpracovatelů jsou zveřejněny na simplyforms.app/legal.

Co je součástí plánu zdarma?

Plán zdarma zahrnuje 50 odeslání denně a 250 e-mailů měsíčně, limit nahrávání souborů 1 MB a jednu povolenou doménu. Nevyžaduje platební kartu. V plánu zdarma se spam řeší omezením četnosti požadavků; možnosti CAPTCHA (ALTCHA, Turnstile, reCAPTCHA) jsou dostupné na placených plánech.

Čím se SimplyForms liší od Formspree nebo Netlify Forms?

Zásadní rozdíl je v ukládání: SimplyForms odeslání nikdy neukládá, zatímco většina form backendů je drží v dashboardu. SimplyForms každé odeslání přepošle na váš e-mail a zapomene ho. Navíc je hostovaný v EU a odesílá přes vlastní mailové servery, ne přes externího poskytovatele e-mailu, což drží počet sub-zpracovatelů nízký.

Jak přidám ochranu proti spamu do svého formuláře?

Každý plán zahrnuje automatické omezení četnosti požadavků. Od plánu Standard můžete zapnout SimplyForms Protection — samohostovaný proof-of-work widget ALTCHA zaměřený na soukromí, který nevyžaduje žádný externí účet. Plán Extend přidává Cloudflare Turnstile a Google reCAPTCHA v3. Plán zdarma se spoléhá pouze na omezení četnosti požadavků.

Obchodní podmínky

Používáním SimplyForms souhlasíte s tím, že službu budete využívat v souladu se zákonem a nebudete přes ni přeposílat spam, malware ani protiprávní obsah. Placené plány jsou účtovány přes Stripe; předplatné lze kdykoli zrušit a zrušení nabývá účinnosti na konci aktuálního zúčtovacího období. Plán Enterprise je účtován dle samostatné dohody. Služba je poskytována „tak, jak je“, bez záruky; neodpovídáme za nepřímé či následné škody. Podmínky můžeme aktualizovat — podstatné změny oznámíme na této stránce.

Zásady ochrany soukromí

Veškerá infrastruktura SimplyForms běží v Evropské unii. API, databáze i SMTP relay zpracovávají data výhradně v EU regionech — žádné odeslání nikdy neopouští EU prostor. SimplyForms je bezstavový e-mailový relay: odeslané formuláře se nikdy neukládají — jsou přeposlány přímo do schránky vlastníka formuláře. Neukládá se žádný obsah formuláře, žádná IP odesílatele ani user-agent. Uchováváme pouze anonymní metriku na odeslání (id formuláře, čas, zda byl odeslán e-mail, kód země, doménu refereru) s 90denní retencí. Metadata webhooku (IP/user-agent/referrer) se odesílají POUZE pokud si je vlastník formuláře výslovně zapne. Data lze kdykoli exportovat (GDPR čl. 20) nebo účet smazat (GDPR čl. 17) v dashboardu.

SimplyForms ochrana je postavena na open-source knihovně ALTCHA (licence MIT, © 2023 Daniel Regeci).