All posts

Loops CSV Import: Clean and Verify Contacts Before You Upload

··5 min read

To import contacts into Loops cleanly, export your users with an email column, drop anyone who did not sign up to hear from you, dedupe, verify the addresses, and upload only the valid rows through Audience, then Import, then CSV. Loops suppresses hard bounces automatically, but each one still counts against your bounce rate, and its docs treat anything over 5% as a reason to stop sending.

Loops is common with SaaS teams who load their user table straight from a database export. That is exactly the kind of list that collects typos, test accounts and signups from throwaway inboxes. Everything below is from Loops' documentation, read on 2 November 2026.

Loops' rules that matter for an import

Rule What Loops says Source
Matching User ID first, then Email; a match updates the contact CSV upload
Default subscription Imported as subscribed unless Subscribed is false Same page
Unsubscribes The importer will not re-subscribe unsubscribed contacts Same page
Suppression Hard bounce or complaint suppresses the contact Suppression
Removing suppressions Paid accounts: up to 100 in a rolling 30 days Same page
Bounce guidance Under 2% healthy, 2 to 5% investigate, over 5% pause Reducing bounce rate
Purchased lists Not allowed, regardless of source or permission Terms

The suppression rule is the one people miss. If a real user's address gets suppressed by mistake, there is a small monthly budget for fixing it. Keeping bad addresses out of the first send is cheaper than spending that budget later.

Step 1: Export from Loops, or from your app

From Loops. If the contacts already live in Loops and you want to re-check them (export contacts):

  1. Open the Audience page.
  2. Apply filters if you only want part of the audience, for example Subscribed is true.
  3. Click the ••• menu at the top right of the filter box and choose Download.

The CSV includes every default and custom contact property, so you get userId and your own fields back as well.

From your app's database. Export at least the user ID, email, first name and signup date. Keep the user ID: Loops matches on it first, which stops a corrected email from creating a second contact. If the data sits in a spreadsheet first, the CSV import formatter renames columns to the Loops property names.

Step 2: Remove rows you should not email

  • Users who never agreed to product or marketing email. Loops' terms ask for "targeted, permission-based messages" to recipients who "explicitly provided their email address for such purpose". Transactional messages are a separate case; this is about campaigns and loops.
  • Unsubscribed users. Either leave them out, or keep them in the file with Subscribed set to false so Loops records them as unsubscribed. Loops will not re-subscribe an existing unsubscribed contact either way.
  • Internal and test accounts. Filter for your own domain, test, example.com and plus-addressed duplicates. The Gmail address normalizer folds name+trial2@gmail.com back to one address, and remove duplicate emails clears exact repeats.
  • Throwaway inboxes. Free-trial products attract them. The bulk disposable email checker finds them without using verification checks.

Step 3: Verify the addresses

Upload the cleaned file on the verify page. Each address gets a live mailbox check, and your other columns, including the user ID, stay in the file. A sample can go through the CSV email verifier first.

Result What to do in Loops
Valid Import as subscribed
Catch-all Import with a property such as emailCheck = catch-all, send after valid
Unknown Hold back, re-check in a day or two
Invalid Leave out, or import with Subscribed = false so nobody re-adds it
Disposable Leave out of campaigns

Signup typos are the usual source of invalid rows in an app's user table: gmial.com, hotmial.com, a missing letter in a company domain. The email typo corrector suggests fixes for obvious domain mistakes. A fixed address still needs checking, because the user may have typed a different name too.

If many signups are coming in fake, fix it at the source rather than at every import. Block disposable emails at signup covers that.

Step 4: Build the import file

Keep the file small and predictable:

userId,email,firstName,lastName,userGroup,source,emailCheck
u_1042,jane@company.com,Jane,Doe,trial,app-signup,valid
  • Headers match Loops property names, so mapping is automatic.
  • Dates as YYYY-MM-DD. Loops does not accept timestamps in a CSV (contact properties).
  • Empty cells are safe. They do not overwrite data already on the contact. Typing null clears a field, so do not use the word as a placeholder.
  • Only the columns you need. Every extra column is one more chance to overwrite a property your app sets through the API.

Step 5: Import only the good rows

Following Loops' CSV upload guide:

  1. On the Audience page, click Import at the top right.
  2. Hover CSV and choose Upload CSV.
  3. Check the review page. It shows duplicates and missing information before you finish.
  4. Decide on Trigger workflows. Leave it off for a back-fill of existing users, unless you really want every imported contact to start an onboarding loop today.
  5. Finish the import. Contacts without a Source value get "CSV Upload".

Import the catch-all rows the same way, with emailCheck set, then build a segment on that property so your first campaign can exclude them.

Step 6: Send to the safest group first

Send your first campaign to valid, recently active users. Watch hard bounces in the campaign stats against Loops' own bands: under 2% is healthy, 2% to 5% means look closer. Then send to the remaining valid contacts, and to the catch-all segment in smaller batches. Should you email catch-all addresses explains why that group is held back.

Keep it clean after the import

A one-off clean-up decays as new users sign up. Two habits keep the Loops audience healthy:

  • Check new signups as they arrive, through the email verification API, before you create the Loops contact, so bad addresses never reach a loop.
  • Re-check dormant users before a large announcement. B2B addresses go stale as people change jobs; see B2B contact data decay.

Checklist

  • User ID column kept so updates match the right contact
  • Unsubscribed users excluded or marked Subscribed = false
  • Test, internal and disposable addresses removed
  • Every address verified; invalid rows left out
  • Dates in YYYY-MM-DD, no null placeholders
  • Trigger workflows set deliberately
  • Catch-all contacts tagged with a property and sent last

Verify before you upload

Upload your user export on the verify page. You get 100 free email checks when you sign in with Google, no card, enough to see how a sample of your user table holds up. For larger lists, monthly plans are on the pricing page.

Common questions

What columns does a Loops CSV need?

Loops does not strictly require any column, but it recommends Email, First Name, Last Name, User Group and Source. Column headers should match the Loops property names so the mapping is automatic. Dates must be in YYYY-MM-DD formats; timestamps are not accepted in a CSV.

Does a Loops CSV import overwrite existing contacts?

It updates them. Loops matches on User ID first and then Email. When a match is found it updates the contact; empty cells do not overwrite existing data, and the text null clears a field. It will not re-subscribe a contact who has already unsubscribed.

What is a good bounce rate in Loops?

Loops' deliverability docs call under 2% healthy, 2% to 5% worth investigating, and over 5% a sign that deliverability is at risk and you should pause and diagnose. These are guidance figures, not published enforcement limits.

Can I upload a purchased list to Loops?

No. Loops' terms say purchased lists may not be used with the service regardless of the source or permission status, and that recipients must have explicitly provided their email address for that purpose.

What happens when a Loops contact hard bounces?

Loops suppresses sending to that contact after a hard bounce or a complaint. Later attempts to email a suppressed contact show as hard bounces. Paid accounts can request up to 100 suppression removals in a rolling 30-day period; free accounts have to ask support.

Check your list before you send

Real mailbox checks over SMTP, and nothing is sent to the address. Sign in with Google and your first 100 email checks are free, no card. Plans for bigger lists are on the pricing page.