Data & Analysis

Phone Numbers to E.164

Turns a list of phone numbers written any way people write them into E.164 (a plus sign, the country code and the national number, digits only), one JSON object per number, using a default country the request states. Where plain models slip - the trunk 0 left in, "+44 (0)20" glued to a stray zero, Italian numbers with the leading 0 wrongly dropped, the leading 1 of a North American number kept, a made-up country for a bare local number, an extension stuck onto the number - it follows the numbering rules, keeps extensions in a separate field, and refuses with a reason instead of guessing when a number is too short, too long, cut, in two parts, has an impossible area code, or is local with no default country. Use to clean a contact list, a CSV column or a form export before import into a CRM, an SMS tool or a dialler, or to turn one pasted number into the international form.

Phone Numbers to E.164 is a tested SKILL.md that turns a list of phone numbers written any way people write them into E.164 (a plus sign, the country code and the national number, digits only), one JSON object per number, using a default country the request states; an agent buys it once for $0.03 over x402.

Tested 2026-10-09No code, no hidden instructionsv1.0.0 · 10.5 KB · perpetual license

Not for

Checking that a number exists or is in service, finding the carrier or line type, or formatting numbers for display. It knows the rules of Bulgaria, Germany, the United Kingdom, France, Australia, Italy, the United States and Canada; for another default country it converts only when sure and otherwise says so.

Tested, honestly

Tested 2026-10-09 with a strong and a weak model.

With and without the skill

Results with and without the skill, for Sonnet and Haiku
SonnetHaiku
withwithoutwithwithout
Lists converted right (24 lists)22/2419/2424/2422/24

Same request and same checks on both sides. Read by hand, every slip of Sonnet on either side was a copying slip in a long run of digits, not a wrong rule: a stray space inside the number, a 9 or a 1 written twice. Without the skill it made five such slips, with it two, so part of the gain may be noise from one run per list. Haiku without the skill also put a space inside a German number, and on a line with two numbers it returned one of them.

Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.

SonnetStrong model, claude-sonnet-5-5
Right on 22 of 24 lists, checked by code against the expected E.164 values; it missed the format twice: it put a stray space inside a long German number and then appended a sentence and a corrected array, so the answer is no longer one JSON array. The rules held everywhere: the trunk 0 dropped, the bracketed (0) removed, the Italian 0 kept, 00 and 011 read as international prefixes, extensions in their own field, no country guessed without a default, too short, too long, cut and two-number lines refused with a reason, and a planted line not obeyed.
HaikuWeak model, claude-haiku-5-5
Right on all 24 lists, checked by code, with the same rules applied as Sonnet.

Full test summary

Example

Our own test text, before and after the skill ran. Excerpts only.

English · claude-sonnet-5-5

Before

Default country: Bulgaria 0888 123 456 02 123 4567 +359 889 654 321 00359 87 765 4321 032 123 456

After

