API Reference

v1.0

REST API documentation for LocalVersion LLM Portal. All endpoints require a Bearer token in the Authorization header unless stated otherwise.

Not authorized
Enter your credentials to test authenticated endpoints

Translation Resources

Access Translation Memories, Glossaries, and Templates stored in the platform.

Translation Memories (TMs) store bilingual sentence pairs extracted from previously translated content in TMX format, indexed with FAISS for fast similarity lookup. When the system translates new strings, it first queries the relevant TM to find fuzzy matches above a similarity threshold — reducing LLM token usage and enforcing consistency across projects.

Common use cases:

  • Populate the TM selector when creating or editing a Translation Template.
  • Check which TMs exist before uploading a new TMX file to avoid duplicates.
  • Retrieve the faissPath to pass directly to the Python translation API for custom FAISS lookups.
Scoping: Non-admin users always receive only their company's TMs. Admins can pass ?company=<id> to scope by company or omit it for all. sourceLang and targetLang must be used together — supplying only one has no effect.

Query Parameters

NameTypeRequiredDescription
sourceLang string optional Filter by source language code (e.g. en)
targetLang string optional Filter by target language code (e.g. es). Must be used together with sourceLang.
company integer optional Company ID — admin only.

Examples

curl -X GET "https://api.localversion.io/api/translation-memories?sourceLang=en&targetLang=es" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/translation-memories?sourceLang=en&targetLang=es', {
  headers: { Authorization: `Bearer ${token}` }
});
const memories = await res.json();

Response 200 OK

[
  {
    "id": "1",
    "name": "Legal EN→ES",
    "description": "Legal domain TM",
    "sourceLanguage": "en",
    "targetLanguage": "es",
    "faissPath": "faiss_dbs_tmx/1742204377945-206",
    "tmxFile": "legal_en_es.tmx"
  }
]
Try it out

Query Parameters

sourceLang
targetLang
company

Retrieves a single Translation Memory record by its unique ID. Use this when you already know the TM identifier and need its full metadata, such as:

  • faissPath — directory path of the FAISS index used by the Python translation service for similarity search.
  • tmxFile — original TMX filename stored in Directus Files, useful for audit trails or re-downloads.
Returns 404 if the ID does not exist, and 400 if the value passed as id is undefined or missing.

Path Parameters

NameTypeRequiredDescription
id string required Translation Memory ID.

Examples

curl -X GET "https://api.localversion.io/api/translation-memories/1" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/translation-memories/1', {
  headers: { Authorization: `Bearer ${token}` }
});
const memory = await res.json();

Response 200 OK

{
  "id": "1",
  "name": "Legal EN→ES",
  "description": "Legal domain TM",
  "sourceLanguage": "en",
  "targetLanguage": "es",
  "faissPath": "faiss_dbs_tmx/1742204377945-206",
  "tmxFile": "legal_en_es.tmx"
}
Try it out

Path Parameters

id

Glossaries store approved terminology pairs in TBX format (Term Base eXchange), also indexed with FAISS. During translation, the system cross-references the glossary to enforce consistent terminology — for example, ensuring "API" is never translated as "interfaz de programación" when an approved translation already exists for that term in the glossary.

Common use cases:

  • Populate the glossary picker when creating or editing Translation Templates.
  • Validate available language pairs before starting a translation job.
  • Retrieve faissPath for direct FAISS-based term lookups in custom pipelines.
Scoping: Same behavior as Translation Memories — non-admins are scoped to their company. Both sourceLang and targetLang must be provided together to apply language filtering.

Query Parameters

NameTypeRequiredDescription
sourceLang string optional Filter by source language.
targetLang string optional Filter by target language.
company integer optional Company ID — admin only.

Examples

curl -X GET "https://api.localversion.io/api/translation-glossaries?sourceLang=en&targetLang=de" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/translation-glossaries?sourceLang=en&targetLang=de', {
  headers: { Authorization: `Bearer ${token}` }
});
const glossaries = await res.json();

Response 200 OK

[
  {
    "id": "3",
    "name": "Tech EN→DE",
    "description": "Technology glossary",
    "sourceLanguage": "en",
    "targetLanguage": "de",
    "faissPath": "faiss_dbs_glossary/1752084816346-252",
    "tbxFile": "glossary_en_de.tbx"
  }
]
Try it out

