Models and pricing
Use the Vercel or OpenAI adapter for standard and premium calls.
Choose the adapter that matches your existing model code. Both use the same session, admission checks, and premium settlement lifecycle.
Standard calls with the Vercel AI SDK
import { enlitt, ENLITT_STANDARD_MODEL } from "@enlitt/sdk/vercel";
import { generateText, streamText } from "ai";
// Run inside session middleware, or pass { session } to enlitt().
const model = enlitt(ENLITT_STANDARD_MODEL);
const result = await generateText({ model, prompt: "Explain photosynthesis." });
console.log(result.text);
const stream = streamText({ model, prompt: "Explain photosynthesis." });
for await (const text of stream.textStream) {
process.stdout.write(text);
}The standard model has a minimal, stable contract:
- Text input and output, with streaming or non-streaming responses.
- Bounded PNG and JPEG image input.
- Automatic function tools, with calls and results across steps; omitting tools disables tool calling.
- Output-token limits, cancellation, normalized usage, and a finish reason.
- At least 131,072 context tokens and 32,768 output tokens.
The SDK rejects locally unsupported standard options: forced tool choice, structured-output enforcement, sampling and parallel-tool controls, files, audio/video input, reasoning controls, and provider-specific options. The standard identifier does not promise every feature of either adapter's underlying SDK.
Premium calls with the Vercel AI SDK
Wrap a provider model you already configure and pay for. The example accepts that model so it does not assume a particular provider or model name:
import { enlitt, type EnlittTarget } from "@enlitt/sdk/vercel";
import { generateText } from "ai";
type ProviderModel = Exclude<EnlittTarget, string>;
export async function summarize(myProviderModel: ProviderModel, prompt: string) {
return generateText({
model: enlitt(myProviderModel),
prompt,
providerOptions: {
enlitt: {
maxCharge: "10000000", // Reserve up to $0.01, subject to the user's limits.
price: "5000000" // Charge $0.005 on completion or cancellation.
}
}
});
}Enlitt checks the session and spending capacity before invoking your provider. If admission succeeds, your server calls the provider directly. You still supply and pay for the provider credentials. A failed provider call charges the user zero; provider errors propagate to your code unchanged.
Maximum and actual price
All monetary inputs are NANOUSD integer strings: "1000000000" is $1,
"10000000" is $0.01, and "0" is valid. Use BigInt for arithmetic;
never send decimals, signs, exponent notation, or leading zeros.
| Options | Behavior |
|---|---|
Constant price only | The maximum defaults to that price. |
maxCharge and constant price | Reserves the maximum; charges the constant, capped by the effective maximum. The constant cannot exceed your declared maximum. |
maxCharge and function price | Runs the function once on completion or cancellation and caps its result. |
maxCharge without price | Accounts the call but charges zero. |
Function price without maxCharge, or neither field | Rejected before a network request. |
The old charge object is unsupported. Use maxCharge and price instead.
Both are forbidden on standard calls.
For token-based pricing, supply rates in NANOUSD per token. These example rates are illustrative, not a provider price list:
import { perToken } from "@enlitt/sdk/vercel";
const pricing = {
maxCharge: "10000000",
price: perToken({ input: "100", output: "200" })
};
// Pass pricing as providerOptions.enlitt on your premium AI SDK call.perToken multiplies total input and output token counts using exact integer
arithmetic. Missing usage counts as zero. Cached and reasoning tokens are
included in the corresponding totals. A custom function receives usage,
output, timing, status, and effectiveMaxChargeNanoUsd in your server process.
It never runs for failed calls. If pricing throws or returns an invalid value,
the charge is zero and onTerminalReportError receives the error.
OpenAI Responses adapter
The standard path needs no OpenAI provider client:
import { enlitt, ENLITT_STANDARD_MODEL } from "@enlitt/sdk/openai";
const client = enlitt();
const response = await client.responses.create({
model: ENLITT_STANDARD_MODEL,
input: "Explain photosynthesis."
});
console.log(response.output_text);For premium, wrap your existing official OpenAI client. Set the example
OPENAI_MODEL environment variable to a model available to your provider account:
import OpenAI from "openai";
import { enlitt } from "@enlitt/sdk/openai";
const model = process.env.OPENAI_MODEL;
if (!model) throw new Error("Set OPENAI_MODEL on the server");
// OpenAI reads your server's OPENAI_API_KEY; Enlitt reads ENLITT_SECRET_KEY.
const client = enlitt(new OpenAI());
const response = await client.responses.create({
model,
input: "Summarize this support ticket.",
enlitt: { maxCharge: "10000000", price: "5000000" }
});
console.log(response.output_text);This adapter supports responses.create() only. It does not expose Chat
Completions, embeddings, images, audio, Realtime, background responses, or
Responses helper methods such as parse, retrieve, and stream.
For streaming, pass stream: true to responses.create() and consume the
returned async iterable with for await. Consume or cancel streams so their
terminal outcome can be reported. await and for await are supported;
OpenAI's .withResponse() and stream helper objects are not.
Call options and reporting
Both adapters accept construction options for secretKey, baseUrl,
session, rateLimit, and onTerminalReportError. The key defaults to
ENLITT_SECRET_KEY; baseUrl defaults to ENLITT_BASE_URL, then the deployed
API origin, and must use HTTPS.
Vercel per-call options go in providerOptions.enlitt; OpenAI per-call options
go in the request's enlitt field. Both support idempotencyKey and string
metadata. Metadata is limited to 16 entries, 64-character keys, and
512-character values; keys cannot start with enlitt_.
Premium calls may set reportingDeadlineMs to allow enough time for generation
and pricing. Enlitt bounds that deadline by server policy. A call that expires
before settlement charges zero. Reporting failure is sent to
onTerminalReportError and does not replace the provider's result or error.
For a direct SDK call or raw HTTP request outside these adapters, use
withPremiumCharge(). See Spending limits
and Idempotency before adding retries.