Compare Contact Enrichment in Retool
Build a Retool app that compares batch contact enrichment from two providers.
Introduction
30 Second Summary
Looking up the same people in two different services quickly turns into repetitive work. The finished answers can still disagree.
In this project, you will build a browser-based contact enrichment comparator in Retool. It previews a cleaned batch of up to 10 profile URLs before comparing LeadIQ with ZoomInfo side by side.
What You'll Build
Your finished app turns up to 10 pasted profile URLs into a side-by-side table that makes each provider's result easy to compare.
By the end of this project, you'll have:
- A cleaned batch preview that removes exact duplicates before enrichment starts. It also blocks oversized or malformed batches.
- A single comparison run that sends the approved profile URLs to both enrichment providers.
- A normalized result table that preserves names, titles, employers, phone fields, no-match outcomes, and provider-specific errors.
- Secret Mission: Download the current comparison as a dated CSV file that a teammate can inspect outside the app.
Are there any prerequisites?
You need a LeadIQ account plus permission to process the business-contact data used for testing. Live ZoomInfo results require a GTM.ai or Enterprise license with API access while demo mode covers accounts without that access.
Before We Start
This first checkpoint locks in whose business-contact data you will test and why you are authorized to process it. That commitment keeps the comparator focused on responsible testing before any setup begins.
Set Up Retool and Connect Both Providers
Your comparator needs a secure place to hold provider permissions before it can process a batch. Retool keeps those connections on the server side.
The LeadIQ connection uses an MCP resource with OAuth. This keeps its credentials outside browser code.
The ZoomInfo connection uses a REST resource for server-to-server access. A demo-mode path keeps the project moving if your account lacks API entitlement.
In this step, get ready to:
- Create a Retool Free organization with a blank app.
- Connect LeadIQ through its OAuth-protected MCP server.
- Configure ZoomInfo for live API access or demo mode.
Create your Retool workspace and blank app
A Retool Free organization provides the workspace for your app. Organization-admin access lets you create the shared provider resources used later.
- Go to login.retool.com in your browser.
- Create a Retool Free organization by completing the sign-up prompts.
- Confirm that your account has organization-admin access.
You'll arrive in your new Retool workspace with permission to create apps and resources.
- Click Create in your workspace.
- Select App.
You'll see the app creation flow.
- Enter Contact Enrichment Comparator as the app name.
- Choose the blank app option to open the current app builder.
You'll see an empty app canvas named Contact Enrichment Comparator.
Why Retool for this project?
Retool places the user interface beside server-side MCP and REST resources. You can build the comparison experience without exposing provider credentials in the browser.
This keeps the project focused on batch validation and provider comparison. One workspace holds the full internal tool.
Can't open the app builder?
- Confirm that you completed the organization setup with the same account now signed in.
- Check that your account has organization-admin access before creating the app.
Ask for help with Retool workspace access. Visit the Retool Community for environment-specific support.
Connect the LeadIQ MCP resource
An MCP server exposes provider actions as typed tools. Retool discovers those tools after authentication so later app functions can call them with structured inputs.
LeadIQ provides EnrichPeople for batches of up to 10 known people. This is the tool your comparator uses in a later step.
- Select Resources in Retool.
- Click Create new.
You'll see the flow for adding a resource to your workspace.
- Select Resource.
- Choose MCP Server as the resource type.
You'll see the MCP Server configuration form.
- Enter LeadIQ MCP as the resource name.
- Enter https://mcp.leadiq.com/mcp as the server URL.
The resource now points to LeadIQ's MCP endpoint.
- Choose Automatic for authentication.
- Click Auto-configure authentication.
Retool reads LeadIQ's OAuth configuration from the server. You do not need to copy a client ID or client secret for this connection.
The next action opens LeadIQ's OAuth flow. You are granting Retool permission to use your LeadIQ account without placing a credential in the app.
- Complete the LeadIQ OAuth flow using your LeadIQ account.
- Save the LeadIQ MCP resource in Retool.
Before you test the connection, what should successful tool discovery add to the tool list?
- Run Retool's connection test for LeadIQ MCP.
- Inspect the discovered tool list after the test passes.
You'll see EnrichPeople in the typed tool list. This proves Retool can reach LeadIQ through the authenticated MCP connection.
Don't see EnrichPeople?
- Confirm that the server URL is exactly https://mcp.leadiq.com/mcp.
- Repeat Auto-configure authentication if the OAuth settings were not discovered.
- Reconnect through LeadIQ OAuth if the authorization did not complete.
Ask for help discovering the LeadIQ tool.
Configure the ZoomInfo REST resource
ZoomInfo API access depends on account entitlement. A Standard App requires a GTM.ai or Enterprise license with API access.
Live access also needs the api:data:contact scope. Demo mode lets you finish the app while an administrator provisions that access.
- Check your ZoomInfo account for permission to create a Standard App.
- Confirm that the Standard App can use Client Credentials.
Client credentials grant server-to-server access. Treat the client secret with the same care as a password.
✔️ I can create a Standard App
- Create a Standard App for the contact enrichment comparator.
- Choose Client Credentials for the app.
The Standard App now has a server-to-server authentication method.
- Grant the api:data:contact scope.
- Copy the ZoomInfo client ID to a secure temporary location.
Your client is now authorized for contact enrichment.
- Store the ZoomInfo client secret in a password manager or another approved secret store.
- Keep the credential screen out of any screenshots.
You now have the two credential values Retool needs for a live connection.
ⓧ API access is unavailable
A normal ZoomInfo login does not guarantee API entitlement. Your app can use demo mode until the required access is provisioned.
- Ask your ZoomInfo administrator for a GTM.ai or Enterprise license with API access.
- Request permission to create a Standard App with the api:data:contact scope.
Continue with the disconnected resource path below. You do not need ZoomInfo credentials for demo mode.
- Switch back to the Retool workspace from earlier.
- Select Resources.
You'll return to the workspace resource list.
- Click Create new.
- Select Resource.
You'll see the supported resource types.
- Choose REST API.
- Enter ZoomInfo API as the resource name.
The new resource now has a name and a REST configuration form.
- Enter https://api.zoominfo.com/gtm as the base URL.
- Select OAuth 2.0 Client Credentials as the authentication method.
Why Client Credentials?
Client Credentials is designed for internal server-to-server integrations without an individual user login. Retool requests access tokens for the resource automatically.
Retool encrypts the client secret stored in its credential field. The secret stays outside your app's browser code.
Finish the resource according to the access state you confirmed in ZoomInfo.
✔️ I have ZoomInfo API credentials
- Enter https://api.zoominfo.com/gtm/oauth/v1/token as the access-token URL.
- Paste your ZoomInfo client ID into its credential field.
The resource now knows where to request tokens and which client is requesting access.
- Paste your ZoomInfo client secret into its credential field.
- Save the ZoomInfo API resource.
Your credential values are now stored in the Retool resource.
- Run the connection test for ZoomInfo API.
You'll see the resource report a successful authenticated connection.
ⓧ I am using demo mode
- Enter https://api.zoominfo.com/gtm/oauth/v1/token as the access-token URL.
- Leave the ZoomInfo credential fields empty.
The resource has the correct endpoint configuration without an active OAuth client.
- Save the ZoomInfo API resource without a live connection.
- Keep the app on the demo-mode path until API access is provisioned.
The disconnected resource is expected in demo mode. It remains visible for the live connection later.
Before the final check, which provider resource should expose a typed tool?
- Return to LeadIQ MCP in the Retool Resources list.
- Run its connection test one more time.
- Inspect its discovered tool list.
You'll see EnrichPeople in the LeadIQ tool list. The successful test confirms that the typed MCP connection is ready.
- Switch back to the Contact Enrichment Comparator app.
- Open the blank app preview.
You'll see the blank app ready for its first interface.
- Return to the workspace Resources list.
- Confirm that LeadIQ MCP appears in the list.
- Confirm that ZoomInfo API appears in the list.
You'll see both provider resources in the workspace. The ZoomInfo resource may remain intentionally disconnected when you are using demo mode.
That is the sensitive setup handled. LeadIQ is connected without browser-side credentials.
Next up, you'll turn the blank canvas into a ten-URL preview that catches duplicates before any provider runs.
Build the Batch Preview
Your connected LeadIQ and ZoomInfo resources are ready inside Retool. The next goal is a safe checkpoint between pasted URLs and those provider connections.
A visible batch preview catches duplicate URLs before any credit-consuming call runs. It blocks oversized batches at the same gate.
In this step, get ready to:
- Build the URL input controls and comparison table.
- Clean the batch before it reaches either provider.
- Prove that previewing stays local and starts each provider at Pending.
Build the preview interface
The preview interface gives pasted profiles a visible checkpoint. It also keeps the comparison action unavailable until the batch is ready.
- Switch back to the Chat tab in the Retool app builder.
- Ask the app-building agent to create the interface by pasting this prompt:
Add a multiline input labeled Profile URLs, helper text that says one URL per line with a maximum of 10, a Preview batch button, a disabled Run comparison button, and a result table.
What Does This Prompt Create?
- The Profile URLs input accepts several profile links in one pasted batch.
- The helper text makes the batch format visible before anyone submits data.
- The Preview batch button creates the local checkpoint.
- The Run comparison button starts disabled so the preview remains a required gate.
- The result table provides a place for the normalized rows.
- Wait for the agent to finish updating the app.
- Confirm the Profile URLs multiline input is visible in the app preview.
- Confirm the helper text says one URL per line with a maximum of 10.
- Confirm the Preview batch button is visible.
- Confirm the Run comparison button is disabled.
- Confirm the result table is visible below the controls.
Good progress. Your blank app now has the controls that make each batch visible before enrichment.
Missing a Preview Control?
- Return to the Chat tab.
- Tell the agent the exact label of the missing control.
- Tell the agent to preserve the controls that are already present.
Ask for help fixing the missing preview controls.
Normalize the batch
Batch normalization turns pasted text into a predictable set of rows. Each unique URL keeps its original value for matching later.
- Return to the Chat tab.
- Ask the app-building agent to normalize the preview by pasting this prompt:
Make Preview batch trim blank lines, preserve the original URL, remove exact duplicates, reject more than 10 unique rows, and populate table columns for Input URL plus LeadIQ and ZoomInfo status, name, title, employer, and phone.
How Does the Batch Change?
- Blank lines are removed before the row count is calculated.
- Each retained row keeps the original input URL.
- Exact duplicates collapse into one row.
- A batch above 10 unique rows is rejected before enrichment.
- The table receives an Input URL column.
- Each provider receives status, name, title, employer, and phone columns.
- Wait for the agent to finish updating the preview workflow.
- Enter one authorized profile URL on the first line of Profile URLs.
- Enter a different authorized profile URL on the second line.
- Repeat the first URL exactly on the third line.
Before you select the button, consider whether the exact duplicate should create a third row.
- Select Preview batch.
You will see two preview rows because the repeated URL is an exact duplicate.
- Confirm each row includes an Input URL value.
- Confirm each provider group contains status, name, title, employer, and phone columns.
You now have visible proof that one duplicated input produces one comparison row.
Still Seeing Three Rows?
- Confirm the third line matches the first line character for character.
- Remove any extra path characters from the duplicated line.
- Ask the agent to apply exact duplicate removal before it populates the table.
Ask for help troubleshooting duplicate removal.
Keep preview local and validate URLs
A local-only preview separates input checks from enrichment. Provider calls stay behind the comparison action so previewing cannot consume credits.
- Return to the Chat tab.
- Ask the app-building agent to isolate the preview by pasting this prompt:
Keep this first version local-only: previewed rows start as Pending, neither connected resource is called, and the Run button remains disabled until every row contains a parseable URL.
Why Keep Preview Local?
- Pending makes the untouched provider state visible in every row.
- Local validation catches malformed input without calling LeadIQ.
- Local validation also avoids calling ZoomInfo.
- The comparison button only becomes available after every retained row contains a parseable URL.
- Wait for the agent to finish updating the local preview workflow.
- Replace the second authorized URL with not-a-url.
Before you preview this batch, consider whether the malformed line should unlock the comparison button.
- Select Preview batch.
You will see the malformed row identified. The Run comparison button stays disabled.
- Replace not-a-url with the second authorized profile URL.
- Confirm the third line remains an exact copy of the first URL.
Before you preview again, predict how many unique rows the table should keep.
- Select Preview batch.
You will see two unique rows. Both provider statuses show Pending.
No provider result fields are populated. The preview has completed without a LeadIQ MCP tool call or a ZoomInfo API request.
That is the safety gate working. Your app reveals the exact batch before enrichment begins.
Preview State Looks Wrong?
- Confirm every retained line contains a complete parseable URL.
- Tell the agent to initialize both provider statuses as Pending.
- Tell the agent to remove provider calls from the Preview batch workflow if enrichment data appears.
Ask for help checking the local-only preview workflow.
Your app now turns pasted URLs into a clean two-provider preview without spending enrichment credits. Next up, you will connect that batch to LeadIQ.
Enrich the Batch with LeadIQ
Your local preview now turns pasted profile URLs into clean rows inside Retool. The next job is to give those rows their first enrichment results.
The LeadIQ MCP resource exposes EnrichPeople as a typed batch tool. This first live run tests how far one provider gets on its own.
In this step, get ready to:
- Create a typed enrichWithLeadIQ function for one batch call.
- Restrict the enrichment request to the required contact fields.
- Run the single-provider workflow to inspect its current coverage.
Create the typed LeadIQ function
A typed function uses the tool definition discovered from the connected resource. Retool can check the tool arguments before the request reaches LeadIQ.
- Switch back to the Chat tab in your open Contact Enrichment Comparator app.
- Enter @ in the prompt field.
- Select LeadIQ MCP from the resource suggestions.
- Create the typed function by submitting this prompt:
@LeadIQ MCP
Create a typed function named enrichWithLeadIQ.
Read the current preview rows.
Extract up to 10 LinkedIn URLs.
Call the discovered EnrichPeople tool exactly once with the full batch.
Keep the function unbound for now.
What does this prompt create?
- The @LeadIQ MCP tag gives the app-building agent access to the connected resource.
- The enrichWithLeadIQ function gathers the current preview rows in one place.
- The single EnrichPeople call sends the full batch instead of making one call per person.
- Review the generated function in the agent's change summary.
You should see a function named enrichWithLeadIQ with one reference to EnrichPeople.
Cannot see the typed tool?
- Confirm that the prompt includes the LeadIQ MCP resource tag.
- Confirm that the generated function refers to EnrichPeople with the same capitalization.
Help me check why Retool cannot use the EnrichPeople tool from my connected LeadIQ MCP resource.
Limit the enrichment request
Direct phone data costs 10 UC per returned person. A narrow request keeps this workflow focused on the fields used by the comparison table.
- Restrict the function's requested data by submitting this follow-up prompt:
Update enrichWithLeadIQ.
Request only profile identity, current title, seniority, employer name, and phone numbers from EnrichPeople.
Do not request work email.
Do not request company firmographics.
Keep one EnrichPeople call for the entire preview batch.
Why keep the request narrow?
The comparator needs identity fields to align each result with its input. Title plus seniority describe the person's current role.
Employer plus phone data provide the values you want to compare. Work email plus company firmographics sit outside this project's scope.
- Review the updated enrichWithLeadIQ function in the agent's change summary.
You should see only profile identity, current title, seniority, employer name, and phone numbers in the requested output scope.
Seeing extra requested fields?
- Remove work email from the generated request.
- Remove company firmographics from the generated request.
- Confirm that the function still makes one EnrichPeople call for the full preview batch.
Help me narrow the LeadIQ EnrichPeople request to the fields required by my comparison table.
Connect the Run comparison button
The button handler needs to preserve the preview as the source of truth. Every input row must survive a match, a no-match response, or a tool failure.
- Bind the interim workflow to the existing button by submitting this prompt:
Update Contact Enrichment Comparator.
Bind Run comparison to enrichWithLeadIQ for the current preview batch.
Preserve every original preview row.
Map returned LeadIQ identity, title, employer, and phone data into the existing LeadIQ columns.
Set LeadIQ status to No match when no person is returned.
Set LeadIQ status to a tool-error state when EnrichPeople fails.
Leave every ZoomInfo field as Pending.
Enable Run comparison only when the preview contains at least one valid row.
Keep Run comparison disabled when the preview contains an invalid URL.
How does the interim workflow behave?
- The button passes the complete preview batch to enrichWithLeadIQ.
- The normalization keeps each original URL as the stable row reference.
- Explicit No match and tool-error states prevent missing results from disappearing.
- The untouched provider fields preserve their existing Pending values.
- Review the button handler in the agent's change summary.
- Confirm that it calls enrichWithLeadIQ once for the current preview.
This run can consume LeadIQ UC because it requests phone data. Keeping the test to two authorized profiles limits the exposure while you prove the workflow.
- Return to the Profile URLs input.
- Replace its contents with two authorized LinkedIn profile URLs.
- Select Preview batch.
You should see two rows with both provider statuses set to Pending.
Before you run the comparison, do you think both providers will return results from this interim workflow?
- Select Run comparison.
You should see each LeadIQ status change to returned data or No match. Matched rows show available name, title, employer, and phone values.
Every ZoomInfo status stays Pending. The pending half now makes the coverage gap concrete.
That's a meaningful milestone: LeadIQ now enriches the whole preview batch without dropping unmatched rows.
LeadIQ results still pending?
- Confirm that Run comparison calls enrichWithLeadIQ.
- Confirm that the preview contains valid LinkedIn profile URLs.
- Check the LeadIQ MCP connection if every row shows a tool-error state.
Help me troubleshoot why my Retool comparison table is not receiving LeadIQ results.
Your batch now has real LeadIQ outcomes for every input row. Next, you'll add the second provider that turns this lookup into a true comparison.
Add ZoomInfo and Merge Results
Your Retool app now enriches a bounded batch through LeadIQ while preserving every original row.
Every ZoomInfo field still stays Pending. A single source cannot reveal coverage differences between providers.
You'll add one bulk REST request. Then runComparison will merge both response shapes into one table.
In this step, get ready to:
- Expose the pending ZoomInfo side with the current single-provider run.
- Create one ZoomInfo bulk contact-enrichment request.
- Merge both provider results without dropping any input rows.
Run the single-provider comparison
The current button still runs only enrichWithLeadIQ. Running it once makes the missing half visible before you change the workflow.
- Return to the app preview from earlier.
- Select Preview batch to reset the same two authorized rows to Pending.
You should see two preview rows with pending provider statuses.
Before you run the comparison, consider whether any ZoomInfo field will leave Pending.
- Select Run comparison.
You'll see LeadIQ values or No match states. Every ZoomInfo column remains Pending.
That shortfall is intentional. The button still has no path to the ZoomInfo resource.
Create the ZoomInfo bulk request
A single JSON:API request can carry every previewed URL. Each response row includes match metadata that reconnects it to the original input.
Why use one bulk request?
A per-contact approach could fan out into ten network calls. The ZoomInfo bulk endpoint keeps the entire batch in one request.
It also returns match information for each input. That gives the merge a stable key even when a contact has no match.
- Create the bulk query by asking the Chat agent to @-tag ZoomInfo API with method POST at path /data/v1/contacts/enrich.
- Ask it to set Accept plus Content-Type to application/vnd.api+json.
- Review the generated query configuration.
You should see one POST request at /data/v1/contacts/enrich. Both request headers should show application/vnd.api+json.
- Ask the agent to add a JSON:API body with type set to ContactEnrich.
- Ask it to build matchPersonInput from one externalURL object per previewed URL.
- Review the generated request body.
You should see ContactEnrich as the resource type. The matchPersonInput collection should contain one externalURL object for each previewed row.
- Ask the agent to set outputFields to firstName, lastName, jobTitle, companyName, phone, mobilePhone, directPhoneAlt, plus mobilePhoneAlt.
- Review the generated outputFields list.
You should see all eight requested fields. The request now covers identity data plus the phone variants needed by the comparison table.
Missing Part of the ZoomInfo Request?
- Compare the generated method against POST.
- Compare the generated path against /data/v1/contacts/enrich.
- Ask the Chat agent to add any missing request field without changing enrichWithLeadIQ.
Need help correcting the resource query?
Merge both provider results
The two providers return different response shapes. runComparison becomes the orchestration layer that preserves each original URL through both paths.
- Replace the interim Run comparison handler by asking the Chat agent to create one function named runComparison.
- Ask runComparison to start enrichWithLeadIQ plus the single ZoomInfo bulk query concurrently.
The agent's change summary should identify both provider calls inside runComparison.
- Ask the agent to map every ZoomInfo response by meta.input.externalURL.
- Ask it to normalize names plus titles from attributes.
- Review the agent's mapping summary.
The mapping should reconnect each ZoomInfo result to the same URL stored in the preview row.
- Ask the agent to normalize employer values from companyName plus any nested company data.
- Ask it to normalize phone values across phone, mobilePhone, directPhoneAlt, plus mobilePhoneAlt.
- Review the updated normalization summary.
The summary should mention the standard contact fields plus nested company data and alternate phone values.
- Ask runComparison to return every original input row when either provider fails or returns no match.
- Ask the agent to display independent LeadIQ and ZoomInfo statuses in the table.
The completed workflow should preserve successful data from one provider when the other provider returns no match or an error.
- Return to the app preview.
- Select Preview batch.
You should see the same two authorized URLs reset to independent pending states.
Keep the Live Check Small
This check can consume LeadIQ UC when phone data is returned. It can also consume ZoomInfo bulk data credits for newly enriched contacts.
- Keep the test to the same two authorized profiles.
Before you run the merged workflow, consider what remains visible if only one provider succeeds.
- Select Run comparison.
You'll see an independent status for LeadIQ and ZoomInfo on every original row. One provider's failure or no-match state should leave the other provider's successful values visible.
What Should I See?
With live ZoomInfo API access, a successful ZoomInfo row shows normalized contact values read from attributes. Its provider status comes from meta.matchStatus.
If the ZoomInfo resource remains intentionally disconnected, its rows should show a provider-specific error. The LeadIQ values should remain visible beside that error.
You've closed the missing half of the table. Both providers now contribute independent evidence to each comparison row.
Still Seeing Pending ZoomInfo Rows?
- Check that the Run comparison handler points to runComparison.
- Confirm that runComparison invokes the existing enrichWithLeadIQ function.
- Confirm that the same function invokes the ZoomInfo bulk query once.
- Ask the agent to preserve the original input rows when a provider call fails.
Help me troubleshoot the merged workflow.
Your two-provider comparison now keeps every original URL through both response paths. Next, you'll add the credit controls plus failure states that make each run safer.
Add Credit and Error Guardrails
Your Retool comparator now sends one batch to LeadIQ and ZoomInfo. The merged table exposes their coverage differences.
Enrichment can consume credits. Every live run needs a clear checkpoint before either provider receives the batch.
Partial provider failure is also normal. Independent result states keep one useful response visible when the other provider fails.
In this step, get ready to:
- Block invalid batches before either provider runs.
- Show worst-case credit exposure before each approved comparison.
- Keep each provider's result visible through partial failures.
Block invalid batches before enrichment
Preflight validation checks the entire batch before a provider call can begin. Each blocking problem needs an inline message that points to the affected input.
- Switch back to the Chat tab in the app builder.
- Ask the agent to add preflight validation to the existing preview workflow.
- Ask the agent to flag every empty line as an inline input error.
- Ask the agent to flag every exact duplicate URL.
- Ask the agent to reject every malformed URL.
- Ask the agent to reject batches above 10 unique rows.
- Ask the agent to keep Run comparison disabled whenever a blocking error exists.
- Ask the agent to prevent runComparison from calling enrichWithLeadIQ or the ZoomInfo bulk request while a blocking error exists.
- Replace the contents of Profile URLs with the same authorized profile URL on two separate lines.
- Select Preview batch.
You should see an inline duplicate warning. The Run comparison button stays disabled. No provider call runs.
Still Able to Run the Duplicate?
- Check that the preview workflow validates the cleaned batch before it enables the run button.
- Check that the duplicate rule compares complete trimmed URL strings.
- Check that every blocking result reaches the disabled state of the Run comparison button.
Need help tracing the validation state?
Confirm worst-case credit exposure
A confirmation modal places a deliberate checkpoint in front of every credit-consuming run. You stay in control until you explicitly approve the comparison.
How Does the Estimate Work?
LeadIQ direct phone data can cost 10 UC for each returned person. The modal therefore shows N × 10 LeadIQ UC as the worst case for N valid rows.
Each newly enriched ZoomInfo contact can consume one bulk data credit. The matching worst case is N ZoomInfo bulk data credits.
Actual use can be lower for missing contacts. It can also be lower for previously unlocked LeadIQ data or ZoomInfo records already under management.
- Ask the agent in the Chat tab to add a confirmation modal immediately before runComparison.
- Ask the agent to derive N from the valid preview rows.
- Ask the agent to display N × 10 LeadIQ UC as the worst-case LeadIQ exposure.
- Ask the agent to display N ZoomInfo bulk data credits as the worst-case ZoomInfo exposure.
- Ask the agent to explain why missing contacts can lower actual usage.
- Ask the agent to explain why previously unlocked or under-management records can lower actual usage.
- Ask the agent to require explicit approval before runComparison starts.
- Ask the agent to keep the modal unavailable while a blocking error exists.
- Replace the duplicate line with a second authorized profile URL.
- Select Preview batch.
Before selecting Run comparison, what worst-case values should the modal calculate for two valid rows?
- Select Run comparison.
You should see a worst case of 20 LeadIQ UC plus 2 ZoomInfo bulk data credits. Neither provider starts while the modal waits for approval.
- Dismiss the modal without approving the run.
Seeing the Wrong Credit Estimate?
- Check that N comes from the valid preview rows instead of the raw input lines.
- Check that duplicate or malformed rows are excluded from the estimate.
- Check that the LeadIQ calculation multiplies N by 10.
Need help fixing the modal calculation?
Preserve partial provider results
An independent status model lets each provider finish on its own terms. A failure on one side cannot erase a useful match from the other side.
Which States Does Each Provider Need?
- Loading shows that the provider request is still in progress.
- Success shows that the provider returned usable contact data.
- No match preserves the input row when the provider finds no contact.
- Authorization identifies a provider access or credential problem.
- Credit limit identifies a provider response caused by unavailable credits.
- Rate limit identifies a provider response caused by request throttling.
- General error preserves any remaining provider failure without hiding the row.
- Switch back to the Chat tab.
- Ask the agent to give LeadIQ an independent status inside runComparison.
- Ask the agent to give ZoomInfo an independent status inside runComparison.
- Ask the agent to map each provider outcome to the seven states listed above.
- Ask the agent to update each provider's state when its own request settles.
- Ask the agent to preserve successful provider fields when the other provider fails.
- Ask the agent to preserve every original input row throughout the merge.
- Return to the Profile URLs input.
- Enter a two-line batch containing one authorized profile URL plus not-a-url.
- Select Preview batch.
The app should identify the malformed row. The run stays blocked. No provider enters a loading state.
- Remove not-a-url from the input.
- Select Preview batch.
Before selecting Run comparison, what worst-case exposure should the modal show for one valid row?
- Select Run comparison.
You should see a worst case of 10 LeadIQ UC plus 1 ZoomInfo bulk data credit. The modal also explains why actual usage can be lower.
- Approve the confirmation to start runComparison.
You should see separate loading states before each provider settles into success, no match, or a provider-specific error. Any successful fields remain visible beside the other provider's final state.
Did One Failure Clear the Whole Row?
- Check that each provider writes only to its own fields within the existing input row.
- Check that a rejected provider request becomes a final error state instead of rejecting the entire merge.
- Check that both provider calls always settle before the merged rows replace the table data.
Need help preserving a successful provider response?
Strong work. Your comparator now blocks risky inputs before they can consume credits.
Each provider can fail without erasing useful data from the other provider.
Secret mission
Export the Comparison as CSV
Your comparison already resolves two providers into one table. Export those normalized rows as a dated CSV so a teammate can inspect the same results in Numbers without opening Retool.
Clean Up Your Resources
Clean Up Your Resources
Your Retool workspace can remain on the Free plan. Idle resources consume no enrichment credits.
Future live comparisons can consume LeadIQ UC. They can also consume ZoomInfo bulk data credits. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- The Retool app named Contact Enrichment Comparator.
- The Retool resource named LeadIQ MCP.
- The Retool resource named ZoomInfo API.
- The LeadIQ OAuth connection used by LeadIQ MCP.
- The ZoomInfo OAuth client credentials used by ZoomInfo API, if live access was configured.
- The exported CSV file named contact-enrichment-comparison-YYYY-MM-DD.csv in your Mac's Downloads folder.
Keep everything running
No action needed. Choose this if you are still testing the comparator with authorized business-contact data.
- Keep Contact Enrichment Comparator unpublished for personal testing.
- Limit access to authorized internal users if you publish the app later.
- Leave LeadIQ MCP connected for future authorized runs.
- Leave ZoomInfo API configured for live access or disconnected for demo mode.
- Keep contact-enrichment-comparison-YYYY-MM-DD.csv if you need the normalized comparison outside Retool.
The idle app does not consume enrichment credits. A future live comparison can use provider credits.
Pause - I'll come back to this later
Stop running comparisons while keeping the app configuration ready for your next authorized batch.
- Stop submitting new batches through Contact Enrichment Comparator.
- Leave the app unpublished while it is paused.
- Keep LeadIQ MCP configured in Retool.
- Keep ZoomInfo API configured in Retool.
- Retain contact-enrichment-comparison-YYYY-MM-DD.csv for your records.
The paused setup uses no enrichment credits because neither provider receives a request.
Delete - I don't want to use this again
Deleting this setup is permanent. Your LeadIQ and ZoomInfo accounts remain available because this cleanup targets the project artifacts and authorizations.
- Return to your Retool workspace's app list.
- Open the action menu for Contact Enrichment Comparator.
- Choose the app deletion option.
- Confirm the deletion.
- Open Resources in Retool.
- Select LeadIQ MCP.
- Use the resource deletion control.
- Repeat the resource deletion for ZoomInfo API.
That is the main cleanup complete: Retool no longer holds the comparator or either provider resource.
Vendor authorization lives outside Retool. It remains active until you disconnect or revoke it.
- Locate Retool's OAuth connection in your LeadIQ account.
- Disconnect that OAuth connection.
- Open the Standard App used by ZoomInfo API if you configured live ZoomInfo access.
- Revoke the OAuth client credentials when the Standard App is no longer needed.
- Rotate the OAuth client secret when another integration still uses the Standard App.
These actions prevent the retired Retool setup from using either provider connection.
The downloaded export is the final local artifact.
- Locate contact-enrichment-comparison-YYYY-MM-DD.csv in the Downloads folder on your Mac.
- Move the CSV file to Trash.
- Empty Trash when you are ready to remove the export permanently.
Your comparator artifacts are now removed. The retired project can no longer consume provider credits.
Nice Work!
Nice Work!
You made it! Your Contact Enrichment Comparator now turns a bounded batch of profile URLs into a credit-aware provider comparison inside Retool.
You've learned how to:
- Build a validated batch workflow that cleans up to 10 profile URLs. Add credit confirmation before provider calls.
- Connect LeadIQ through an OAuth-protected MCP server. Connect ZoomInfo through an OAuth 2.0 Client Credentials REST resource.
- Normalize two response models into a side-by-side comparison table. Preserve no-match states plus provider-specific failures without hiding successful data.
- Secret Mission: Build a CSV export that preserves normalized results with safe quoting. Verify its columns plus row count in Numbers.
Ready to quiz yourself?