# Contact Forms API & Anti-Spam Endpoints

> Collect website contact form leads directly in your inbox with zero backend code. Includes honeypot bot trap, spam shield, and instant email dispatch.

SadaSend provides instant, zero-maintenance form endpoints for static sites, modern JavaScript frameworks, and no-code builders. Create an endpoint in your dashboard, embed the snippet, and inquiries arrive in your inbox.

## How it works

Traditional contact forms require a backend Node.js server, AWS Lambda function, or PHP script just to forward inquiries to your email.

With SadaSend Contact Forms, you submit directly to our API endpoint. Submissions are screened through our invisible honeypot shield and disposable domain blocker, forwarded to your inbox, and logged in your dashboard inbox with instant CSV export.

## Standard endpoint & parameter reference

Endpoint URL: `POST https://api.sadasend.com/forms/submit`

Accepts standard `application/x-www-form-urlencoded`, `multipart/form-data`, or `application/json`.

| Parameter | Type | Required | Description |

| --- | --- | --- | --- |

| access_key | string | Yes | Your unique public form endpoint key from /app/forms. |
| name | string | Recommended | Visitor name. Used in notifications and {{name}} template variables. |
| email | string | Recommended | Visitor email. Automatically set as the Reply-To address. |
| subject | string | Optional | Custom email subject line for the incoming lead notification. |
| redirect | string | Optional | Redirect URL after submission (for static HTML forms). |
| botcheck | string | Optional | Invisible honeypot field. Keep hidden and empty; if filled, bot is trapped. |
| [custom] | string | Optional | Any custom fields (e.g. phone, company, message) are captured automatically. |

## Plain HTML embed snippet

Paste this snippet into any static website or landing page template:

```html
<form action="https://api.sadasend.com/forms/submit" method="POST">
  <!-- Required SadaSend Access Key -->
  <input type="hidden" name="access_key" value="sada_form_your_key_here" />
  <input type="hidden" name="redirect" value="https://yoursite.com/thank-you" />

  <!-- Invisible Honeypot Spam Shield (Keep Hidden) -->
  <input type="checkbox" name="botcheck" class="hidden" style="display: none;" />

  <!-- Visitor Inputs -->
  <input type="text" name="name" required placeholder="Your Name" />
  <input type="email" name="email" required placeholder="you@company.com" />
  <textarea name="message" required placeholder="How can we help?"></textarea>

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

## Vanilla JavaScript (Fetch API with FormData)

For single-page applications or static templates requiring inline success feedback without page redirects:

```javascript
const form = document.getElementById('contact-form');
const submitBtn = document.getElementById('submit-btn');
const result = document.getElementById('result');

form.addEventListener('submit', async (e) => {
  e.preventDefault();
  submitBtn.disabled = true;
  submitBtn.textContent = 'Sending...';
  result.textContent = '';

  const formData = new FormData(form);
  formData.append('access_key', 'sada_form_your_key_here');

  try {
    const response = await fetch('https://api.sadasend.com/forms/submit', {
      method: 'POST',
      headers: { Accept: 'application/json' },
      body: formData,
    });

    const data = await response.json();
    if (response.ok && data.success) {
      result.textContent = 'Thank you! Your message has been sent.';
      form.reset();
    } else {
      result.textContent = 'Error: ' + (data.message || 'Submission failed');
    }
  } catch (error) {
    result.textContent = 'Network error. Please try again.';
  } finally {
    submitBtn.disabled = false;
    submitBtn.textContent = 'Send Message';
  }
});
```

## React & Next.js integration

Integrates cleanly with React 18/19 and Next.js (App Router or Pages Router). Works as a Client Component (`"use client"`) with no backend API route required:

```tsx
'use client';

import React, { useState } from 'react';

