**Source URL:** https://limited.veevavault.dev/commercial/vault-sdk/services/translation-service

# File Translation Service

`FileTranslationService` submits batches of files to a translation provider asynchronously. When the run completes, Vault invokes a post-processing event handler that saves the translated output in Vault. For example, the translated output may be saved as a new document, a new version, a rendition, or an attachment.

`FileTranslationService` is typically invoked from a user action, entry action, workflow job step, or agent tool.

## Key Functionality

A translation run has three components:

1.  **Initiation**: Your code assembles a `FileTranslationBatchRequest`. This includes one `FileTranslationInput` per file, a connection name identifying the translation provider, an event handler API name, and an optional `FileTranslationParameters` instance to hold the context your handler will need. Calling `batchTranslateFiles` queues the job.
2.  **Translation**: The job runtime submits each file to the provider identified by the connection record and polls for results.
3.  **Post-processing**: When all files have completed or failed, Vault invokes the `FileTranslationEventHandler` you specified, which saves the translated output in Vault and has access to the original collection of parameters for any additional context it needs. For example, the translated output may be saved as a new document, a new version, a rendition, or an attachment.

## Submitting a Translation Batch

The following example demonstrates locating `FileTranslationService` via `ServiceLocator`, building one `FileTranslationInput` per file, then building and executing the `FileTranslationBatchRequest`.

```java
FileTranslationService translationService = ServiceLocator.locate(FileTranslationService.class);

// Build the input for a single file
FileTranslationInput input = translationService.newFileTranslationInputBuilder()
    .withSourceFile(sourceFileReference)
    .withSourceLanguageCode("en")          // optional; omit to let the provider detect it
    .withTargetLanguageCode("es")
    .build();

// Build the batch request
FileTranslationBatchRequest request = translationService.newFileTranslationBatchRequestBuilder()
    .withFileTranslationInputs(VaultCollections.asList(input))
    .withConnectionName("my_provider__c")  // api_name__sys of the Translation Provider connection record
    .withEventHandlerApiName("my_translation_handler__c")
    .build();

// Submit the batch
translationService.batchTranslateFiles(request)
    .onErrors(errors -> {
        for (FileTranslationSubmissionError error : errors) {
            // Log or handle error here
        }
    })
    .execute();
```

`batchTranslateFiles` returns a `FileTranslationBatchOperation` that exposes three strategies for pre-queue validation failures:

*   `ignoreErrors()`: Submit valid rows; skip invalid rows silently.
*   `onErrors` + `ignoreErrors()`: Handle row-level failures, then submit valid rows.
*   `rollbackOnErrors()`: Fail the entire batch if any row is invalid; nothing is queued.

`FileTranslationErrorType` describes the possible pre-queue validation failures:

*   `SOURCE_FILE_NOT_READABLE`
*   `PROVIDER_NOT_FOUND`
*   `PROVIDER_NOT_ACTIVE`
*   `EVENT_HANDLER_NOT_FOUND`
*   `SOURCE_FORMAT_UNSUPPORTED`
*   `TARGET_LANGUAGE_UNSUPPORTED`

<Aside type="note">
A single `FileTranslationBatchRequest` may contain at most 500 `FileTranslationInput` entries. Requests exceeding this limit fail pre-queue validation.
</Aside>

## File Translation Parameters

`FileTranslationParameters` represents a keyed, serializable collection of parameters attached to the batch request. Vault carries it across the asynchronous boundary and makes it available to the event handler via `FileTranslationEventHandlerContext`. Use it to pass any context your handler needs, such as source document IDs, configuration names, or notification flags.

Set scalar values using `FileTranslationParameterValueType` constants:

```java
FileTranslationParameters parameters = translationService.newFileTranslationParametersBuilder()
    .appendValue("config_name", "my_translation_config__c")
    .appendValue("send_notification", true)
    .build();
```

For structured data, implement `FileTranslationParameterValue` in a `@UserDefinedClass`. All fields must use scalars or collections of scalars to ensure serialization across the asynchronous boundary.

```java
@UserDefinedClassInfo()
public class MyTranslationContext implements FileTranslationParameterValue {
    private String sourceDocumentVersionId;
    private String targetLanguageCode;
    // getters and setters
}
```

Retrieve values in the event handler using `FileTranslationEventHandlerContext#getParameter`:

```java
// Scalar value
String configName = context.getParameter("config_name", FileTranslationParameterValueType.STRING);
// Custom type
MyTranslationContext ctx = context.getParameter("my_context", MyTranslationContext.class);
```

## Implementing a File Translation Event Handler

Vault invokes `FileTranslationEventHandler` when a translation run completes. It owns all post-processing: storing the translated files, updating records, and notifying users.

Implement the `FileTranslationEventHandler` interface and annotate the class with `@FileTranslationEventHandlerInfo`. The `apiName` attribute must be unique within your Vault and follow standard naming conventions (`__c` for custom handlers).

The interface requires two methods, both receiving a `FileTranslationEventHandlerContext`:

