Enlitt

Idempotency

Every call has one identity, safe to retry without double-charging.

Every underlying model invocation made through enlitt() — standard or premium — has exactly one identity, sent as the Idempotency-Key header (and additionally as call_id on the premium preflight). Retrying the identical step reuses that identity; the wire deduplicates on it, so a retried call never charges, reserves, or invokes a provider twice for the same step.

Supplying your own key

await generateText({
  model: enlitt(ENLITT_STANDARD_MODEL),
  prompt,
  providerOptions: {
    enlitt: {
      idempotencyKey: "ticket-42-summary-attempt"
    }
  }
});

idempotencyKey must be 16–200 visible ASCII characters. Supply your own key when you already have a natural, stable identifier for the logical operation being retried (a job ID, a request ID your own system generated). Omit it and the SDK generates a fresh crypto.randomUUID() base per invocation.

Why a key is a base, not the final identity

The SDK never sends your key unchanged. It appends the number of items in the call's prompt — never a hash or any other read of your content — producing `${base}.${promptItemCount}` as the final identity. This is what makes identity behave correctly inside a tool-calling loop: within one generateText run, the prompt grows by at least one item before each subsequent model invocation, so distinct steps of the same loop get distinct identities automatically, while a genuine retry of one step — which re-presents the identical prompt — reuses the same identity and is deduplicated.

This means you do not need to generate a new key per retry, and should not: the point of supplying a base at all is that the same base, retried, collapses to the same call. Generating a fresh key on every attempt (for example, inside the function that performs the retry, rather than once before the retry loop begins) defeats the protection entirely and is the one mistake this mechanism exists to prevent.

Where else idempotency applies

Frontend's own dashboard mutations (creating an application, creating or rotating an API key) follow the identical pattern at the HTTP layer: a key is generated once on the client, cached against the specific thing being mutated, reused across retries of that one action until it succeeds, and only then discarded. Account closure and authorization revocation are idempotent by construction and take no key at all — retrying either one is always safe without any header.

On this page