Query Parameters

sourceLang
targetLang
company

Fetches a single glossary record by ID, including its faissPath and tbxFile metadata. Useful when you need to pass the FAISS index path directly to the Python API for real-time term validation during translation, or when rendering a glossary detail view.

Path Parameters

NameTypeRequiredDescription
id string required Glossary ID.

Examples

curl -X GET "https://api.localversion.io/api/translation-glossaries/3" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/translation-glossaries/3', {
  headers: { Authorization: `Bearer ${token}` }
});
const glossary = await res.json();

Response 200 OK

{
  "id": "3",
  "name": "Tech EN→DE",
  "description": "Technology glossary",
  "sourceLanguage": "en",
  "targetLanguage": "de",
  "faissPath": "faiss_dbs_glossary/1752084816346-252",
  "tbxFile": "glossary_en_de.tbx"
}
Try it out

Path Parameters

id

Translation Templates are the central configuration objects of the translation pipeline. A single template ties together everything the system needs to translate a piece of content:

  • Language pair — source and target language for this template.
  • LLM settings — which AI provider (OpenAI, Azure, etc.) and model to use.
  • System prompt — custom instructions that guide translation style, tone, and domain expertise.
  • Translation Memories — one or more TMs queried for fuzzy matches before calling the LLM.
  • Glossaries — terminology files enforcing consistent term translation.
  • Temperature & context flags — fine-tune LLM creativity and context-awareness.

This endpoint returns the full object graph of each template including nested prompt, TMs, glossaries, and LLM settings — making it suitable for building template editors or for selecting the right template before starting a translation job.

Scoping: Non-admins see only their company's templates. Admins pass ?company=<id> to filter by company or omit it for all companies.

Query Parameters

NameTypeRequiredDescription
company integer optional Company ID — admin only.

Examples

curl -X GET "https://api.localversion.io/api/translation-templates" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/translation-templates', {
  headers: { Authorization: `Bearer ${token}` }
});
const templates = await res.json();

Response 200 OK

[
  {
    "id": "5",
    "name": "Legal EN→ES Standard",
    "sourceLanguage": "en",
    "targetLanguage": "es",
    "model": "gpt-4o",
    "temperature": 0.3,
    "prompt": { "id": "2", "name": "Legal Prompt" },
    "translationMemories": [{ "id": "1", "name": "Legal EN→ES" }],
    "glossaries": []
  }
]
Try it out

Query Parameters

company

Retrieves a single Translation Template by its ID with the full object graph: associated prompt, TMs, glossaries, and LLM settings. Use this when you need the complete configuration to:

  • Display or edit a specific template in a form.
  • Build a translation pipeline that resolves all dependencies (TMs, glossaries, model) from a single template ID.
  • Export or inspect a template's configuration before cloning it for another language pair.

Path Parameters

NameTypeRequiredDescription
id string required Template ID.

Examples

curl -X GET "https://api.localversion.io/api/translation-templates/5" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/translation-templates/5', {
  headers: { Authorization: `Bearer ${token}` }
});
const template = await res.json();

Response 200 OK

{
  "id": "5",
  "name": "Legal EN→ES Standard",
  "sourceLanguage": "en",
  "targetLanguage": "es",
  "model": "gpt-4o",
  "temperature": 0.3
}
Try it out

Path Parameters

id

Returns the list of AI models available from the configured LLM provider (e.g. OpenAI). The model list is fetched live from the provider's API, so it always reflects the currently available models at the time of the call.

Use this to populate the model dropdown when creating or editing a Translation Template. The returned identifiers (e.g. gpt-4o, gpt-4o-mini) can be used directly as the model field in template create/update requests.

This endpoint calls an external provider API. Response depends on the LLM configuration in the server environment — if the provider is unreachable, it returns a 500 error.

Examples

curl -X GET "https://api.localversion.io/api/translation-templates/models" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/translation-templates/models', {
  headers: { Authorization: `Bearer ${token}` }
});
const { models } = await res.json();

Response 200 OK

