All posts

How to Verify Emails With Power Automate: HTTP Action, Parse JSON, Retries

··12 min read

To verify emails in Power Automate, add an HTTP action that sends each address to an email verification API, parse the JSON reply, and branch on the status with a Switch. The HTTP action is a premium connector, so the flow needs a Premium or Process license. Turn on Secure Inputs and Secure Outputs so the API key stays out of run history. For tables, keep the loop's concurrency low and let the retry policy handle rate-limit replies. Valid addresses go on, risky ones go to review, and invalid ones get flagged.

This guide builds that flow step by step with SimpleVerifier's API. The same pattern works with any verification API that takes an email and returns a status.

Why a flow cannot do this alone

Power Automate can trim text and test whether it contains an @. That is a syntax check. Whether jane@company.com has a mailbox behind it needs a DNS lookup and a short SMTP conversation with the recipient's mail server. Our guide to syntax checks vs SMTP verification shows what each layer catches. A verification API does that work. Your flow sends the address, reads the answer and acts on it.

Before you build: licensing

Check this first, because it decides whether the flow will run at all.

The HTTP action carries the Premium label in the designer. Microsoft's Power Automate licensing FAQ says users on the Power Automate Free license or one of the Microsoft 365 plans can only access standard connectors. The same FAQ says a flow without premium connectors can run on a Microsoft 365 license, which is why many Forms and SharePoint flows never hit this question.

Your options, from Microsoft's license types page:

License What it covers Daily action limit
Microsoft 365 (seeded) Standard connectors only 6,000 per user
Power Automate Premium Standard, premium and custom connectors 40,000 per user
Power Automate Process Assigned to one flow; premium connectors whoever runs it 250,000 per license

The 6,000 figure for Microsoft 365 comes from Microsoft's seeded license comparison. To see what you have, open Power Automate and select Settings > View my licenses.

One more check: your admin may block HTTP connectors through a data policy. Microsoft's connector classification page describes how admins can classify or block HTTP. If the action is greyed out, ask before you build.

On the API side, SimpleVerifier's API is included with a subscription. Keys start with sv_live_ and are shown once. The API docs explain how to create one.

What you will build

The main flow has six steps:

  1. Trigger: a new Microsoft Forms response, a new SharePoint list item, or a schedule that reads an Excel table.
  2. Compose: trims and lowercases the email.
  3. HTTP: calls the verification API.
  4. Parse JSON: turns the reply into fields you can use.
  5. Switch: branches on status.
  6. Write back: updates the list item, adds a row, or sends an alert.

Step 1: Pick a trigger

Source Trigger Notes
Microsoft Forms When a new response is submitted Then add Get response details to read the answers
SharePoint list When an item is created Do not use "created or modified" if the flow writes back to the same item
Excel table Recurrence (schedule) The Excel connector has no new-row trigger; list rows on a schedule

All three connectors are standard. Microsoft's Forms connector reference lists When a new response is submitted and Get response details. The trigger only returns a response ID, so the second action is needed to read the email field. Forms works with organizational accounts only.

For SharePoint, the connector reference describes When an item is created or modified as firing "each time it is modified." A flow that writes the result back to the same item would trigger itself again. Use When an item is created instead.

Step 2: Normalise the address

Add a Compose action named Clean email. Set its input to this expression:

toLower(trim(outputs('Get_response_details')?['body/r1a2b3c4']))

Replace the path with the dynamic content for your email question or column. For a SharePoint trigger it is usually triggerOutputs()?['body/Email'].

Normalising first means Jane@Company.com and jane@company.com are checked and stored as one address.

Step 3: Configure the HTTP action

Add the HTTP action and rename it Verify email. Names matter, because later expressions refer to them.

Field Value
Method GET
URI https://simpleverifier.com/api/v1/verify?email=@{encodeUriComponent(outputs('Clean_email'))}
Headers Authorization : Bearer sv_live_...
Body Leave empty

encodeUriComponent() matters. Addresses can contain +, which a query string would otherwise read as a space.

If you prefer POST, the API also accepts a JSON body:

Field Value
Method POST
URI https://simpleverifier.com/api/v1/verify
Headers Authorization : Bearer sv_live_... and Content-Type : application/json
Body { "email": "@{outputs('Clean_email')}" }

The reply looks like this:

{
  "email": "jane@company.com",
  "status": "valid",
  "reason": "Mailbox exists",
  "mailbox_checked": true
}

status is valid, risky or invalid. reason explains it, for example "Accepts all addresses", "Role-based address" or "Mailbox not found". The API docs list every reason.

Secure the key

