FormLynk — Connect your forms. Send anywhere.
ECOSYSTEM & COMPATIBILITY

Connect with your entire stack.

From modern React meta-frameworks and static site generators to transactional SMTP providers and outbound webhook automations.

03UNIVERSAL COMPATIBILITY

One API. Any frontend or framework.

Whatever technology you use to render your user interface, submitting a form is as simple as making a single HTTPS POST request to FormLynk.

Next.js

App Router / Pages

Native Client Component fetch with TypeScript typings & zero bundle bloat.

POST /api/v1/forms/submit→

React

Vite / CRA / SPAs

Standard async event handlers and hook integration in any React frontend.

POST /api/v1/forms/submit→

Vue.js / Nuxt

Vue 3 Composition API

Reactive v-model bindings sending direct REST JSON payloads.

POST /api/v1/forms/submit→

Svelte / SvelteKit

Reactive Web Apps

Lightweight fetch dispatch with Svelte stores or standard forms.

POST /api/v1/forms/submit→

Static HTML

Vanilla Web

Works with pure <form> tags or micro JS snippets with file attachments.

POST /api/v1/forms/submit→

WordPress

Custom Blocks & Themes

Bypass bloated form plugins and heavy database bloat on WP hosting.

POST /api/v1/forms/submit→

Shopify

Liquid & Hydrogen

Custom wholesale, return, and lead capture forms without monthly app fees.

POST /api/v1/forms/submit→

PHP

Server-to-Server

Send server-side form payloads securely using Private API Keys (sk_live_).

POST /api/v1/forms/submit→

Mobile Apps

iOS / Android / Flutter

Submit in-app feedback, bug reports, and KYC documents via standard HTTPS.

POST /api/v1/forms/submit→
Supports both JSON payloads and multipart/form-data for file attachments.
Explore all integration guides →
04NEXT.JS & VERCEL OPTIMIZED

Deploy your frontend anywhere.

Build pure static or serverless Next.js applications on Vercel, Cloudflare, Netlify, or AWS without provisioning server databases or custom API route workers.

Zero Serverless Function Cold Starts:

Avoid burning serverless execution limits on form submission processing.

Safe Browser Public Key Architecture:

Store NEXT_PUBLIC_FORM_API_KEY safely in client bundles. Protected via strict domain CORS whitelisting.

Built-in Bot Honeypot (_gotcha):

Included in the payload without loading heavy third-party client scripts.

ENVIRONMENT CONFIGURATION:
.env.local
NEXT_PUBLIC_FORM_API_KEY=pk_live_xxxxxxxxx
components/ContactForm.tsx
typescript
1"use client";
2import { useState } from "react";
3
4export default function ContactForm() {
5 const [status, setStatus] = useState<{
6 loading: boolean;
7 success: boolean;
8 error: string | null;
9 }>({ loading: false, success: false, error: null });
10
11 async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
12 e.preventDefault();
13 setStatus({ loading: true, success: false, error: null });
14
15 const form = e.currentTarget;
16 const formData = new FormData(form);
17 const data = Object.fromEntries(formData.entries());
18
19 try {
20 const response = await fetch("https://api.formlynk.io/api/v1/forms/submit", {
21 method: "POST",
22 headers: {
23 "Content-Type": "application/json",
24 "X-API-Key": process.env.NEXT_PUBLIC_FORM_API_KEY!,
25 },
26 body: JSON.stringify({
27 form_id: "contact",
28 ...data,
29 }),
30 });
31
32 const result = await response.json();
33 if (response.ok && result.success) {
34 setStatus({ loading: false, success: true, error: null });
35 form.reset();
36 } else {
37 setStatus({
38 loading: false,
39 success: false,
40 error: result.error?.message || "Submission failed. Please try again.",
41 });
42 }
43 } catch (err) {
44 setStatus({ loading: false, success: false, error: "Network connection error." });
45 }
46 }
47
48 return (
49 <form onSubmit={handleSubmit} className="space-y-4">
50 {/* Honeypot field (hidden from real users, traps automated bots) */}
51 <input
52 type="text"
53 name="_gotcha"
54 style={{ display: "none" }}
55 tabIndex={-1}
56 autoComplete="off"
57 />
58
59 <div>
60 <label htmlFor="name" className="block text-sm font-medium text-slate-700">Name</label>
61 <input id="name" type="text" name="name" required className="w-full border px-3 py-2 rounded" />
62 </div>
63
64 <div>
65 <label htmlFor="email" className="block text-sm font-medium text-slate-700">Email</label>
66 <input id="email" type="email" name="email" required className="w-full border px-3 py-2 rounded" />
67 </div>
68
69 <div>
70 <label htmlFor="message" className="block text-sm font-medium text-slate-700">Message</label>
71 <textarea id="message" name="message" required rows={4} className="w-full border px-3 py-2 rounded" />
72 </div>
73
74 {status.error && <p className="text-sm text-red-600">{status.error}</p>}
75 {status.success && <p className="text-sm text-green-600">Thank you! Your message was received.</p>}
76
77 <button
78 type="submit"
79 disabled={status.loading}
80 className="px-5 py-2.5 bg-ink text-white font-medium rounded hover:bg-black transition"
81 >
82 {status.loading ? "Sending..." : "Send Message"}
83 </button>
84 </form>
85 );
86}
05INTEGRATION SAMPLES

From form to API in minutes.