*   `onCompleteWithSuccess`: Vault calls this method only when every input in the batch succeeded. Use `context.getResults()` to retrieve each `FileTranslationResultSuccess`.
*   `onCompleteWithError`: Vault calls this method when any input failed, even if other inputs in the same batch succeeded. Use both `context.getResults()` for successes and `context.getErrors()` for failures.

```java
import com.veeva.vault.sdk.api.translation.*;

@FileTranslationEventHandlerInfo(apiName = "my_translation_handler__c")
public class MyTranslationHandler implements FileTranslationEventHandler {

    @Override
    public void onCompleteWithSuccess(FileTranslationEventHandlerContext context) {
        for (FileTranslationResultSuccess result : context.getResults()) {
            // Retrieve the successfully translated file
            FileReference translatedFile = result.getFileReference();
        }
    }

    @Override
    public void onCompleteWithError(FileTranslationEventHandlerContext context) {
        for (FileTranslationResultSuccess result : context.getResults()) {
            // Retrieve the successfully translated file
            FileReference translatedFile = result.getFileReference();
        }
        for (FileTranslationResultError result : context.getErrors()) {
            // Log or handle provider-level error here
        }
    }
}
```

`FileTranslationProviderErrorType` describes possible provider-side failures on a `FileTranslationResultError`:

*   `INVALID_REQUEST`
*   `AUTHENTICATION_FAILED`
*   `PROVIDER_UNAVAILABLE`
*   `PROVIDER_ERROR`
*   `UNEXPECTED_ERROR`

### Document Translation Event Handlers

Instead of implementing your own `FileTranslationEventHandler`, you can use one of the two document translation event handlers by passing its API name constant to `withEventHandlerApiName`:

*   `DocumentCreationHandlerParameters.API_NAME` (`document_creation__sys`): Creates a new translated document per successfully translated file, copying fields from a source document version and linking each translation back to it.
*   `DocumentUpdateHandlerParameters.API_NAME` (`document_update__sys`): Creates a new version of an existing target document from the translated content. Only appropriate when a single target language is selected and the batch has exactly one input.

Each platform handler requires its own collection of parameters, built via `FileTranslationService` and attached to `FileTranslationParameters` under the handler's `PARAMETER_NAME`. See the [`Doctranslationsconfig`](/commercial/mdl/component-types/doctranslationsconfig) component type for information about how to configure field copy and relationship behavior.

## Example: Using a Document Translation Event Handler

The following example builds a translation request using the `document_creation__sys` platform handler, which creates a new translated document for each successfully translated file.

```java
FileTranslationService translationService = ServiceLocator.locate(FileTranslationService.class);

// Build the platform handler parameters
DocumentCreationHandlerParameters handlerParameters = translationService
    .newDocumentCreationHandlerParametersBuilder()
    .withInstanceId("1000443")
    .withSourceDocumentId("1502")
    .withSourceMajorVersion("1")
    .withSourceMinorVersion("0")
    .withTargetLanguageCodes(VaultCollections.asList("fr", "de"))
    .withNotifyOnCompletion(true)
    .build();

// Attach the handler parameters to the batch parameters collection
FileTranslationParameters parameters = translationService.newFileTranslationParametersBuilder()
    .appendValue(DocumentCreationHandlerParameters.PARAMETER_NAME, handlerParameters)
    .build();

// Build the input
FileTranslationInput input = translationService.newFileTranslationInputBuilder()
    .withSourceFile(sourceFileReference)
    .withTargetLanguageCode("es")
    .build();

// Build and submit the batch
FileTranslationBatchRequest request = translationService.newFileTranslationBatchRequestBuilder()
    .withFileTranslationInputs(VaultCollections.asList(input))
    .withConnectionName("deepl")
    .withEventHandlerApiName(DocumentCreationHandlerParameters.API_NAME)
    .withParameters(parameters)
    .build();

translationService.batchTranslateFiles(request)
    .onErrors(errors -> {
        for (FileTranslationSubmissionError error : errors) {
            // Log or handle error here
        }
    })
    .execute();
```

See [`DocumentCreationHandlerParameters`](https://repo.veevavault.com/javadoc/vault-sdk-api/26.2.3/docs/javadoc/com/veeva/vault/sdk/api/translation/DocumentCreationHandlerParameters.html) and [`DocumentUpdateHandlerParameters`](https://repo.veevavault.com/javadoc/vault-sdk-api/26.2.3/docs/javadoc/com/veeva/vault/sdk/api/translation/DocumentUpdateHandlerParameters.html) in the Javadocs for the full set of parameters each platform handler requires.

<Aside type="note">
Entry actions, workflow job steps, and agent tools use the same `batchTranslateFiles` pattern to invoke `FileTranslationService`.
</Aside>

---

**Previous:** [Settings Services](/commercial/vault-sdk/services/settings-service)  
**Next:** [File Staging Service](/commercial/vault-sdk/services/file-staging-service)