Open the HTTP action's Settings and turn on Secure Inputs and Secure Outputs. Microsoft's guide to managing sensitive input says this prevents the values "from being shown in the logs." A lock icon appears on the action.

Two limits to know. First, secure outputs also hide the reply in run history, which makes debugging harder. Turn them off while testing, then back on. Second, anyone who can edit the flow can still read the header in the designer. Keep co-owners to people who need them, and give the flow its own key so you can revoke it alone.

Timeouts

A mailbox check waits on the recipient's mail server. Most answer in seconds. Some are slow, and our API docs recommend allowing about 30 seconds. Power Automate's limits page gives an outbound synchronous request 120 seconds, so the default is already long enough. You do not need to change it.

Step 4: Parse the reply

Add Parse JSON. Content: the Body of Verify email. Schema:

{
  "type": "object",
  "properties": {
    "email": { "type": "string" },
    "status": { "type": "string" },
    "reason": { "type": "string" },
    "mailbox_checked": { "type": "boolean" }
  },
  "required": ["status"]
}

You can also select Use sample payload to generate schema and paste the example reply above. Microsoft's data operations guide describes that option. If you generate it, trim the required list to status so a missing optional field never fails the run.

Step 5: Branch on the status

Add a Switch on status from Parse JSON:

Case What to do
valid Continue: add to the CRM, the mailing list or the sales queue
risky Write the status and reason; route to a person, not an automated sequence
invalid Write the status; for a form, email the person to ask for a correct address
Default Log it. This catches anything unexpected

Keep the reason with the record. "Accepts all addresses" is a catch-all domain and "Role-based address" is an info@ inbox. They need different handling. Our guide to accept-all vs unknown results explains the risky reasons.

Step 6: Write the result back

For a SharePoint list, add two columns: Email status (Choice: valid, risky, invalid) and Email reason (single line of text). Add an Update item action in each branch with the trigger's item ID.

For Microsoft Forms, add a row to an Excel table or a SharePoint list that collects responses, with the status alongside.

Add a third column for the check date. A result describes the mailbox on that day. Our re-verification cadence guide covers when it goes stale.

Retries and error handling

Two kinds of failure need different treatment.

Temporary: 429 (more than 120 calls a minute on one key) and 503 (the service is briefly unavailable). Retry these. Microsoft's error handling guide, which the Power Automate limits page links to for retry policies, says an HTTP action that fails with "a 408, 429, or 5xx response" is resent per its retry policy. The default policy retries with growing waits. If you want something predictable, open Settings > Retry policy, choose Fixed interval, and set a count of 3 with an interval of PT30S. The minimum allowed interval is 5 seconds.

