API Reference
v1.0
REST API documentation for LocalVersion LLM Portal.
All endpoints require a Bearer token in the Authorization header unless stated otherwise.
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
faissPathto pass directly to the Python translation API for custom FAISS lookups.
?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
| Name | Type | Required | Description |
|---|---|---|---|
| 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"
}
]
Query Parameters
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.
id is undefined or missing.Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| 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"
}
Path Parameters
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
faissPathfor direct FAISS-based term lookups in custom pipelines.
sourceLang and targetLang must be provided together to apply language filtering.Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| 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"
}
]
Query Parameters
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
| Name | Type | Required | Description |
|---|---|---|---|
| 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"
}
Path Parameters
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.
?company=<id> to filter by company or omit it for all companies.Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| 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": []
}
]
Query Parameters
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
| Name | Type | Required | Description |
|---|---|---|---|
| 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
}
Path Parameters
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.
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"]
}
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"]
}
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).
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" }
]
}
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:
- The user opens the Crowdin integration screen and selects a template for each target language.
- Associations are saved via
POST /associate. - When Crowdin fires a build webhook, the system calls this endpoint to resolve which template handles each language.
- Strings are then translated using the matched template's full configuration.
{ "message": "No associations found for this project" } with status 200 when no associations have been saved for the project — not a 404.Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| 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"
}
]
}
Path Parameters
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;progressgoes from 0 to 100.finished— build is complete;downloadUrlis a pre-signed temporary URL valid for ~1 hour.failed— build failed on Crowdin's side; start a new build to retry.
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
| Name | Type | Required | Description |
|---|---|---|---|
| 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=..."
}
Path Parameters
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
projectIdwith 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
| Name | Type | Required | Description |
|---|---|---|---|
| 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"
}
Path Parameters
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
fileIdto pass to thecrowdin-stringsendpoint. - Audit which source files are registered in a project and their types.
path field (e.g. /src/components/ui.json).Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| 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" }
]
}
Path Parameters
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, andtargetLanguageId— are required. - For large files, this call may take several seconds as it fetches all strings in paginated batches from Crowdin's API.
- The
sourceLanguageandtargetLanguagein the response reflect the Crowdin project configuration, which may differ from the template's language pair settings.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| projectId | string | required | Crowdin project ID. |
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| 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"
}
]
}
Path Parameters
Query Parameters
Terminology & RAG
Search the terminology knowledge base and manage RAG documents stored in Qdrant.
Searches the AI-powered terminology knowledge base using a multi-step RAG pipeline:
- The
termis forwarded to an n8n webhook, which embeds it using the configured embedding model. - The embedding is used to query the Qdrant vector store scoped to the user's company collection, retrieving the most semantically relevant document chunks.
- The retrieved chunks + the optional
promptare passed to an LLM, which generates a grounded definition or explanation.
Use the optional prompt field to guide the response format — for example: "Explain in one sentence", "Give the Spanish equivalent", or "Compare with the term 'localization'".
Request Body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
| term | string | required | The term to look up. |
| prompt | string | optional | Optional custom prompt to guide the AI response. |
Examples
curl -X POST "https://api.localversion.io/api/terminology/search" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "term": "neural machine translation", "prompt": "Explain in simple terms" }'
const res = await fetch('/api/terminology/search', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ term: 'neural machine translation' })
});
const { term, definition } = await res.json();
Response 200 OK
{
"term": "neural machine translation",
"definition": "Neural machine translation (NMT) is an approach that uses a large neural network...",
"language": "en"
}
Request Body (JSON)
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.
?company=<id> to filter by company.Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| 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
}
Query Parameters
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.
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
| Name | Type | Required | Description |
|---|---|---|---|
| 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"
}
Query Parameters
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:
- The
promptis forwarded to an n8n webhook. - n8n embeds the prompt and retrieves the most relevant chunks from the user's company Qdrant collection.
- 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"
prompt field itself. Response time is typically 3–15 seconds depending on document volume and LLM latency.Request Body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
| 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"
}
Request Body (JSON)