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_ or UNKNOWN_ 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.
function keyValue(
input: KeyValueInput,
deps?: KeyValueDeps,
): Promise<KeyValueResult>;Prop
Type
Returns: KeyValueResult
Throws: UNKNOWN_, UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, UNKNOWN_
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? }.
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.
function keyContext(
input: KeyContextInput,
deps?: KeyContextDeps,
): Promise<KeyContext>;Prop
Type
Returns: KeyContext
Throws: UNKNOWN_, UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, UNKNOWN_
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.
function localeHistory(
input: LocaleHistoryInput,
deps?: LocaleHistoryDeps,
): Promise<LocaleHistoryResult>;Prop
Type
Returns: LocaleHistoryResult
Throws: LOCALE_, LOCALE_
Each commit carries hash, author (the name after .mailmap, never the email), authorDate, subject and touchedPaths. limit defaults to LOCALE_ (50), capped at LOCALE_ (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_ or LOCALE_, the result is { available: false, reason }, a reason from LOCALE_. 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.
function editEntry(
input: EditEntryInput,
deps?: EditEntryDeps,
): Promise<EditEntryResult>;Prop
Type
Returns: EditEntryResult
Throws: UNKNOWN_, UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, UNKNOWN_, KEY_, LOCK_, RUN_, TARGET_, LOCALE_, LOCK_, LOCK_, PROVENANCE_
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_ 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_ 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.
With actor: "agent", a key matching the config's pinnedKeys throws KEY_ before anything is written. A person's edit of a pinned key is accepted.
lockAcquireTimeoutMs bounds the wait for the locale's write lock before the call fails with LOCK_ (ten minutes by default), onLockWait reports that wait, and an invalid bound fails with LOCK_ 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.
function retranslateEntry(
input: RetranslateEntryInput,
deps?: RetranslateEntryDeps,
): Promise<RetranslateEntryResult>;Prop
Type
Returns: RetranslateEntryResult
Throws: MACHINE_, LOCK_, UNKNOWN_, UNKNOWN_, LOCALE_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, UNKNOWN_, KEY_, KEY_, PROVIDER_, NETWORK_, CONFIG_, LOCK_, RUN_, TARGET_, LOCALE_, LOCK_, PROVENANCE_, SENSITIVE_
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_ or AUTH_. Under provider: { id: "none" } it throws MACHINE_ 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_ before the provider is called.
A key whose value a person wrote, imported, or changed outside verbatra throws KEY_ 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_ 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.
function approveEntry(
input: ReviewDecisionInput,
deps?: ReviewDecisionDeps,
): Promise<ReviewDecisionResult>;Prop
Type
Returns: ReviewDecisionResult
Throws: REVIEWER_, LOCK_, UNKNOWN_, UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, UNKNOWN_, LOCK_, RUN_, REVIEW_, LOCALE_, REVIEW_, LOCK_, PROVENANCE_, PROVENANCE_
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_ when the key has no value or a different one,
and REVIEW_ when the source changed since the value was written. reviewer is
optional free text of 1 to 64 characters with no control characters (REVIEWER_
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.
function rejectEntry(
input: ReviewDecisionInput,
deps?: ReviewDecisionDeps,
): Promise<ReviewDecisionResult>;Prop
Type
Returns: ReviewDecisionResult
Throws: REVIEWER_, LOCK_, UNKNOWN_, UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, UNKNOWN_, LOCK_, RUN_, REVIEW_, LOCALE_, TARGET_, REVIEW_, REVIEW_, LOCK_, PROVENANCE_, PROVENANCE_
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_ after
restoring the file.
Both calls take the locale's write lock with lockAcquireTimeoutMs and onLockWait as in
editEntry; LOCK_ 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_ 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.
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.
function localeValues(
input: LocaleValuesInput,
deps?: LocaleValuesDeps,
): Promise<readonly LocaleValues[]>;Prop
Type
Returns: readonly LocaleValues[]
Throws: UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, UNKNOWN_
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 _ 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_ agent tool page with it. Read-only.
function localeValuesPage(
input: LocaleValuesPageInput,
deps?: LocaleValuesDeps,
): Promise<LocaleValuesPage>;Prop
Type
Returns: LocaleValuesPage
Throws: UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, UNKNOWN_, PAGE_, PAGE_
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_ (200) by default, PAGE_ (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_ (512) characters. The MCP server and Studio accept a query of at most LOCALE_ (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_, and every later entry that needs the same lock
gets { locale, key, ok: false, skipped: true, code: "LOCK_ instead of
waiting again; entries of other locales are still decided.
function approveEntries(
input: ReviewEntriesInput,
deps?: ReviewDecisionDeps,
): Promise<ReviewEntriesResult>;Prop
Type
Returns: ReviewEntriesResult
Throws: LOCK_
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.
function rejectEntries(
input: ReviewEntriesInput,
deps?: ReviewDecisionDeps,
): Promise<ReviewEntriesResult>;Prop
Type
Returns: ReviewEntriesResult
Throws: LOCK_
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_ rather than report approvals it could not save.
function approveLocale(
input: ApproveLocaleInput,
deps?: ApproveLocaleDeps,
): Promise<ApproveLocaleResult>;Prop
Type
Returns: ApproveLocaleResult
Throws: REVIEWER_, LOCK_, UNKNOWN_, UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, LOCK_, RUN_, LOCALE_, LOCK_, PROVENANCE_, PROVENANCE_
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_ unless includeHuman: true is passed. The lock options
work as in approveEntries, and the wait ends before the provider is called.
function retranslateEntries(
input: RetranslateEntriesInput,
deps?: RetranslateEntryDeps,
): Promise<RetranslateEntriesResult>;Prop
Type
Returns: RetranslateEntriesResult
Throws: LOCK_
An error that would fail every entry alike stops the provider calls: MISSING_,
AUTH_, RATE_ (which covers an exhausted quota), NETWORK_,
PROVIDER_, CONFIG_, or MACHINE_. 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_, 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.
class BatchInterruptedError<R = ReviewBatchOutcome | RetranslateBatchOutcome> extends ErrorProp
Type