Skip to main content

CEL Functions

Functions available in Telo CEL expressions (!cel "..." tags and the ${{ }} holes of !interpolate). This page is generated from the runtime registry, so it matches what the kernel actually provides. Locally, telo cel functions prints the same list and telo cel eval "<expr>" evaluates an expression.

non-deterministic functions re-evaluate per call (in an x-telo-eval: compile field they bake once at load, which telo check warns about). host functions need the kernel's host handlers (Node crypto / Buffer).

Call form​

A signature's shape is how you must call it. upper(string): string is a global function — upper(name); string.startsWith(string): bool is a method on its receiver — name.startsWith('x'). Writing one as the other does not type-check, and no cast repairs it. Some names exist in both forms (trim, split, size, join), some in only one.

Telo's own functions below are global. CEL's built-ins are mostly methods and are listed at the end — they were previously absent from this page entirely, which is why calling them globally was such a common mistake.

CEL has no assignment or statements. Reuse a subexpression with the cel.bind(name, init, expr) macro, and use default(value, fallback) / optional access (x.?field.orValue(d)) where you'd reach for ??.

Collections​

SignatureDescription
join(list, string): stringJoin list elements into a string with a separator.
keys(map): listList a map's keys.
values(map): listList a map's values.
distinct(list): listRemove duplicate elements, preserving order.
reverse(list): listReverse a list (copy; never mutates the input).
flatten(list): listFlatten one level of nested lists.
sort(list): listSort a list numerically (numbers) or lexicographically; copy.
range(int): list<int>Integers [0, n-1] (empty for n <= 0); materializes indices for an unknown-length list.
enumerate(list): listPair each element with its zero-based position as {index, value}.
slice(dyn, int, int): dynTake the half-open range [start, end) of a string, bytes or list.
compact(dyn): dynDrop entries whose value is null or the empty string, from a map or a list.
merge(map, map): mapCombine two maps, with the right-hand map winning on a shared key. Use it to add to a map rather than replace it — merge(defaults, overrides).

Strings​

SignatureDescription
lower(string): stringLowercase a string.
upper(string): stringUppercase a string.
trim(string): stringStrip leading/trailing whitespace.
replace(string, string, string): stringReplace all occurrences of a substring.
split(string, string): listSplit a string on a separator into a list.
regexReplace(string, string, string, string?): stringReplace every regex match (RE2 syntax) with a replacement ($1 backrefs); flags like 'i', 'm', 's'.
regexExtract(string, string, string?): stringFirst whole match of a regex (RE2 syntax), or '' when there is none.
regexExtractAll(string, string, string?): list<string>Every whole match of a regex (RE2 syntax), in order.
regexGroups(string, string, string?): list<string>Capture groups of the first regex match (RE2 syntax); empty list when there is no match.
trimPrefix(string, string): stringStrip a leading prefix if present.
trimSuffix(string, string): stringStrip a trailing suffix if present.
string.joinPath(string): stringJoin a relative path onto a path with the host's separator (\ on Windows). On a host path it yields a host path; an absolute argument is refused. (host)

Math​

SignatureDescription
abs(dyn): doubleAbsolute value.
floor(dyn): doubleRound down to an integer.
ceil(dyn): doubleRound up to an integer.
round(dyn, int?): doubleRound to the nearest integer, or to the given number of decimal places (0–10). The two-argument form shares the formatter's rounding rule, so a rounded value and the cell rendered beside it agree at the boundary. An integer past 2^53 is refused rather than rounded to a neighbour.
min(list): dynSmallest element (by numeric value); null for an empty list.
max(list): dynLargest element (by numeric value); null for an empty list.
sum(list): doubleSum of a list's numeric elements; 0 for an empty list.
avg(list): dynArithmetic mean of a list's numeric elements; null for an empty list.

JSON​

SignatureDescription
json(dyn): stringSerialize any value to a JSON string. (host)
parseJson(string): dynParse a JSON string into a value (numbers come back as doubles).

Encoding​

