Tritium Web API (v 1.0.0)
Initialize Tritium
Tritium can be embedded in a web application as a WebAssembly-powered editor. Follow the basic installation instructions at tritium.legal/wasm, including adding a canvas with the ID tritium-canvas. Import the bundle as an ES module and await the import before using the API:
<canvas id="tritium-canvas"></canvas>
<script type="module">
const tritium = await import("https://tritium.legal/static/init.js");
await tritium.start();
</script>
The awaited import initializes the WebAssembly bundle. Awaiting start() then launches Tritium in the canvas and resolves when the editor is ready. Calling it without an argument uses the default launch settings.
Adjust Settings
Each setting is optional. Omitted settings retain their default value.
interface Identity {
/** Author's given name. Defaults to `null`. */
firstName?: string | null;
/** Author's family name. Defaults to `null`. */
lastName?: string | null;
/** Author's organization. Defaults to `null`. */
organization?: string | null;
}
interface AutoSaveSettings {
/** Wait after the last edit before requesting a save, in milliseconds. Defaults to 3000. */
debounceMs?: number;
}
interface Settings {
/** Author information used for document changes and comments. Defaults to an empty identity. */
identity?: Identity;
/** Opens every file in read-only mode. Defaults to `false`.
*
* NOTE: This setting cannot be modified in the application, and a restart is required to affect
* a change.
*/
readonlyMode?: boolean;
/** Automatically requests a save after edits. Set to `null` to disable. Defaults to `{ debounceMs: 3000 }`. */
autoSaveSettings?: AutoSaveSettings | null;
/** Shows the Tritium logo in the application. Defaults to `true`. */
showLogo?: boolean;
/** Shows a dark frame with dark page background with light text. Defaults to `false`. */
darkMode?: boolean;
/** Shows formatting marks in documents. Defaults to `true`. */
formattingMarks?: boolean;
/** Produces blacklines instead of colored redlines. Defaults to `false`. */
blacklineMode?: boolean;
/** Configures and enables the in-app assistant. Defaults to `null`. */
provider?: Provider | null;
/** Internal configuration values. */
installId?: string;
recentFolders?: string[];
recentFiles?: string[];
panels?: string[][];
cleanExit?: boolean;
authToken?: string | null;
}
The main user-facing settings are:
| Property | Default | Purpose |
|---|---|---|
identity | Empty identity | Author information used for document changes and comments. |
readonlyMode | false | Automatically open all files in read-only mode. |
autoSaveSettings | { debounceMs: 3000 } | Request a save after 3 seconds without edits; set to null to disable. |
showLogo | true | Show the Tritium logo in the application. |
darkMode | false | Show white text on a dark page background. |
formattingMarks | true | Shows formatting marks in documents. |
blacklineMode | false | Produce blacklines instead of redlines. |
provider | null | Configures and enables the in-app assistant. |
The remaining properties represent installation, authentication, or session state and are for internal use.
Auto-save applies to edited DOCX documents that already have a path and are neither generated nor read-only. It makes one save attempt after editing stops for debounceMs milliseconds; a further edit permits another attempt. In the WebAssembly build, the attempt calls setSaveHandler; the host is responsible for persisting the file. A newly created document without a path is not auto-saved.
Configure the Assistant
The in-application assistant is disabled by default in the WebAssembly build. It is enabled only when settings.provider is supplied.
To connect the assistant to your own backend, use a Custom provider and set its url to your endpoint:
await tritium.start({
settings: {
provider: {
Custom: {
name: "Example assistant",
url: "https://assistant.example.com/v1/chat/completions",
model: "example-model",
token: "optional-bearer-token",
location: "memory",
payloadType: "json",
},
},
},
});
The provider schema is:
type Provider =
| { Tritium: ProviderConfiguration }
| { OpenAI: ProviderConfiguration }
| { Claude: ProviderConfiguration }
| { DeepSeek: ProviderConfiguration }
| { Gemini: ProviderConfiguration }
| { Custom: ProviderConfiguration };
interface ProviderConfiguration {
name?: string;
token?: string | null;
model?: string | null;
url?: string;
queryParameters?: [string, string][];
location?: "memory" | { file: string };
payloadType?: "json" | "form";
}
A custom endpoint must implement the OpenAI Chat Completions API, including streamed Server-Sent Events and OpenAI-style tool calls. The integration will not work with an incompatible request or response format.
Tritium sends token, when present, as a bearer token. Because WebAssembly runs in the browser, the endpoint must also permit requests from the embedding application's origin. Avoid placing long-lived secrets in client-side code; a backend-controlled short-lived credential or authenticated proxy is preferable.
Start Tritium
start(options?: LaunchOptions): Promise<void>
All launch options are optional:
interface LaunchOptions {
folder?: string;
files?: File[];
settings?: Settings;
}
folderis the logical path of the folder to show in Tritium's library.filescontains browserFileobjects to load. Withoutfolder, the files are opened directly. Withfolder, they are loaded as files in that folder.settingsoverrides Tritium's defaults for this launch.
For example, an application can start Tritium with files selected by the user:
const files = Array.from(fileInput.files ?? []);
await tritium.start({
folder: "matter-123",
files,
settings: {
darkMode: true,
formattingMarks: false,
identity: {
firstName: "Alex",
lastName: "Morgan",
organization: "Example LLP",
},
},
});
Always await start() before calling other session APIs.
Open Files and Folders
The following APIs add documents to a running Tritium session. Await start() before using them.
openFile
openFile(file: File): Promise<void>
Reads and opens a browser File, making it the active document.
openFolder
openFolder(path: string, files: File[]): Promise<void>
Sets the logical library folder and opens its files.
openArrayBuffer
openArrayBuffer(path: string, buffer: ArrayBuffer, activate: boolean): void
Opens an in-memory document. Set activate to true to make it active.
openBytes
openBytes(path: string, bytes: Uint8Array, activate: boolean): void
This is the byte-array equivalent of openArrayBuffer.
Use Tools
After Tritium has been started, getToolCatalog() returns the available tools. Each entry includes the tool's name, description, input schema, and whether it can modify a document:
interface ToolCatalog {
apiVersion: "1.0.0";
tools: ToolDefinition[];
}
interface ToolDefinition {
name: string;
description: string;
modifiesDocument: boolean;
inputSchema: Record<string, unknown>;
}
Use the returned inputSchema to construct valid arguments, then invoke the tool by name with callTool(name, args). Arguments must be JSON-serializable. Tool names such as list_documents remain snake_case protocol identifiers; argument and result properties use camelCase.
const catalog = tritium.getToolCatalog();
const tool = catalog.tools.find(({ name }) => name === "list_documents");
if (!tool) {
throw new Error("This Tritium build does not provide list_documents");
}
const result = await tritium.callTool(tool.name /* i.e., "list_documents" */, {});
const outcome = result.output;
if (outcome.ok) {
console.log(outcome.data);
console.log(result.displayText);
} else {
console.error(outcome.error.code, outcome.error.message);
}
callTool() always resolves to a ToolResult, including for invalid calls and execution failures. Inspect the discriminated output union to determine whether the call succeeded:
interface ToolResult {
output: ToolCallOutput;
displayText: string;
}
type ToolCallOutput =
| {
ok: true;
data: unknown;
}
| {
ok: false;
error: {
code:
| "not_running"
| "not_ready"
| "cancelled"
| "unknown_tool"
| "invalid_arguments"
| "execution_failed"
| "apply_failed"
| "unsupported_effect"
| "stale_segment_ids";
message: string;
retryable: boolean;
};
};
displayText is a short human-readable summary for logs or UI. The structured output.data value is the result intended for programmatic use or for returning to an LLM. Tool-specific data uses camelCase property names, for example documentIndex, segmentCount, and segmentIdsStale.
The catalog is the source of truth for the tools and argument schemas in the loaded bundle. Check result.output.ok before accessing data, and do not assume that every release exposes the same catalog.
Document and segment identifiers
Call list_documents to obtain document indexes before invoking document-specific tools. read_document returns structured data in this form:
interface ReadDocumentData {
documentIndex: number;
filename: string;
segmentCount: number;
segments: Array<{ id: number; text: string }>;
}
Call read_document with camelCase arguments, for example callTool("read_document", { documentIndex: 0 }).
Segment IDs describe the document state returned by the read call. After a modifying tool succeeds, its data contains segmentIdsStale: true; read the document again before issuing another segment-based edit.
Save, Exit and Error Handlers
Register optional host event handlers before calling start() so the host can observe the entire Tritium session.
setSaveHandler
setSaveHandler(handler: (file: File) => void): void
Register a save handler so the host application can persist documents. Tritium calls this handler whenever a document is saved and passes the complete saved document as a browser File. The file's name, type, size, and contents are available through the standard File API.
tritium.setSaveHandler((file) => {
console.log(`Saving ${file.name} (${file.size} bytes)`);
uploadSavedFile(file);
});
The callback transfers responsibility for persistence to the host application, including for auto-save requests. Its return value is not awaited, so the host should handle and report asynchronous upload failures itself.
setExitHandler
setExitHandler(handler: () => void): void
Register an exit handler to restore the host application's UI or perform other cleanup after Tritium shuts down:
tritium.setExitHandler(() => {
document.querySelector("#host-application").hidden = false;
});
Call tritium.shutdown() to close the current Tritium session. Shutdown removes the editor session and then invokes the registered exit handler. Tritium does not modify browser history.
setDocumentErrorHandler
type DocumentErrorCode =
| "parse_error"
| "initialization_failed"
| "unsupported_format";
interface DocumentError {
code: DocumentErrorCode;
message: string;
path: string | null;
}
setDocumentErrorHandler(handler: (error: DocumentError) => void): void
Register a document error handler so the host application can report failures to open or initialize documents. code is a machine-readable category, message describes the failure, and path identifies the affected document when available.
tritium.setDocumentErrorHandler(({ code, message, path }) => {
console.error(`Tritium document error (${code})`, { message, path });
});
The handler is called synchronously. Its return value is not awaited, so the host should handle failures from any asynchronous reporting itself.
setPanicHandler
interface PanicReport {
summary: string;
detail: string;
}
setPanicHandler(handler: (report: PanicReport) => void): void
Register a panic handler so the host application can capture an unexpected internal Tritium failure. summary contains the panic message, while detail includes diagnostic context such as the source location and, when available, a backtrace.
tritium.setPanicHandler(({ summary, detail }) => {
console.error(`Tritium panicked: ${summary}`, { detail });
});
The handler is called synchronously while Tritium is processing the panic. Its return value is not awaited. The panic continues after the handler returns, so the host should not assume that the current Tritium session remains usable.
Register panic, document error, save, and exit handlers before calling start(). Each handler is optional:
const tritium = await import("https://tritium.legal/static/init.js");
tritium.setPanicHandler(handlePanic);
tritium.setDocumentErrorHandler(handleDocumentError);
tritium.setSaveHandler(handleSavedFile);
tritium.setExitHandler(handleTritiumExit);
await tritium.start();
Future versions of this API will add these handlers to the launch settings.
Tool Description
The following tools are available in the current build, but they may be added, removed, or changed in future releases.
Agents should call getToolCatalog() at runtime and treat its returned names, descriptions, and input schemas as canonical. This section describes the current API, but runtime discovery is preferred.
Every tool is invoked with callTool(name, args) and returns a ToolResult.
list_documents
callTool(name: "list_documents", args: Record<string, never>): Promise<ToolResult>
Lists the open documents. Successful result data contains a documents array whose entries have index, filename, active, and nullable path properties. Use these indexes in calls to document-specific tools.
await tritium.callTool("list_documents", {})
/*
{
output: {
ok: true,
data: {
documents: [
{ index: 0, filename: "contract.docx", active: true, path: "/matter/contract.docx" },
{ index: 1, filename: "schedule.docx", active: false, path: null }
]
}
},
displayText: "Listed 2 open document(s)."
}
*/
read_document
callTool(name: "read_document", args: { documentIndex: number }): Promise<ToolResult>
Reads every segment in a document. Successful result data contains documentIndex, filename, segmentCount, and a segments array of { id, text } objects.
await tritium.callTool("read_document", {
documentIndex: 0,
})
/*
{
output: {
ok: true,
data: {
documentIndex: 0,
filename: "contract.docx",
segmentCount: 2,
segments: [
{ id: 0, text: "Services Agreement" },
{ id: 1, text: "This agreement begins on 1 September 2026." }
]
}
},
displayText: "Read 2 segment(s) from \"contract.docx\"."
}
*/
list_comments
callTool(name: "list_comments", args: { documentIndex: number }): Promise<ToolResult>
Lists all comments in a DOCX document. Call list_documents first to obtain the document index. Comments are not currently supported for PDF documents.
Successful result data contains documentIndex, commentCount, and a comments array. Each comment contains its string id, author, nullable date, text content, startSegment, and nullable endSegment. A point comment has a null endSegment.
await tritium.callTool("list_comments", {
documentIndex: 0,
})
/*
{
output: {
ok: true,
data: {
documentIndex: 0,
commentCount: 1,
comments: [{
id: "0",
author: "Alex Morgan",
date: "2026-09-21T10:30:00Z",
content: "Please confirm this date.",
startSegment: 1,
endSegment: 1
}]
}
},
displayText: "Read 1 comment(s) from \"contract.docx\"."
}
*/
list_revisions
callTool(name: "list_revisions", args: { documentIndex: number }): Promise<ToolResult>
Lists all tracked changes in a DOCX document. Call list_documents first to obtain the document index. Revisions are not currently supported for PDF documents.
Successful result data contains documentIndex, revisionsCount, and a revisions array. Each revision contains its string id, a revisionType of "insertion" or "deletion", nullable author and date values, startSegment, and nullable endSegment.
await tritium.callTool("list_revisions", {
documentIndex: 0,
})
/*
{
output: {
ok: true,
data: {
documentIndex: 0,
revisionsCount: 1,
revisions: [{
id: "2",
revisionType: "insertion",
author: "Alex Morgan",
date: "2026-09-21T10:30:00Z",
startSegment: 1,
endSegment: 2
}]
}
},
displayText: "Read 1 revision(s) from \"contract.docx\"."
}
*/
read_segments
callTool(name: "read_segments", args: { documentIndex: number; startId: number; endId: number }): Promise<ToolResult>
Reads an inclusive range of segments. Successful result data contains documentIndex, the requestedRange, and the matching segments.
await tritium.callTool("read_segments", {
documentIndex: 0,
startId: 10,
endId: 20,
})
/*
{
output: {
ok: true,
data: {
documentIndex: 0,
requestedRange: { startId: 10, endId: 20 },
segments: [
{ id: 10, text: "10. Confidentiality" },
{ id: 11, text: "Each party must keep information confidential." }
]
}
},
displayText: "Read 2 segment(s) from range [10, 20]."
}
*/
search_text
callTool(name: "search_text", args: { query: string; documentIndex?: number }): Promise<ToolResult>
Searches for a case-insensitive substring across every open document, or within one document when documentIndex is supplied. Successful result data contains query, totalMatches, and matching documents and segments.
await tritium.callTool("search_text", {
query: "termination",
documentIndex: 0,
})
/*
{
output: {
ok: true,
data: {
query: "termination",
totalMatches: 1,
documents: [{
index: 0,
filename: "contract.docx",
segments: [{ id: 24, text: "Either party may terminate on 30 days' notice." }]
}]
}
},
displayText: "Found 1 matching segment(s)."
}
*/
close_document
callTool(name: "close_document", args: { documentIndex: number }): Promise<ToolResult>
Closes an open document by its index. Call list_documents first to obtain the current index. Closing a document does not save it first.
await tritium.callTool("close_document", {
documentIndex: 0,
})
/*
{
output: {
ok: true,
data: { status: "accepted", documentIndex: 0 }
},
displayText: "Queued closing document: \"contract.docx\""
}
*/
save_document
callTool(name: "save_document", args: { documentIndex: number }): Promise<ToolResult>
Requests that an open document be saved by its index. Call list_documents first to obtain the current index. In the WebAssembly build, saving a DOCX document with unsaved changes passes the complete file to the callback registered with setSaveHandler.
await tritium.callTool("save_document", {
documentIndex: 0,
})
/*
{
output: {
ok: true,
data: { status: "accepted", documentIndex: 0 }
},
displayText: "Queued saving document: \"contract.docx\""
}
*/
compare_documents
callTool(name: "compare_documents", args: { originalIndex: number; modifiedIndex: number }): Promise<ToolResult>
Requests a redline comparison between two open documents. Successful result data confirms the accepted originalIndex and modifiedIndex.
await tritium.callTool("compare_documents", {
originalIndex: 0,
modifiedIndex: 1,
})
/*
{
output: {
ok: true,
data: { status: "accepted", originalIndex: 0, modifiedIndex: 1 }
},
displayText: "Queued redline comparison: \"contract.docx\" (original) vs \"revised-contract.docx\" (modified)."
}
*/
replace_segment
callTool(name: "replace_segment", args: { documentIndex: number; segmentId: number; newText: string }): Promise<ToolResult>
Replaces the text of one segment. Read the document first to obtain its current segment IDs.
await tritium.callTool("replace_segment", {
documentIndex: 0,
segmentId: 12,
newText: "The replacement paragraph text.",
})
/*
{
output: {
ok: true,
data: { status: "accepted", documentIndex: 0, segmentId: 12, segmentIdsStale: true }
},
displayText: "Queued replacement of segment 12."
}
*/
insert_segment
callTool(name: "insert_segment", args: { documentIndex: number; beforeId: number; text: string }): Promise<ToolResult>
Inserts one segment before beforeId. Use the document's segment count as beforeId to append at the end.
await tritium.callTool("insert_segment", {
documentIndex: 0,
beforeId: 12,
text: "A newly inserted paragraph.",
})
/*
{
output: {
ok: true,
data: { status: "accepted", documentIndex: 0, beforeId: 12, segmentIdsStale: true }
},
displayText: "Queued segment insertion before position 12."
}
*/
delete_segment
callTool(name: "delete_segment", args: { documentIndex: number; segmentId: number }): Promise<ToolResult>
Deletes one segment using its current segment ID.
await tritium.callTool("delete_segment", {
documentIndex: 0,
segmentId: 12,
})
/*
{
output: {
ok: true,
data: { status: "accepted", documentIndex: 0, segmentId: 12, segmentIdsStale: true }
},
displayText: "Queued deletion of segment 12."
}
*/
batch_edit
callTool(name: "batch_edit", args: { documentIndex: number; edits: Array<{ segmentId: number; newText: string }> }): Promise<ToolResult>
Replaces several segments in one operation. Passing an empty edits array succeeds as a no-op.
await tritium.callTool("batch_edit", {
documentIndex: 0,
edits: [
{ segmentId: 12, newText: "First replacement." },
{ segmentId: 15, newText: "Second replacement." },
],
})
/*
{
output: {
ok: true,
data: { status: "accepted", documentIndex: 0, editCount: 2, segmentIdsStale: true }
},
displayText: "Queued 2 edit(s) for document 0."
}
*/
create_document
callTool(name: "create_document", args: { filename: string; segments: string[] }): Promise<ToolResult>
Creates a DOCX document. Each string in segments becomes one document segment, and at least one segment is required.
await tritium.callTool("create_document", {
filename: "draft.docx",
segments: ["Draft agreement", "1. Definitions", "2. Term"],
})
/*
{
output: {
ok: true,
data: { status: "accepted", filename: "draft.docx", segmentCount: 3 }
},
displayText: "Queued creation of \"draft.docx\" with 3 segment(s)."
}
*/
draft_section
callTool(name: "draft_section", args: { documentIndex: number; beforeId: number; segments: string[] }): Promise<ToolResult>
Inserts several new segments before beforeId. Use the current segment count to append the section at the end.
await tritium.callTool("draft_section", {
documentIndex: 0,
beforeId: 12,
segments: ["3. Confidentiality", "Each party must keep information confidential."],
})
/*
{
output: {
ok: true,
data: {
status: "accepted",
documentIndex: 0,
beforeId: 12,
segmentCount: 2,
segmentIdsStale: true
}
},
displayText: "Queued 2 drafted segment(s) at position 12 in document 0."
}
*/
Segment IDs are positional identifiers for the document state returned by read_document or read_segments. After an edit succeeds with segmentIdsStale: true, read the document again before making another segment-based call.
TypeScript Declarations
TypeScript declarations are available at https://tritium.legal/static/init.d.ts
Download the declaration file into your project, for example:
curl -fsSL https://tritium.legal/static/init.d.ts -o src/types/init.d.ts
Then, add it to your tsconfig.json:
{
"compilerOptions": {
"paths": {
"https://tritium.legal/static/init.js": [
"./src/types/init.d.ts"
]
}
}
}