{
  "models": ["gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "gpt-3.5-turbo"]
}
Try it out

Returns all language codes registered in the platform's language catalogue (stored in Directus), sorted alphabetically. These are the exact codes accepted by sourceLanguage and targetLanguage fields across translation resources and templates.

Use this endpoint to populate language selector dropdowns in forms. Codes follow ISO 639-1 format (e.g. en, es, de, fr, ja, zh). Only languages explicitly registered in your Directus instance are returned — not the full ISO language list.

Examples

curl -X GET "https://api.localversion.io/api/translation-templates/languages" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/translation-templates/languages', {
  headers: { Authorization: `Bearer ${token}` }
});
const { languages } = await res.json();

Response 200 OK

{
  "languages": ["de", "en", "es", "fr", "it", "ja", "pt", "zh"]
}
Try it out

Remote Translations

Interact with Crowdin projects — retrieve files, strings, builds, and template associations.

Returns all translation templates using server-side admin credentials stored in environment variables — no user Bearer token is required. This endpoint is designed for server-to-server calls within the Crowdin App integration flow, where no user session is available (e.g. when Crowdin sends a webhook to install the app or trigger a build).

Security note: Although no Bearer token is required, this endpoint uses privileged admin credentials internally. Do not call it from untrusted client-side code or expose the URL in public-facing contexts.

Examples

curl -X GET "https://api.localversion.io/api/remoteTranslations/templates"
const res = await fetch('/api/remoteTranslations/templates');
const { templates } = await res.json();

Response 200 OK

{
  "templates": [
    { "id": "5", "name": "Legal EN→ES Standard" },
    { "id": "6", "name": "Marketing EN→FR" }
  ]
}
Try it out

Retrieves the template-to-language associations saved for a specific Crowdin project. An association maps a target language (e.g. es) to a Translation Template ID, so the system knows which template configuration — including which TMs, glossaries, and LLM settings — to apply when translating strings for that language in the project.

Typical workflow:

  1. The user opens the Crowdin integration screen and selects a template for each target language.
  2. Associations are saved via POST /associate.
  3. When Crowdin fires a build webhook, the system calls this endpoint to resolve which template handles each language.
  4. Strings are then translated using the matched template's full configuration.
Returns { "message": "No associations found for this project" } with status 200 when no associations have been saved for the project — not a 404.

Path Parameters

NameTypeRequiredDescription
projectId string required Crowdin project ID.

Examples

curl -X GET "https://api.localversion.io/api/remoteTranslations/associations/123456"
const res = await fetch('/api/remoteTranslations/associations/123456');
const { associations } = await res.json();

Response 200 OK

{
  "associations": [
    {
      "id": "10",
      "projectId": "123456",
      "targetLanguageId": "es",
      "templateId": "5",
      "domain": "legal",
      "associatedAt": "2025-06-01T10:00:00.000Z"
    }
  ]
}
Try it out

Path Parameters

projectId

Polls the status of a Crowdin translation build previously started. Crowdin builds are asynchronous — you start one with a POST request and then poll this endpoint until status === "finished", at which point a temporary downloadUrl is included for downloading the translated ZIP.

Build lifecycle:

  • created — build has been queued by Crowdin.
  • inProgress — Crowdin is compiling translated files; progress goes from 0 to 100.
  • finished — build is complete; downloadUrl is a pre-signed temporary URL valid for ~1 hour.
  • failed — build failed on Crowdin's side; start a new build to retry.
Recommended polling interval: 2–5 seconds. The downloadUrl expires after ~1 hour — download promptly after receiving a finished status. This endpoint also handles Crowdin organization accounts automatically by trying both API base URLs.

Path Parameters

NameTypeRequiredDescription
projectId string required Crowdin project ID.
buildId string required Build ID returned by the project-build POST endpoint.

Examples

curl -X GET "https://api.localversion.io/api/remoteTranslations/project-build/123456/789"
const res = await fetch('/api/remoteTranslations/project-build/123456/789');
const build = await res.json();
if (build.downloadUrl) window.location.href = build.downloadUrl;

Response 200 OK

{
  "status": "finished",
  "progress": 100,
  "downloadUrl": "https://crowdin.com/backend/download/project/123456.zip?signature=..."
}
Try it out

