Remove non-ASCII characters
Café becomes Cafe, Straße becomes Strasse and São Paulo becomes Sao Paulo, while emoji, CJK characters, currency signs and curly quotes are deleted. Plain text for old systems, CSV exports and strict mail relays. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- Hello, café 🎉!
- Result
- Hello, cafe !
- Length
- 13
- Original length
- 15
- Removed
- 1
Legacy systems, serial protocols, CSV exporters, and picky mail relays still break when a single emoji, smart quote, or accented letter slips into a field they treat as seven-bit ASCII. This remove-non-ascii-characters tool takes any non-empty string, folds Latin accents to their plain bases, then deletes every remaining character outside the ASCII range so the result is clean seven-bit text. Emoji, CJK, currency signs, and typographic symbols disappear; café becomes cafe; already-plain ASCII is returned unchanged.
How non-ASCII removal works under the hood
Removing non-ASCII is a short deterministic pipeline, not a locale guess and not a machine-learning rewrite. First the engine applies Unicode Normalization Form D, which separates a base letter from its combining diacritical marks, so é becomes e plus a combining acute, ñ becomes n plus a combining tilde, and ü becomes u plus a combining diaeresis. Second, every combining mark in the common mark ranges is deleted, leaving the bare Latin bases for Western European, Central European, and many Vietnamese tone-marked letters.
Third, a fixed transliteration table rewrites letters that survive NFD without becoming ASCII: Nordic and Icelandic forms such as ø, æ, ð, and þ; German sharp s; French and Latin ligatures œ; Polish and Slavic stroke letters such as ł and đ; and a few Maltese and horned Vietnamese bases. The table is case-preserving where both cases exist, so Æ becomes AE and ß becomes ss.
Fourth, a single walk keeps only code points from U+0000 through U+007F and drops everything else: emoji, CJK, Cyrillic, Arabic, currency signs, curly quotes, em dashes, and leftover symbols. ASCII letters, digits, punctuation, spaces, tabs, and newlines stay in their original order. The algorithm then reports how many leftover non-ASCII code points were deleted and whether the string changed at all.
Empty strings fail validation before any transform runs. Because the path is pure parse work over strings, latency stays sub-millisecond for typical form sizes and the published cost model is analytic rather than model-token based.
What you send and what you get back
Send a single required field named text containing the non-empty string you want cleaned to ASCII. Classic checks include Café becoming Cafe, naïve becoming naive, São Paulo becoming Sao Paulo, Straße becoming Strasse, and a string such as Hello, café 🎉 becoming Hello, cafe with the emoji gone. Already-plain ASCII such as ABC-123 returns unchanged, changed is false, and removed is zero, which is useful as a no-op detector in ETL guards.
The engine does not collapse leftover spaces after a deleted symbol, does not change case, and does not invent Latin spellings for Cyrillic or CJK—those scripts are simply deleted. That is the product intent of this landing: seven-bit ASCII for legacy systems, not a full transliterator.
Where a remove-non-ASCII tool shows up in real work
Operations teams paste console dumps, ticket fragments, and vendor filenames that pick up emoji, smart quotes, or currency signs from chat and mail, then need a field a mainframe, POS terminal, or seven-bit SMTP hop will accept. Data engineers cleaning CRM exports and warehouse loads often force free-text columns to ASCII before joining on soft keys or writing files for tools that still assume Latin-1 or even 7-bit encodings.
Publishers and CMS editors scrub pasted titles that look fine on screen but carry typographic dashes and CJK leftovers that break old RSS consumers or filename rules. Product and growth teams fold display names into ASCII fallbacks when a downstream vendor rejects anything outside 0x00–0x7F, while still wanting José to become Jose rather than Js. If you later need hyphenated URL slugs, case folding, or phonetic romanization of non-Latin scripts, treat those as separate landings.
Keep requests under the documented length cap, pin the result string in tests, and you get reproducible ASCII without standing up an encoding library of your own.
What you can do with it
Sanitize fields for seven-bit legacy systems
Fold accents and drop emoji, CJK, and typographic symbols so mainframe, POS, and SMTP fields accept the value as plain ASCII.
Clean CSV, logs, and warehouse columns
Force free-text columns to ASCII before joins, file drops, and tools that still assume Latin-1 or 7-bit encodings.
FAQ
What does remove non-ASCII characters do?
It folds Latin accents to plain letters, then deletes every remaining character outside U+0000–U+007F—emoji, CJK, currency signs, and typographic symbols—so the result is clean seven-bit ASCII.
How is this different from remove accents?
Remove-accents keeps emoji, CJK, and other unmapped scripts and only simplifies diacritics. This tool also deletes those leftover non-ASCII characters so legacy systems receive ASCII only.
What happens to emoji, CJK, and smart quotes?
They are deleted after the accent fold. A string such as Hello, café 🎉 becomes Hello, cafe (the emoji is gone; leftover spaces are not collapsed).
What happens if I send empty text?
Empty strings are rejected so clients notice missing fields instead of receiving a silent empty result.
What does it cost?
The browser tool is free and runs locally.
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/str/remove-non-ascii \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Café 🎉 — São Paulo"}'const res = await fetch("https://api.kit.forhosting.com/str/remove-non-ascii", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Café 🎉 — São Paulo"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/str/remove-non-ascii",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Café 🎉 — São Paulo"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/str/remove-non-ascii", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Café 🎉 — São Paulo"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Café 🎉 — São Paulo"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/str/remove-non-ascii", 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": "Café 🎉 — São Paulo"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "str.remove_non_ascii",
"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.
Limits
max_chars | 100000 |
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
Empty input is rejected with invalid_input instead of a silent blank success. Successful API calls cost $0.002 per item; validation failures are not billed.
How non-ASCII removal works under the hood
There is no locale parameter, no random sampling, and no clock: the same input always yields the same JSON. Extremely long payloads above the documented character cap also fail with invalid_input so a single request cannot monopolize Worker memory.
What you send and what you get back
Aliases such as input, value, data, s, message, string, content, and body are accepted for convenience when wiring older clients or spreadsheet columns. Numbers and booleans are coerced to their decimal or true/false text forms; objects, arrays, NaN, and Infinity are rejected with invalid_input. On success the response echoes the original text, the ASCII-only result, the result length, the original length, a removed count of leftover non-ASCII code points dropped after the accent fold, a boolean changed flag, and operation set to remove_non_ascii. Wire the free browser form for quick paste-and-copy work, then call the identical contract from scripts when you sanitize log lines, CSV columns, or API payloads. Pricing for successful API calls is the published base of $0.002 per item; validation failures including empty text do not consume prepaid balance.
Where a remove-non-ASCII tool shows up in real work
This page is not the same search as remove-accents-from-text: that sibling keeps emoji and CJK and only folds diacritics. It is also not remove-control-characters, which keeps printable Unicode and only deletes C0/C1 codes. Because this capability is a pure parse engine, API pricing is the published base of $0.002 per successful item and failed validation does not consume balance.
Integration use cases
Deterministic fixtures and CMS paste hygiene
Produce the same ASCII result in the browser and the API for golden tests, filenames, and titles pasted from chat.