Skip to content
indraft
Start free

Cookbook

Turn a form submission into work somebody owns

Your CRM used to host the form. This one does not, so the wiring happens in whatever automation tool you already run. Here is the whole path from the form you have to a record somebody owns.

The situation

A form on your site. Contact us, request a demo, download the thing. In a traditional CRM you embed their form, it creates a lead, and a rule notifies somebody. Indraft hosts no forms and never will: it is a customer record, not a website.

So the form stays where it is, and something in the middle turns a submission into a record and a next action. That middle is an automation tool. Make and n8n are the two people reach for, both do this in three steps, and neither needs you to write anything.

Before you go looking for it

There is no Indraft app in either tool's library. Do not spend twenty minutes searching for one and conclude we are not supported. The Indraft side of every scenario in this recipe is a plain HTTP call, and both tools have a module for that: HTTP, make a request in Make, the HTTP Request node in n8n.

Configured once, it looks like this in either of them, and everything else in this recipe is a variation on the body.

Agent

Method POSTURL https://api.indraft.io/v1/contacts:upsertHeaders Authorization: Bearer ind_live_... Content-Type: application/jsonBody JSON, mapped from the form fields

Make that token a narrow one. This scenario writes contacts, companies, interactions and tasks, and it never needs to read your pipeline or touch your settings, so give it only the scopes it uses. A public form is the most exposed thing you will point at your CRM.

Start from the form you already have

The first step of the scenario is the form, and which trigger you pick depends on what your form tool can do. Three cases, in the order you should hope for them.

  • Your form tool has a ready-made trigger. Typeform, Jotform and Webflow all have one in both Make and n8n, as do most of the well-known ones. Pick it, authorise it, choose the form. The fields arrive named, which is the part that saves you the afternoon.
  • It can call a webhook. Nearly all of them can, including the form built into your site builder. Use the generic trigger, Custom webhook in Make or the Webhook node in n8n, copy the URL it gives you, and paste that into your form tool's notification settings. Submit the form once and the tool learns the field names from the real submission.
  • It can only send you an email. The oldest and least pleasant case, and still workable: trigger on the notification email arriving and pull the fields out of the body. Do this only if the first two are genuinely unavailable, because it breaks the day somebody edits the email template.

What must be true when you are done

  • A submission becomes a contact and a company, matched not duplicated.
  • What they typed is preserved, not paraphrased into a lead source field.
  • Somebody owns the follow-up, with a date.
  • Submitting twice does not create two of anything.
  • The webhook cannot be used to fill your CRM with rubbish.

This is an automation, not an agent

Worth saying plainly because it is tempting to hand the whole thing to an agent. The form already told you the fields. There is nothing to read and nothing to work out, so the job wants to be deterministic, instant, and identical at three in the morning.

Four HTTP modules in a row, each one the block above with a different URL: match or create the company from the email domain, match or create the contact from the email address, record what they typed, and create a task for whoever is on duty. Two of those four need a decision, and they are the rest of this recipe.

Map the submission id into the idempotency key

Forms get double-submitted, retried by the browser, and replayed by the automation tool itself when a run fails halfway. Every form tool gives its submission a unique id. Map it into the idempotency key on each of the four calls and all of that stops being your problem.

Agent

Body displayName {{ name }} from the trigger email {{ email }} from the trigger assertionKind "user_supplied" fixed idempotencyKey {{ submission_id }} from the trigger

The assertion kind is the other fixed value worth understanding. A person typed this into your form, so it is user-supplied rather than something an agent observed, and that outranks anything an enrichment job later decides it knows better about. It is one field, and it is the difference between the name the customer gave you and the name a data vendor overwrote it with.

Keep what they actually wrote

The single most common loss in this pipeline: the message box gets mapped to nothing, or squeezed into a lead-source dropdown, and the one piece of genuine signal in the whole submission disappears.

Indraft takes both. Map the raw message into evidenceText, which is stored verbatim, and put a one-line reading into summary. If your automation tool has an AI step you already pay for, that summary is a good use of it. If not, mapping the first line of the message is fine and still better than losing it.

Agent

URL https://api.indraft.io/v1/interactionsBody interactionType "note" direction "inbound" subject {{ form_name }} summary a one-line reading of the message evidenceText {{ message }} verbatim, never edited

Six weeks later the summary is what somebody skims and the quote is what settles an argument about what was asked for.

Guard the webhook

The URL your automation tool gave you is public, and it now writes to your CRM. Three things, none of which is Indraft's job and all of which your automation tool can do.

Check the submission came from your form. If you used a ready-made trigger, this is already handled: the tool is authenticated to your form account and nothing else can feed it. If you used a generic webhook, most form tools will send a signature or let you add a secret header, and a filter step that drops anything without it takes a minute. Without that, anybody who learns the URL can post contacts into your workspace at whatever rate they like.

Drop the junk before you write it. Free-mail addresses, empty message bodies, obvious keyboard mashing. A filter step costs nothing, and it is much cheaper to not create a record than to clean one up, because the cleanup falls on whoever works the queue.

Let it retry, and tell you when it stops. Both tools retry a failed step and both can run an error path when it finally gives up. Point that at a channel somebody reads. The scheduling recipe covers why that half matters more than people expect.

Where the agent does belong

After the record exists. The scenario is done in a moment and knows nothing; the interesting question is whether this lead is worth a call today, and that needs reading.

You

Anything come in overnight worth my time? Give me the ones where the message says something specific, and tell me why.

That question cannot be a rule, which is exactly why it is not one. The scenario does the part a rule is good at and stops.

Verify it

  • Submit your own form twice. One contact, one company, one interaction, one task. If you get two of anything, the submission id is not reaching the idempotency key.
  • Submit from an address at a company you already have. It should attach to the existing company rather than making a second one.
  • Post to the webhook URL yourself, with nonsense in it. If a contact appears, anyone who finds that URL can fill your CRM.
  • Read the record as a stranger. Can you tell what they asked for without opening the original email? If not, the message body is being dropped somewhere in the mapping.

Run it again

Check the junk rate monthly, and check the scenario is still running while you are there. Form spam arrives in waves, and the first sign is usually a queue of contacts nobody recognises rather than an alert. A scenario that was switched off during an edit looks exactly like a quiet fortnight for inbound.