SignatureDescription
base64Encode(string): stringEncode a UTF-8 string as base64. (host)
base64Decode(string): stringDecode a base64 string to UTF-8. (host)
bytesFromBase64(string): bytesDecode a base64 string to raw bytes.
bytesToBase64(bytes): stringEncode raw bytes as a base64 string.
urlEncode(string): stringPercent-encode a URI component.
urlDecode(string): stringDecode a percent-encoded URI component.

Hashing​

SignatureDescription
sha256(string): stringSHA-256 hash, hex-encoded. (host)
md5(string): stringMD5 hash, hex-encoded. (host)
sha1(string): stringSHA-1 hash, hex-encoded. (host)
sha512(string): stringSHA-512 hash, hex-encoded. (host)
hmac(string, string, string): stringHMAC of message under key for an algorithm (e.g. 'sha256'), hex. (host)

Null handling​

SignatureDescription
default(dyn, dyn): dynReturn the value, or the fallback when it is null.
coalesce(list): dynFirst non-null element of a list, or null.

Time​

SignatureDescription
now(): timestampCurrent instant as a native timestamp, for comparison and duration arithmetic. (non-deterministic)
nowIso(string?): stringCurrent time as ISO-8601; UTC by default, or in the given IANA timezone. (non-deterministic)
today(string?): stringCurrent calendar date (YYYY-MM-DD); UTC by default, or in the given IANA timezone. (non-deterministic)
nowMillis(): intCurrent time as epoch milliseconds (absolute; timezone-independent). (non-deterministic)
nowSeconds(): intCurrent time as epoch seconds (absolute; timezone-independent). (non-deterministic)
dateIn(timestamp, string?): stringCalendar date (YYYY-MM-DD) of an instant, in an IANA zone (UTC by default).
isoIn(timestamp, string?): stringISO-8601 rendering of an instant, in an IANA zone (UTC by default).
startOfMonth(timestamp, string?): timestampMidnight on the 1st of the instant's month, in an IANA zone (UTC by default).
addMonths(timestamp, int, string?): timestampShift an instant by whole months in an IANA zone, clamping the day of month (Jan 31 + 1 month is Feb 28).

Formatting​

SignatureDescription
format(dyn, string): stringFormat a number with a d3-format specifier (.2f, ,.2f, .1%, .2s).
fixed(dyn, int): stringFixed-decimal string with the given number of places (0–10).
formatDuration(dyn, int): stringRender a minute count against a declared day length: formatDuration(510, 480) is 1d 30m. The day length is an argument because it is a policy, not arithmetic. The result is a rendering for a reader, not a duration literal — its d is the declared day, so it must not be fed back into a field that parses a duration.

UUID​

SignatureDescription
uuidv1(): stringTime-based UUID (v1). (non-deterministic)
uuidv4(): stringRandom UUID (v4). (non-deterministic)
uuidv6(): stringTime-ordered UUID (v6). (non-deterministic)
uuidv7(): stringTime-ordered UUID (v7). (non-deterministic)
uuidv3(string, string): stringName-based UUID (v3, MD5) under a namespace UUID.
uuidv5(string, string): stringName-based UUID (v5, SHA-1) under a namespace UUID.
uuidValidate(string): boolTrue if the string is a valid UUID.
uuidVersion(string): intThe version number of a UUID.

CEL built-ins​

Provided by CEL itself, grouped by what they are called on.

