Number to words
Spell a number in English or Spanish words: in check mode 12.5 becomes twelve and 50/100, the legal-style line for cheques and invoices, while plain reading spells 12.50 as twelve point five zero. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Input value
- 0
- Language and locale
- En
- Word format
- Cardinal
- Number in words
- zero
Turn a canonical number string into spelled words in English or Spanish. Use cardinal mode for plain reading and check mode for amounts with two-digit cents.
Canonical input only — no floats and no thousand separators
A valid form is an optional leading minus, plain digits, and an optional decimal point with fractional digits. Leading zeros (except the single digit zero), commas, spaces, a leading plus sign and scientific notation are rejected with a clear validation error. The integer part may use up to fifteen digits (zero through 10^15−1).
Cardinal mode allows up to six fractional digits; check mode allows at most two and never rounds.
English short scale and Spanish formal scale
English follows the US short scale: thousand, million, billion for 10^9 and trillion for 10^12. Compound tens use a hyphen (twenty-one) and hundreds never insert a British and (one hundred one, not one hundred and one). Spanish follows RAE-style formal wording: 10^9 is mil millones and 10^12 is billón.
Exact one hundred in a group is cien; 101–199 use ciento. Irregular hundreds quinientos, setecientos and novecientos are spelled as fixed forms. Apocope applies only before a scale word: veintiún mil and treinta y un mil, while a bare 21 remains veintiuno.
Cardinal mode versus check mode
Cardinal mode spells the integer and, when a decimal point is present, each fractional digit one by one after point or punto, preserving trailing zeros (12.50 becomes twelve point five zero). Check mode is for cheque-style amounts: the integer words, then and NN/100 in English or con NN/100 in Spanish, always with two digits for the cents field. A single fractional digit pads to tenths of a dollar (12.5 becomes 50/100).
No currency name is added in version one, so you can append dollars, euros or pesos outside the tool if your document needs them.
Negatives, zero and deterministic defaults
Negative values take a minus or menos prefix before the body. Minus zero and minus zero with all-zero fractions collapse to plain zero so the signed form does not invent a distinct spelling. When locale is omitted the tool uses English; when mode is omitted it uses cardinal.
Both defaults are echoed in the structured result together with the original value string and the exact words field your pipeline can store or print.
What you can do with it
Cheque and invoice amounts in words
Generate the legal-style amount line for checks or invoices with fixed NN/100 cents and no currency name surprises.
Accessibility and screen-reader labels
Spell displayed totals so assistive technology reads natural language instead of a raw digit string.
Bilingual en/es documents
Produce English and Spanish wording from the same canonical number for contracts and customer notices.
Deterministic tests in pipelines
Assert exact words strings in CI without depending on floating-point formatting or locale libraries.
FAQ
What is the range?
The absolute integer part must be between 0 and 10^15−1 inclusive. Larger values return a validation error.
Does English use and inside hundreds?
No. Cardinal English is American short scale without a British and between hundred and the remainder. The word and appears only in check mode as the separator before NN/100.
How does Spanish handle one thousand?
Exactly one thousand is mil, never un mil. One million is un millón; one billion (10^9) is mil millones; one trillion (10^12) is un billón.
Are fractional digits rounded in check mode?
No. More than two fractional digits is an error. One digit is padded with a trailing zero to form cents.
Is the browser tool free?
Yes. The page runs locally and free in desktop and mobile browsers.
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/text/number-to-words \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"value":"1234.56"}'const res = await fetch("https://api.kit.forhosting.com/text/number-to-words", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"value": "1234.56"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/text/number-to-words",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"value": "1234.56"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/text/number-to-words", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"value":"1234.56"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"value":"1234.56"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/text/number-to-words", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"value": "1234.56"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "text.number_to_words",
"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_int_digits | 15 |
max_frac_digits_cardinal | 6 |
max_frac_digits_check | 2 |
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
The free browser tool and the API share one deterministic oracle: same input, same words, every time.
Canonical input only — no floats and no thousand separators
Pass value as a string so large integers never pass through IEEE-754. That strict shape keeps bank-style amounts and large invoice totals stable across the free page and the API.
Technical questions
Why must value be a string?
JSON numbers are IEEE-754 doubles and cannot represent every 15-digit integer exactly. A digit string keeps the oracle integer-pure.