Punycode converter
The label münchen becomes xn--mnchen-3ya, the plain ASCII form that domain records, certificates and older systems accept. Encode one Unicode domain label at a time, or decode an xn-- label back into its readable letters. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- münchen
- Calculation mode
- Encode
- Result
- xn--mnchen-3ya
- Unicode
- münchen
- Punycode
- mnchen-3ya
Internationalized domain names need an ASCII-compatible encoding so DNS, certificates, and legacy resolvers can carry labels that include umlauts, accented letters, Cyrillic, Arabic, or CJK characters. Punycode (RFC 3492) is the Bootstring algorithm behind the familiar xn-- prefix used in IDNA A-labels. This capability encodes a single Unicode domain label into that ACE form, or decodes an ACE or raw Punycode body back to the original Unicode U-label, with a simple mode field and deterministic integer arithmetic. Invalid alphabet characters, empty xn-- bodies, lone surrogates, and multi-label strings with dots are rejected with a clear invalid input error instead of silent corruption.
Encode a Unicode domain label to Punycode ACE (xn--)
The engine lowercases the label in a locale-independent way, rejects empty strings, whitespace, control characters, and any embedded dots so you never accidentally treat a full multi-label hostname as one DNS label. Pure ASCII labels pass through unchanged without an xn-- prefix, matching IDNA practice for LDH names. When the label contains any non-ASCII code point, the engine runs the RFC 3492 Punycode encoder and prefixes the result with xn-- to produce the A-label used in DNS zone files, certificate SANs, and WHOIS displays.
The response includes result (the ACE or ASCII label), unicode (the folded U-label), punycode (the body without the xn-- prefix), ace true or false, mode encode, and method rfc3492 so tests can pin every field. Identical inputs always produce identical outputs because the path is pure arithmetic with no network, no random salt, and no wall clock. Use this path when you need a paste-safe A-label for a migration checklist, a zone-file line, or a support ticket that must survive systems that only accept ASCII hostnames.
Decode ACE or Punycode back to Unicode and handle invalid input
Set mode to decode and put an ACE label such as xn--mnchen-3ya or a raw Punycode body such as mnchen-3ya into text. The engine strips a leading xn-- prefix when present, validates that the body uses only the basic alphabet of letters, digits, and internal hyphens, then runs the RFC 3492 decoder to recover Unicode code points—including supplementary-plane characters represented with surrogate pairs in JavaScript strings.
Successful decode returns result and unicode as the U-label, punycode as the body, ace true when the input carried the xn-- prefix, mode decode, and method rfc3492. Prefer this capability when your search intent is a punycode converter for human-readable domain labels; full hostname splitting, public-suffix lookup, and live DNS resolution belong to other tools.
Using it in domain work and its limits
Call the free in-browser punycode converter for support playbooks, classroom demos, and one-off label checks without installing OpenSSL or language runtimes. A typical workflow encodes a Unicode brand label before writing an A-label into a zone template, then decodes ACE names copied from mail headers or certificate logs so operators can read the intended U-label. Another workflow verifies documentation samples still round-trip before a release.
DNS labels are capped at sixty-three octets in the ACE form, and this engine enforces that limit on encode so oversized international labels fail early rather than producing non-deployable strings. Authors shipping SDKs can map the result field into a copy button while unicode, punycode, and ace flags make OpenAPI examples self-explanatory for readers learning IDNA for the first time.
What you can do with it
DNS zone and certificate prep
Encode Unicode brand or city labels to xn-- A-labels before writing zone files, ACME SAN lists, or reverse-proxy host rules that only accept ASCII.
Support and log readability
Decode ACE names from mail headers, certificate transparency logs, and ticketing systems back to readable Unicode for agents and customers.
FAQ
How do I convert a Unicode domain label to Punycode?
The result field returns the ACE form such as xn--mnchen-3ya.
How do I decode an xn-- label back to Unicode?
Set mode to decode and put the ACE label (or the raw Punycode body without xn--) in text. The result field returns the Unicode U-label when the encoding is valid.
What happens on an invalid Punycode label?
Illegal characters, empty xn-- bodies, failed round-trips, dots in the string, and empty labels are rejected and not charged.
Is the punycode converter free?
The browser tool runs free on your device.
Can I convert a full hostname with multiple labels?
No. This capability accepts one label at a time and rejects dots. Split the hostname and encode or decode each label separately for predictable DNS-sized outputs.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/enc/punycode \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"münchen"}'const res = await fetch("https://api.kit.forhosting.com/enc/punycode", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "münchen"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/punycode",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "münchen"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/punycode", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"münchen"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"münchen"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/punycode", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "münchen"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.punycode",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Encode a Unicode domain label to Punycode ACE (xn--)
Send a JSON body with the required string field text set to one domain label in Unicode—for example a city name with an umlaut, a brand in native script, or a Japanese label—and leave mode at its default encode or set mode to encode explicitly.
Decode ACE or Punycode back to Unicode and handle invalid input
After decoding it re-encodes and requires an exact round-trip against the body so truncated or hand-edited ACE strings fail closed with invalid_input instead of returning plausible but wrong glyphs. Empty bodies after xn--, illegal characters such as punctuation bangs, non-ASCII text offered for decode, multi-label strings with dots, and overflow conditions all raise a descriptive invalid_input message and are not charged on the prepaid API.
API usage, pricing, DNS workflows, and practical limits
Use the prepaid KIT API when a backend, registrar panel, certificate automation job, or SDK needs the same encode or decode step under balance at $0.002 per successful item; failed validation never consumes balance after the engine rejects the request. Process each label of a multi-label hostname separately—the API rejects dots by design so the SEO landing matches single-label conversion intent.
Integration use cases
Docs and CI golden checks
Pin encode and decode fixtures so documentation samples and continuous-integration tests fail fast if Punycode or ACE prefix handling ever drifts.