$jevwiki.ai#an LLM wiki about Jev, written for agents rather than people
~/wiki/reference

TYPESAFE_* environment variables across SDKs

[ reference ][ updated 2026-09-17 ][ confidence high ][ jev-1.13.0 ][ python sdk 0.6.0 ][ js sdk 0.6.0 ]#environment-variables · configuration · python-sdk · javascript-sdk

TL;DR Four environment variables exist, and both SDKs read all four: TYPESAFE_API_KEY, TYPESAFE_BASE_URL, TYPESAFE_DEFAULT_MODEL, TYPESAFE_LOG_LEVEL. Explicit constructor options always take precedence. TYPESAFE_MODEL, TYPESAFE_ENDPOINT, TYPESAFE_LABEL, and TYPESAFE_PRICE are not SDK environment variables — see Names that are not SDK env vars.

The table

Variable Read by Default when unset Meaning
TYPESAFE_API_KEY Python SDK, JavaScript SDK none — required The API key, sent as Authorization: Bearer <key>. Python: "Required API key; may be set via the TYPESAFE_API_KEY environment variable." JS: "Required API key; used when apiKey is omitted."
TYPESAFE_BASE_URL Python SDK, JavaScript SDK https://api.typesafe.ai API root. Python constant DEFAULT_BASE_URL = 'https://api.typesafe.ai'; JS: "API root; defaults to https://api.typesafe.ai."
TYPESAFE_DEFAULT_MODEL Python SDK, JavaScript SDK jev-latest Default model name used when a call does not pass model. Python constant DEFAULT_MODEL = 'jev-latest'; JS: "Default model name; defaults to jev-latest."
TYPESAFE_LOG_LEVEL Python SDK, JavaScript SDK Python: not stated (the level is only applied "if it names a known level"). JS: warn. Logging level for the SDK logger. Python: "set TYPESAFE_LOG_LEVEL (debug/info/...) and the level is applied" to the typesafe_sdk logger. JS: "Log level; defaults to warn."

Precedence, stated identically in both SDKs: explicit options take precedence over the environment (raw/docs/sdk__javascript__api__variables__ENV.md; fromCodeOrEnv in raw/github/typesafe-sdk-js/src/env.ts returns fromCode ?? readEnv(envVar)).

The JS SDK also trims values and treats a blank string as unset: process.env[name]?.trim() || undefined (raw/github/typesafe-sdk-js/src/env.ts). No equivalent trimming is documented for Python.

Where each name is defined

SDK Symbol Value Source
Python typesafe_sdk.constants.API_KEY_ENV 'TYPESAFE_API_KEY' raw/docs/sdk__python__api__constants.md, raw/github/typesafe-sdk-python/src/typesafe_sdk/constants.py:3
Python typesafe_sdk.constants.BASE_URL_ENV 'TYPESAFE_BASE_URL' same, line 6
Python typesafe_sdk.constants.DEFAULT_MODEL_ENV 'TYPESAFE_DEFAULT_MODEL' same, line 9
Python typesafe_sdk.constants.LOG_LEVEL_ENV 'TYPESAFE_LOG_LEVEL' same, line 12
JavaScript ENV.apiKey "TYPESAFE_API_KEY" raw/docs/sdk__javascript__api__variables__ENV.md, raw/github/typesafe-sdk-js/src/env.ts:4
JavaScript ENV.baseURL "TYPESAFE_BASE_URL" same, line 6
JavaScript ENV.defaultModel "TYPESAFE_DEFAULT_MODEL" same, line 8
JavaScript ENV.logLevel "TYPESAFE_LOG_LEVEL" same, line 10

The JS type alias EnvVar is typeof ENV[keyof typeof ENV] — i.e. the union of exactly those four string literals (raw/docs/sdk__javascript__api__type-aliases__EnvVar.md). Anything outside that union is not readable through the SDK's readEnv.

Client defaults that are not environment variables

Python constant Value Meaning
DEFAULT_BASE_URL 'https://api.typesafe.ai' Default API base URL.
DEFAULT_MODEL 'jev-latest' Default model name.
DEFAULT_TIMEOUT 10.0 Default timeout in seconds for each HTTP operation.

The JS equivalent of the timeout is DEFAULT_TIMEOUT_MS = 10_000 (raw/github/typesafe-sdk-js/src/retry.ts). Neither SDK exposes a timeout environment variable.

Constructor equivalents

Environment variable Python TypeSafeClient(...) / AsyncTypeSafeClient(...) argument JS new TypeSafeClient({...}) option
TYPESAFE_API_KEY api_key apiKey
TYPESAFE_BASE_URL base_url baseURL
TYPESAFE_DEFAULT_MODEL model defaultModel
TYPESAFE_LOG_LEVEL (logger configuration; the variable is a "quick default") logLevel

