Jaro similarity calculator for two strings
MARTHA and MARHTA score 0.9444444444444445, close to 1 although two letters swapped places. Jaro rewards shared characters in a compatible order instead of counting edits, which suits names and short codes. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- First
- MARTHA
- Second
- MARHTA
- Similarity
- 0.9444444444
Jaro similarity measures how closely two strings resemble each other by looking for characters that match within a limited distance and checking whether those matched characters keep the same order. The result ranges from zero for strings with no qualifying matches to one for identical strings. It is especially useful for short names, labels, identifiers, and other values where minor substitutions or transpositions should not automatically make two records unrelated.
Understand what the Jaro score represents
Jaro similarity is a character-based measure designed for fuzzy comparison. It does not ask how many insertions, deletions, or substitutions would transform one value into another. Instead, it finds equal characters that occur within a matching window based on the length of the longer string.
It then combines three proportions: the share of the first string that matched, the share of the second string that matched, and the share of matched characters that remained in a compatible order. A result of one means the strings are identical under this procedure, while zero means that no characters qualified as matches. Names, compact codes, and short catalog labels often benefit from Jaro because it rewards shared characters and ordering without treating every small displacement as a completely separate editing operation.
Prepare strings and interpret comparisons consistently
The comparison is exact and case-sensitive. Uppercase and lowercase letters are different characters, spaces and punctuation participate in the calculation, and no accents are removed. The implementation compares Unicode code points, so a supplementary character such as many emoji is handled as one comparison element rather than two UTF-16 code units.
It does not perform Unicode normalization, however, which means visually similar text can differ when one value uses a precomposed character and another uses a base character followed by a combining mark. Prepare both inputs in the same way before calling the capability if your workflow needs case folding, whitespace cleanup, accent handling, or Unicode normalization. Keeping those choices outside the calculator makes the score reproducible and prevents hidden cleanup from changing identifiers that must remain literal.
Two empty strings return one because they are identical, while one empty and one non-empty string return zero. When comparing many records, apply one preprocessing policy to the whole collection and document it alongside the threshold you choose.
Use the score safely in fuzzy matching workflows
A Jaro score works best as evidence inside a matching workflow, not as proof that two records describe the same entity. Start with representative labeled pairs from your own data, calculate their scores, and examine where true and false matches overlap. You can then select a review band or threshold that fits the consequences of an incorrect decision.
For customer or supplier records, combine the string score with independent fields such as a stable internal identifier, verified address component, or date rather than merging solely because two names look similar. The method is symmetric, so swapping the first and second strings produces the same result, which makes it convenient for pairwise ranking and deduplication. It also focuses on character proximity and order; it does not understand meaning, synonyms, transliteration, or phonetics.
For longer prose or semantic comparison, another technique is more appropriate.
What you can do with it
Rank possible duplicate names
Score pairs of customer, supplier, or contact names before sending ambiguous candidates to human review.
Compare short catalog labels
Find product or category labels that differ through a small typo or local character transposition.
Test fuzzy matching rules
Generate deterministic scores for labeled examples while selecting and documenting an application-specific threshold.
FAQ
What range does the result use?
The similarity is between zero and one. One represents identical strings, and zero represents no qualifying character matches.
Is the comparison case-sensitive?
Yes. Convert both strings to a common case before submission if your matching policy should ignore letter case.
Does it remove accents or punctuation?
No. Every supplied Unicode code point participates exactly as provided, including spaces, punctuation, and accented characters.
Is Jaro similarity the same as Jaro-Winkler similarity?
No. Jaro-Winkler adds a prefix-based adjustment. This capability returns the unadjusted Jaro similarity only.
What score should count as a match?
There is no universal threshold. Choose one with representative labeled data and consider a review band for uncertain pairs.
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/jaro-similarity \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"first":"MARTHA","second":"MARHTA"}'const res = await fetch("https://api.kit.forhosting.com/str/jaro-similarity", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"first": "MARTHA",
"second": "MARHTA"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/str/jaro-similarity",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"first": "MARTHA",
"second": "MARHTA"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/str/jaro-similarity", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"first":"MARTHA","second":"MARHTA"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"first":"MARTHA","second":"MARHTA"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/str/jaro-similarity", 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": "MARTHA",
"second": "MARHTA"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "str.jaro_similarity",
"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
Understand what the Jaro score represents
Values between those endpoints indicate degrees of resemblance, but the capability does not label any particular score as a match or non-match. That threshold belongs to your application and should reflect the cost of false positives and false negatives.
Technical questions
What does an API comparison cost?
Each API request costs $0.002.