Input formats
What a valid input file looks like and what you get back in the cleaned output. We accept CSV, TSV, TXT, XLSX (Excel), and JSON.
Supported file types
- CSV (
.csv): standard comma-separated, quoted fields supported (RFC 4180). - TSV (
.tsv): tab-separated. Auto-detected by sniffing the first line. - TXT (
.txt): one phone per line, no header required. We treat it as a single-column file. - Excel (
.xlsx,.xls): first sheet only. We convert it to CSV on the server. - JSON (
.json): either an array of phone strings (["+1...", "+44..."]) or an array of contact objects ([{"phone":"+1...","name":"..."}]). For wrapping shapes like{"records":[…]}we unwrap the first array-valued property. - Apple Numbers (
.numbers): not yet supported. Export to CSV from Numbers (File → Export To → CSV) and re-upload.
Input requirements
Whichever format you pick, the file needs:
- A header row (CSV/TSV/XLSX) with any column names. TXT has no header. JSON: column names come from object keys.
- One phone column. The cleaner auto-suggests columns named
phone,mobile,cell,tel, ore164-style; you select the single column you want cleaned. - Up to 100,000 rows and 50 MB. Split larger files for now.
Accepted phone formats
Our parser handles every common phone-number shape, punctuation, spaces, parentheses, leading zeros, country codes:
- E.164:
+447400123456 - International with spaces:
+44 7400 123 456 - National (UK):
07400 123456 - US national with separators:
(415) 555-2671 - Mixed punctuation:
+1.415.555.2671,+1-415-555-2671
When a number is in national format (no leading +), the cleaner uses your selected default country to decide which dial plan applies.
Extra columns
Other columns are passed through without modification, useful for keeping internal IDs alongside cleaned numbers. The output preserves the original file order and original column order. Our cleaning columns are appended on the right.
Output: full_results.csv
By default, the file is your original CSV with our cleaning columns appended on the right. So an upload like:
name,phone,email,campaign Alice,07400 123456,alice@example.com,welcome
becomes:
name,phone,email,campaign,original_row_number,source_phone_column,input_phone,normalized_e164,… Alice,07400 123456,alice@example.com,welcome,1,phone,07400 123456,+447400123456,…
If your downstream pipeline expects only the cleaning columns, toggle "Simplified export" on the upload screen. That flips the output to one result row per uploaded row, with these columns only:
| Column | Type | Description |
|---|---|---|
original_row_number | integer | 1-indexed row in the source CSV (excludes header). |
source_phone_column | string | The selected column this phone value came from. |
input_phone | string | The raw value from the phone column. |
normalized_e164 | string? | E.164 form, e.g. +447400123456. |
valid | boolean? | true/false/null. null when we couldn't reach the provider. |
country | string? | 2-letter ISO code. |
country_name | string? | Human-readable country. |
region | string? | Continent / region. |
line_type | enum | mobile · landline · voip · toll_free · unknown |
carrier | string? | Best-effort carrier name. |
sms_ready | boolean | True when the row is a valid, non-duplicate mobile. |
call_ready | boolean | True when the row is a valid, non-duplicate mobile or landline. |
reason | enum | See the reason list below. |
duplicate | boolean | True if a previous row had the same normalized E.164. |
duplicate_of_row | integer? | First row that produced the same E.164. |
cached | boolean | True if served from cache (no paid lookup). |
checked_at | ISO 8601 | When the worker ran. |
error_code | string? | Set when something went wrong. |
Reason values
valid_mobile, sms_ready and call_ready truevalid_landline, call_ready truevalid_voip, call_ready true (mixed SMS support)valid_toll_free, neither sms_ready nor call_readyinvalid_number, provider says it's not a real numberduplicate, same E.164 as an earlier rowunknown_line_type, can't tellprovider_unavailable, provider failed; refundedmalformed_input, couldn't even parse locally
Output: sms_ready_only.csv
A shortlist of just the rows where sms_ready=true. Smaller column set so you can paste it straight into an SMS tool:
original_row_number, source_phone_column, input_phone, normalized_e164, country, line_type, carrier, reason
Other download presets
Completed batches also expose filtered exports generated from full_results.csv. These keep the same columns as the full export, so your original IDs, names, and campaign fields stay attached.
| File | Use it for | Rows included |
|---|---|---|
valid_rows_only.csv | Removing unusable rows before CRM import or manual review. | Rows with a normalized number and no invalid, malformed, unresolved, or provider-failed result. |
call_ready_only.csv | Calling workflows where landlines and VoIP numbers are still useful. | Valid, non-duplicate mobile, landline, or VoIP rows. |
deduped_best_rows.csv | Keeping one record per phone number without losing the best contact row. | One row per normalized number, preferring the row with more original contact data. |
Campaign tool presets
Completed batches also include CSV presets for common campaign tools. These are generated from full_results.csv; they do not call HubSpot, Klaviyo, Pipedrive, Twilio SendGrid, or any dialer.
| File | Rows included | Important note |
|---|---|---|
twilio_sendgrid_contacts.csv | sms_ready=true | Uses phone_number_id as the first column for SendGrid Marketing Campaigns. |
hubspot_contacts_sms_ready.csv | sms_ready=true | Maps the cleaned number to Mobile phone number; phone alone is not HubSpot's dedupe key. |
klaviyo_sms_contacts.csv | sms_ready=true | Includes Klaviyo country values where documented. SMS consent is not encoded. |
pipedrive_people_call_ready.csv | call_ready=true | People imports need Person - Name; blank-name rows are warned before export. |
generic_dialer_call_ready.csv | call_ready=true, deduped | E.164-first lead file for dialers without a shared import standard. |
sms_ready means technically SMS-ready. It does not mean the contact has marketing consent.
What counts as a billable row?
- Unique parseable numbers, debit 1 credit per paid lookup.
- Duplicates of an earlier row, free.
- Malformed input (empty, non-digits, too short), free.
- Cache hits, free (we cache successful lookups for 24 hours).
- Unresolved lookups, refunded automatically.