export function ContactForm() {
  const [status, setStatus] = useState<'idle' | 'sending' | 'success' | 'error'>('idle');
  const [errorMessage, setErrorMessage] = useState('');

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setStatus('sending');
    const form = e.currentTarget;
    const formData = new FormData(form);

    try {
      const res = await fetch('https://api.sadasend.com/forms/submit', {
        method: 'POST',
        headers: { Accept: 'application/json' },
        body: formData,
      });

      const data = await res.json();
      if (res.ok && data.success) {
        setStatus('success');
        form.reset();
      } else {
        setStatus('error');
        setErrorMessage(data.message || 'Submission failed');
      }
    } catch (err) {
      setStatus('error');
      setErrorMessage('Network error submitting form');
    }
  }

  if (status === 'success') {
    return <div className="text-emerald-700 font-medium">Thank you! Your message has been sent.</div>;
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <input type="hidden" name="access_key" value="sada_form_your_key_here" />
      <input type="checkbox" name="botcheck" className="hidden" style={{ display: 'none' }} />

      <div>
        <label className="block text-sm font-medium">Name</label>
        <input name="name" type="text" required className="w-full border rounded px-3 py-2" />
      </div>

      <div>
        <label className="block text-sm font-medium">Email</label>
        <input name="email" type="email" required className="w-full border rounded px-3 py-2" />
      </div>

      <div>
        <label className="block text-sm font-medium">Message</label>
        <textarea name="message" required rows={4} className="w-full border rounded px-3 py-2" />
      </div>

      {status === 'error' && <p className="text-red-600 text-sm">{errorMessage}</p>}

      <button
        type="submit"
        disabled={status === 'sending'}
        className="px-4 py-2 bg-emerald-800 text-white rounded font-medium text-sm disabled:opacity-50"
      >
        {status === 'sending' ? 'Sending...' : 'Send Message'}
      </button>
    </form>
  );
}
```

## Astro static site integration

Astro enables fast static sites. You can embed SadaSend directly in an `.astro` component with zero client runtime dependencies, or with a client script for smooth AJAX feedback:

```astro
---
// src/components/ContactForm.astro
const ACCESS_KEY = "sada_form_your_key_here";
---

<form id="contact-form" class="space-y-4">
  <input type="hidden" name="access_key" value={ACCESS_KEY} />
  <input type="checkbox" name="botcheck" class="hidden" style="display: none;" />

  <div>
    <label for="name" class="block text-sm font-medium">Name</label>
    <input type="text" id="name" name="name" required class="w-full border px-3 py-2 rounded" />
  </div>

  <div>
    <label for="email" class="block text-sm font-medium">Email</label>
    <input type="email" id="email" name="email" required class="w-full border px-3 py-2 rounded" />
  </div>

  <div>
    <label for="message" class="block text-sm font-medium">Message</label>
    <textarea id="message" name="message" required rows="4" class="w-full border px-3 py-2 rounded"></textarea>
  </div>

  <button type="submit" id="submit-btn" class="px-4 py-2 bg-emerald-800 text-white rounded">
    Send Message
  </button>
  <div id="form-result" class="text-sm font-medium mt-2"></div>
</form>

<script>
  const form = document.getElementById("contact-form") as HTMLFormElement;
  const result = document.getElementById("form-result") as HTMLElement;
  const btn = document.getElementById("submit-btn") as HTMLButtonElement;

  form?.addEventListener("submit", async (e) => {
    e.preventDefault();
    btn.disabled = true;
    btn.textContent = "Sending...";
    result.textContent = "";

    try {
      const response = await fetch("https://api.sadasend.com/forms/submit", {
        method: "POST",
        body: new FormData(form),
        headers: { Accept: "application/json" },
      });
      const data = await response.json();
      if (response.ok && data.success) {
        result.textContent = "Thank you! Your message has been sent.";
        form.reset();
      } else {
        result.textContent = data.message || "Something went wrong.";
      }
    } catch (err) {
      result.textContent = "Network error. Please try again.";
    } finally {
      btn.disabled = false;
      btn.textContent = "Send Message";
    }
  });
