Provider retries can duplicate side effects
The same entry may arrive repeatedly during the documented retry window, so every attempt must remain one delivery identity.
Cognito Forms CRM delivery
Keep Cognito Forms' documented retry window duplicate-safe, forward only approved contact fields, and retain a LeadProof receipt for the final CRM handoff.
Paid plan uses secure Stripe checkout · plan assigned after verified payment · activate with the checkout emailCognito Forms can retry a webhook up to 15 times over 72 hours after most 4xx or 5xx responses, and its JSON webhook can contain the complete form entry. Without a stable entry identity and strict field allowlist, one temporary adapter failure can create duplicate CRM work or forward documents and unrelated response data that the destination never needed.
Cognito Forms submit webhook -> private adapter -> durable queue -> LeadProof -> CRMThe same entry may arrive repeatedly during the documented retry window, so every attempt must remain one delivery identity.
Cognito Forms can include every entry field and short-lived document links; a lead adapter should select only the approved contact fields.
A 2xx from the receiving adapter should mean the mapped event is durable, not merely that the request reached application memory.
Implementation
Keep the tools that create and process the lead. Standardize only the fragile handoff between them.
Platform reference: Cognito Forms webhook documentation ↗Open sandbox instructions →https://leadproof.jessesay.chatgpt.site/api/v1/leadsimport crypto from "node:crypto";
function sameSecret(supplied, expected) {
if (!supplied || !expected) return false;
const left = Buffer.from(supplied);
const right = Buffer.from(expected);
return left.length === right.length && crypto.timingSafeEqual(left, right);
}
app.post(
"/cognito/submission/:token",
(req, res, next) => {
if (
!sameSecret(
req.params.token,
process.env.COGNITO_WEBHOOK_ROUTE_TOKEN
)
) {
return res.sendStatus(404);
}
return next();
},
express.json({ limit: "64kb" }),
async (req, res) => {
const entryId = req.body?.id;
const lead = {
name: typeof req.body?.name === "string" ? req.body.name : undefined,
email: typeof req.body?.email === "string" ? req.body.email : undefined,
phone: typeof req.body?.phone === "string" ? req.body.phone : undefined
};
if (typeof entryId !== "string" || !lead.name || !lead.email) {
await recordRejectedEntry({
source: "cognito_forms",
reason: "missing_approved_fields"
});
return res.sendStatus(204);
}
await deliveryQueue.send({ entryId, lead });
return res.sendStatus(202);
}
);
export async function deliverCognitoLead({ entryId, lead }) {
const response = await fetch(
"https://leadproof.jessesay.chatgpt.site/api/v1/leads",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LEADPROOF_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": entryId
},
body: JSON.stringify({
destination: process.env.CRM_WEBHOOK_URL,
...lead,
source: "cognito_forms"
})
}
);
if (!response.ok) throw new Error("Lead delivery failed");
const delivery = await response.json();
await persistReceipt(entryId, delivery.receipt?.id);
}Questions
Cognito Forms includes an id in its documented JSON examples. Using that source identity keeps repeated webhook attempts attached to one LeadProof delivery event.
Cognito Forms documents retries for most 4xx and 5xx responses. A success response should be sent only after the mapped event is durable enough for the worker to finish later.
No. Map only the fields authorized for CRM delivery. The adapter example excludes document links, uploads, signatures, payments, and unrelated form answers.
Get an explainable risk score, prioritized fixes, and the right LeadProof plan.