Quoted-printable encoder and decoder
Turn Hello café into Hello caf=C3=A9 and back again: accents and symbols become equals-sign hex pairs, plain letters stay readable, and soft line breaks keep long lines in check. Handy for reading raw email bodies. 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é
- Calculation mode
- Encode
- Result
- Hello caf=C3=A9
- Encoding
- quoted-printable
- Input bytes
- 11
- Output bytes
- 15
This quoted-printable encoder converts plain UTF-8 text into MIME Quoted-Printable and decodes QP strings back to readable text using the rules from RFC 2045 section 6.7. Quoted-printable keeps most ASCII characters readable while encoding non-safe octets as equals-sign hex escapes, which is why email bodies, legacy mail gateways, and many MIME tooling paths still rely on it for international text without forcing full Base64 opacity. The engine is fully deterministic: the same input and mode always produce the same result, with no network calls, no random salts, and no date-dependent shortcuts. Common checks include encoding Hello café to Hello caf=C3=A9 and decoding that string back to the original phrase.
Where you meet quoted-printable in email
Developers meet quoted-printable when they inspect email bodies marked Content-Transfer-Encoding: quoted-printable, craft international plain-text messages for SMTP gateways, or debug why a café accent turned into equals-hex pairs in a raw message dump. Frontend and support teams decode QP snippets during ticket investigation without pasting data into ad-hoc scripts that mishandle soft line breaks. Backend services encode configuration samples or short multilingual strings before putting them in MIME parts where 8-bit clean transport is not guaranteed.
Quality engineers generate deterministic encode and decode pairs for contract tests so a mail library that claims QP support cannot silently change hex casing rules or drop soft breaks. Pair it with Base64 helpers when you need related transfer encodings, and with other text tools when you are building a small lab of free, deterministic encoders.
What you can do with it
Email body debugging
Encode or decode MIME quoted-printable snippets from raw messages so accents and soft line breaks match what mail clients display.
Legacy gateway prep
Turn UTF-8 plain text into transport-safe quoted-printable before sending through restricted 7-bit paths.
FAQ
What does the quoted-printable encoder cost?
It is free in your browser on this page.
How is quoted-printable different from Base64?
Quoted-printable keeps most ASCII readable and only escapes non-safe octets as =XX. Base64 encodes every byte into an opaque alphabet and is better for pure binary.
What happens if an escape sequence is malformed?
Incomplete =XX, non-hex digits after =, or a trailing lone = are all rejected rather than guessed.
Is the result deterministic?
Yes. The same text and mode always produce the same result with no network, randomness, or date-dependent behavior.
Why does é turn into =C3=A9 in quoted-printable?
In UTF-8 the letter é takes two bytes, C3 and A9. Quoted-printable writes every byte outside plain ASCII as an equals sign followed by two hex digits, so one accented letter becomes six characters.
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/quoted-printable \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Hello café"}'const res = await fetch("https://api.kit.forhosting.com/enc/quoted-printable", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Hello café"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/quoted-printable",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Hello café"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/quoted-printable", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Hello café"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Hello café"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/quoted-printable", 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": "Hello café"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.quoted_printable",
"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
Use it free in the browser for mail debugging and MIME practice, or call the API at $0.002 per successful request when pipelines need reproducible quoted-printable transforms in CI and backend services.
What quoted-printable is and what this tool returns
Quoted-printable is a content-transfer encoding defined for MIME so mostly textual data can travel through 7-bit or restricted mail paths without becoming opaque Base64. Safe printable ASCII characters usually appear as themselves, the equals sign is reserved as the escape introducer, and any other octet is written as an equals sign followed by two hexadecimal digits. Soft line breaks — an equals sign at the end of a line before a CRLF — let encoders keep each encoded line within the classic seventy-six character limit without inserting hard newlines into the decoded text. This page always follows that contract for UTF-8 text: encode mode UTF-8 encodes your string, maps each byte to a literal or an equals-hex token, and inserts soft breaks so lines stay within the limit; decode mode removes soft breaks, expands equals-hex pairs into bytes, and rejects incomplete or non-hex escape sequences instead of guessing. The JSON response includes result for the transformed string, mode echoing encode or decode, encoding fixed to quoted-printable, and input_bytes plus output_bytes so you can assert sizes in tests. There is no streaming path and no silent repair of broken QP: either the string is valid quoted-printable text or the request fails with invalid_input. If you need opaque binary packing, prefer Base64 or Base64url endpoints; this landing is for the readable, email-oriented QP encoding that mail clients and MIME libraries already expect.
How text and mode are read and how results stay reproducible
Encode accepts any Unicode string, converts it with the platform TextEncoder to UTF-8 bytes, then emits quoted-printable with uppercase hex escapes and soft CRLF wraps. After bytes are recovered, a fatal UTF-8 decode ensures binary garbage does not become mojibake text. The preferred payload field is text, with aliases input, value, and s so forms, query strings, and SDK clients can reuse the same contract without renaming columns. Mode defaults to encode and accepts decode explicitly; aliases op, direction, and action map to the same switch for scripts that already use those names. Decode requires a well-formed QP string: a lone equals at the end of input, an equals followed by one character only, or an equals followed by non-hex digits all fail with a clear invalid_input message naming the malformed escape. Pair the free browser run on this page with the priced API when you need the identical mathematical result inside an automated pipeline without re-implementing quoted-printable tables yourself. Invalid inputs return invalid_input and are not charged, which keeps validation cheap while successful transforms remain a fixed item price.
Where quoted-printable fits in email, MIME, and test fixtures
Educators use the same tool when teaching the difference between Base64 opacity and quoted-printable readability for mostly textual payloads. On this page the work runs entirely in your browser; through the API each successful lookup costs $0.002, failed validation is not charged, and nothing is stored after the response returns. That split — free interactive exploration and a priced, identical API — matches the rest of the KIT tier-A catalog and lets you move from a classroom demo to an automated pipeline without changing the encoded result.
Integration use cases
MIME fixture generation
Produce reproducible QP strings for unit tests, golden files, and SMTP or IMAP integration checks.
Technical questions
What modes are supported?
mode=encode (default) turns plain text into quoted-printable. mode=decode turns a QP string back into UTF-8 text.