This SDK empowers you to build your own branded translation AI leveraging our translation fine-tuned language model.
All major translation features are accessible, making it easy to integrate and customize for your needs.
- Text Translation: Single strings, multiple strings, and complex text blocks
- Document Translation: Word, PDF, and other document formats with status monitoring
- Image Translation: Translate whole images or extract and translate text blocks
- Audio Translation: Audio file translation with status monitoring
- Translation Memory: Store and reuse translations for consistency
- Glossaries: Enforce terminology standards across translations
- Styleguides: Define tone, voice, and writing style rules for translations
- Language Detection: Automatic source language identification
- Advanced Options: Translation instructions and more
Lara's SDK full documentation is available at https://developers.laratranslate.com/
dotnet add package Lara.Sdkusing System;
using System.Threading.Tasks;
using Lara.Sdk;
class Program
{
static async Task Main(string[] args)
{
// Set your credentials using environment variables (recommended)
var credentials = new Credentials(
Environment.GetEnvironmentVariable("LARA_ACCESS_KEY_ID"),
Environment.GetEnvironmentVariable("LARA_ACCESS_KEY_SECRET")
);
// Create translator instance
var lara = new Translator(credentials);
// Simple text translation
try
{
var result = await lara.Translate("Hello, world!", "en-US", "fr-FR");
Console.WriteLine($"Translation: {result.Translation}");
// Output: Translation: Bonjour, le monde !
}
catch (LaraException e)
{
Console.WriteLine($"Translation error: {e.Message}");
}
}
}The examples/ directory contains comprehensive examples for all SDK features.
All examples use environment variables for credentials, so set them first:
export LARA_ACCESS_KEY_ID="your-access-key-id"
export LARA_ACCESS_KEY_SECRET="your-access-key-secret"- TextTranslation.cs - Complete text translation examples
- Single string translation
- Multiple strings translation
- Translation with instructions
- TextBlocks translation (mixed translatable/non-translatable content)
- Auto-detect source language
- Advanced translation options
- Get available languages
- Quality estimation
- Detect language
cd examples
dotnet run -- text-translation- DocumentTranslation.cs - Document translation examples
- Basic document translation
- Advanced options with memories and glossaries
- Step-by-step translation with status monitoring
cd examples
dotnet run -- document-translation- ImageTranslation.cs - Image translation examples
- Basic image translation
- Advanced options with memories and glossaries
- Extract and translate text from an image
cd examples
dotnet run -- image-translation- AudioTranslation.cs - Audio translation examples
- Basic audio translation
- Advanced options with memories and glossaries
- Step-by-step translation with status monitoring
cd examples
dotnet run -- audio-translation- MemoriesManagement.cs - Memory management examples
- Create, list, update, delete memories
- Add individual translations
- Multiple memory operations
- TMX file import with progress monitoring and callback URLs
- Asynchronous memory export with callback URLs
- Translation deletion
- Translation with TUID and context
cd examples
dotnet run -- memories-management- GlossariesManagement.cs - Glossary management examples
- Create, list, update, delete glossaries
- CSV import with status monitoring and callback URLs
- Glossary export and asynchronous export with callback URLs
- Glossary terms count
- Import status checking
cd examples
dotnet run -- glossaries-management- StyleguideManagement.cs - Styleguide management examples
- Create, list, get, update, delete styleguides
- Update name, content, or both at once
- Handling of non-existent styleguides
cd examples
dotnet run -- styleguides-managementThe SDK supports authentication via access key and secret:
var credentials = new Credentials("your-access-key-id", "your-access-key-secret");
var lara = new Translator(credentials);Environment Variables (Recommended):
export LARA_ACCESS_KEY_ID="your-access-key-id"
export LARA_ACCESS_KEY_SECRET="your-access-key-secret"var credentials = new Credentials(
Environment.GetEnvironmentVariable("LARA_ACCESS_KEY_ID"),
Environment.GetEnvironmentVariable("LARA_ACCESS_KEY_SECRET")
);// Create translator with credentials
var lara = new Translator(credentials);// Basic translation
var result = await lara.Translate("Hello", "en-US", "fr-FR");
// Multiple strings
var result = await lara.Translate(new[] {"Hello", "World"}, "en-US", "fr-FR");
// TextBlocks (mixed translatable/non-translatable content)
var textBlocks = new List<TextBlock>
{
new TextBlock("Translatable text", true),
new TextBlock("<br>", false), // Non-translatable HTML
new TextBlock("More translatable text", true),
};
var result = await lara.Translate(textBlocks, "en-US", "fr-FR");
// With advanced options
var options = new TranslateOptions
{
Instructions = new[] {"Formal tone"},
AdaptTo = new[] {"mem_1A2b3C4d5E6f7G8h9I0jKl"}, // Replace with actual memory IDs
Glossaries = new[] {"gls_1A2b3C4d5E6f7G8h9I0jKl"}, // Replace with actual glossary IDs
Style = TranslationStyle.Fluid,
TimeoutInMillis = 10000
};
var result = await lara.Translate("Hello", "en-US", "fr-FR", options);var filePath = "/path/to/your/document.txt"; // Replace with actual file path
var fileStream = await lara.Documents.Translate(filePath, "en-US", "fr-FR");
// With options
var options = new DocumentTranslateOptions
{
AdaptTo = new[] {"mem_1A2b3C4d5E6f7G8h9I0jKl"}, // Replace with actual memory IDs
Glossaries = new[] {"gls_1A2b3C4d5E6f7G8h9I0jKl"} // Replace with actual glossary IDs
};
var fileStream = await lara.Documents.Translate(filePath, "en-US", "fr-FR", options);//Optional: upload options
var uploadOptions = new DocumentUploadOptions
{
AdaptTo = new[] {"mem_1A2b3C4d5E6f7G8h9I0jKl"}, // Replace with actual memory IDs
Glossaries = new[] {"gls_1A2b3C4d5E6f7G8h9I0jKl"} // Replace with actual glossary IDs
};
var document = await lara.Documents.Upload(filePath, "en-US", "fr-FR", uploadOptions);var status = await lara.Documents.Status(document.Id);var downloadOptions = new DocumentDownloadOptions();
var fileStream = await lara.Documents.Download(document.Id, downloadOptions);var imagePath = "/path/to/your/image.png"; // Replace with actual file path
// Translate image and receive a translated image stream
var translatedImageStream = await lara.Images.Translate(imagePath, "en", "fr", new ImageTranslateOptions
{
Model = ImageTranslationModel.Inpainting,
Style = TranslationStyle.Faithful
});
// Extract and translate text blocks from an image
var textBlocks = await lara.Images.TranslateText(imagePath, "en", "fr", new ImageTextTranslateOptions
{
AdaptTo = new[] {"mem_1A2b3C4d5E6f7G8h9I0jKl"},
Glossaries = new[] {"gls_1A2b3C4d5E6f7G8h9I0jKl"}
});Request layout independently of verbose match details, then render the supplied translations:
var result = await lara.Images.TranslateText(imagePath, "en", "fr",
new ImageTextTranslateOptions { IncludeLayout = true });
if (result.Paragraphs.Length > 0)
{
var paragraph = result.Paragraphs[0];
result.Paragraphs[0] = new ImageParagraph(paragraph.Text, "Bonjour !")
{
BBox = paragraph.BBox,
LinesBBoxes = paragraph.LinesBBoxes,
TextInfo = paragraph.TextInfo,
Alignment = paragraph.Alignment
};
}
await using var rendered = await lara.Images.RenderTranslated(
imagePath, result.SourceLanguage, "fr", result.Paragraphs,
ImageTranslationModel.Overlay);
await using var output = File.Create("rendered.png");
await rendered.CopyToAsync(output);When IncludeLayout is true, every paragraph contains complete layout metadata and can be passed
directly to a classic rendering model. The properties remain nullable because ImageParagraph also
represents text-only responses when layout is not requested. Rendering uses the supplied translations
without translating again and defaults to GenerativeFast. Pass model and noTrace to configure rendering.
Overlay and Inpainting require BBox, LinesBBoxes, TextInfo, and Alignment on every paragraph;
generative models accept text-only paragraphs or complete layout. Memory and glossary matches are
omitted from rendering requests. Dispose the returned stream after reading it.
var filePath = "/path/to/your/audio.mp3"; // Replace with actual file path
var audioStream = await lara.Audio.Translate(filePath, "en-US", "fr-FR");
// With options
var options = new AudioTranslateOptions
{
AdaptTo = new[] {"mem_1A2b3C4d5E6f7G8h9I0jKl"}, // Replace with actual memory IDs
Glossaries = new[] {"gls_1A2b3C4d5E6f7G8h9I0jKl"} // Replace with actual glossary IDs
};
var audioStream = await lara.Audio.Translate(filePath, "en-US", "fr-FR", options);// Optional: upload options
var uploadOptions = new AudioUploadOptions
{
AdaptTo = new[] {"mem_1A2b3C4d5E6f7G8h9I0jKl"}, // Replace with actual memory IDs
Glossaries = new[] {"gls_1A2b3C4d5E6f7G8h9I0jKl"} // Replace with actual glossary IDs
};
var audio = await lara.Audio.Upload(filePath, "en-US", "fr-FR", uploadOptions);var status = await lara.Audio.Status(audio.Id);var audioStream = await lara.Audio.Download(audio.Id);// Create memory
var memory = await lara.Memories.Create("MyMemory");
// Create memory with external ID (MyMemory integration)
var memory = await lara.Memories.Create("Memory from MyMemory", "aabb1122"); // Replace with actual external ID
// Important: To update/overwrite a translation unit you must provide a tuid. Calls without a tuid always create a new unit and will not update existing entries.
// Add translation to single memory
var memoryImport = await lara.Memories.AddTranslation("mem_1A2b3C4d5E6f7G8h9I0jKl", "en-US", "fr-FR", "Hello", "Bonjour", "greeting_001");
// Add translation to multiple memories
var memoryIds = new List<string> {"mem_1A2b3C4d5E6f7G8h9I0jKl", "mem_2XyZ9AbC8dEf7GhI6jKlMn"}; // Replace with actual memory IDs
var memoryImport = await lara.Memories.AddTranslation(memoryIds, "en-US", "fr-FR", "Hello", "Bonjour", "greeting_002");
// Add with context
var memoryImport = await lara.Memories.AddTranslation(
"mem_1A2b3C4d5E6f7G8h9I0jKl", "en-US", "fr-FR", "Hello", "Bonjour", "tuid",
"sentenceBefore", "sentenceAfter"
);
// TMX import from file
var tmxFilePath = "/path/to/your/memory.tmx"; // Replace with actual TMX file path
var memoryImport = await lara.Memories.ImportTmx("mem_1A2b3C4d5E6f7G8h9I0jKl", tmxFilePath);
// TMX import with a callback URL
var memoryImportWithCallback = await lara.Memories.ImportTmx(
"mem_1A2b3C4d5E6f7G8h9I0jKl",
tmxFilePath,
callbackUrl: "https://example.com/webhooks/lara-memory-import"
);
// Start an asynchronous memory export; Lara will notify the callback URL when ready
var memoryExport = await lara.Memories.ExportAsync(
"mem_1A2b3C4d5E6f7G8h9I0jKl",
"https://example.com/webhooks/lara-memory-export"
);
Console.WriteLine($"Export job ID: {memoryExport.JobId}");
// Delete translation
// Important: if you omit tuid, all entries that match the provided fields will be removed
var deleteJob = await lara.Memories.DeleteTranslation(
"mem_1A2b3C4d5E6f7G8h9I0jKl", "en-US", "fr-FR", "Hello", "Bonjour", "greeting_001"
);
// Wait for import completion
var completedImport = await lara.Memories.WaitForImport(memoryImport, progressCallback, TimeSpan.FromMinutes(5));
// Share with the account or a group; shares can be renamed, listed, and revoked
await lara.Memories.AddAccountShare(memory.Id, "Team memory");
await lara.Memories.RenameAccountShare(memory.Id, "Company memory");
await lara.Memories.AddGroupShare(memory.Id, "grp_1A2b3C4d5E6f7G8h9I0jKl", "Marketing memory");
var shares = await lara.Memories.GetShares(memory.Id);
await lara.Memories.RevokeGroupShare(memory.Id, "grp_1A2b3C4d5E6f7G8h9I0jKl");
await lara.Memories.RevokeAccountShare(memory.Id);// Create glossary
var glossary = await lara.Glossaries.Create("MyGlossary");
// Import a glossary file (use GlossaryFileFormat.Tbx for TBX files)
var glossaryFilePath = "/path/to/your/glossary.csv";
var glossaryImport = await lara.Glossaries.ImportFile(
"gls_1A2b3C4d5E6f7G8h9I0jKl",
glossaryFilePath,
new GlossaryImportOptions { ContentType = GlossaryFileFormat.CsvTableUni });
// Omit options to use unidirectional CSV.
// CSV import with a callback URL; Lara notifies the callback URL once the import finishes
var glossaryImportWithCallback = await lara.Glossaries.ImportFile(
"gls_1A2b3C4d5E6f7G8h9I0jKl",
glossaryFilePath,
new GlossaryImportOptions { CallbackUrl = "https://example.com/webhooks/lara-glossary-import" }
);
// Check import status
var importStatus = await lara.Glossaries.GetImportStatus(glossaryImport.Id);
// Wait for import completion
var completedImport = await lara.Glossaries.WaitForImport(glossaryImport, progressCallback, TimeSpan.FromMinutes(5));
// Export glossary
var csvData = await lara.Glossaries.Export("gls_1A2b3C4d5E6f7G8h9I0jKl", "csv/table-uni", "en-US");
// Start an asynchronous glossary export; Lara will notify the callback URL when ready
var glossaryExport = await lara.Glossaries.ExportAsync(
"gls_1A2b3C4d5E6f7G8h9I0jKl",
"https://example.com/webhooks/lara-glossary-export",
GlossaryFileFormat.CsvTableUni,
"en-US" // optional source language filter
);
Console.WriteLine($"Export job ID: {glossaryExport.JobId}");
// Get glossary terms count
var counts = await lara.Glossaries.Counts("gls_1A2b3C4d5E6f7G8h9I0jKl");
// Glossaries support the same account and group sharing workflow
await lara.Glossaries.AddAccountShare(glossary.Id, "Team glossary");
var glossaryShares = await lara.Glossaries.GetShares(glossary.Id);
await lara.Glossaries.RevokeAccountShare(glossary.Id);// Create styleguide
var styleguide = await lara.Styleguides.Create(
"MyStyleguide",
"Use a formal tone. Prefer British English spelling. Avoid contractions."
);
// List all styleguides
var styleguides = await lara.Styleguides.List();
// Get a styleguide by ID (returns null if not found)
var retrieved = await lara.Styleguides.Get("sg_1A2b3C4d5E6f7G8h9I0jKl");
// Update a styleguide β omit fields you don't want to change
// Update only the name
var renamed = await lara.Styleguides.Update("sg_1A2b3C4d5E6f7G8h9I0jKl", "UpdatedName");
// Update only the content
var updatedContent = await lara.Styleguides.Update(
"sg_1A2b3C4d5E6f7G8h9I0jKl",
content: "Use a casual tone. Prefer American English spelling."
);
// Update both name and content
var updated = await lara.Styleguides.Update(
"sg_1A2b3C4d5E6f7G8h9I0jKl",
"FinalName",
"Use clear and concise language. Avoid jargon."
);
// Share a styleguide and inspect visible account, group, and user shares
await lara.Styleguides.AddGroupShare(styleguide.Id, "grp_1A2b3C4d5E6f7G8h9I0jKl", "Marketing styleguide");
var styleguideShares = await lara.Styleguides.GetShares(styleguide.Id);
// Delete a styleguide
var deleted = await lara.Styleguides.Delete("sg_1A2b3C4d5E6f7G8h9I0jKl");public class TranslateOptions
{
public string[] AdaptTo { get; set; } // Memory IDs to adapt to
public string[] Glossaries { get; set; } // Glossary IDs to use
public string[] Instructions { get; set; } // Translation instructions
public TranslationStyle Style { get; set; } // Translation style (Fluid, Faithful, Creative)
public string ContentType { get; set; } // Content type (text/plain, text/html, etc.)
public bool? Multiline { get; set; } // Enable multiline translation
public int? TimeoutInMillis { get; set; } // Request timeout in milliseconds
public string SourceHint { get; set; } // Hint for source language detection
public bool? NoTrace { get; set; } // Disable request tracing
public bool? Verbose { get; set; } // Enable verbose response
public TranslatePriority Priority { get; set; } // Translation priority
}The SDK supports full language codes (e.g., en-US, fr-FR, es-ES) as well as simple codes (e.g., en, fr, es):
// Full language codes (recommended)
var result = await lara.Translate("Hello", "en-US", "fr-FR");
// Simple language codes
var result = await lara.Translate("Hello", "en", "fr");The SDK supports all languages available in the Lara API. Use the Languages() method to get the current list:
var languages = await lara.Languages();
Console.WriteLine($"Supported languages: [{string.Join(", ", languages)}]");Memories, glossaries, styleguides, and their share entries expose PermissionMask from the API's permission_mask field. Masks use read (r), write (w), export (e), and share (s) positions; - means absent. Supported masks are r---, rw--, r-e-, r--s, rwe-, rw-s, r-es, and rwes.
On memory, glossary, and styleguide resources, PermissionMask is optional and is null when omitted by the API, including POST, PUT, and DELETE resource responses. GET list and detail responses report the combined effective mask from the caller's applicable shares. Resources embedded in GET /shares responses report the selected share's stored mask; individual share entries report their own required stored mask.
The legacy permissions field and its read/write compatibility API have been removed. Use PermissionMask to inspect the read, write, export, and share bits. Share-entry masks are required, matching the service contract. Resource masks remain optional.
The SDK provides detailed error information:
try
{
var result = await lara.Translate("Hello", "en-US", "fr-FR");
Console.WriteLine($"Translation: {result.Translation}");
}
catch (LaraException e)
{
Console.WriteLine($"API Error: {e.Message}");
}
catch (LaraTimeoutException e)
{
Console.WriteLine($"Timeout Error: {e.Message}");
}- .NET 9.0 or higher
- Valid Lara API credentials
Run the examples to test your setup:
# All examples use environment variables for credentials, so set them first:
export LARA_ACCESS_KEY_ID="your-access-key-id"
export LARA_ACCESS_KEY_SECRET="your-access-key-secret"# Run example files
cd examples
dotnet run -- text-translation
dotnet run -- image-translation
dotnet run -- document-translation
dotnet run -- audio-translation
dotnet run -- memories-management
dotnet run -- glossaries-management
dotnet run -- styleguides-managementThis project is licensed under the MIT License - see the LICENSE file for details.
Happy translating! πβ¨