Global functions​

  • !(bool): bool
  • !=(bool, bool): bool
  • !=(bytes, bytes): bool
  • !=(double, double): bool
  • !=(google.protobuf.Duration, google.protobuf.Duration): bool
  • !=(google.protobuf.Timestamp, google.protobuf.Timestamp): bool
  • !=(int, int): bool
  • !=(list<A>, list<A>): bool
  • !=(map<K, V>, map<K, V>): bool
  • !=(null, null): bool
  • !=(optional<A>, optional<A>): bool
  • !=(string, string): bool
  • !=(type, type): bool
  • !=(uint, uint): bool
  • %(int, int): int
  • %(uint, uint): uint
  • *(double, double): double
  • *(int, int): int
  • *(uint, uint): uint
  • +(bytes, bytes): bytes
  • +(double, double): double
  • +(google.protobuf.Duration, google.protobuf.Duration): google.protobuf.Duration
  • +(google.protobuf.Duration, google.protobuf.Timestamp): google.protobuf.Timestamp
  • +(google.protobuf.Timestamp, google.protobuf.Duration): google.protobuf.Timestamp
  • +(int, int): int
  • +(list<A>, list<A>): list<A>
  • +(string, string): string
  • +(uint, uint): uint
  • -(double): double
  • -(double, double): double
  • -(google.protobuf.Duration, google.protobuf.Duration): google.protobuf.Duration
  • -(google.protobuf.Timestamp, google.protobuf.Duration): google.protobuf.Timestamp
  • -(google.protobuf.Timestamp, google.protobuf.Timestamp): google.protobuf.Duration
  • -(int): int
  • -(int, int): int
  • -(uint, uint): uint
  • /(double, double): double
  • /(int, int): int
  • /(uint, uint): uint
  • <(bool, bool): bool
  • <(bytes, bytes): bool
  • <(double, double): bool
  • <(double, int): bool
  • <(double, uint): bool
  • <(google.protobuf.Duration, google.protobuf.Duration): bool
  • <(google.protobuf.Timestamp, google.protobuf.Timestamp): bool
  • <(int, double): bool
  • <(int, int): bool
  • <(int, uint): bool
  • <(string, string): bool
  • <(uint, double): bool
  • <(uint, int): bool
  • <(uint, uint): bool
  • <=(bool, bool): bool
  • <=(bytes, bytes): bool
  • <=(double, double): bool
  • <=(double, int): bool
  • <=(double, uint): bool
  • <=(google.protobuf.Duration, google.protobuf.Duration): bool
  • <=(google.protobuf.Timestamp, google.protobuf.Timestamp): bool
  • <=(int, double): bool
  • <=(int, int): bool
  • <=(int, uint): bool
  • <=(string, string): bool
  • <=(uint, double): bool
  • <=(uint, int): bool
  • <=(uint, uint): bool
  • ==(bool, bool): bool
  • ==(bytes, bytes): bool
  • ==(double, double): bool
  • ==(google.protobuf.Duration, google.protobuf.Duration): bool
  • ==(google.protobuf.Timestamp, google.protobuf.Timestamp): bool
  • ==(int, int): bool
  • ==(list<A>, list<A>): bool
  • ==(map<K, V>, map<K, V>): bool
  • ==(null, null): bool
  • ==(optional<A>, optional<A>): bool
  • ==(string, string): bool
  • ==(type, type): bool
  • ==(uint, uint): bool
  • >(bool, bool): bool
  • >(bytes, bytes): bool
  • >(double, double): bool
  • >(double, int): bool
  • >(double, uint): bool
  • >(google.protobuf.Duration, google.protobuf.Duration): bool
  • >(google.protobuf.Timestamp, google.protobuf.Timestamp): bool
  • >(int, double): bool
  • >(int, int): bool
  • >(int, uint): bool
  • >(string, string): bool
  • >(uint, double): bool
  • >(uint, int): bool
  • >(uint, uint): bool
  • >=(bool, bool): bool
  • >=(bytes, bytes): bool
  • >=(double, double): bool
  • >=(double, int): bool
  • >=(double, uint): bool
  • >=(google.protobuf.Duration, google.protobuf.Duration): bool
  • >=(google.protobuf.Timestamp, google.protobuf.Timestamp): bool
  • >=(int, double): bool
  • >=(int, int): bool
  • >=(int, uint): bool
  • >=(string, string): bool
  • >=(uint, double): bool
  • >=(uint, int): bool
  • >=(uint, uint): bool
  • bool(bool): bool
  • bool(string): bool
  • bytes(bytes): bytes
  • bytes(string): bytes
  • double(double): double
  • double(int): double
  • double(string): double
  • double(uint): double
  • duration(google.protobuf.Duration): google.protobuf.Duration
  • duration(string): google.protobuf.Duration
  • dyn(A): dyn
  • in(A, list<A>): bool
  • in(K, map<K, V>): bool
  • int(double): int
  • int(google.protobuf.Duration): int
  • int(google.protobuf.Timestamp): int
  • int(int): int
  • int(string): int
  • int(uint): int
  • matches(string, string): bool
  • size(bytes): int
  • size(list<A>): int
  • size(map<K, V>): int
  • size(string): int
  • string(bool): string
  • string(bytes): string
  • string(double): string
  • string(google.protobuf.Duration): string
  • string(google.protobuf.Timestamp): string
  • string(int): string
  • string(string): string
  • string(uint): string
  • timestamp(google.protobuf.Timestamp): google.protobuf.Timestamp
  • timestamp(int): google.protobuf.Timestamp
  • timestamp(string): google.protobuf.Timestamp
  • type(bool): type
  • type(bytes): type
  • type(double): type
  • type(google.protobuf.Duration): type
  • type(google.protobuf.Timestamp): type
  • type(int): type
  • type(list<A>): type
  • type(map<K, V>): type
  • type(null): type
  • type(optional<A>): type
  • type(string): type
  • type(type): type
  • type(uint): type
  • uint(double): uint
  • uint(int): uint
  • uint(string): uint
  • uint(uint): uint

