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.
Zaregistrujte se
Vytvořte si účet a získejte svůj jedinečný Form ID
Změňte action URL
Nahraďte atribut action ve vašem formuláři
Hotovo!
Váš formulář nyní funguje a odesílá e-maily
<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í s AI agentem
Formulář za vás může napojit AI asistent. Pro Claude Code máme oficiální open-source skill. Jinému asistentovi stačí vložit do chatu krátký návod níže.
Claude Code
Skill najde formulář ve vašem projektu, nasměruje odesílání na SimplyForms a s vámi ho vyzkouší. Poradí si s čistým HTML i s formuláři v Reactu, Vue nebo Nuxtu.
Instalace skillu (jednorázově)
git clone https://github.com/simplyforms/public-claude-skill ~/.claude/skills/simplyformsPříklad promptu
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.Co skill udělá podle plánu
- Free: formulář napojí a CAPTCHA nepřidá. Plán Free ji nemá, spam u něj hlídá limit odeslání.
- Standard a vyšší: do formuláře přidá i widget ochrany SimplyForms. Ochranu zapne až ve chvíli, kdy je widget nasazený: přes API klíč, nebo vás pošle do dashboardu. Na plánu Extend umí místo ní nastavit Cloudflare Turnstile nebo Google reCAPTCHA.
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-skillJiní asistenti
Zkopírujte návod níže a vložte ho asistentovi do chatu. Podrobnosti najde v /llms.txt a /llms-full.txt, přesný popis API v /openapi.json.
Návod pro agenta
Connect this website's form to SimplyForms (https://simplyforms.app), a hosted form backend that emails every submission to the site owner and does not store it.
- Endpoint: POST https://api.simplyforms.app/v1/forms/FORM_ID. FORM_ID is in the SimplyForms dashboard; ask me for it. Submitting needs no API key.
- Keep the existing field names: they become the labels in the email. A field named "subject" sets the email subject; fields whose name starts with "_" are left out of the email.
- Either set the form's action to the endpoint with method="POST" (works without JavaScript: the visitor lands on a SimplyForms thank-you page, or on the URL in a hidden "_redirect" field when it is on the same https site), or submit with fetch(endpoint, { method: "POST", body: new FormData(form) }) and show an inline thank-you when the response is 200 with {"success": true}.
- For file inputs use enctype="multipart/form-data" (FormData does this). Attachment limit per submission: Free 1 MB, Standard 5 MB, Extend 50 MB.
- Errors come back as JSON with "ok": false, "code" and "message" at the top level; read body.code and body.message (the "detail" copy is deprecated).
- Add no CAPTCHA on the Free plan. On paid plans spam protection is switched on in the dashboard; the widget is described in the full guide.
Full guide: https://simplyforms.app/llms-full.txtZákladní formulář
Jednoduchý kontaktní formulář se jménem, e-mailem a zprávou.
<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>Co návštěvník uvidí po odeslání
Obyčejný formulář funguje i bez JavaScriptu. Po odeslání pošleme návštěvníka na naši stránku s poděkováním a s odkazem zpět na váš web. Když se odeslání nepovede, stejná stránka mu srozumitelně vysvětlí proč.
Chcete vlastní stránku s poděkováním? Přidejte do formuláře skryté pole _redirect s její adresou. Musí být na stejném webu jako formulář a web musí běžet na https (http jen na localhostu). Jinak zobrazíme naši stránku.
<form action="https://api.simplyforms.app/v1/forms/YOUR_FORM_ID" method="POST">
<!-- Optional: your own thank-you page instead of ours.
A path like /thanks works too. -->
<input type="hidden" name="_redirect" value="https://example.com/thanks" />
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>Když formulář odesíláte JavaScriptem (fetch), k přesměrování nedojde: API vrátí JSON a poděkování zobrazíte přímo na stránce.
Vícestupňový formulář
Rozložte dlouhý formulář do více kroků pro lepší UX.
<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).
<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>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 a pole začínající podtržítkem (_*) se do těla e-mailu nevypisují. Pole from_name určuje jméno odesílatele ve vaší schránce (zobrazí se jako „Název webu via SimplyForms“) a do těla se nevypisuje; od plánu Standard si v dashboardu nastavíte pevné jméno bez dovětku „via SimplyForms“. Platná adresa v poli email (nebo _replyto, které má přednost) se použije jako Reply-To, takže návštěvníkovi odpovíte obyčejným Odpovědět. Pole ccemail je zastaralé: projdou jen adresy, které už jsou nastavené v Recipients, a ty kopii dostanou i bez něj, takže příjemce navíc přidat nemůže — další příjemce nastavte v dashboardu v sekci Recipients. Pole _redirect určuje stránku, na kterou po odeslání obyčejného formuláře přesměrujeme (viz Základní formulář).
<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 />
<!-- from_name -> sender name in your inbox: "Acme website via SimplyForms" -->
<input type="hidden" name="from_name" value="Acme website" />
<!-- Extra recipients: configure them under Recipients in the dashboard.
The legacy ccemail field is deprecated and cannot add a new recipient. -->
<!-- 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" />
<!-- _redirect -> your own thank-you page after a plain form submit
(same https site as the form; otherwise our thank-you page) -->
<input type="hidden" name="_redirect" value="https://example.com/thanks" />
<button type="submit">Send</button>
</form>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)
<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)
<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).
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.
<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>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.
<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.
<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.
<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>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.
Konfigurace webhooku
V dashboardu SimplyForms otevřete Integrace a nastavte svůj webhook:
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 automaticallyPříklad webhook payloadu
{
"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)
// 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:
# Instalace ngrok
npm install -g ngrok
# Spusteni tunelu
ngrok http 3000
# Pouzijte vygenerovanou URL (napr. https://abc123.ngrok.io)
# jako webhook URL v SimplyForms dashboarduRetry 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:
<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:
{
"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:
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.
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 SimplyForms
ID: sub_xyz789
Cas: 10.1.2025 14:30Př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 bandclean-card: Clean Card, light bg, purple top accent barbold-header: Bold Header, full-width dark header with white titlenotification: Notification, inline NEW badge, compact paddingeditorial: Editorial, serif fonts, warm paper tonesdark-first: Dark First, dark-mode-first with light media query
Ž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.
<!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á | Popis | Pří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 }} |
fields | Slovní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).
<!-- 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
<!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>Plain text fallback
Vždy přidejte plain text verzi pro e-mailové klienty, které nepodporují HTML:
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
POST https://api.simplyforms.app/v1/forms/{FORM_ID}Kanonická routa je /v1/forms/{FORM_ID}. Původní cesta /submit/{FORM_ID} funguje dál jako trvalý alias.
Hlavičky
| Hlavička | Hodnota | Povinné |
|---|---|---|
Content-Type | application/x-www-form-urlencoded, multipart/form-data, application/json | Ano |
Response
{
"success": true
}
// Submissions are relayed, never stored — there is no submissionId.
// It means the notification email was handed to the mail server. If that
// fails you get 502 DELIVERY_FAILED; past the monthly email limit and its
// grace allowance, 429 MONTHLY_EMAIL_LIMIT_REACHED (see below).Odeslání obyčejným formulářem z prohlížeče dostane místo JSON přesměrování 303 na stránku s poděkováním (viz Základní formulář).
Chybová odpověď
Každá chyba je objekt s ok: false, code a message přímo na nejvyšší úrovni, některé kódy přidávají další pole (třeba reset_date). Řiďte se podle body.code. Pole detail obsahuje kvůli starším klientům totéž znovu; je zastaralé a v příští verzi zmizí. Při překročení limitu požadavků (429, RATE_LIMIT_EXCEEDED) má odpověď hlavičku Retry-After.
// Every error: "ok": false, "code" and "message" at the top level,
// sometimes extra fields (reset_date, errors, challenge_required, ...)
{
"ok": false,
"code": "DAILY_LIMIT_EXCEEDED",
"message": "Daily submission limit exceeded.",
"reset_date": "2026-10-06T00:00:00+00:00",
"detail": {
"ok": false,
"code": "DAILY_LIMIT_EXCEEDED",
"message": "Daily submission limit exceeded.",
"reset_date": "2026-10-06T00:00:00+00:00"
}
}
// "detail" repeats the same object for older clients and is deprecated.
// Codes: INVALID_FORM_ID_FORMAT, INVALID_FORM_ID (401), EMPTY_PAYLOAD,
// UNSUPPORTED_CONTENT_TYPE, INVALID_JSON, INVALID_PAYLOAD, INVALID_REQUEST (422),
// CAPTCHA codes (CAPTCHA_FAILED, ALTCHA_EXPIRED, ...), VALIDATION_FAILED,
// DOMAIN_LIMIT_EXCEEDED (403), FILE_SIZE_LIMIT_EXCEEDED, FILE_TOO_LARGE,
// PAYLOAD_TOO_LARGE (413), DAILY_LIMIT_EXCEEDED, MONTHLY_EMAIL_LIMIT_REACHED,
// RATE_LIMIT_EXCEEDED (429, Retry-After header), SUBMISSION_FAILED, INTERNAL_ERROR (500),
// DELIVERY_FAILED (502: the email could not be sent, try again)
// JavaScript: if (!response.ok) show(body.message), branch on body.codeČ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 prodává a fakturuje Paddle jako prodejce (merchant of record); 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).