Permanent: 400 (no email sent), 401 (bad or revoked key) and 402 (the key's subscription is not active). Retrying will not help.

To stop one failure from killing the run, add a Compose or Update item after the HTTP action, open its Settings, and set Run after to has failed and has timed out. Write check failed to the status column so the row can be retried later. The same Microsoft guide explains run-after statuses and how to group steps in a Scope to catch failures in one place.

Variant: verify an Excel table on a schedule

Many teams keep leads in an Excel table on OneDrive or SharePoint. The Excel Online (Business) connector has actions but no new-row trigger, so run the flow on a schedule:

  1. Recurrence: every hour.
  2. List rows present in a table: the leads table.
  3. Filter array: keep rows where Email status is empty.
  4. Apply to each over the filtered rows: Compose, HTTP, Parse JSON, Switch.
  5. Update a row in each branch, with the key column set to your email column.

Three connector limits from Microsoft's Excel connector reference shape this design:

Limit Value What to do
Rows returned by List rows 256 by default Turn on pagination in the action's settings
Calls per connection 100 per 60 seconds Keep the loop slow; each update is a call
Update a row with duplicate keys Only the first match is updated Dedupe the email column first

The key column name is also case-sensitive.

Concurrency: the setting that protects both limits

Microsoft's limits page says Apply to each concurrency is 1 by default and can be set from 1 to 50. Leave it at 1, or set it to 2.

Here is why. At concurrency 1, the loop makes one verification call, then one Excel update, then moves on. Even if every call returned instantly, the Excel connector's 100 calls a minute would stop you before the API's 120. Raising concurrency to 20 to "go faster" mostly produces 429 replies from both sides.

If your trigger can fire many runs at once, such as a Forms link shared to a large audience, you can also turn on Concurrency Control in the trigger's settings. The limits page notes it is off by default, ranges from 1 to 100, and "can't be undone without deleting and re-adding the trigger." Decide before you enable it.

Worked example: a webinar registration form

This example is illustrative. A marketing team collects webinar registrations with Microsoft Forms and stores them in a SharePoint list.

  1. A registrant types Sam.Lee@Example-Corp.com and submits.
  2. Get response details reads the email answer.
  3. Clean email returns sam.lee@example-corp.com.
  4. Verify email returns status: risky, reason: Accepts all addresses.
  5. The Switch takes the risky case. Create item adds the registration with Email status = risky and Email reason = Accepts all addresses.
  6. The registration still goes through. The sales team sees the flag and checks the contact before any follow-up sequence.

A valid result would have gone straight to the reminder list. An invalid one would have triggered a short email asking for a working address.

Action count for one registration: trigger, Get response details, Compose, HTTP, Parse JSON, Switch, Create item. That is seven actions. At 300 registrations a month, about 2,100 actions, which is far inside the 40,000 a day a Premium license allows.

Test before you switch it on

Run five test submissions: an address you own (expect valid), a made-up address at gmail.com (expect invalid; Yahoo hides mailbox status, so it is a poor test), an address at a domain that accepts all mail (expect risky), an address with capitals and spaces (it should arrive normalised), and a run with a wrong key (expect a 401 and check failed). Then restore the key, turn Secure Outputs back on, and enable the flow.

When to upload a CSV instead

Power Automate is good at checking records as they arrive. It is a poor way to clean a list you already have.

Each row costs several actions against your daily limit, the Excel connector throttles at 100 calls a minute, and the verification API allows 120 calls a minute per key. A 10,000-row table would take well over an hour and use tens of thousands of actions. A CSV upload runs the same syntax, domain, disposable and mailbox checks in bulk and returns separate valid, risky and invalid files. Our guide to cleaning and verifying a list in Excel walks through the export and re-import. For the API approach in other tools, see verifying new leads with Zapier, Make or a webhook.

Common problems

Symptom Likely cause Fix
Flow suspended or HTTP greyed out No premium entitlement, or a data policy blocks HTTP Check Settings > View my licenses; ask your admin
Every call returns 401 Header value missing "Bearer " Set the header to Bearer sv_live_...
402 on every call Subscription not active Check the plan; pay-as-you-go packs do not include API access
Bursts of 429 Concurrency raised, or several flows share one key Set concurrency to 1 or 2; give each flow its own key
Flow runs twice per item Trigger is "created or modified" and the flow updates the item Switch to "When an item is created"
Addresses with + fail Email not encoded in the URI Wrap it in encodeUriComponent()

What it costs

On SimpleVerifier, API access comes with Pro at $29.99 a month, with unlimited email verification and no per-call credits. Email + Phone at $49.99 a month adds 5,000 live phone carrier lookups through the same API. Pay-as-you-go packs, $9 for 2,500 or $19 for 10,000 emails, cover CSV uploads only and credits never expire. If a flow like this would save your team manual checks, see pricing.

The short version

Confirm you have a premium entitlement. Trim and lowercase the email, then call the verification endpoint from the HTTP action with the email URL-encoded and the key in a secured header. Parse the reply, Switch on status, and write the status, reason and date back. Keep loop concurrency at 1 or 2, use a fixed retry policy for 429 and 503, and catch failures with run-after. Use CSV uploads for existing lists.

Common questions

Can Power Automate verify an email address?

Not by itself. Power Automate moves data between services. To confirm a mailbox exists, call an email verification API from the HTTP action and route on the result. Expressions such as contains() only check the shape of the text.

Is the HTTP action premium in Power Automate?

Yes. It carries the Premium label in the designer. Microsoft's licensing FAQ says users on the Power Automate Free license or a Microsoft 365 plan can only use standard connectors, so a flow with the HTTP action needs a Power Automate Premium user license or a Process license on the flow.

How do I hide an API key in Power Automate?

Open the HTTP action's Settings and turn on Secure Inputs and Secure Outputs. Microsoft documents this as the way to keep sensitive values out of run history. Anyone who can edit the flow can still see the header in the designer, so limit co-owners.

How do I stay under an API rate limit in Power Automate?

Keep the loop slow. Apply to each runs one iteration at a time by default, and you can raise it to 50. For a 120-calls-a-minute API, a concurrency of 1 or 2 is enough. The HTTP action's retry policy resends requests that return 429, which covers the occasional burst.

Should I verify a whole Excel file with Power Automate?

Usually not. Every row costs several actions against your daily action limit, and the Excel connector is throttled per connection. Upload the file as a CSV instead and use the flow for new rows only.

Verify unlimited addresses for $29.99/month

Real SMTP mailbox checks. No credits, no per-email fees.

Get Started