Skip to content

Reference / SDK

Edit and review

Read, edit, approve, reject and retranslate one key, read values in bulk or page by page, or review and retranslate many at once.

Single-key operations

These are the seams Verbatra Studio drives; use them to build your own review tooling. Those that take a locale and a key resolve them fresh on every call and throw UNKNOWN_LOCALE or UNKNOWN_KEY when either does not exist.

keyValue Available from 0.5.0

Reads one key's current source value and, when present, its current target value for one locale. Read-only.

Signature
function keyValue(
  input: KeyValueInput,
  deps?: KeyValueDeps,
): Promise<KeyValueResult>;

Prop

Type

Returns: KeyValueResult

Throws: UNKNOWN_FORMAT, UNKNOWN_LOCALE, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, UNKNOWN_KEY

Example: Edit and retranslate a single key

Returns { source, target? }; target is absent exactly when the key does not yet exist in that locale, and when present comes with provenance, the key's interpreted KeyProvenance: { origin, provider?, model?, reviewState, reviewer? }.

Available from 0.12.0

The result also carries description when the source file gives the key one: an ARB @key.description, an XLIFF note, or a gettext, Apple .strings or .NET .resx comment.

keyContext Available from 0.12.0

Reads what a translator needs to write one key in one target locale: everything keyValue returns, plus the glossary terms that apply to the source text and the key's maxLength. Pass a draft to check it against those terms. Read-only. To re-read a file-backed glossary from disk, it takes loaded from loadConfigWithMeta, not a bare config.

Signature
function keyContext(
  input: KeyContextInput,
  deps?: KeyContextDeps,
): Promise<KeyContext>;

Prop

Type

Returns: KeyContext

Throws: UNKNOWN_FORMAT, UNKNOWN_LOCALE, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, UNKNOWN_KEY

An unreadable glossary does not throw: glossary is empty and glossaryNotice carries the error's code and redacted message. draftCheck says, per applying term, whether the draft uses the required translation and which forbidden renderings it uses.

localeHistory Available from 0.12.0

Lists the recent git commits that touched the source or a target locale file, newest first. Read-only; it runs git log through the injectable execFile.

Signature
function localeHistory(
  input: LocaleHistoryInput,
  deps?: LocaleHistoryDeps,
): Promise<LocaleHistoryResult>;

Prop

Type

Returns: LocaleHistoryResult

Throws: LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION

Each commit carries hash, author (the name after .mailmap, never the email), authorDate, subject and touchedPaths. limit defaults to LOCALE_HISTORY_LIMIT_DEFAULT (50), capped at LOCALE_HISTORY_LIMIT_CAP (200), rounded down and at least 1. Control and bidirectional formatting characters are stripped from author and subject; a commit whose metadata does not parse is left out. Without git or a repository, or when git log exceeds LOCALE_HISTORY_TIMEOUT_MS or LOCALE_HISTORY_MAX_OUTPUT_BYTES, the result is { available: false, reason }, a reason from LOCALE_HISTORY_UNAVAILABLE_REASONS. See Studio and MCP.

editEntry Available from 0.5.0

Writes one human-typed correction for one key and locale. The candidate value passes the same integrity gate as a provider translation before anything reaches disk; on acceptance the locale file and the lock entry for that key are updated inside the locale's write lock. Never calls a provider.

Signature
function editEntry(
  input: EditEntryInput,
  deps?: EditEntryDeps,
): Promise<EditEntryResult>;

Prop

Type

Returns: EditEntryResult

Throws: UNKNOWN_FORMAT, UNKNOWN_LOCALE, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, UNKNOWN_KEY, KEY_PINNED, LOCK_CONTENDED, RUN_CANCELLED, TARGET_UNWRITABLE, LOCALE_STATE_NOT_CARRIED_OVER, LOCK_TIMEOUT_INVALID, LOCK_FILE_INVALID, PROVENANCE_FILE_INVALID

Example: Edit and retranslate a single key

Returns { accepted: true, value }, or { accepted: false, reason: "placeholder" | "markup" | "icu" | "degenerate" | "empty", value } with nothing written (the integrity gate). Build any schema over the reasons from the exported INTEGRITY_GATE_REASONS tuple. "empty" refuses a blank value for a source that has text; clear a key with the workbook's [[CLEAR]] sentinel instead. A placeholder or markup refusal also carries details: each placeholder or tag behind it, prefixed - when the candidate dropped it or + when it invented it.

The value is recorded in verbatra.provenance.json with the origin human; pass actor: "agent" when an AI agent wrote it, so the record says so (the caller asserts it, nothing verifies it). A corrupt provenance file throws PROVENANCE_FILE_INVALID before the value is gated and nothing is written; one from a newer verbatra, or one the record would grow past the size verbatra reads back, is left untouched and the value is written without a record.

