EdgeSubmit Documentation
Add form submissions to any website. No backend required.
https://api.edgesubmit.comAll API endpoints accept and return JSON. CORS is enabled for all origins by default.
Quick Start
Get form submissions working in 2 minutes:
- Create an account — Go to the dashboard and enter your email.
- Copy your API key — You'll get an API key that starts with
es_. - 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
The main form submission endpoint. Accepts form data via JSON, URL-encoded, or multipart.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
access_key | string | Yes | Your EdgeSubmit API key |
[any field] | string | No | Any form field — all are included in the email |
Content Types
application/json— JSON bodyapplication/x-www-form-urlencoded— Standard HTML formmultipart/form-data— File upload forms
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.
| Field | Description |
|---|---|
access_key | Your API key (required) |
_subject | Custom email subject line |
_redirect | URL to redirect to after submission (for HTML forms) |
_replyto | Set the reply-to address on the notification email |
_from_name | Custom "from" name on the notification email |
_honeypot | Hidden field — if filled, submission is silently dropped (spam protection) |
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
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
List all API keys for your account.
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
List recent form submissions with pagination.
GET /api/stats
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
| Plan | Monthly Submissions | Rate (per minute) |
|---|---|---|
| Free | 250 | 5 |
| Pro | 2,500 | 30 |
| Business | 100,000 | 100 |
When you hit a rate limit, the API returns a 429 status. Monthly limits reset on your account anniversary date.
Error Codes
| Status | Error | Description |
|---|---|---|
400 | Invalid request body | Could not parse the request |
401 | Missing access_key | No API key in form data |
401 | Invalid API key | Key not found or inactive |
429 | Rate limit exceeded | Too many requests per minute |
429 | Monthly limit reached | Upgrade plan for more submissions |
500 | Internal server error | Something went wrong on our end |