Path Parameters

projectId
buildId

Fetches basic metadata for a Crowdin project: its display name and URL identifier (the slug used in Crowdin's web interface and API paths). Useful for:

  • Displaying the project name in UI dropdowns or integration setup screens.
  • Correlating a numeric projectId with its human-readable identifier.
  • Verifying that the system can reach the project before starting a build.

This endpoint transparently handles both standard Crowdin accounts (api.crowdin.com) and Crowdin Enterprise organization accounts (<org>.api.crowdin.com) — it tries both API bases and returns the first successful result.

Path Parameters

NameTypeRequiredDescription
projectId string required Crowdin project ID.

Examples

curl -X GET "https://api.localversion.io/api/remoteTranslations/crowdin-project/123456"
const res = await fetch('/api/remoteTranslations/crowdin-project/123456');
const project = await res.json();

Response 200 OK

{
  "id": "123456",
  "name": "My Product v2",
  "identifier": "my-product-v2"
}
Try it out

Path Parameters

projectId

Lists all files in a Crowdin project, automatically paginating through all pages (Crowdin returns up to 500 files per page, this endpoint fetches all of them in a loop). Each file object includes its id, name, full path within the project, and type (e.g. json, strings, xliff).

Use this endpoint to:

  • Display a file picker before starting a single-file translation build.
  • Retrieve a fileId to pass to the crowdin-strings endpoint.
  • Audit which source files are registered in a project and their types.
For projects with many files this call may take a few seconds since it fetches all pages. Response is a flat array — Crowdin folder hierarchy is reflected in the path field (e.g. /src/components/ui.json).

Path Parameters

NameTypeRequiredDescription
projectId string required Crowdin project ID.

Examples

curl -X GET "https://api.localversion.io/api/remoteTranslations/crowdin-files/123456"
const res = await fetch('/api/remoteTranslations/crowdin-files/123456');
const { data } = await res.json();

Response 200 OK

{
  "data": [
    { "id": "1001", "name": "ui.strings", "path": "/ui.strings", "type": "strings" },
    { "id": "1002", "name": "help.json",  "path": "/help.json",  "type": "json" }
  ]
}
Try it out

Path Parameters

projectId

Fetches all source strings from a specific Crowdin file and joins them with existing translations for the specified target language. The join is performed by stringId, so each returned item contains both the original source text and its current translated value (empty string if not yet translated).

This endpoint powers the Crowdin QA view — providing side-by-side source/translation pairs that editors review before approving a build. It also retrieves TM and glossary matches for each string to assist reviewers.

Important details:

  • All three parameters — projectId, fileId, and targetLanguageId — are required.
  • For large files, this call may take several seconds as it fetches all strings in paginated batches from Crowdin's API.
  • The sourceLanguage and targetLanguage in the response reflect the Crowdin project configuration, which may differ from the template's language pair settings.

Path Parameters

NameTypeRequiredDescription
projectId string required Crowdin project ID.

Query Parameters

NameTypeRequiredDescription
fileId string required Crowdin file ID.
targetLanguageId string required Target language code (e.g. es).

Examples

curl -X GET "https://api.localversion.io/api/remoteTranslations/crowdin-strings/123456?fileId=1001&targetLanguageId=es"
const res = await fetch(
  '/api/remoteTranslations/crowdin-strings/123456?fileId=1001&targetLanguageId=es'
);
const { sourceLanguage, targetLanguage, data } = await res.json();

Response 200 OK

{
  "sourceLanguage": "en",
  "targetLanguage": "es",
  "data": [
    {
      "stringId": 501,
      "source_language": "en",
      "target_language": "es",
      "original_text": "Save changes",
      "translated_text": "Guardar cambios"
    }
  ]
}
Try it out

Path Parameters

projectId

Query Parameters

fileId
targetLanguageId

Terminology & RAG

Search the terminology knowledge base and manage RAG documents stored in Qdrant.

Returns the list of documents registered in the RAG knowledge base for the authenticated user's company. Each document record contains:

  • id — Directus record ID, used when removing a document via the remove endpoint.
  • title — human-readable document name shown in the Knowledge Management UI.
  • controlDocument — optional reference number or code for internal tracking (e.g. SG-2025-001).
  • docId — the Qdrant point UUID that identifies this document's vector chunks in the collection.

Use this endpoint to display the document management table, pre-populate dropdowns, or retrieve IDs before calling the remove endpoint. For large document libraries, use limit and offset to paginate efficiently.

The default limit is 10,000 (effectively all documents). Non-admin users are automatically scoped to their company; admins can pass ?company=<id> to filter by company.

Query Parameters

NameTypeRequiredDescription
limit integer optional Max number of documents to return (default: 10000).
offset integer optional Pagination offset (default: 0).
company integer optional Company ID — admin only.

Examples

curl -X GET "https://api.localversion.io/api/rag/documents?limit=20&offset=0" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/rag/documents?limit=20&offset=0', {
  headers: { Authorization: `Bearer ${token}` }
});
const { documents, limit, offset } = await res.json();