Available from 0.12.0

With actor: "agent", a key matching the config's pinnedKeys throws KEY_PINNED before anything is written. A person's edit of a pinned key is accepted.

Available from 0.12.0

lockAcquireTimeoutMs bounds the wait for the locale's write lock before the call fails with LOCK_CONTENDED (ten minutes by default), onLockWait reports that wait, and an invalid bound fails with LOCK_TIMEOUT_INVALID before anything is read.

retranslateEntry Available from 0.5.0

Re-runs the provider for exactly one key and locale through the provider path and integrity gate translate uses, and on acceptance writes the locale file and lock entry for that key only.

Signature
function retranslateEntry(
  input: RetranslateEntryInput,
  deps?: RetranslateEntryDeps,
): Promise<RetranslateEntryResult>;

Prop

Type

Returns: RetranslateEntryResult

Throws: MACHINE_TRANSLATION_DISABLED, LOCK_TIMEOUT_INVALID, UNKNOWN_FORMAT, UNKNOWN_LOCALE, LOCALE_UNSUPPORTED_BY_PROVIDER, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, UNKNOWN_KEY, KEY_PINNED, KEY_PROTECTED, PROVIDER_CONSTRUCTION_FAILED, NETWORK_POLICY_VIOLATION, CONFIG_INVALID, LOCK_CONTENDED, RUN_CANCELLED, TARGET_UNWRITABLE, LOCALE_STATE_NOT_CARRIED_OVER, LOCK_FILE_INVALID, PROVENANCE_FILE_INVALID, SENSITIVE_CONTENT_WITHHELD

Example: Edit and retranslate a single key

Returns { accepted: true, value, reviewReasons } (the review reason codes of the new value) or the refusal editEntry returns. Unlike translate, a provider failure here throws: a ProviderError, exported from @verbatra/sdk, with a stable code such as RATE_LIMITED or AUTH_FAILED. Under provider: { id: "none" } it throws MACHINE_TRANSLATION_DISABLED first, before reading or locking anything.

The new value is recorded in verbatra.provenance.json as machine, with the id of the provider that answered and the configured model. A provider from your own createProvider is recorded under its own id, and without the model when that id differs from the configured one. A corrupt provenance file throws PROVENANCE_FILE_INVALID before the provider is called.

Available from 0.12.0

A key whose value a person wrote, imported, or changed outside verbatra throws KEY_PROTECTED inside the write lock, before the provider is called, unless includeHuman: true is passed or the config sets humanEdits: "overwrite"; under a provenance file from a newer verbatra, any existing value counts as protected. A key matching pinnedKeys throws KEY_PINNED before the provider is constructed, even with includeHuman.

approveEntry Available from 0.12.0

Records that a person reviewed one key's current value in one locale and accepts it. It writes only verbatra.provenance.json, never a locale file or the lock file, and calls no provider. The approval also stores the lock file's source hash for the key, so it reads as unreviewed again once the source changes; any later write that changes the value starts a fresh, unreviewed record.

Signature
function approveEntry(
  input: ReviewDecisionInput,
  deps?: ReviewDecisionDeps,
): Promise<ReviewDecisionResult>;

Prop

Type

Returns: ReviewDecisionResult

Throws: REVIEWER_INVALID, LOCK_TIMEOUT_INVALID, UNKNOWN_FORMAT, UNKNOWN_LOCALE, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, UNKNOWN_KEY, LOCK_CONTENDED, RUN_CANCELLED, REVIEW_VALUE_CHANGED, LOCALE_STATE_NOT_CARRIED_OVER, REVIEW_SOURCE_CHANGED, LOCK_FILE_INVALID, PROVENANCE_FILE_INVALID, PROVENANCE_FILE_UNWRITABLE

Example: Work through the review queue

expectedValue is the text the reviewer saw, or pass expectedValueHash with the valueMarker that produced it: the call throws REVIEW_VALUE_CHANGED when the key has no value or a different one, and REVIEW_SOURCE_CHANGED when the source changed since the value was written. reviewer is optional free text of 1 to 64 characters with no control characters (REVIEWER_INVALID otherwise), stored in the committed file and never filled in by verbatra. Returns { locale, key, provenance }. A value with no record yet, or one changed outside verbatra, is recorded with the origin unknown.

rejectEntry Available from 0.12.0

