I had a lot of fun “stretching my brain/skills” to support an org to collect contact info in an innovative and data-minded way. In this blog post, I’ll go over the dilemma, the path(s) not taken, and how I set up the winning option. The tools that I used for this project were Salesforce, FormAssembly + prefil (paid product), phoning a friend, and wracking my brain (yes, that is a tool hehe). Make sure to read to the end for some important considerations when you build a solution like this!
the dilemma
A grassroots org is nearly ready to launch registration for their flagship program. Therefore, they want to develop a contact list of everyone who should receive an invite to sign up. They started a spreadsheet which they could easily circulate among staff and stakeholders, but it was filled out inconsistently and there may be duplicates on that spreadsheet compared to other contact lists floating around. We really wanted all of the contact data to “live” in the same system.
the path(s) *not* taken
The first time I heard about this problem, I suggested that everyone type contacts directly into Salesforce using my tried and true “search twice, enter once” [reframe of “measure twice, cut once”] method. However, we quickly realized a few key reasons why this would not work:
- In this grassroots org, they were soliciting contact info from board members, super-volunteers, and staff. They did not all have access to Salesforce and it did not make sense to give them all licenses.
- The contact info required for this outreach was different than the standard page layout for new Contacts. We did not want to create a new “Record Type” or temporary page layout for this specific need.
- I realized that we were going to want to store data on more than one object (ie Contact, Campaign Member, Affiliation) so the new Contact standard data entry process would not have worked anyway. We were already edging into Screen Flow territory, let alone the access problem in Point 1 above.
what I built
Instead, we decided to leverage the form-building software that they already had. However, the technical requirements were a bit tricky and required me to divide “the form” into “two forms” (in the back end) and do some fancy footwork with multiple “connectors” to reduce duplicates. Let’s dive in!
First, I created a VERY simple contact form. Only 3 questions! I also added “ReCAPTCHA” just incase the link to this form got out and it got spammed. What could be simpler? No further explanation necessary.

So, what makes this form special?
Well, when you click “Next” a bunch of automation happens between the Form and Salesforce. As you can see in the screenshot below, the form looks for a matching contact in Salesforce and proceeds to UPDATE that Contact (if it’s a direct match) or CREATE a new Contact. This is important because we do not want to create a new contact if that person’s contact info is already recorded.
If you are trying this at home, the “mapping” screenshot that you see below is from the “Submit” Connector in FormAssembly.

Things get cooler from here!
We want to collect some more info about these individuals, but if there is a matching Contact that is already in the system, we want to SHOW the data we already have. Why?
- We want to prevent saving over data
- This gives the Form-Filler-Outer a chance to verify and add on to the data we already have
- Save time so Form-Filler-Outer is not retyping data we already have
So, we needed a way to redirect to a new form page that is “pre-filled” with the data we already have on that Contact. If the Contact is new, we will have no additional data to show. But if the Contact is pre-existing, we’ll have some info already on file.
How do you do that?
It’s with a combo of two “features” in FormAssembly.
If you are trying this at home, the “redirect” screenshot that you see below is from the Notification settings menu in FormAssembly. Note that instead of Acknowledgment text, we send the Form-Filler-Outer to a new form URL. Instructions for this are covered here. Your email field might not have the same numbering as mine.

Now that we’ve done the “Redirect” to Form 2, we need to make Form 2 “smart” using FormAssembly Prefil. Form 2 gets TWO connectors. Are two Connectors better than one?


The first connector looks like this:
It starts with “looking up” a Contact based on the email that was passed in the Redirect URL. It will ALWAYS find a Contact because the Contact was either created or updated in the previous step. Then, it pre-populates the Form with data that might already be in Salesforce. So the Form-Filler-Outer might see data about the Contact that they did not have to enter! Important consideration here: keeping the form link private, keeping notes on the Contact kind and considerate since people outside of the org staff will have access to the data. I mean, shouldn’t we ALWAYS be kind and considerate?

Ok last step, we let the Form-Filler-Outer complete the form and save their responses back in Salesforce. This is accomplished with a regular post-submit Connector, with only one fancy tip. Instead of using email or other matching criteria to find the contact in the post-submit Connector, I use the ContactId that we looked up earlier (and stored in a hidden field). Saves a step and keeps the form consistent!

Now is the time to add those bells and whistles that make the form “pop.” Add a nice Form Acknowledgment to Form 2 (since there is no further redirect). Add a pop of color with logos, graphics, or nice form design elements.
things to consider when building a form like this
- Security – you are opening up access to data to people who do not have a Salesforce “login” (which is one layer of security, but not perfect in an of itself either). Important to build a strong culture of not sharing the link outside the inner circle of org groupies and not using the form to “lookup” random contacts just to see what’s in there. I actually don’t think many people would stoop to this level, but best to avoid it!
- Connector timing – in the first build of this form, the Redirect + Prefil worked for existing Contacts, but did not work for new Contacts. The reason for this is that the API that makes the new Contact was taking too long, and the 2nd Form was loading before the 1st Form Connector had finished doing its job. I had to phone a friend on this one and Michael Kolodner suggested that I use the “submit” connector instead of the “post submit” connector for Form 1, which immediately solved the problem. Thank you, MK!
- Adding to a Campaign – I am adding contacts to a Campaign for “outreach for Flagship program” – but you may want to think about ways that you want to categorize Contacts that were added/updated this way so that you can scan for issues later on. I use the Connector to create a Campaign History record connecting the Contact to a specific Campaign. But we may outgrow this if usage of this Form takesoff and expands beyond this recruitment effort. I also map the “Form Response URL” to a custom field on the Campaign History record in case I ever need to reconcile FA and Salesforce (please Gd let me avoid this for the rest of my days).
- Documentation – it is not obvious to the Form-Filler-Outers or to anyone besides an experienced technical team (you!) that they are interacting with two completely separate forms with a Redirect and a Prefill sitting between them like handshake. So, it’s important to have really clear instructions about how to update each form (ie when new fields are added, or if forms are taken out of circulations… “both parts” need to be archived).
Instead of using Email ‘equals’ email as the unsafe query parameter on your second form, I suggest using the alias %%SFA_CONTACT%%. That should populate with a Contact ID successfully whether or not you had to create a new Contact or update an existing one on your first form. Since the Contact ID is difficult to guess, that would also provide security in case someone fiddles with the email address that appears in the URL bar to try to pull up someone else’s information. For more information, look for the help article on FormAssembly’s knowledge base called “Object Alias”.
Thanks Josue! I did try this originally but it did not work when a new Contact was created, only in the upsert scenario. Perhaps I made a silly mistake on the way. I would like to give this another try.
Hugely helpful – thanks for sharing!!