Response 200 OK

{
  "documents": [
    {
      "id": "42",
      "title": "Product Style Guide 2025",
      "controlDocument": "SG-2025-001",
      "docId": "qdrant-point-uuid-abc123"
    }
  ],
  "limit": 20,
  "offset": 0
}
Try it out

Query Parameters

limit
offset
company

Returns raw vector points directly from the Qdrant collection associated with the authenticated user's company. Each point includes its full payload (metadata like title, company, page number) stored alongside the embedding.

This endpoint is primarily useful for:

  • Debugging — verifying that a document was correctly chunked and indexed after upload.
  • Auditing — inspecting what metadata is stored with each vector chunk (e.g. confirming company scoping is correct).
  • Development — understanding the collection's data structure before building custom Qdrant queries.
The collection name is derived from the company name: Treasury_<CompanyName>. Admins can override with ?companyName=OtherCompany. Fetching large numbers of points can be slow — use a small limit (e.g. 20–50) for quick checks during development.

Query Parameters

NameTypeRequiredDescription
limit integer optional Max points to return (default: 5000).
offset integer optional Pagination offset (default: 0).
companyName string optional Override company name — admin only.

Examples

curl -X GET "https://api.localversion.io/api/rag/qdrant/points?limit=100" \
  -H "Authorization: Bearer <token>"
const res = await fetch('/api/rag/qdrant/points?limit=100', {
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();

Response 200 OK

{
  "result": {
    "points": [
      {
        "id": "uuid-abc123",
        "payload": { "title": "Product Style Guide 2025", "company": "Acme Corp", "page": 1 }
      }
    ],
    "next_page_offset": null
  },
  "status": "ok"
}
Try it out

Query Parameters

limit
offset
companyName

Chat with My Docs

Ask questions against the documents uploaded to your RAG knowledge base.

Sends a free-form question or message to the RAG-powered chatbot. Unlike terminology/search which focuses on single-term lookups, this endpoint supports conversational, multi-part queries — allowing users to ask complex questions, request summaries, or explore topics in depth using the content stored in uploaded documents.

Pipeline:

  1. The prompt is forwarded to an n8n webhook.
  2. n8n embeds the prompt and retrieves the most relevant chunks from the user's company Qdrant collection.
  3. The retrieved context + prompt are passed to the configured LLM, which generates a grounded, document-backed response.

Example prompts:

  • "Summarize the key points of the brand style guide"
  • "What are the approved rules for translating product names into Spanish?"
  • "Compare how the terms 'user' and 'customer' are defined in our documentation"
No conversation memory: each request is independent — the chatbot does not retain context between calls. For multi-turn conversations, include prior context within the prompt field itself. Response time is typically 3–15 seconds depending on document volume and LLM latency.

Request Body (application/json)

FieldTypeRequiredDescription
prompt string required The question or message to send to the AI agent.

Examples

curl -X POST "https://api.localversion.io/api/terminology/chat" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "prompt": "What is the brand voice defined in the style guide?" }'
const res = await fetch('/api/terminology/chat', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ prompt: 'What is the brand voice defined in the style guide?' })
});
const { definition } = await res.json();

Response 200 OK

{
  "definition": "According to the Product Style Guide 2025, the brand voice should be clear, concise, and human...",
  "language": "en"
}
Try it out

Request Body (JSON)