UTF-8 byte encoder
Find the exact UTF-8 bytes of any word or phrase: “Hi” becomes the hex pairs 48 69, one pair per byte, and pasted hex decodes back to the original characters. Byte sequences that are not valid UTF-8 are refused, never patched. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- Hi
- Calculation mode
- Encode
- Result
- 48 69
- Input
- Hi
- Hex
- 48 69
- Hex compact
- 4869
A UTF-8 byte encoder turns readable characters into the exact sequence of bytes Unicode assigns under UTF-8, shown as two-digit hexadecimal pairs, and a matching decoder rebuilds the original string from those bytes. Enter plain text and choose encode to receive space-separated hex pairs—one pair per octet—or paste hex and choose decode to recover the text.
How text becomes UTF-8 hex bytes and why validity matters
Computers store text as sequences of bytes. UTF-8 encodes every Unicode code point as one to four bytes: basic Latin letters often need a single byte that matches classic ASCII, while accented Latin, many non-Latin scripts, and emoji need two, three, or four bytes. Encoding walks the string with a standard UTF-8 encoder, then writes each byte as two lowercase hexadecimal digits from zero through two hundred fifty-five, joining pairs with a single space so humans can count octets at a glance.
Decoding does the reverse: it splits the input into candidate pairs, requires each pair to be exactly two hex digits, converts each pair to a byte, then interprets the byte array as UTF-8 with fatal validation. If a pair is one digit, three digits, or a non-hex character, or if the continuous hex string has odd length, the converter must fail. More importantly, even well-formed hex can describe bytes that are not valid UTF-8—for example a lone continuation byte or a truncated multi-byte lead.
What you can do with it
Homework checks for UTF-8 multi-byte encodings
Students encode short phrases with accents or emoji, compare hand-written hex pairs to the deterministic result, and decode teacher-provided hex without a spreadsheet.
Protocol and networking teaching demos
Workshops show how printable labels become octets on the wire, then force invalid UTF-8 hex to illustrate strict framing and decoder rules.
FAQ
What does the UTF-8 byte encoder output?
In encode mode it returns space-separated two-digit hex pairs (one per UTF-8 byte), a compact hex string, and arrays of pairs and integer byte values. In decode mode it returns the recovered UTF-8 text.
Does it support emoji and non-Latin scripts?
Yes. Encoding uses UTF-8, so multi-byte characters become multiple hex pairs. Decoding rejects byte sequences that are not valid UTF-8.
Can I paste hex without spaces?
Yes, if the continuous string is only hexadecimal digits and its length is a multiple of two.
Is the UTF-8 byte encoder free?
The browser tool is free and runs locally.
What happens if the hex is not valid UTF-8?
The tool refuses it instead of inventing replacement characters. A lone continuation byte, a cut-off multi-byte character, an odd number of digits or a non-hex character all stop the conversion, so the mistake stays visible.
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/utf8-bytes \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Hi"}'const res = await fetch("https://api.kit.forhosting.com/enc/utf8-bytes", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Hi"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/utf8-bytes",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Hi"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/utf8-bytes", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Hi"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Hi"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/utf8-bytes", 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": "Hi"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.utf8_bytes",
"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
Invalid hex, an odd number of digits, or a byte sequence that is not legal UTF-8 returns a clear invalid_input error instead of inventing replacement characters.
How text becomes UTF-8 hex bytes and why validity matters
Silent padding would change the payload and hide worksheet mistakes. Emitting the Unicode replacement character would hide that defect; this tool rejects with invalid_input so callers see the same hard error a strict parser would raise. This landing targets people searching for a UTF-8 byte encoder, text to hex bytes tool, or UTF-8 hex decoder online; it is not a binary bit-group converter and not a general encoding detector for legacy code pages.
How to call the API and what the response contains
The default mode is encode: the UTF-8 bytes of text become space-separated two-digit hex pairs. Mode decode treats text as hex pairs—whitespace-separated octets, optional zero-x prefixes, or a continuous hex string whose length is a multiple of two—and returns the recovered UTF-8 string. Send a JSON body with a required string field text (aliases input, value, and data) and an optional mode that is either encode or decode. Input length is capped at one hundred thousand characters so a single request cannot exhaust Worker memory on huge strings. On success for encode, the response includes mode, input, result and hex with the same space-separated hex string, hex_compact without spaces, pairs as an array of two-character strings, bytes as the integer byte values, byte_count, and a short English message. On success for decode, the response includes mode, input, result and text with the decoded UTF-8 string, hex normalized to space-separated pairs, hex_compact, the same pairs and bytes arrays, byte_count, and a matching message. Failed validation—missing text, non-string text, oversize input, an unknown mode, an invalid hex pair, odd continuous hex length, or decoded bytes that are not valid UTF-8—returns invalid_input and is never charged. Pricing is a flat $0.002 per successful request with unit item and zero marginal unit price.
Practical tips, limits, and related tools
Prefer decode when you already hold hex from a packet capture, a log line, or a textbook and want the characters back. Round-trip checks are the fastest smoke test: encode a short word such as Hi, confirm the two pairs match the known ASCII bytes forty-eight and sixty-nine in hex, then decode those pairs and confirm you recover the original string. Prefer this capability when the search intent is text versus UTF-8 hex octets; use the text-to-binary converter when you need eight-bit groups of zeros and ones, and use a convert-to-UTF-8 repair tool when the problem is wrong source encoding rather than hex presentation. When teaching, show the same emoji or accented letter next to a plain ASCII letter so students see multi-byte UTF-8 octets appear as extra hex pairs rather than a single mystery code. Deliberately submit an incomplete multi-byte sequence such as a single lead byte without its continuation, or an odd-length continuous hex string, to assert that your client handles invalid_input and the error message that names invalid UTF-8 or invalid hex. Keep payloads under the published character limit; multi-megabyte dumps belong offline. This tool is not a binary bit converter—binary groups are base two, not base sixteen—and it is not a mojibake repair tool that guesses Latin-1 or Windows-1252. Failed tasks that return invalid_input do not consume prepaid balance, which keeps exploratory scripts cheap when learners paste incomplete hex.
Integration use cases
Unit-test fixtures for codecs and parsers
Generate known hex byte strings from fixture text and assert decode recovers the same UTF-8 bytes in CI without ad-hoc TextEncoder helpers.
Technical questions
What happens on an invalid UTF-8 sequence?
Decode mode uses fatal UTF-8 validation. Hex that forms incomplete multi-byte sequences or illegal bytes returns invalid_input instead of replacement characters.