Copy and paste production-ready snippets into your codebase. No proprietary SDKs, bloated dependencies, or complex setup steps.

Production Next.js 14/15 Client Component with FormLynk endpoint, state handling, and honeypot.Full API Docs
components/ContactForm.tsx
typescript
1"use client";
2import { useState } from "react";
3
4export default function ContactForm() {
5 const [status, setStatus] = useState<{
6 loading: boolean;
7 success: boolean;
8 error: string | null;
9 }>({ loading: false, success: false, error: null });
10
11 async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
12 e.preventDefault();
13 setStatus({ loading: true, success: false, error: null });
14
15 const form = e.currentTarget;
16 const formData = new FormData(form);
17 const data = Object.fromEntries(formData.entries());
18
19 try {
20 const response = await fetch("https://api.formlynk.io/api/v1/forms/submit", {
21 method: "POST",
22 headers: {
23 "Content-Type": "application/json",
24 "X-API-Key": process.env.NEXT_PUBLIC_FORM_API_KEY!,
25 },
26 body: JSON.stringify({
27 form_id: "contact",
28 ...data,
29 }),
30 });
31
32 const result = await response.json();
33 if (response.ok && result.success) {
34 setStatus({ loading: false, success: true, error: null });
35 form.reset();
36 } else {
37 setStatus({
38 loading: false,
39 success: false,
40 error: result.error?.message || "Submission failed. Please try again.",
41 });
42 }
43 } catch (err) {
44 setStatus({ loading: false, success: false, error: "Network connection error." });
45 }
46 }
47
48 return (
49 <form onSubmit={handleSubmit} className="space-y-4">
50 {/* Honeypot field (hidden from real users, traps automated bots) */}
51 <input
52 type="text"
53 name="_gotcha"
54 style={{ display: "none" }}
55 tabIndex={-1}
56 autoComplete="off"
57 />
58
59 <div>
60 <label htmlFor="name" className="block text-sm font-medium text-slate-700">Name</label>
61 <input id="name" type="text" name="name" required className="w-full border px-3 py-2 rounded" />
62 </div>
63
64 <div>
65 <label htmlFor="email" className="block text-sm font-medium text-slate-700">Email</label>
66 <input id="email" type="email" name="email" required className="w-full border px-3 py-2 rounded" />
67 </div>
68
69 <div>
70 <label htmlFor="message" className="block text-sm font-medium text-slate-700">Message</label>
71 <textarea id="message" name="message" required rows={4} className="w-full border px-3 py-2 rounded" />
72 </div>
73
74 {status.error && <p className="text-sm text-red-600">{status.error}</p>}
75 {status.success && <p className="text-sm text-green-600">Thank you! Your message was received.</p>}
76
77 <button
78 type="submit"
79 disabled={status.loading}
80 className="px-5 py-2.5 bg-ink text-white font-medium rounded hover:bg-black transition"
81 >
82 {status.loading ? "Sending..." : "Send Message"}
83 </button>
84 </form>
85 );
86}
11SMTP INFRASTRUCTURE

Bring your own SMTP or use our shared mailer.

Every project workspace can connect its own dedicated transactional SMTP credentials. Passwords and API tokens are encrypted at rest with AES-256.

SendGrid

Supported

Connect your SendGrid API key or SMTP user with TLS authentication.

smtp.sendgrid.netPort 587 / 465

Postmark

Supported

Ultra-fast transactional deliverability with Postmark server tokens.

smtp.postmarkapp.comPort 587 / 2525

Amazon SES

Supported

Low-cost high-volume deliverability via your dedicated AWS SES credentials.

email-smtp.*.amazonaws.comPort 587 / 465

Mailgun

Supported

Custom domain routing with Mailgun SMTP credentials per project.

smtp.mailgun.orgPort 587

Brevo (Sendinblue)

Supported

European data-residency compliant transactional relay integration.

smtp-relay.brevo.comPort 587

Default Shared Mailer

Included Free

Zero configuration needed. Included out-of-the-box on all plans.

System Managed RelayPort Encrypted Queue
SMTP passwords and authorization secrets are strictly encrypted at rest inside the database using AES-256-CBC.
09AUTOMATION & INTEGRATION

Outbound HMAC webhooks in real time.

Sync submissions directly to Zapier, Make, HubSpot, Slack, or internal REST APIs with cryptographically verifiable HMAC-SHA256 signatures.

WEBHOOK EVENT DISPATCHER
OUTBOUND HTTP HEADERS:
X-Webhook-Signature: sha256=d87f98e72c0192e4483a992bc8310f823485ab921c
Content-Type: application/json
{
  "event": "submission.created",
  "timestamp": "2026-09-26T15:20:00Z",
  "project_id": "prj_01h9x4b9e28k",
  "submission_id": "sub_8f92ab31c4e2",
  "form": {
    "id": "contact",
    "name": "Main Contact Form"
  },
  "data": {
    "name": "Sarah Chen",
    "email": "sarah@techcorp.com",
    "phone": "+1 415-555-0199",
    "message": "We need a custom enterprise SLA for high-volume lead capture."
  },
  "client": {
    "ip_address": "198.51.100.42",
    "origin": "https://techcorp.com"
  }
}
Cryptographic Verification:Calculate HMAC-SHA256 using your secret token and compare against the X-Webhook-Signature header with timing-safe equality to verify authenticity.