process.env, os.environ, os.Getenv, System.getenv. There is no separate configuration API to learn. Stateful Actors read theirs the same way, through process.env, using the scoped tables in telnyx.toml.
What’s in the environment
Declaring variables
Define non-sensitive configuration under[env_vars] in func.toml (or telnyx.toml; for actors, see Scoped variables for actors):
- All values are strings. Parse numbers and booleans in your code.
- Changes take effect on the next
telnyx-edge ship— there is no live update. - Names share the
envnamespace with bindings. If an[env_vars]entry has the same name as a declared binding — or is namedSECRETSwhile a[[secrets]]block is declared —shipwarns that one shadows the other onenvand still proceeds; rename one. (A binding namedSECRETS, or a duplicate[[secrets]]handle, is a hard error.)
[env_vars] values are plaintext in the manifest and end up in version control. Put credentials in secrets instead.
Reading variables
- TypeScript / JavaScript
- Python
- Go
- Quarkus (Java)
Scoped variables for actors
In atelnyx.toml project, [env_vars] also takes scope sub-tables, and each [[actors]] block can carry its own env_vars. This is how a Stateful Actor gets configuration — keys written directly under [env_vars] reach the function only. A func.toml project accepts the scoped tables too; with no actors declared, only the function-reaching scopes have any effect.
- Function =
[env_vars.shared]→[env_vars]→[env_vars.function] - Actor type =
[env_vars.shared]→[env_vars.actor]→ that type’s[[actors]]env_vars
LOG_LEVEL=info, REGION=us-east; Call sees LOG_LEVEL=debug, MAX_TURNS=20, REGION=us-east; Queue sees LOG_LEVEL=warn, REGION=us-east. Nothing in [env_vars.function] or a flat key ever reaches an actor, and nothing actor-scoped reaches the function.
Actor code reads the result from process.env, exactly like the function:
- One actor type has one environment. Several
[[actors]]blocks may bind the sametype, but they must declare identicalenv_vars(one block setting them and another omitting them counts as a conflict) — otherwiseshipfails. To give every handle the same values, put them on each block or use[env_vars.actor]. - Actor env applies from the function that defines the actor class. A reference binding to a type another function owns does not deploy that type’s runtime, so any
env_varson that block,[env_vars.actor], and the actor half of[env_vars.shared]are not applied —shipwarns and proceeds. Declare actor env in the owning function’s manifest. - Changes take effect on the next
ship, like any other[env_vars]change. A variable you delete is removed from the actor on that deploy. - Unknown scope names are rejected —
[env_vars.actors](plural) is an error, not silently ignored. Every value must be a string.
Testing locally
telnyx-edge dev (CLI v0.5.12 and later) applies the same resolution: it runs one actor runtime per actor type, each with only its own resolved environment, and gives the function its function-scope set. It validates the manifest with the same rules as ship, so a manifest ship would reject fails locally first. On start it reports what it passed:
PATH, PORT and DAPR_HTTP_PORT in an actor scope (and PORT, DAPR_HTTP_PORT, DAPR_HOST, TELNYX_CONFIG_PATH and FUNCTION_ENTRY for the function) are set by the local stack itself, so dev ignores your value with a warning.
Names, values, and limits
ship rejects a manifest that breaks any of these, naming each offending key:
- Names use letters, digits, and underscores, start with a letter or underscore, and are at most 255 characters.
- Values are strings of at most 10,000 bytes, and may not begin with
{{— that syntax is a deploy-time template, not a literal. To reference a secret, use secrets instead. - At most 50 variables per workload, counted after resolution: the function’s resolved set and each actor type’s resolved set are capped independently.
- Reserved everywhere:
TELNYX_RUNTIME_BINDINGS,TELNYX_ACCOUNT_ID,TELNYX_BINDINGS_JSON,EC_ACTOR_ROUTER_URL,EC_ACTOR_WS_DIAL. - Reserved in any scope that reaches an actor (
[env_vars.shared],[env_vars.actor],[[actors]]env_vars) — the actor runtime sets these itself:ACTOR_ENTRY,BUNDLE_REF,POD_IP,SQLITE_SIDECAR_PORT,TELNYX_ACTOR_DATA_DIR,TELNYX_ACTOR_METHOD_TIMEOUT_MS,TELNYX_ACTOR_STATE_STORE,TELNYX_API_BASE_URL,TELNYX_BUILTIN_ACTOR_TYPE,TELNYX_CONFIG_PATH,TELNYX_OBJECTSTORE_BUCKET,TELNYX_OBJECTSTORE_HOST,TELNYX_OBJECTSTORE_REGION,TELNYX_SECRETS_BINDING,TELNYX_SQL_ENGINE,TELNYX_WS_DIAL_AUTH,TELNYX_WS_DIAL_AUTH_KEY,TELNYX_WS_DIAL_AUTH_KEY_PREVIOUS.
Environment variables vs secrets
Next Steps
- Secrets — the server-side counterpart for sensitive values, including the typed
env.SECRETSsurface for TypeScript - Bindings — typed, pre-authenticated handles instead of raw variables
- Configuration — the full manifest reference: every
func.tomlandtelnyx.tomlkey