Skip to main content
The hosted Entri service at app.nt3.io is being retired. Entri is now open source, and you keep using it by running your own instance. This guide moves your organization, with its history intact, from app.nt3.io to that instance.
Timeline
  • 30 November 2026: last day to request a full export of your organization, and the day app.nt3.io shuts down. After that date, hosted data can no longer be exported.
Request your export from the Entri team at bram@xlab.be well before the deadline. Exports are prepared by hand.
There are two ways to move:

Full migration

What the export contains

The export is an archive with your organization’s data. Every document keeps its original ID, so all references survive the move. Passwords. By default, the export contains no password hashes or OAuth tokens. Users set a new password with Forgot password on your instance, which needs email configured, or sign in with Google or GitHub if you enable them. If you want users to keep their passwords, ask for an export with credentials when you request it. Treat that archive like a password database. Changes made on app.nt3.io after the export are not included. Agree on a cut-off time with your team, and stop working on the hosted instance at that point.

Steps

1

Deploy your instance

Deploy Entri with Docker Compose or Kubernetes. Use the same version as the hosted service or newer. Set ENCRYPTION_KEY and configure email.
Do not sign up or create any users yet. The import refuses to run if an account with one of your users’ email addresses already exists on the instance. If you already created a test account, delete it or start with a fresh database.
Make sure migrations have run. With Docker Compose, the migrate service runs them on docker compose up -d. With Helm, the migration hook runs them on install. You can also run them by hand:
2

Request your export

Contact the Entri team at bram@xlab.be. Tell them:
  • your organization’s name or slug on app.nt3.io
  • whether users should keep their passwords (an export with credentials)
  • a public key or other secure channel for receiving the archive
You receive an encrypted archive, for example acme-2026-01-31.tar.gz.age, with the password or key sent separately. Decrypt it (age -d -i key.txt acme-2026-01-31.tar.gz.age > acme.tar.gz, or as instructed) and keep it private: it contains all your data.
3

Get the import tool

The tool is in the Entri repository, in tools/org-migration. It is plain Node.js, needs Node.js 20.19 or later, tar, and the mongodb driver, and it writes directly to your instance’s MongoDB.
4

Import

Use the same connection string as your instance’s MONGO_URI, including the database name. Run a dry run first: it checks everything and writes nothing.
MongoDB is only reachable inside the Compose network (entri_default), so run the tool in a throwaway Node container. Put the archive in the current directory and replace PASS with MONGO_ROOT_PASSWORD from your .env:
The import refuses to write anything when:
  • your instance is behind the export on database migrations. Upgrade Entri and run migrate first. If your instance is ahead, add --allow-newer-target.
  • the organization already exists on the instance. Add --force to update it: it upserts by ID and never deletes anything.
  • another organization on the instance uses the same slug
  • a user on the instance has the same email as an imported user but a different ID. The tool lists every conflict.
Writes are idempotent, so if an import is interrupted, run it again.
5

Restart Entri and sign in

Everyone signs in again. Without an export with credentials, users choose Forgot password first.

Post-import checklist

1

Email

Configure SMTP or Resend before you tell users to sign in, so password resets and invitations arrive. See Email.
2

Close sign-up

Your users now exist, so set DISABLE_SIGNUP=true to allow new accounts by invitation only.
3

AI provider keys

An owner or admin enters the OpenAI and Anthropic keys again in Organization settings. They are encrypted with your instance’s ENCRYPTION_KEY.
4

Webhooks

Imported webhooks are deactivated, and their signing secrets were replaced with unknown values. A secret is shown only when a webhook is created, so delete each webhook, create it again, and put the new secret in your receiver.
5

GitHub sync

The imported connection points at the hosted GitHub App, which does not work with your instance. Register your own GitHub App, install it, and reconnect under Settings → Integrations. The repository, branch and mode settings on your projects are kept.
6

Social login

To offer “Sign in with Google” or “Sign in with GitHub”, create your own OAuth apps with callback URLs on your domain and set GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET and GITHUB_CLIENT_ID/GITHUB_CLIENT_SECRET. See Social login. The hosted OAuth apps only work for app.nt3.io.
7

Search index

Skip this if you use the default MongoDB search. With Typesense or Algolia, rebuild each project’s index as a signed-in user or with an API token of the organization:
8

CLI

Existing API tokens keep working, but the CLI must point at your instance. Each developer logs in again:
To point everyone on a project at your instance, add this to .nt3.yml:
The CLI only sends a stored token to the URL it was saved for, so a developer who logged in to app.nt3.io gets a clear error until they log in again.
9

CI pipelines

Set NT3_API_URL next to NT3_API_TOKEN. The existing token values keep working:
NT3_API_TOKEN is only sent to NT3_API_URL. Without it, the CLI keeps calling app.nt3.io.
10

Delete the archive

Once everything works, delete the archive and any decrypted copies.

Lightweight migration

If you only need your keys and translations, you can move them yourself with the CLI, project by project, without an export from the Entri team.
This path loses data. On the new instance:
  • Translation statuses are reset. Every imported translation becomes Translated: Reviewed and Approved states are lost.
  • History, comments and the activity log are not carried over.
  • Translation memory is not carried over.
  • Key metadata your file format cannot express (for example descriptions or context in a JSON file) is lost.
  • Members, API tokens, webhooks, project settings (such as AI tone and context) and the GitHub connection must be set up again.
  • Glossary part of speech and notes are not part of the CSV export.
1

Set up the new instance

Deploy your instance, sign up, and create your organization. For each project, create a project with the same source language. Create an API token on the new instance.
2

Pull from app.nt3.io

In the repository that holds your .nt3.yml, with a token from app.nt3.io:
This writes the source language and every target language to the paths in .nt3.yml.
3

Point the project at your instance

In .nt3.yml, replace project_id with the new project’s ID and add api_url:
4

Push to your instance

push uploads the source file first, then every target-language file it finds, and enables those languages in the project.
5

Move glossaries

On app.nt3.io, open Glossary, select a glossary and choose Export as CSV. On your instance, create a glossary with the same name and choose Import terms (CSV or TBX).
6

Redo the rest

Invite your team, re-create webhooks, add AI keys, and update CLI and CI configuration as in the post-import checklist.