On bytes​

  • bytes.at(int): int
  • bytes.base64(): string
  • bytes.hex(): string
  • bytes.json(): dyn
  • bytes.size(): int
  • bytes.string(): string

On google.protobuf.Duration​

  • google.protobuf.Duration.getHours(): int
  • google.protobuf.Duration.getMilliseconds(): int
  • google.protobuf.Duration.getMinutes(): int
  • google.protobuf.Duration.getSeconds(): int

On google.protobuf.Timestamp​

  • google.protobuf.Timestamp.getDate(): int
  • google.protobuf.Timestamp.getDate(string): int
  • google.protobuf.Timestamp.getDayOfMonth(): int
  • google.protobuf.Timestamp.getDayOfMonth(string): int
  • google.protobuf.Timestamp.getDayOfWeek(): int
  • google.protobuf.Timestamp.getDayOfWeek(string): int
  • google.protobuf.Timestamp.getDayOfYear(): int
  • google.protobuf.Timestamp.getDayOfYear(string): int
  • google.protobuf.Timestamp.getFullYear(): int
  • google.protobuf.Timestamp.getFullYear(string): int
  • google.protobuf.Timestamp.getHours(): int
  • google.protobuf.Timestamp.getHours(string): int
  • google.protobuf.Timestamp.getMilliseconds(): int
  • google.protobuf.Timestamp.getMilliseconds(string): int
  • google.protobuf.Timestamp.getMinutes(): int
  • google.protobuf.Timestamp.getMinutes(string): int
  • google.protobuf.Timestamp.getMonth(): int
  • google.protobuf.Timestamp.getMonth(string): int
  • google.protobuf.Timestamp.getSeconds(): int
  • google.protobuf.Timestamp.getSeconds(string): int

On list<A>​

  • list<A>.size(): int

On list<string>​

  • list<string>.join(): string
  • list<string>.join(string): string

On map<K, V>​

  • map<K, V>.size(): int

On optional<A>​

  • optional<A>.hasValue(): bool
  • optional<A>.or(optional<A>): optional<A>
  • optional<A>.orValue(A): A
  • optional<A>.value(): A

On string​

  • string.contains(string): bool
  • string.endsWith(string): bool
  • string.indexOf(string): int
  • string.indexOf(string, int): int
  • string.lastIndexOf(string): int
  • string.lastIndexOf(string, int): int
  • string.lowerAscii(): string
  • string.matches(string): bool
  • string.size(): int
  • string.split(string): list<string>
  • string.split(string, int): list<string>
  • string.startsWith(string): bool
  • string.substring(int): string
  • string.substring(int, int): string
  • string.trim(): string
  • string.upperAscii(): string