Documentation
Intégrez en quelques minutes.
Votre site ne touche jamais au SMTP. Il détient deux valeurs et appelle deux endpoints — le service se charge de l'envoi, du filtrage anti-spam et de la réponse automatique à votre image.
1Le contrat à deux valeurs
Créez un formulaire dans votre tableau de bord et copiez son ID. Donnez à votre site exactement deux valeurs :
FORM_API_URLL'origine du service — là où partent les défis et les soumissions.
FORM_IDL'UUID d'un formulaire. Chaque site (ou chaque formulaire) a le sien.
2L'assistant à copier-coller
Fonctionne avec Astro, Next.js, Nuxt, Vue, Svelte, ou un simple <script type="module">.
// form-service.js — drop into any project (framework-agnostic)
const API_URL = import.meta.env.PUBLIC_FORM_API_URL; // or process.env / hardcode
const FORM_ID = import.meta.env.PUBLIC_FORM_ID; // UUID from your dashboard
async function sha256Hex(text) {
const buf = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
return [...new Uint8Array(buf)].map(b => b.toString(16).padStart(2, "0")).join("");
}
export async function submitForm(fields, { lang = "en" } = {}) {
// 1. Get a proof-of-work challenge
const c = await (await fetch(`${API_URL}/api/challenge`)).json();
// 2. Solve it (costs a bot CPU, costs your user ~a blink)
let nonce = 0;
const prefix = "0".repeat(c.difficulty);
while (!(await sha256Hex(`${c.challenge}:${nonce}`)).startsWith(prefix)) nonce++;
// 3. Submit the fields
const res = await fetch(`${API_URL}/api/submit/${FORM_ID}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
...fields,
_lang: lang,
_gotcha: "", // honeypot — leave empty
pow_challenge: c.challenge,
pow_timestamp: c.timestamp,
pow_nonce: String(nonce),
}),
});
if (!res.ok) throw new Error((await res.json()).error ?? "Submission failed");
return res.json();
}3Utilisez-le
import { submitForm } from "./form-service";
await submitForm({
name: "Ada Lovelace",
email: "ada@example.com", // used for the branded auto-reply
message: "I'd like a quote.",
});email field— s'il est présent, l'expéditeur reçoit votre réponse automatique à votre image._lang— "en" ou "fr" — sélectionne la langue de la réponse automatique._gotcha— champ honeypot caché. Les humains le laissent vide ; les bots le remplissent et sont écartés en silence.files— envoyez des données en base64 — elles sont téléversées vers le stockage et arrivent sous forme de liens de téléchargement.
4Laissez votre IA le faire
Vous utilisez Claude, Cursor ou Copilot ? Nous publions un fichier d'installation lisible par machine à /llm-install.md — collez ce prompt et votre IA réalise toute l'intégration, correctement, du premier coup :
Read https://inlett.vercel.app/llm-install.md
and integrate Inlet into this project exactly as it instructs.
My values: FORM_API_URL=https://inlett.vercel.app FORM_ID=<paste yours>Utilisateurs de Claude Code : déposez notre fichier skill .claude/skills/inlet/SKILL.md et Claude câble seul les formulaires, honeypots et webhooks dans n'importe quel projet.
5Webhooks (optionnel)
Ajoutez une URL de webhook à un formulaire et chaque lead stocké est envoyé (POST) à votre endpoint sous forme de submission.created, signé façon Stripe dans l'en-tête X-Inlet-Signature — vérifiez-le et rejetez les rejeux en cinq lignes :
// Verify Inlet's webhook signature (Node) — read the RAW body first.
import crypto from "node:crypto";
export function verifyInletWebhook(rawBody, sigHeader, secret, toleranceSec = 300) {
const p = Object.fromEntries(sigHeader.split(",").map(s => s.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${p.t}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(p.t)) < toleranceSec;
return fresh && crypto.timingSafeEqual(Buffer.from(p.v1), Buffer.from(expected));
}La livraison est asynchrone avec une nouvelle tentative — un endpoint hors service ne peut jamais bloquer ni perdre un lead. Les endpoints doivent être en https.
Ce qui se passe côté serveur
Quatre barrières anti-spam. Honeypot, vérification par preuve de travail, filtre NLP par mots-clés, blocage VPN/cloud par DNS inversé. Les tentatives bloquées sont journalisées, jamais délivrées.
Deux e-mails. Le propriétaire reçoit la notification du lead ; l'expéditeur reçoit une réponse automatique à l'image de votre client — logo, couleurs, nom d'expéditeur. La bascule SMTP de secours fait qu'un identifiant défaillant ne perd jamais un lead.