Translation sync and your glossary
How TidyKB finds translations that fell behind, drafts them with your glossary, checks them before you see them, and saves them into Freshdesk as drafts only.
Updated
In Freshdesk, every language of an article is its own article, and nothing tells you when one has fallen behind the original. Translation sync is the loop that closes: find the translations that are behind, draft them again with your wording, let a human read the drafts, and put them into Freshdesk as drafts.
Nothing here is ever published by TidyKB.
How "outdated" is decided
By hashing, not by timestamps. When a scan sees a translation and its primary article in sync, it records the primary's content hash as a baseline. A translation is outdated when that hash has since moved — a fact, not a guess.
| Status | Means |
|---|---|
| Outdated | The primary article's content hash has moved away from the recorded sync point |
| Looks behind | We never saw the pair in sync, and at the baseline Freshdesk's timestamps said the translation was already older. Shown as an estimate, never as a fact. |
| Missing | There is no translation in that language at all |
| Human-edited | Somebody changed the translation in Freshdesk after our last sync |
Two absences are treated carefully. A pair with no recorded baseline is not reported as in sync — nothing is claimed about it. And "missing" is only offered for languages the last full scan read completely: a language a scan could not finish reading proves nothing about what does not exist.
Planning a batch
The translations page lists your languages with those counts. Pick languages, optionally narrow to specific articles, and TidyKB plans a batch: one row per (article, language) pair.
- Human-edited translations are left out unless you explicitly include them. Including them records your consent on the row, and the save step checks for it again before it writes over somebody's own text.
- A batch is capped at 500 rows and says when it was truncated, so a whole-knowledge-base translation runs as several batches and a quota problem shows up early rather than after an hour.
- The word estimate is shown before you start, counted exactly the way the pipeline will count it, and checked against your monthly quota first. A workspace with no words left is refused before anything is spent.
- One draft per source version. Planning the same batch twice reports that the drafts already exist and queues nothing, so the same text is never paid for twice.
Each row then goes to the model on its own. Rows that were skipped — over quota, not on your plan, human-edited, already in sync, source gone — cost nothing.
The glossary
One glossary per language pair, editable in the app or as a CSV round trip, with four columns:
| Column | Meaning |
|---|---|
source | The word in your primary language |
target | What it must become. Leave it empty to mean "never translate this" |
case_sensitive | Whether the match respects capitalisation |
note | A note for whoever maintains the list |
There is also a style note per pair — formality, tone, house voice — which is sent with every article of that language.
Export the CSV, edit it in a spreadsheet, upload it back. Up to 500 terms. The glossary and the instructions travel in a cached block that is stable per language pair, so a long glossary does not cost you per article.
What is checked before you see a draft
The model's answer is not trusted. Every chunk is validated before a draft exists at all:
- Placeholders. Every tag, inline code element, comment, template variable and bare URL is replaced by a numbered token before the text is sent, and each token must come back exactly once — not missing, not duplicated, not invented.
- Tags. The set of HTML tags after restoring must be identical to the source's. A model that typed markup of its own fails.
- Numbers and URLs. No number dropped, invented or changed (
1,234.50,1.234,50and Arabic-Indic digits are the same number), no URL rewritten or added. - Glossary. A term whose source appears but whose target does not is a failure, as is a do-not-translate string that came back changed.
- Untranslated. A long segment that came back identical, or that contains no character of the target script, is a failure.
- Length. A chunk far shorter or longer than its source is a failure.
A chunk that fails is re-sent once, with its errors. If it fails again, the whole article fails: no draft is stored, and the reasons are listed on the row. An invalid translation never reaches your help center.
Reassembly is byte-exact: an article whose chunks all came back unchanged is returned identical to the source, down to the non-breaking spaces and line endings.
Saving into Freshdesk
Review the drafts, then type SAVE DRAFTS to confirm the batch. Per translation:
- Read the translation in its own language. A 404 means there is none, so this is a create.
- Compare it with the sync point. If it was edited by a human, or its hash has moved, or we hold no baseline for it, it is not ours to replace: the row becomes a conflict and nothing is written. The only way past is the consent you recorded when planning.
- Write it — a create with
status: draft, or an update of an existing draft's title and body, whose status is never re-sent. - Read it back and store what Freshdesk now holds, which is both the new baseline and what undo will argue with.
A published translation is skipped, and we say so
If the translation is already published, TidyKB writes nothing and tells you why. Replacing it would need a draft staged beside the live page, and Freshdesk has not been proven able to do that. The alternatives are both wrong: unpublishing takes a page your readers use off the portal, and writing live publishes machine translation nobody reviewed. So we leave it alone. A missing translation and an existing draft are both safe — the portal showed nothing for them before and shows nothing after.
Every request names the target language, and a contract test asserts it: TidyKB never writes to the primary article. A row whose target language has become the primary language since the batch was planned is refused before a single request is sent.
Undoing a batch
One button per batch, for the translations it wrote.
- A translation that existed before gets its snapshot back — title, body and published state — and its old baseline with it, so it is theirs again.
- A translation TidyKB created cannot be deleted: the Freshdesk API has no delete endpoint, and TidyKB's allowlist has none either. Undo empties its body and leaves an empty, unpublished draft. The result names each one and links to it in Freshdesk so you can delete it there. If you delete it and undo runs again, the 404 is read as success, not as a conflict.
- Anything edited after our save, including a draft somebody already emptied, is a conflict and is never forced.
- Like find & replace, undo asks only for an edit key and the global safety switch — not your plan, and not a second confirm.
Words and plans
Translation sync is on Team and Pro. The monthly quota is 150,000 source words on Team and 500,000 on Pro, measured in UTC months and reset on the 1st. Words are counted for every article actually sent to the model — drafts that came back fine and drafts that failed validation, because both were paid for. Skips count nothing. See billing, plans and limits.
Freshdesk and Freddy are trademarks of Freshworks Inc. TidyKB is an independent product and is not affiliated with, endorsed or sponsored by any company named on this page.
FAQ
Questions, answered
Does TidyKB publish translations?
Never. Every translation is written into Freshdesk as a draft, and TidyKB never touches the primary article. A translation that is already published is skipped and left alone, because staging a draft next to a live page is not something Freshdesk’s API has been proven to do, and the two alternatives — unpublishing a page readers use, or publishing unreviewed machine translation — are both wrong.
How does TidyKB know a translation is out of date?
By comparing hashes, not timestamps. When a translation and its primary article were last in sync, TidyKB recorded the primary’s content hash. A translation is outdated when that hash has moved. Where there is no recorded sync point, TidyKB falls back to Freshdesk’s timestamps, marks the row as an estimate and says so.
Will it overwrite a translation my team edited by hand?
Not unless you ask for it twice. A translation edited since our last sync is left out of a batch by default. Including it records your consent on the row, and the save step checks for that consent again before it writes. Without it the row becomes a conflict and nothing is written.
What happens to a translation TidyKB created, if I undo?
Its body is emptied and it stays an unpublished draft, because Freshdesk’s API has no endpoint to delete a translation. TidyKB tells you which ones to delete in Freshdesk and links to each. Nothing a reader could see was ever affected: the portal returns a 404 for that language before and after.
What counts against my monthly word quota?
The source words of every article TidyKB actually sent to the model: drafts that came back fine and drafts that failed validation, because both were paid for. Rows skipped before anything was spent — over quota, not on your plan, human-edited, already in sync — count nothing. The quota is checked before a batch starts and resets on the 1st, measured in UTC months.
Related
- Billing, plans and limits What each plan includes, how articles and translation words are counted, what happens when you hit a limit, and how Paddle handles payment, VAT and invoices.
- Find & replace: preview, confirm, undo How a bulk find and replace runs: the read-only preview, the second Freshdesk key fixes need, the typed confirm, and what one-click undo can and cannot put back.
- Translation sync When a primary Freshdesk article changes, its translations are flagged as outdated and re-drafted with your glossary for review.
See your help center’s score.
Paste a URL. No signup, no API key, no call.