Records that a person reviewed one key's current value in one locale and refuses it, and removes it from the locale file and the lock file, so check and diff report it missing and the next translate fills it again (under provider: { id: "none" } it stays missing until someone writes one). The provenance record stays as rejected with a hash of the removed text, and this machine's matching memory entry is dropped; a later translate skips any exact or fuzzy memory hit for the key matching that hash, so no machine's memory brings the text back. Calls no provider.

Signature
function rejectEntry(
  input: ReviewDecisionInput,
  deps?: ReviewDecisionDeps,
): Promise<ReviewDecisionResult>;

Prop

Type

Returns: ReviewDecisionResult

Throws: REVIEWER_INVALID, LOCK_TIMEOUT_INVALID, UNKNOWN_FORMAT, UNKNOWN_LOCALE, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, UNKNOWN_KEY, LOCK_CONTENDED, RUN_CANCELLED, REVIEW_VALUE_CHANGED, LOCALE_STATE_NOT_CARRIED_OVER, TARGET_UNWRITABLE, REVIEW_REJECT_UNSUPPORTED, REVIEW_RESTORE_FAILED, LOCK_FILE_INVALID, PROVENANCE_FILE_INVALID, PROVENANCE_FILE_UNWRITABLE

Example: Work through the review queue

The input is checked like approveEntry, except that a stale source does not block a rejection. Returns { locale, key, provenance }. A format that keeps a key it was not given, XLIFF, throws REVIEW_REJECT_UNSUPPORTED after restoring the file.

Both calls take the locale's write lock with lockAcquireTimeoutMs and onLockWait as in editEntry; LOCK_TIMEOUT_INVALID means the bound is not a whole number of milliseconds of at least 0. The timeout does not bound the lock-file guard taken to record the decision, which always allows the ten-minute default.

Neither reports a decision it could not save: a provenance file from a newer verbatra, or one the decision would grow past the size verbatra reads back, throws PROVENANCE_FILE_UNWRITABLE before anything is written.

createValueMarker Available from 0.12.0

Creates the marker a surface uses to show a value without its text: mark(value) returns [redacted length=<n> hash=<h>], and hash(value) returns h, a 16-digit hex HMAC keyed with a random salt (or the given salt), so a hash matches only under the same marker. Pass that marker as valueMarker to approveEntry or rejectEntry to accept expectedValueHash in place of expectedValue. verbatra mcp --redact-values creates one per server start.

Signature
function createValueMarker(salt?: Uint8Array): ValueMarker;

Returns: ValueMarker

Bulk content reads Available from 0.10.0

localeValues

Reads every key's current source and target text across the requested target locales in one pass over the files on disk, for instance to search values rather than key names: the bulk counterpart to keyValue. Read-only.

Signature
function localeValues(
  input: LocaleValuesInput,
  deps?: LocaleValuesDeps,
): Promise<readonly LocaleValues[]>;

Prop

Type

Returns: readonly LocaleValues[]

Throws: UNKNOWN_FORMAT, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, UNKNOWN_LOCALE

Example: Read every value in bulk

An omitted locales covers every configured target locale. Returns one { locale, keys, values } per locale: keys lists every key in source order, then the target-only ones, and values maps each key to { source?, target? }. No target means not yet translated there; no source means orphaned (gone from the source). values has no prototype, so every key, even __proto__ or constructor, is an own property and an absent key reads as undefined.

Each pair with a target also carries provenance, the same KeyProvenance keyValue reports.

localeValuesPage Available from 0.12.0

Reads one page of localeValues, optionally narrowed to exact keys or to a query matched against key, source and target text, ignoring case, and returns a cursor for the next page. The MCP server and Studio's verbatra_locale_values agent tool page with it. Read-only.

Signature
function localeValuesPage(
  input: LocaleValuesPageInput,
  deps?: LocaleValuesDeps,
): Promise<LocaleValuesPage>;

Prop

Type

Returns: LocaleValuesPage

Throws: UNKNOWN_FORMAT, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, UNKNOWN_LOCALE, PAGE_CURSOR_INVALID, PAGE_LIMIT_INVALID

Returns { locales, nextCursor? }: each locale with an entry on the page carries entries, each { key, source?, target?, provenance? } as localeValues reports it, ordered by locale and then by key. A page holds at most limit entries: PAGE_LIMIT_DEFAULT (200) by default, PAGE_LIMIT_CAP (1000) at most. Pass nextCursor back as cursor, with the same filters, until it is absent. Every call reads the files again, so a cursor whose key moved or is gone is refused rather than skipping or repeating entries.

A cursor is at most PAGE_CURSOR_MAX_LENGTH (512) characters. The MCP server and Studio accept a query of at most LOCALE_VALUES_QUERY_MAX_LENGTH (500) characters.

Batch review and retranslation Available from 0.12.0

