EdgeSubmit Documentation

Add form submissions to any website. No backend required.

Base URL: https://api.edgesubmit.com
All API endpoints accept and return JSON. CORS is enabled for all origins by default.

Quick Start

Get form submissions working in 2 minutes:

  1. Create an account — Go to the dashboard and enter your email.
  2. Copy your API key — You'll get an API key that starts with es_.
  3. Add the form — Point your HTML form to our endpoint:
<!-- Drop this into any HTML page -->
<form action="https://api.edgesubmit.com/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_API_KEY" />
  <input type="text" name="name" required />
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>
  <button type="submit">Send</button>
</form>

That's it. Submissions will be emailed to the address tied to your API key.

Authentication

EdgeSubmit uses API keys for authentication. Include your API key as a form field named access_key in every submission.

Your API key starts with es_ and is 64+ characters long. Keep it in your frontend code — it's designed to be public-facing (like a Stripe publishable key). Origin restrictions can be configured per key for extra security.

For dashboard API endpoints (/api/*), use the user_id query parameter returned during registration.

POST /submit

POST /submit

The main form submission endpoint. Accepts form data via JSON, URL-encoded, or multipart.

Request Body

FieldTypeRequiredDescription
access_keystringYesYour EdgeSubmit API key
[any field]stringNoAny form field — all are included in the email

Content Types

Success Response

{
  "success": true,
  "message": "Submission received"
}

Error Response

{
  "success": false,
  "error": "Missing access_key. Include your EdgeSubmit API key in the form data."
}

Special Fields

These optional fields control behavior. They are not included in the email body.

FieldDescription
access_keyYour API key (required)
_subjectCustom email subject line
_redirectURL to redirect to after submission (for HTML forms)
_replytoSet the reply-to address on the notification email
_from_nameCustom "from" name on the notification email
_honeypotHidden field — if filled, submission is silently dropped (spam protection)

POST /api/register

POST /api/register

Create a new account and get your first API key.

// Request
{
  "email": "you@example.com",
  "name": "Your Name"
}

// Response (201)
{
  "ok": true,
  "user_id": "abc123...",
  "api_key": "es_xxxx...",
  "plan": "free",
  "monthly_limit": 250
}

POST /api/auth

POST /api/auth

Login or register in one call. If the email exists, returns existing user data. Otherwise creates a new account.

// Request
{
  "email": "you@example.com",
  "name": "Your Name"  // optional, used on first registration
}

// Response — existing user
{
  "ok": true,
  "action": "login",
  "user": { "id": "...", "email": "...", "plan": "free" }
}

// Response — new user (201)
{
  "ok": true,
  "action": "register",
  "user": { "id": "...", "email": "...", "plan": "free" },
  "api_key": "es_xxxx..."
}

GET /api/keys

GET /api/keys?user_id=YOUR_USER_ID

List all API keys for your account.

POST /api/keys

POST /api/keys

Create a new API key.

{
  "user_id": "your_user_id",
  "to_email": "inbox@example.com",
  "label": "My Website",
  "allowed_origins": "https://mysite.com"
}

GET /api/submissions

GET /api/submissions?user_id=YOUR_USER_ID&limit=50&offset=0

List recent form submissions with pagination.

GET /api/stats

GET /api/stats?user_id=YOUR_USER_ID

Get submission counts and usage stats for the current billing period.

Framework Examples

HTML Form

<form action="https://api.edgesubmit.com/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_KEY" />
  <input name="name" required />
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>
  <button type="submit">Send</button>
</form>

JavaScript (fetch)

const res = await fetch("https://api.edgesubmit.com/submit", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    access_key: "YOUR_KEY",
    name: "Jane",
    email: "jane@example.com",
    message: "Hello!"
  })
});
const data = await res.json();

React / Next.js

async function handleSubmit(e) {
  e.preventDefault();
  const form = new FormData(e.target);
  form.append("access_key", "YOUR_KEY");
  const res = await fetch("https://api.edgesubmit.com/submit", {
    method: "POST", body: form
  });
  const data = await res.json();
}

cURL

curl -X POST https://api.edgesubmit.com/submit \
  -H "Content-Type: application/json" \
  -d '{"access_key":"YOUR_KEY","name":"Test","email":"t@t.com","message":"Hi"}'

Rate Limits

PlanMonthly SubmissionsRate (per minute)
Free2505
Pro2,50030
Business100,000100

When you hit a rate limit, the API returns a 429 status. Monthly limits reset on your account anniversary date.

Error Codes

StatusErrorDescription
400Invalid request bodyCould not parse the request
401Missing access_keyNo API key in form data
401Invalid API keyKey not found or inactive
429Rate limit exceededToo many requests per minute
429Monthly limit reachedUpgrade plan for more submissions
500Internal server errorSomething went wrong on our end