How to add to TM automatically after AI pre-translation without approving?

Hello,

I am using Crowdin Enterprise, a file-based project.

Currently having issues with the fact that Ai-generated translations are not added to TM unless approved.
However when adding a string manually or when uploading translations using UI (and ticking the “Add to TM” option), they do get added to TM.
In both cases the translations are not approved, but in one case they are added to TM, and in another they are not.
Why is it important? My use case: I have a project with simultaneous work on multiple branches and I want any AI pre-translations in all branches to be registered in TM so that when the feature is merged to our main branch on the GitHub side, the following automation is run:

  1. Delete the feature branch from Crowdin
  2. Upload sources from the main branch
  3. Run TM pre-translation using CLI on the main branch
  4. All translations are added

But since the AI pre-translations are not added to the TM, step 3 fails with “Not present in TM”.

I know there are 2 workarounds to this:

  1. Disable duplicates and never delete the feature branches.
  2. After AI pre-translation, upload all translation using CLI with --auto-approve-imported.

However both have disadvantages:

  1. Feature branches will pile up and it will be hard to track which ones can be safely deleted. Also, TM is basically never populated with anything unless approved, so it becomes useless
  2. All strings will be approved, so it hard to track which ones are actually approved by human and which ones are just “approved to be added to TM”

Possible fixes:

  1. Add some CLI flag to crowdin pre-translate that will add AI-generated messages to the TM.
  2. Expose “Add to TM” checkbox logic for the crowdin push translations
  3. Create some global parameter that will always treat AI-generated messages as trustworthy enough to be added to the TM

Hi @nogaman ,

This is the default behavior of the system. The AI translations are not added to TM automatically because they are made by a machine. After they are reviewed by a human and approved, they are saved to the TM as well.

When you upload the translations, they are added to the TM because they are considered to be done by a human and thus correct. Unfortunately, there is nothing we can do from our side. The only solution is to approve the translations done by AI.

There is actually a bug related to this. So I’ve noticed that if you pre-translate a string using AI and then try to upload the same translation, it won’t get to TM. But if you skip the pre-translation step and just upload directly, it will get there.
It creates an incosistency bug that if uploaded message is the same as pre-translated one, Crowdin just ignores it and thus does not add it to TM, while if it’s new, it is added.
In this case I can’t just approve it, because approval should be done by a proofreader.

Adding an option to add uploaded via CLI translation to TM will sove both of the problems and I believe adding it won’t be too difficult, as you already have such option in the UI.

:folded_hands:

I would love to see one of the proposed solutions implemented in the product for more refined control over TM utilization in pre-translation by TM and AI (for consistent translations) without the need to approve.
Ideologically, approved by human or approved for TM should be differentiated.
Thanks

Hi @nogaman ,

Thanks for your feedback!

What you’re describing is expected system behavior, not a bug.

The core purpose of Crowdin’s TM is to store and reuse high-quality, human-approved translations. This is fundamental to maintaining translation quality and consistency across projects.

AI-generated translations are treated in the same way as machine translation. This means that only verified content is added to the Translation Memory, and AI-generated translations are not included unless they are approved, either manually or through a workflow.

If you upload Xliff translation, the system considers it as “added by human”, just like they were added in Crowdin Editor, so it’s expected that they come directly into the translation memory.

However, if your XLIFF file contains the same translation with the same status, the system will not overwrite the AI version. This is done on purpose to avoid saving AI-generated content as final without review. Note that if the uploaded translation has a higher status (for example, Approved or Final), it will override the AI-provided translation and get added to the TM.

At this point, we’re not planning any changes to this logic, so it might be a good idea to take a look at your current translation workflow.

A typical setup is: AI provides the first draft, then a human reviews it (either selectively or in bulk) and once approved, the translations are saved to the TM.

It just does not work for a workflow with multiple parallel branches. There are only 2 ways to share translations between branches: TM and duplicates. Both approaches are not great:

  1. TM is bound to approvals

  2. Duplicates don’t work well when deleting branches

We have like 10-20 branches merged a month and if we don’t delete them regularly, the Crowdin project will just turn into a mess. Imagine 300+ branches in one year, that’s too much even just for people to scroll through.

We can’t block our releases waiting for proofreaders approvals for every feature in every language, because it will affect our go-to-market metric. Instead, we want to release the feature ASAP with AI pre-translated string and then eventually go through approvals asynchronously.

I don’t think you understand how your product is used in a fast-paced environment of 2025’s software engineering. There are not so many companies that can afford the idealistic way of mandatory approval of every string. Manual review requires people intervention and it’s always slow.

Moreover, considering that with latest AI models the quality of pre-translation rises, it should be totally okay to allow adding AI-generated messages to TM. It should not break the current Crowdin’s recommended approach, it just gives freedom to your customers to decide what to think of TM themselves. We are okay to treat TM as just a place to store translations to share them between branches without approval.

Could you please propose alternative ways to achieve sharing of messages between branches, so that branches can be deleted without fear of losing translations, while still leaving them unapproved?

If that isn’t possible, I would greatly appreciate concrete next steps rather than simply hearing “it’s a feature, not a bug.” Could you kindly share this feedback with your product team and ask them to provide further details?

Hi @nogaman

Can you provide some context about why duplicates don’t work for you?

They were basically designed for multiple branches:

When a former master string is deleted, the duplicate becomes the new master string (the translation history is shared as well). This should work really well, so if you have any trouble managing duplicates, please let me know.

This solves the problem for us! Thank you very much for the answer.

My tests show that deleting a branch does indeed make the duplicate become the new master string.

The reason why it was not working before is because I deleted feature branch from Crowdin before the newly merged to our GH main branch source strings were pushed to Crowdin. We will adjust our deployment scripts to account for that.

But still I have a question:

Imagine there are 2 branches - main (root Crowdin branch) and feature_1 (same name in Crowdin), where in feature_1 branch lots of new strings were added and pre-translated using AI without approvals.

  1. Then on GH repo side feature_1 is merged into main branch
  2. GH actions automation runs crowdin push sources from that main branch
  3. immediately after crowdin branch delete feature_1 is run to delete feature_1 from Crowdin
    Is it guaranteed that at the moment of uploading sources (step 2 above) the duplicates are properly registered so that deleting a branch (step 3) won’t remove the translations completely?

Hi @nogaman
If you update translations only in one place (the Crowdin project) in master strings only your workflow should work as expected. Once the master strings are deleted from the project, hidden duplicates will automatically be reverted to visible master strings

Since we don’t commit directly to the master branch, you’ll always be able to verify translations before merging it to the main branch