Reference / SDK
RunSummary
What translate, importWorkbook and watch resolve to, field by field, so a script can read the usage and notices of a run.
The RunSummary anatomy
translate, importWorkbook, and each successful watch run resolve to a RunSummary:
interface RunSummary {
dryRun: boolean; // true when nothing was written and no provider was called
locales: LocaleSummary[]; // one entry per target locale, in config order
succeeded: string[]; // locales whose run succeeded
partial: string[]; // locales written with keys still missing; the CLI exits 1 on these
failed: string[]; // locales whose run failed
usage?: UsageSummary; // summed input/output tokens; absent when no call reported usage
budget?: RunBudget; // present when maxTokens is configured or passed to the run
estimate?: RunEstimate; // present only when the run was asked for a pre-run estimate
cancelled?: true; // present only when the run's signal aborted it
}
interface LocaleSummary {
locale: string;
status: "succeeded" | "partial" | "failed";
translated: string[]; // keys translated this run (in dry-run, keys that would be)
cacheHits: string[]; // keys served from the translation-memory cache this run
fuzzyHits: FuzzyCacheHit[]; // reuses for a source string that changed, with their scores
unchanged: string[]; // keys already up to date
orphaned: string[]; // target keys with no matching source key (always reported)
pruned: string[]; // orphaned keys removed this run; empty unless pruning is on
invalidIcuSource: string[]; // source keys skipped for invalid ICU
emptySource?: string[]; // source keys with an empty value; nothing is sent or written for them
integrityMismatches: string[]; // translations the integrity gate withheld
integrityRefusals?: { key: string; reason: string; details?: string[] }[]; // why each was withheld; translate, watch, and importWorkbook
providerFailures: string[]; // keys withheld because nothing was translated for them
budgetWithheld: string[]; // keys never sent because a "stop" budget already tripped
sensitiveWithheld: string[]; // keys sensitiveData kept from the provider (block or redact)
generated: string[]; // CLDR plural forms synthesized this run
unfilled: string[]; // blank import rows, or keys a human-only translate left for a human
protected: { key: string; reason: string; suggestion?: string; suggestionStatus?: string }[]; // keys left for a person
malformedRows: { row: number; line?: number; column: string }[]; // import only: rows the reader could not parse
duplicateKeys: { key: string; row: number; line?: number }[]; // import only: later rows for a duplicated key
notices: LocaleNotice[]; // provider notices and SDK notices for this locale
needsReview: { key: string; reasons: string[] }[]; // accepted keys flagged for a second look
usage?: UsageSummary; // this locale's summed tokens; absent if nothing reported usage
error?: { code: string; message: string }; // only on a "failed" locale, and not on every one
}The parts worth knowing:
- needsReview lists accepted, written keys the review heuristics flagged, each with its reason
codes, listed and explained under Review flags. The set
ships as the
REVIEW_tuple, so build any runtime schema or exhaustive lookup from that rather than retyping the members. A review flag is advisory and never withholds a key, so a key never appears in bothREASON_ CODES needsReviewandintegrityMismatches. See Review in Studio for working the queue. - notices live per locale, never at the top level. They cover provider notices (say, a DeepL
degradation), listed under Provider notices, and SDK
notices, whose codes form the
SdkNoticeCodeunion and are explained under Run notices. A run-wide notice, such as the cache notice (one file, shared by every locale), is attached to each locale in the run. - usage is
undefined, never a fabricated zero, whenever nothing in that scope reported usage: a dry run never calls a provider, and DeepL never reports tokens.RunSummary.usageis the sum over the locales. - budget appears only when
maxTokensis configured or passed to the run:{ maxTokens, behavior, supported, tokensUsed, exceeded }.supportedsays whethertokensUsedis entirely the provider's own reported usage; it isfalseas soon as one request came back without a usable figure, and the total is then partly verbatra's projection, which is counted and enforced just the same. A dry run, or any run that sent no request, reportssupported: truewithtokensUsed: 0: nothing was sent, so nothing was projected. Underbehavior: "stop"the ceiling is checked before every request the run sends, each half of a re-split request included, sotokensUsedlands at or belowmaxTokensapart from one residual: the last request admitted is reconciled to what the provider reported, which can push the total past the ceiling after the fact. Nothing further is sent once it does. Two things sit outside what a reservation can bound, because they happen inside a request it already admitted: the provider layer sends one repair call of its own when keys come back missing, so one admitted batch can cost up to about twice its projection, and the count is only as good as what the provider reports. Both land at reconciliation, and nothing further is admitted once they do. The budget bounds onetranslatecall:watchstarts a fresh one per run, andretranslateEntryis not covered by it at all. - error.code on a failed locale is a preserved string (the underlying provider or adapter code,
with
LOCALE_only as a fallback), so do not treat it as a closed set. AFAILED failedlocale does not always carryerror: one whose every key was withheld, and so listed inintegrityMismatches,providerFailures, orbudgetWithheld, fails with nothing thrown. Its reason is in those lists and in itsnotices, such asSUB_for a failed provider batch orBATCH_ FAILED BUDGET_for the token budget. TestTOKENS_ EXCEEDED status, never the presence oferror. - cancelled appears only when the run's
signalaborted it.RUN_says what that leaves behind.CANCELLED - estimate appears only when the run was asked for a pre-run estimate. Its
caveatslist is never empty and names what the figure leaves out, asEstimateCaveatCodemembers:CACHE_: the translation memory is not read, so keys a live run would serve from the cache are still counted. Applies to every estimate.NOT_ CONSULTED SOURCE_: a live run sends one representative per identical source string; the estimate counts every key. Applies to every estimate.DUPLICATES_ NOT_ DEDUPLICATED TRANSPORT_: one billable call is counted per planned request, although the provider SDKs may retry a failed call underneath it and a retried attempt can still be billed. Applies to every estimate.RETRIES_ NOT_ COUNTED TRANSLATION_: the response is sized from the source plus a fixed expansion allowance, so a target language that runs longer reports more completion tokens. Token-billed providers only.LENGTH_ IS_ ESTIMATED TOKEN_: tokens are derived from character counts, not the provider's own tokenizer. Token-billed providers only.COUNT_ IS_ HEURISTIC REPAIR_: the repair round for keys that came back missing, and the retry in halves for a cut-off response, are not counted. Token-billed providers only.REQUESTS_ NOT_ COUNTED
- cacheHits lists keys served from the translation-memory cache rather than
the provider. fuzzyHits lists the keys that reused a translation for a source string
that had changed, each carrying
key,similarity, and thepreviousSourceit matched; it is empty unlessfuzzyCacheis enabled, and those keys are never counted in cacheHits. unfilled, malformedRows, and duplicateKeys are populated only byimportWorkbook(atranslaterun leaves them empty): a blank row whose key still needs a translation at import time (whether it was exported asnewor aschanged), a workbook row the reader could not parse, and a duplicated key whose first occurrence won. The optionallineon the last two is the file line the record starts on, present only for a delimited (csvortsv) import. The one exception is a human-only project: theretranslateandwatchlist in unfilled every key the translation memory had no exact entry for, and fuzzyHits stays empty because fuzzy reuse is never applied there. - protected lists the keys a
translaterun left alone, each with itsreason(human,import,external, orpinned) and, underhumanEdits: "suggest", asuggestion(the provider's answer or an exact translation-memory entry, never a fuzzy match), which was not written, and asuggestionStatus:plannedon a dry run,suggested, or why not (integrity-mismatch,provider-failure,budget-withheld,sensitive-withheld). A failed suggestion never changes the locale's status. They are not in translated, never change a locale's status, and stay stale forcheck.importWorkbookleaves it empty. See Protecting human translations.
Two of these entry types are exported on their own: each protected entry is a ProtectedKey, and each SDK notice in notices is an SdkNotice.
Prop
Type
Prop
Type
budgetStanding Available from 0.11.0
Classifies a RunBudget into one of three BudgetStanding values, the same classification the CLI
budget line, Studio, and the usage.summary agent tool report: "within" when the run never
reached its ceiling, "stopped-before-ceiling" when a "stop" budget withheld a request while
tokensUsed was still below maxTokens, and "reached" when tokensUsed reached or passed
maxTokens. Use it rather than reading exceeded alone, which is true in both of the last two
cases.
function budgetStanding(budget: RunBudget): BudgetStanding;Returns: BudgetStanding