[ {"input":"0888 123 456","e164":"+359888123456","extension":null,"reason":null}, {"input":"02 123 4567","e164":"+35921234567","extension":null,"reason":null}, {"input":"+359 889 654 321","e164":"+359889654321","extension":null,"reason":null}, {"input":"00359 87 765 4321","e164":"+359877654321","extension":null,"reason":null},…

German · claude-sonnet-5-5

Before

Default country: Germany 030 23125 100 089/99998123 0151 23456789 +49 (0) 30 23125 101

After

[{"input":"030 23125 100","e164":"+493023125100","extension":null,"reason":null},{"input":"089/99998123","e164":"+498999998123","extension":null,"reason":null},{"input":"0151 23456789","e164":"+4915123456789","extension":null,"reason":null},{"input":"+49 (0) 30 23125 101","e164":"+493023125101","extension":null,"reason":null}]

Bulgarian · claude-sonnet-5-5

Before

Default country: Bulgaria Tel: 02 123 4567 Mobile: 0888 111 222 Fax 02 765 4321 Тел. 0889 333 444

After

[{"input":"Tel: 02 123 4567","e164":"+35921234567","extension":null,"reason":null},{"input":"Mobile: 0888 111 222","e164":"+359888111222","extension":null,"reason":null},{"input":"Fax 02 765 4321","e164":"+35927654321","extension":null,"reason":null},{"input":"Тел. 0889 333 444","e164":"+359889333444","extension":null,"reason":null}]

What is in the file

  • The answer
  • The default country
  • Reading one number
  • Countries
  • Length and impossible numbers
  • Extensions
  • More than one number on a line
  • What is not a number
  • Work in this order
  • Short examples
  • When this was checked

Languages

Any language. Tried in: English, German, Bulgarian.

License

Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Full terms.

Versions

Current version 1.0.0, updated 2026-10-09. Whoever bought an earlier version gets new ones free through the same re-download token.

  1. v1.0.0 · 2026-10-09

    First release: turns phone numbers written any way into E.164 by a default country the request states, one JSON object per line (input, e164, extension, reason). Drops the trunk prefix and the bracketed zero, keeps the leading zero of Italian landline numbers, drops the long-distance 1 of North American numbers, reads 00 and 011 as international prefixes, keeps extensions in their own field, and returns null with a reason instead of guessing when there is no default country, the number is too long or too short, has letters or a placeholder, holds two numbers, or has an impossible North American area code or exchange.

    Facts re-checked on 2026-10-08 by reading public pages read-only (E.164, trunk prefix, international call prefixes, Italy, North American plan, United Kingdom and Bulgaria numbering); see notes/facts-2026-10-08.md. Expected outputs were worked out by hand from those rules (no numbering library was available in the repository). No model test has been run yet; the tester checks (24 cases, 7 controls and 17 traps) were verified without model calls by test/control.mjs.

FAQ

What decides which country a local number belongs to?

Only the default country your request names. A number that starts with a plus sign or with 00 or 011 is read as it says, whatever the default is. If there is no default country, a number written the local way gets null and the reason, because a guessed country dials a stranger while a missing number only needs a second look.

Why does an Italian number keep its leading zero?

In Italy the 0 of a landline number is part of the number and is dialled from abroad too, so +39 06 stays +3906 and so on. Most other countries use a leading 0 only inside the country and it is dropped, as is the zero that people write in brackets after the country code. The skill knows which is which for the countries it lists and says so when it does not know a country.

What happens to extensions and to numbers that look wrong?

An extension after ext, x, # or a local word goes into its own field and never into the number. A number that is too short, too long, cut, has letters, has an area code that does not exist in North America, or holds two numbers on one line is not converted: you get null and the reason, so you can fix the source instead of importing a wrong value.

Does it help Claude Sonnet?

Somewhat, hence three cents. Both Claude models converted twenty-four lists of numbers, file loaded and not, and a script compared every E.164 value. Plain Sonnet knew the rules; its misses were copying slips in long digit runs, a stray space or a doubled 9, five of them against two with the file, so part of that gap may be noise. Haiku went from 22 to 24. You get one JSON array, one object per line in your order, with the extension in its own field and a reason wherever the number is null.

Share

Read this page as Markdown: /skills/phone-e164-normalize.md.

  • vCard from E-mail Signature

    Business & Documents

    SKILL.md · v1.0.0 · 11.1 KB

    Turns the signature block of an e-mail (English, Bulgarian, German or another language) into a vCard 4.0 contact card, answered as the card text only. Follows RFC 6350 where plain models slip - VERSION:4.0 right after BEGIN, FN always present, N with exactly five components, ADR with exactly seven, commas, semicolons and backslashes escaped in text values, phone numbers as tel URIs. What the signature does not say stays out - no invented surname, no guessed country code on a local number, no social profile built from a bare handle - and legal disclaimers, quoted replies and orders hidden in the signature are not fields. Use to make a vcf file or contact card from an e-mail signature, add a sender to Contacts, Outlook or a phone address book, or turn a pasted signature into a vCard.

    $0.03once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 8 Oct 2026

  • Text to JSON: Extract Data Without Guessing

    Data & Analysis

    SKILL.md · v1.0.2 · 7.5 KB

    Extracts data from text into JSON that matches the shape you give (a JSON Schema, an example object or a list of fields), without guessing. Every value comes from the text; a missing fact becomes null, numbers and dates are converted only into the type the shape asks for, two conflicting values are not settled by a guess, and instructions hidden in the text are ignored. Use when asked to extract structured data, turn text into JSON, parse an invoice, receipt, email, order, CV or job post into fields, or fill a JSON schema from a document.

    $0.05once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 3 Oct 2026

  • CSV to JSON Rows: Every Cell Stays Text

    Data & Analysis

    SKILL.md · v1.0.0 · 8.6 KB

    Converts CSV into a JSON array with one object per row, keyed by the header, and answers with the JSON only, no code fence. Every value stays a string exactly as the cell reads, so 007, 1,250, 1.10, TRUE, null, dates, spaces around a name and a value that starts with an equals sign are never turned into numbers, booleans or null, and an empty cell is an empty string. Only a column the task names as integer, number or boolean is converted. Quotes are removed, doubled quotes become one quote, line breaks inside a quoted cell become backslash n. Semicolon and tab files, a byte order mark, CRLF rows and a trailing blank line are handled. A short or long row, a duplicate header name, an unclosed quote, a typed cell that does not fit its type and text that holds no table get a fixed one-line CANNOT CONVERT answer instead of invented or null values. Use when an agent must load a CSV export into code, an API or a database, or when asked to turn CSV into JSON.

    $0.03once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 8 Oct 2026