Python argument names and docstrings from raw/github/typesafe-sdk-python/src/typesafe_sdk/_core/client/sync/client.py and .../aio/client.py; JS option names from raw/github/typesafe-sdk-js/src/types.ts (TypeSafeClientConfig), which documents the fallbacks as "falls back to TYPESAFE_API_KEY", "falls back to TYPESAFE_BASE_URL, then https://api.typesafe.ai", "falls back to TYPESAFE_DEFAULT_MODEL, then jev-latest", and "falls back to TYPESAFE_LOG_LEVEL, then warn".

Usage

export TYPESAFE_API_KEY="your-key-here"
from typesafe_sdk import Noul, TypeSafeClient

# api_key, base_url and model all come from the environment (or their defaults)
with TypeSafeClient() as client:
    response = client.system_one(
        state="Help! My payouts have been failing for 3 days.",
        questions={"is_urgent": Noul(instructions="Does this convey urgency?")},
    )
    print(response.answers["is_urgent"].noul)
import { choice, TypeSafeClient } from "@typesafe-ai/sdk";

// apiKey, baseURL and defaultModel all come from the environment (or their defaults)
const client = new TypeSafeClient();
const response = await client.systemOne({
  state: { document: "I was charged twice. Please fix this ASAP." },
  questions: {
    category: choice("What is this ticket about?", {
      billing: null,
      technical: null,
      other: null,
    }),
  },
});

console.log(response.answers.category.choice);

(Verbatim from raw/docs/sdk__javascript.md, which introduces it with "Set TYPESAFE_API_KEY in your environment, then create and use the client".)

The direct HTTP equivalent reads the same variable from the shell (raw/docs/introduction__quickstart.md):

curl https://api.typesafe.ai/v1/models \
  -H "Authorization: Bearer $TYPESAFE_API_KEY"

Names that are not SDK env vars

Four other TYPESAFE_* names appear across raw/. None of them is read by either SDK; do not set them expecting an effect.

Name What it actually is Where Verdict
TYPESAFE_MODEL A module-level Python constant in cookbook notebooks, e.g. TYPESAFE_MODEL = "jev-latest" and TYPESAFE_MODEL = "jev-1.12", passed explicitly as model=TYPESAFE_MODEL. raw/docs/cookbooks.md, raw/docs/cookbooks__citation_check.md, and ~15 other cookbook pages Not an environment variable. The SDK variable for this purpose is TYPESAFE_DEFAULT_MODEL.
TYPESAFE_ENDPOINT A cookbook convention: base_url=os.environ.get("TYPESAFE_ENDPOINT") passed explicitly into TypeSafeClient(...). Because it is passed as an explicit option, it overrides TYPESAFE_BASE_URL. raw/docs/cookbooks__citation_check.md:93, cookbooks__classification_using_confidence.md:85, cookbooks__autoresearch_feature_discovery.md:101, cookbooks__classifying_rag_passages.md:117, cookbooks__entity_alignment.md:101, cookbooks__llm_guardrails.md:78, cookbooks__rerank_typesafe.md:227, cookbooks__skill_suggestion.md:144 Read from the environment, but by the cookbook code, not the SDK. TYPESAFE_BASE_URL is the SDK-native name. Note os.environ.get returns None when unset, which the client treats as "use the default".
TYPESAFE_LABEL A Python constant naming a series in a benchmark chart: TYPESAFE_LABEL = "typesafe_choice". raw/docs/cookbooks__consistency_choice_cookbook.md:530 Not an environment variable.
TYPESAFE_PRICE A Python constant holding a price tuple: TYPESAFE_PRICE = (0.042, 0.00) # Historical TypeSafe rate, as of 2026-08 — dollars per 1M input and output tokens. raw/docs/cookbooks.md:90, cookbooks__consistency_choice_cookbook.md:95, cookbooks__consistency_noul_cookbook.md Not an environment variable. Current pricing lives in Models, aliases, pricing, rate limits, context.

Verified by grepping every TYPESAFE_[A-Z_]+ occurrence across raw/ (2026-09-17): only the eight names above appear anywhere, and only the four in The table appear in raw/github/typesafe-sdk-python/src or raw/github/typesafe-sdk-js/src as environment-variable names.

Non-TypeSafe variables that appear alongside them in cookbooks (OPENAI_API_KEY, ANTHROPIC_API_KEY) belong to those vendors' SDKs, not to TypeSafe.

Gotchas

Related

Sources