Levenshtein edit distance calculator for two strings
Levenshtein edit distance expresses how many single-character changes are needed to turn one string into another.
Run — free
Enter any two strings and this calculator returns the minimum number of insertions, deletions, and substitutions required. It is useful when an exact equality check is too strict but you still need a clear, reproducible measure of difference. The comparison is deterministic, case-sensitive, and performed directly on Unicode code points without network access or probabilistic scoring.
What the distance tells you
A Levenshtein distance is a nonnegative integer. A result of zero means the two strings are identical, while a result of one means that one insertion, deletion, or substitution can make them equal. Larger results require more edits. For example, changing one letter is a substitution, adding a missing letter is an insertion, and removing an extra letter is a deletion. The algorithm considers all valid edit sequences and returns the smallest total rather than applying changes greedily from left to right. That distinction matters when repeated characters or shifted fragments create several possible alignments. The result is case-sensitive, so uppercase and lowercase forms count as different characters. It is also an absolute count, not a percentage. A distance of three may be substantial for a four-character code but minor for a long paragraph. When comparing strings of very different lengths, remember that the length difference alone establishes a minimum number of required insertions or deletions. Interpret the integer alongside the strings' lengths and your application's tolerance.
How the calculation works
The calculator uses dynamic programming to evaluate the cheapest way to transform every prefix of the first string into every prefix of the second. Each position considers three possibilities: insert the current character, delete a character, or substitute one character for another. Matching characters add no cost. The final cell contains the minimum edit count for the complete strings. This implementation stores only the previous and current rows of that calculation, which preserves the exact result while using memory proportional to the shorter input rather than allocating the full matrix. Characters are read as Unicode code points, so a supplementary character represented by a surrogate pair in JavaScript is treated as one comparison element. No normalization or case folding is performed. Consequently, visually similar text can differ when it uses distinct code points, combining marks, capitalization, or compatibility forms. Normalize or standardize text before sending it if your workflow intends those representations to be equivalent. Given the same two strings, the capability always returns the same integer.
Using the result in a workflow
Send the two values in the <code>first</code> and <code>second</code> fields. Both fields must be strings, although an empty string is valid and produces a distance equal to the other string's number of Unicode code points. The returned object contains the <code>distance</code> integer. A common workflow compares a submitted name with a known name and then applies a threshold chosen for the expected string length. Another checks whether a corrected identifier is within one edit of the original. Avoid treating one universal threshold as meaningful for every input: short product codes, personal names, and sentences have very different error profiles. If length-independent ranking is required, calculate a normalized score in your own application from the returned distance and an explicitly chosen denominator. Also decide whether punctuation, whitespace, accents, and letter case should matter before comparison; this capability preserves all of them exactly. The browser execution is suitable for interactive checks, while automated API requests use the same deterministic implementation at $0.002 per request. Invalid non-string values are rejected instead of being coerced silently.
What you can do with it
Detect likely typing mistakes
Measure how many character edits separate a submitted word or name from an expected value before applying a domain-specific threshold.
Compare record identifiers
Flag identifiers that differ by only one or two insertions, deletions, or substitutions for careful review.
Evaluate text corrections
Quantify the character-level change between an original string and a corrected version with a reproducible integer.
FAQ
What operations count toward the distance?
Each single-character insertion, deletion, or substitution costs one. The smallest possible total is returned.
Is the comparison case-sensitive?
Yes. Uppercase and lowercase characters are different unless you convert them to a common case before sending them.
Can either string be empty?
Yes. The distance from an empty string is the number of Unicode code points in the other string.
Does the calculator normalize Unicode text?
No. It compares Unicode code points as supplied, so normalize combining forms beforehand if they should be treated as equivalent.
Does it return a similarity percentage?
No. It returns the absolute minimum edit count. You can derive a normalized measure using a denominator appropriate to your application.
What does an API request cost?
Each API request costs $0.002. The capability can also run in the browser for interactive use.
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/text-similarity-levenshtein \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"first":"kitten","second":"sitting"}'const res = await fetch("https://api.kit.forhosting.com/text/text-similarity-levenshtein", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"first": "kitten",
"second": "sitting"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/text/text-similarity-levenshtein",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"first": "kitten",
"second": "sitting"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/text/text-similarity-levenshtein", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"first":"kitten","second":"sitting"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"first":"kitten","second":"sitting"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/text/text-similarity-levenshtein", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"first": "kitten",
"second": "sitting"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "text.text_similarity_levenshtein",
"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_tokens | 20000 |
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. |