Each of these runs the matching single-key call once per entry, in order, and returns { results } with one outcome per entry. A failed entry does not stop the batch: its outcome is { locale, key, ok: false, code, message }, with the code of the SdkError, adapter error, or ProviderError and a redacted message. Any other error stops the batch with a BatchInterruptedError. An empty entries list returns an empty results.

approveEntries

Runs approveEntry per entry with the same checks; reviewer applies to every entry. A successful outcome is { ok: true, locale, key, provenance }. lockAcquireTimeoutMs bounds each entry's wait for its locale's write lock, and onLockWait reports that wait. An entry whose lock stays taken past the timeout fails with LOCK_CONTENDED, and every later entry that needs the same lock gets { locale, key, ok: false, skipped: true, code: "LOCK_CONTENDED", message } instead of waiting again; entries of other locales are still decided.

Signature
function approveEntries(
  input: ReviewEntriesInput,
  deps?: ReviewDecisionDeps,
): Promise<ReviewEntriesResult>;

Prop

Type

Returns: ReviewEntriesResult

Throws: LOCK_TIMEOUT_INVALID

rejectEntries

Runs rejectEntry per entry, removing each rejected value. A successful outcome is { ok: true, locale, key, provenance }. A lock timeout skips the later entries needing that lock, as in approveEntries.

Signature
function rejectEntries(
  input: ReviewEntriesInput,
  deps?: ReviewDecisionDeps,
): Promise<ReviewEntriesResult>;

Prop

Type

Returns: ReviewEntriesResult

Throws: LOCK_TIMEOUT_INVALID

approveLocale Available from 0.12.0

Approves a locale's whole review queue, or only its values with one of origins, in one write of verbatra.provenance.json under the locale's write lock, each recorded as approveEntry records one. It takes no expected value and approves what the queue holds when it runs, so show the reviewer the queue first. Returns { locale, approved, sourceChanged }: the keys approved, and the queued keys left unreviewed because their source changed since they were written. Calls no provider, and fails with PROVENANCE_FILE_UNWRITABLE rather than report approvals it could not save.

Signature
function approveLocale(
  input: ApproveLocaleInput,
  deps?: ApproveLocaleDeps,
): Promise<ApproveLocaleResult>;

Prop

Type

Returns: ApproveLocaleResult

Throws: REVIEWER_INVALID, LOCK_TIMEOUT_INVALID, UNKNOWN_FORMAT, UNKNOWN_LOCALE, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, LOCK_CONTENDED, RUN_CANCELLED, LOCALE_STATE_NOT_CARRIED_OVER, LOCK_FILE_INVALID, PROVENANCE_FILE_INVALID, PROVENANCE_FILE_UNWRITABLE

retranslateEntries

Runs retranslateEntry per entry, so it makes up to one provider call per entry. It is not a translate run: maxTokens and budgetBehavior do not apply, and the number of entries is the only bound on what it spends. A completed outcome is { ok: true, locale, key, result }, where result is what retranslateEntry returned, including a value the integrity gate refused. A value a person wrote fails with KEY_PROTECTED unless includeHuman: true is passed. The lock options work as in approveEntries, and the wait ends before the provider is called.

Signature
function retranslateEntries(
  input: RetranslateEntriesInput,
  deps?: RetranslateEntryDeps,
): Promise<RetranslateEntriesResult>;

Prop

Type

Returns: RetranslateEntriesResult

Throws: LOCK_TIMEOUT_INVALID

Available from 0.12.0

An error that would fail every entry alike stops the provider calls: MISSING_API_KEY, AUTH_FAILED, RATE_LIMITED (which covers an exhausted quota), NETWORK_POLICY_VIOLATION, PROVIDER_CONSTRUCTION_FAILED, CONFIG_INVALID, or MACHINE_TRANSLATION_DISABLED. The entry that hit it fails as usual, and every entry after it gets { locale, key, ok: false, skipped: true, code, message } naming that code, without another provider call.

A lock timeout skips the later entries needing that lock with LOCK_CONTENDED, as in approveEntries; for a format that keeps all locales in one file, that is every later entry.

BatchInterruptedError Available from 0.12.0

Thrown by approveEntries, rejectEntries, and retranslateEntries when an error that is not the outcome of one entry, such as an unexpected file-system failure, stops a batch part way. results holds the outcomes of the entries completed before it, in order, whose writes stay on disk; entry names the { locale, key } that was running, and cause is the original error. Entries after entry did not run.

Signature
class BatchInterruptedError<R = ReviewBatchOutcome | RetranslateBatchOutcome> extends Error

Prop

Type

Edit on GitHub

On this page