</script>
```

## Vue 3 & Nuxt 3 component

For Vue 3 and Nuxt 3 applications, use the Composition API with `<script setup>` and reactive submission status:

```vue
<script setup lang="ts">
import { ref } from 'vue';

const status = ref<'idle' | 'sending' | 'success' | 'error'>('idle');
const message = ref('');

async function handleSubmit(event: Event) {
  status.value = 'sending';
  const form = event.target as HTMLFormElement;
  const formData = new FormData(form);

  try {
    const res = await fetch('https://api.sadasend.com/forms/submit', {
      method: 'POST',
      headers: { Accept: 'application/json' },
      body: formData,
    });
    const data = await res.json();
    if (res.ok && data.success) {
      status.value = 'success';
      message.value = 'Thank you! Your message has been sent.';
      form.reset();
    } else {
      status.value = 'error';
      message.value = data.message || 'Submission failed.';
    }
  } catch (e) {
    status.value = 'error';
    message.value = 'Network error. Please try again.';
  }
}
</script>

<template>
  <form @submit.prevent="handleSubmit" class="space-y-4">
    <input type="hidden" name="access_key" value="sada_form_your_key_here" />
    <input type="checkbox" name="botcheck" class="hidden" style="display: none;" />

    <div>
      <label class="block text-sm font-medium">Name</label>
      <input type="text" name="name" required class="w-full border px-3 py-2 rounded" />
    </div>

    <div>
      <label class="block text-sm font-medium">Email</label>
      <input type="email" name="email" required class="w-full border px-3 py-2 rounded" />
    </div>

    <div>
      <label class="block text-sm font-medium">Message</label>
      <textarea name="message" required rows="4" class="w-full border px-3 py-2 rounded"></textarea>
    </div>

    <p v-if="status === 'success'" class="text-sm text-emerald-600 font-medium">{{ message }}</p>
    <p v-if="status === 'error'" class="text-sm text-red-600 font-medium">{{ message }}</p>

    <button type="submit" :disabled="status === 'sending'" class="px-4 py-2 bg-emerald-800 text-white rounded">
      {{ status === 'sending' ? 'Sending...' : 'Send Message' }}
    </button>
  </form>
</template>
```

## Webflow form settings guide

Connect any native Webflow form without Zapier or third-party paid automations:

## Framer embed & code component

Framer sites can receive inquiries using either the Embed component or a custom Code Component:

## WordPress & Elementor HTML embed

Replace heavy, vulnerable form plugins (like Contact Form 7 or WPForms) that bloat page load speeds:

## cURL & terminal testing

Test form endpoints directly from your command line or integrate with backend shell scripts:

```bash
curl -X POST https://api.sadasend.com/forms/submit \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "access_key": "sada_form_your_key_here",
    "name": "Jane Doe",
    "email": "jane@company.com",
    "subject": "Inquiry regarding Enterprise Services",
    "message": "Hello, we would like to schedule a product walkthrough."
  }'
```

## Spam defense & bot trapping

SadaSend shields your inbox against automated form abuse through a multi-tier defense:

• **Invisible Honeypot Shield**: The hidden botcheck field catches automated scripts. When filled, SadaSend returns HTTP 200 { success: true } so the bot believes it succeeded, while silently blocking email notifications.

• **Disposable Domain Blocker**: Rejects temporary 10-minute email domains (e.g. Mailinator, TempMail).

• **CORS Origin Lock**: Restrict submissions exclusively to your verified website domains.

## Free plan quota & Starter upgrades

• **Free Plan**: Includes 2 active form endpoints, 250 submissions/month, basic honeypot shielding, and CSV export.

• **Starter Plan ($12/mo)**: Unlocks up to 10 form endpoints, automated customer confirmation emails (auto-responders), CC & BCC notifications, custom branded email templates, and real-time webhook forwarding to Telegram and Zapier/Make.
