Browse our collection of clear, ready-to-use documentation. Explore clear, practical guides with ready-to-use examples so you can implement, customize, and launch in minutes.
Get a working contact form in under 2 minutes. No backend code needed — just HTML.
create form & copy your unique endpoint.
Set your HTML form's action to your endpoint URL and method to POST.
Every submission goes straight to your email and shows up in your dashboard.
The simplest setup — just point your form's action to your endpoint URL and you're ready to go.
<form action="https://000form.com/f/YOUR_FORM_ID" method="POST"> <input type="text" name="name" placeholder="Your name" required> <input type="email" name="email" placeholder="Your email" required> <textarea name="message" placeholder="Your message"></textarea> <button type="submit">Send</button> </form>
Add these as hidden inputs to your form to turn on extra features. All of them are optional — only use the ones you need.
Set a custom subject line on the email you receive. If you don't add this, the subject will be New Form Submission from 000form.
<input type="hidden" name="_subject" value="New contact from website">
Name your email field email and we'll automatically set it as the reply-to address — so you can reply directly to the person from your inbox.
<input type="email" name="email" placeholder="Your email">
Send a copy of the notification email to one or more extra addresses. Good for when more than one person needs to see each submission.
<!-- One address --> <input type="hidden" name="_cc" value="team@yourcompany.com"> <!-- Multiple addresses — separate with commas --> <input type="hidden" name="_cc" value="sales@co.com, support@co.com">
Send the user to your own thank-you page after they submit. Without this, they'll land on the default 000form confirmation page.
<input type="hidden" name="_next" value="https://yoursite.com/thank-you">
Choose how your notification email looks. If you don't pick one, basic is used by default.
| Value | What it looks like |
|---|---|
basic |
Simple list — one field per row. Clean and easy to read. Used by default. |
box |
Each field gets its own bordered box. Images show as previews inside the email. |
table |
Two-column table — field name on the left, value on the right. |
<input type="hidden" name="_template" value="basic"> <!-- default --> <input type="hidden" name="_template" value="box"> <input type="hidden" name="_template" value="table">
Send an automatic reply to the person who filled in your form. Your form needs an email field for this to work.
<!-- A default subject line is added for you --> <input type="hidden" name="_auto-response" value="Thanks for getting in touch! We'll get back to you shortly.">
<input type="hidden" name="_auto-response" value="Hi {name}, we got your message on {date}.|We received your message!">
| Placeholder | Gets replaced with |
|---|---|
{name} | What the user typed in the name field |
{email} | What the user typed in the email field |
{date} | Today's date (YYYY-MM-DD) |
Block submissions that contain certain words. If any field in the form has a banned word, the email is dropped before it reaches your inbox. The person still sees a success message, so they won't know it was blocked.
<!-- Separate banned words or phrases with commas --> <input type="hidden" name="_blacklist" value="buy now, click here, casino, free money">
Add a hidden field that spam bots fill in on their own. Real people never see it, so only bots trigger it. Any submission with this field filled in gets dropped.
<!-- Hidden from people — bots fill it in, which triggers the block --> <input type="text" name="_gotcha" style="display:none;">
Let people attach files when they submit. Files are sent as email attachments. With the box template, images also show up as previews inside the email.
<input type="file" name="upload">
<input type="file" name="uploads[]" multiple>
<!-- Add enctype="multipart/form-data" whenever you use file inputs --> <form action="https://000form.com/f/YOUR_FORM_ID" method="POST" enctype="multipart/form-data"> <input type="text" name="name" required> <input type="email" name="email" required> <input type="file" name="uploads[]" multiple> <button type="submit">Send</button> </form>
| Limit | Value |
|---|---|
Per file | 10 MB max |
Per submission | Up to 5 files |
enctype | Must be multipart/form-data — required for file inputs to work |
Submit the form without reloading the page. Add Accept: application/json to your request and you'll get a JSON response back instead of a page redirect.
const form = document.getElementById('YOUR-FORM-ID'); const responseBox = document.getElementById('form-response'); form.addEventListener('submit', async (e) => { e.preventDefault(); const btn = form.querySelector('button[type="submit"]'); btn.disabled = true; btn.textContent = 'Sending...'; try { const res = await fetch(form.action, { method: 'POST', body: new FormData(form), headers: { 'Accept': 'application/json' } }); const data = await res.json(); if (res.ok && data.success) { responseBox.innerHTML = '<span style="color:#00ff88">✓ Message sent Successfully!</span>'; form.reset(); // If _next is set, send the user there if (data.redirect) location.href = data.redirect; } else { throw new Error(data.message || 'Something went wrong'); } } catch (err) { responseBox.innerHTML = `<span style="color:#ef4444">✗ ${err.message}</span>`; } finally { btn.disabled = false; btn.textContent = 'Send Message'; } });
<!-- Replace YOUR_FORM_ID with your actual form ID from the dashboard --> <form id="contact-form" action="https://000form.com/f/YOUR_FORM_ID" method="POST"> <input type="text" name="name" placeholder="Your name" required> <input type="email" name="email" placeholder="Your email" required> <textarea name="message" placeholder="Your message" required></textarea> <div id="form-response"></div> <button type="submit">Send Message</button> </form> <script> document.getElementById('contact-form').addEventListener('submit', async function(e) { e.preventDefault(); const form = this; const box = document.getElementById('form-response'); const btn = form.querySelector('button[type="submit"]'); box.innerHTML = ''; btn.disabled = true; btn.textContent = 'Sending...'; try { const res = await fetch(form.action, { method: 'POST', body: new FormData(form), headers: { 'Accept': 'application/json' } }); const statusCode = res.status; const text = await res.text(); let data = {}; try { data = JSON.parse(text); } catch(err) {} if (statusCode === 200 && data.success) { box.innerHTML = '<p style="color:#22c55e;font-weight:500;">✓ Message sent successfully!</p>'; form.reset(); if (data.redirect) location.href = data.redirect; return; } if (statusCode === 422) { if (data.validation_error && Array.isArray(data.errors)) { box.innerHTML = data.errors.map(e => `<p style="color:#ef4444;margin:4px 0;">✗ ${e.field}: ${e.message}</p>` ).join(''); } else if (data.errors) { box.innerHTML = Object.entries(data.errors).map(([field, errs]) => `<p style="color:#ef4444;margin:4px 0;">✗ ${field}: ${errs[0]}</p>` ).join(''); } else { box.innerHTML = '<p style="color:#ef4444;">✗ Validation failed.</p>'; } return; } if (statusCode === 403) { box.innerHTML = '<p style="color:#ef4444;">✗ Form is not active or email is not verified.</p>'; return; } box.innerHTML = `<p style="color:#ef4444;">✗ ${data.message || data.error || 'Something went wrong.'}</p>`; } catch(err) { box.innerHTML = `<p style="color:#ef4444;">✗ Network error: ${err.message}</p>`; } finally { btn.disabled = false; btn.textContent = 'Send Message'; } }); </script>
Add a beautiful chat widget to your website that submits directly to 000form. Perfect for customer support or live chat integration.
<!-- Replace YOUR_FORM_ID with your actual form ID --> <script src="https://000form.com/formbutton/YOUR_FORM_ID/widget.js" defer></script>
| Feature | Description |
|---|---|
💬 Live chat |
Floating chat button with popup interface |
📱 Responsive |
Works perfectly on mobile and desktop |
🔔 Notifications |
Unread message indicator badge |
Everything included on the free plan.