diff --git a/apl/scalar-functions/array-functions.mdx b/apl/scalar-functions/array-functions.mdx
index 5331b854..92af42f3 100644
--- a/apl/scalar-functions/array-functions.mdx
+++ b/apl/scalar-functions/array-functions.mdx
@@ -21,6 +21,8 @@ The table summarizes the array functions available in APL.
| [array_shift_left](/apl/scalar-functions/array-functions/array-shift-left) | Shifts the values inside a dynamic array to the left. |
| [array_shift_right](/apl/scalar-functions/array-functions/array-shift-right) | Shifts values inside an array to the right. |
| [array_slice](/apl/scalar-functions/array-functions/array-slice) | Extracts a slice of a dynamic array. |
+| [array_sort_asc](/apl/scalar-functions/array-functions/array-sort-asc) | Sorts an array in ascending order. |
+| [array_sort_desc](/apl/scalar-functions/array-functions/array-sort-desc) | Sorts an array in descending order. |
| [array_split](/apl/scalar-functions/array-functions/array-split) | Splits an array to multiple arrays according to the split indices and packs the generated array in a dynamic array. |
| [array_sum](/apl/scalar-functions/array-functions/array-sum) | Calculates the sum of elements in a dynamic array. |
| [bag_has_key](/apl/scalar-functions/array-functions/bag-has-key) | Checks whether a dynamic property bag contains a specific key. |
diff --git a/apl/scalar-functions/array-functions/array-sort-asc.mdx b/apl/scalar-functions/array-functions/array-sort-asc.mdx
new file mode 100644
index 00000000..b904e8a9
--- /dev/null
+++ b/apl/scalar-functions/array-functions/array-sort-asc.mdx
@@ -0,0 +1,103 @@
+---
+title: array_sort_asc
+description: 'This page explains how to use the array_sort_asc function in APL.'
+---
+
+Use the `array_sort_asc` function to return a new array that contains all the elements of the input array, sorted in ascending order. This function is useful when you want to normalize the order of array elements for comparison, presentation, or further processing—such as identifying patterns, comparing sequences, or selecting boundary values.
+
+You can apply `array_sort_asc` to arrays of numbers, strings, or dynamic objects, making it useful across many telemetry, logging, and security data scenarios.
+
+## For users of other query languages
+
+If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.
+
+
+
+
+In Splunk SPL, arrays are typically handled through `mvsort`, which sorts multivalue fields in ascending order. In APL, `array_sort_asc` provides similar functionality but works on dynamic arrays and returns a new sorted array.
+
+
+```sql Splunk example
+| eval sorted_values = mvsort(multivalue_field)
+````
+
+```kusto APL equivalent
+datatable(arr: dynamic)
+[
+ dynamic([4, 2, 5])
+]
+| extend sorted_arr = array_sort_asc(arr)
+```
+
+
+
+
+
+
+ANSI SQL does not directly support array data types or array sorting. You typically normalize arrays with `UNNEST` and sort the results using `ORDER BY`. In APL, you can sort arrays inline using `array_sort_asc`, which is more concise and expressive.
+
+
+```sql SQL example
+SELECT val
+FROM UNNEST([4, 2, 5]) AS val
+ORDER BY val ASC
+```
+
+```kusto APL equivalent
+print sorted_arr = array_sort_asc(dynamic([4, 2, 5]))
+```
+
+
+
+
+
+
+## Usage
+
+### Syntax
+
+```kusto
+array_sort_asc(array)
+```
+
+### Parameters
+
+| Name | Type | Required | Description |
+| ----- | ------- | -------- | ------------------------------------------------------------------------- |
+| array | dynamic | ✔️ | An array of values to sort. Can be numbers, strings, or other primitives. |
+
+### Returns
+
+A new array that contains the same elements as the input array, sorted in ascending order. If the input is not an array, the function returns an empty array.
+
+## Example
+
+**Query**
+
+```kusto
+['sample-http-logs']
+| project sort = array_sort_asc(dynamic(['x', 'a', 'm', 'o', 'i']))
+```
+
+[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20project%20sort%20%3D%20array_sort_asc(dynamic(%5B'x'%2C%20'a'%2C%20'm'%2C%20'o'%2C%20'i'%5D))%22%7D)
+
+**Output**
+
+```json
+[
+ [
+ "a",
+ "i",
+ "m",
+ "o",
+ "x"
+ ]
+]
+```
+
+## List of related functions
+
+- [array_index_of](/apl/scalar-functions/array-functions/array-index-of): Returns the position of an element in an array. Use after sorting to find where values fall.
+- [array_length](/apl/scalar-functions/array-functions/array-length): Returns the number of elements in an array. Use to understand array size before or after sorting.
+- [array_slice](/apl/scalar-functions/array-functions/array-slice): Returns a subrange of the array. Useful after sorting to get top-N or bottom-N elements.
+- [array_sort_desc](/apl/scalar-functions/array-functions/array-sort-desc): Sorts array elements in descending order. Use when you need reverse ordering.
diff --git a/apl/scalar-functions/array-functions/array-sort-desc.mdx b/apl/scalar-functions/array-functions/array-sort-desc.mdx
new file mode 100644
index 00000000..5e02efcf
--- /dev/null
+++ b/apl/scalar-functions/array-functions/array-sort-desc.mdx
@@ -0,0 +1,104 @@
+---
+title: array_sort_desc
+description: 'This page explains how to use the array_sort_desc function in APL.'
+---
+
+Use the `array_sort_desc` function in APL to sort the elements of an array in descending order. This function is especially useful when working with numerical data or categorical data where you want to prioritize higher values first—such as showing the longest durations, highest response times, or most severe error codes at the top of an array.
+
+You can use `array_sort_desc` in scenarios where ordering matters within grouped aggregations, such as collecting response times per user or span durations per trace, and then sorting them to identify the highest or most impactful values.
+
+## For users of other query languages
+
+If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.
+
+
+
+
+Splunk doesn’t have a direct equivalent to `array_sort_desc`, but similar outcomes can be achieved using `mvsort` with a custom sort order (and sometimes `reverse`). In APL, `array_sort_desc` explicitly performs a descending sort on array elements, making it more straightforward.
+
+
+```sql Splunk example
+... | stats list(duration) as durations by id
+... | eval durations=reverse(mvsort(durations))
+````
+
+```kusto APL equivalent
+['otel-demo-traces']
+| summarize durations=make_list(duration) by trace_id
+| extend durations=array_sort_desc(durations)
+```
+
+
+
+
+
+
+ANSI SQL does not support arrays or array functions natively. You typically use window functions or subqueries to order values. In APL, you can work with arrays directly and apply `array_sort_desc` to sort them.
+
+
+```sql SQL example
+SELECT trace_id, ARRAY_AGG(duration ORDER BY duration DESC) AS durations
+FROM traces
+GROUP BY trace_id;
+```
+
+```kusto APL equivalent
+['otel-demo-traces']
+| summarize durations=make_list(duration) by trace_id
+| extend durations=array_sort_desc(durations)
+```
+
+
+
+
+
+
+## Usage
+
+### Syntax
+
+```kusto
+array_sort_desc(array)
+```
+
+### Parameters
+
+| Name | Type | Required | Description |
+| ----- | ----- | -------- | ----------------------------------------------------- |
+| array | array | ✔️ | The input array whose elements are sorted descending. |
+
+### Returns
+
+If the input is a valid array, the function returns a new array with its elements sorted in descending order. If the array is empty or contains incompatible types, it returns an empty array.
+
+## Example
+
+**Query**
+
+```kusto
+['sample-http-logs']
+| project sort = array_sort_desc(dynamic(['x', 'a', 'm', 'o', 'i']))
+```
+
+[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20project%20sort%20%3D%20array_sort_desc(dynamic(%5B'x'%2C%20'a'%2C%20'm'%2C%20'o'%2C%20'i'%5D))%22%7D)
+
+**Output**
+
+```json
+[
+ [
+ "x",
+ "o",
+ "m",
+ "i",
+ "a"
+ ]
+]
+```
+
+## List of related functions
+
+- [array_index_of](/apl/scalar-functions/array-functions/array-index-of): Returns the index of a value in an array. Useful after sorting to locate specific elements.
+- [array_length](/apl/scalar-functions/array-functions/array-length): Returns the number of elements in an array. Useful for measuring the size of arrays before or after sorting.
+- [array_slice](/apl/scalar-functions/array-functions/array-slice): Extracts a range of elements from an array. Use it after sorting to get the top N or bottom N values.
+- [array_sort_asc](/apl/scalar-functions/array-functions/array-sort-asc): Sorts an array in ascending order. Use this when you want to prioritize smaller values first.
diff --git a/apl/scalar-functions/string-functions.mdx b/apl/scalar-functions/string-functions.mdx
index 909f96c9..c7cc739d 100644
--- a/apl/scalar-functions/string-functions.mdx
+++ b/apl/scalar-functions/string-functions.mdx
@@ -9,54 +9,57 @@ keywords: ['axiom documentation', 'documentation', 'axiom', 'string functions',
| **Function Name** | **Description** |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
-| [base64_encode_tostring()](#base64-encode-tostring) | Encodes a string as base64 string. |
-| [base64_decode_tostring()](#base64-decode-tostring) | Decodes a base64 string to a UTF-8 string. |
-| [countof()](#countof) | Counts occurrences of a substring in a string. |
-| [countof_regex()](#countof-regex) | Counts occurrences of a substring in a string. Regex matches don’t. |
-| [coalesce()](#coalesce) | Evaluates a list of expressions and returns the first non-null (or non-empty for string) expression. |
-| [extract()](#extract) | Get a match for a regular expression from a text string. |
-| [extract_all()](#extract-all) | Get all matches for a regular expression from a text string. |
-| [format_bytes()](#format-bytes) | Formats a number of bytes as a string including bytes units |
-| [format_url()](#format-url) | Formats an input string into a valid URL by adding the necessary protocol if it’s escaping illegal URL characters. |
-| [indexof()](#indexof) | Function reports the zero-based index of the first occurrence of a specified string within input string. |
-| [isempty()](#isempty) | Returns true if the argument is an empty string or is null. |
-| [isnotempty()](#isnotempty) | Returns true if the argument isn’t an empty string or a null. |
-| [isnotnull()](#isnotnull) | Returns true if the argument is not null. |
-| [isnull()](#isnull) | Evaluates its sole argument and returns a bool value indicating if the argument evaluates to a null value. |
-| [parse_bytes()](#parse-bytes) | Parses a string including byte size units and returns the number of bytes |
-| [parse_json()](#parse-json) | Interprets a string as a JSON value) and returns the value as dynamic. |
-| [parse_url()](#parse-url) | Parses an absolute URL string and returns a dynamic object contains all parts of the URL. |
-| [parse_urlquery()](#parse-urlquery) | Parses a url query string and returns a dynamic object contains the Query parameters. |
-| [replace()](#replace) | Replace all regex matches with another string. |
-| [replace_regex()](#replace-regex) | Replaces all regex matches with another string. |
-| [replace_string()](#replace-string) | Replaces all string matches with another string. |
-| [reverse()](#reverse) | Function makes reverse of input string. |
-| [split()](#split) | Splits a given string according to a given delimiter and returns a string array with the contained substrings. |
-| [strcat()](#strcat) | Concatenates between 1 and 64 arguments. |
-| [strcat_delim()](#strcat-delim) | Concatenates between 2 and 64 arguments, with delimiter, provided as first argument. |
-| [strcmp()](#strcmp) | Compares two strings. |
-| [strlen()](#strlen) | Returns the length, in characters, of the input string. |
-| [strrep()](#strrep) | Repeats given string provided number of times (default = 1). |
-| [substring()](#substring) | Extracts a substring from a source string. |
-| [toupper()](#toupper) | Converts a string to upper case. |
-| [tolower()](#tolower) | Converts a string to lower case. |
-| [trim()](#trim) | Removes all leading and trailing matches of the specified cutset. |
-| [trim_regex()](#trim-regex) | Removes all leading and trailing matches of the specified regular expression. |
-| [trim_end()](#trim-end) | Removes trailing match of the specified cutset. |
-| [trim_end_regex()](#trim-end-regex) | Removes trailing match of the specified regular expression. |
-| [trim_start()](#trim-start) | Removes leading match of the specified cutset. |
-| [trim_start_regex()](#trim-start-regex) | Removes leading match of the specified regular expression. |
-| [url_decode()](#url-decode) | The function converts encoded URL into a regular URL representation. |
-| [url_encode()](#url-encode) | The function converts characters of the input URL into a format that can be transmitted over the Internet. |
-| [gettype()](#gettype) | Returns the runtime type of its single argument. |
-| [parse_csv()](#parse-csv) | Splits a given string representing a single record of comma-separated values and returns a string array with these values. |
+| [base64_decode_toarray](/apl/scalar-functions/string-functions/base64-decode-toarray) | Decode a Base64-encoded string into an array of bytes. |
+| [base64_decode_tostring](#base64-decode-tostring) | Decodes a base64 string to a UTF-8 string. |
+| [base64_encode_fromarray](/apl/scalar-functions/string-functions/base64-encode-fromarray) | Convert a sequence of bytes into a Base64-encoded string. |
+| [base64_encode_tostring](#base64-encode-tostring) | Encodes a string as base64 string. |
+| [countof](#countof) | Counts occurrences of a substring in a string. |
+| [countof_regex](#countof-regex) | Counts occurrences of a substring in a string. Regex matches don’t. |
+| [coalesce](#coalesce) | Evaluates a list of expressions and returns the first non-null (or non-empty for string) expression. |
+| [extract](#extract) | Get a match for a regular expression from a text string. |
+| [extract_all](#extract-all) | Get all matches for a regular expression from a text string. |
+| [format_bytes](#format-bytes) | Formats a number of bytes as a string including bytes units |
+| [format_url](#format-url) | Formats an input string into a valid URL by adding the necessary protocol if it’s escaping illegal URL characters. |
+| [indexof](#indexof) | Function reports the zero-based index of the first occurrence of a specified string within input string. |
+| [isempty](#isempty) | Returns true if the argument is an empty string or is null. |
+| [isnotempty](#isnotempty) | Returns true if the argument isn’t an empty string or a null. |
+| [isnotnull](#isnotnull) | Returns true if the argument is not null. |
+| [isnull](#isnull) | Evaluates its sole argument and returns a bool value indicating if the argument evaluates to a null value. |
+| [parse_bytes](#parse-bytes) | Parses a string including byte size units and returns the number of bytes |
+| [parse_json](#parse-json) | Interprets a string as a JSON value) and returns the value as dynamic. |
+| [parse_url](#parse-url) | Parses an absolute URL string and returns a dynamic object contains all parts of the URL. |
+| [parse_urlquery](#parse-urlquery) | Parses a url query string and returns a dynamic object contains the Query parameters. |
+| [replace](#replace) | Replace all regex matches with another string. |
+| [replace_regex](#replace-regex) | Replaces all regex matches with another string. |
+| [replace_string](#replace-string) | Replaces all string matches with another string. |
+| [reverse](#reverse) | Function makes reverse of input string. |
+| [split](#split) | Splits a given string according to a given delimiter and returns a string array with the contained substrings. |
+| [strcat](#strcat) | Concatenates between 1 and 64 arguments. |
+| [strcat_delim](#strcat-delim) | Concatenates between 2 and 64 arguments, with delimiter, provided as first argument. |
+| [strcmp](#strcmp) | Compares two strings. |
+| [strlen](#strlen) | Returns the length, in characters, of the input string. |
+| [strrep](#strrep) | Repeats given string provided number of times (default = 1). |
+| [substring](#substring) | Extracts a substring from a source string. |
+| [toupper](#toupper) | Converts a string to upper case. |
+| [tolower](#tolower) | Converts a string to lower case. |
+| [totitle](#totitle) | Converts a string to title case. |
+| [trim](#trim) | Removes all leading and trailing matches of the specified cutset. |
+| [trim_regex](#trim-regex) | Removes all leading and trailing matches of the specified regular expression. |
+| [trim_end](#trim-end) | Removes trailing match of the specified cutset. |
+| [trim_end_regex](#trim-end-regex) | Removes trailing match of the specified regular expression. |
+| [trim_start](#trim-start) | Removes leading match of the specified cutset. |
+| [trim_start_regex](#trim-start-regex) | Removes leading match of the specified regular expression. |
+| [url_decode](#url-decode) | The function converts encoded URL into a regular URL representation. |
+| [url_encode](#url-encode) | The function converts characters of the input URL into a format that can be transmitted over the Internet. |
+| [gettype](#gettype) | Returns the runtime type of its single argument. |
+| [parse_csv](#parse-csv) | Splits a given string representing a single record of comma-separated values and returns a string array with these values. |
Each argument has a **required** section which is denoted with `required` or `optional`
- If it’s denoted by `required` it means the argument must be passed into that function before it'll work.
- if it’s denoted by `optional` it means the function can work without passing the argument value.
-## base64_encode_tostring()
+## base64_encode_tostring
Encodes a string as base64 string.
@@ -70,7 +73,7 @@ Encodes a string as base64 string.
Returns the string encoded as base64 string.
-- To decode base64 strings to UTF-8 strings, see [base64_decode_tostring()](#base64-decode-tostring)
+- To decode base64 strings to UTF-8 strings, see [base64_decode_tostring](#base64-decode-tostring)
### Examples
@@ -85,7 +88,7 @@ base64_encode_tostring(string)
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20encoded_base64_string%20%3D%20base64_encode_tostring(content_type)%22%7D)
-## base64_decode_tostring()
+## base64_decode_tostring
Decodes a base64 string to a UTF-8 string.
@@ -99,7 +102,7 @@ Decodes a base64 string to a UTF-8 string.
Returns UTF-8 string decoded from base64 string.
-- To encode strings to base64 string, see [base64_encode_tostring()](#base64-encode-tostring)
+- To encode strings to base64 string, see [base64_encode_tostring](#base64-encode-tostring)
### Examples
@@ -114,7 +117,7 @@ base64_decode_tostring(string)
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20decoded_base64_string%20%3D%20base64_decode_tostring(%5C%22VGhpcyBpcyBhbiBlbmNvZGVkIG1lc3NhZ2Uu%5C%22)%22%7D)
-## countof()
+## countof
Counts occurrences of a substring in a string.
@@ -142,7 +145,7 @@ countof(search, text)
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20count%20%3D%20countof(%5C%22con%5C%22%2C%20%5C%22content_type%5C%22)%22%7D)
-## countof_regex()
+## countof_regex
Counts occurrences of a substring in a string. regex matches don’t.
@@ -168,7 +171,7 @@ countof_regex(regex, text)
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20count%20%3D%20countof_regex(%5C%22c.n%5C%22%2C%20%5C%22content_type%5C%22)%22%7D)
-## coalesce()
+## coalesce
Evaluates a list of expressions and returns the first non-null (or non-empty for string) expression.
@@ -198,7 +201,7 @@ The value of the first argument whose value isn’t null (or not-empty for strin
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20req_duration_ms%2C%20server_datacenter%2C%20predicate%20%3D%20coalesce(content_type%2C%20method%2C%20status)%22%7D)
-## extract()
+## extract
Retrieve the first substring matching a regular expression from a source string.
@@ -235,7 +238,7 @@ extract("x=([0-9.]+)", 1, "axiom x=65.6|po") == "65.6"
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20project%20extract_sub%20%3D%20%20extract(%5C%22x%3D(%5B0-9.%5D%2B)%5C%22%2C%201%2C%20%5C%22axiom%20x%3D65.6%7Cpo%5C%22)%20%3D%3D%20%5C%2265.6%5C%22%22%7D)
-## extract_all()
+## extract_all
Retrieve all substrings matching a regular expression from a source string. Optionally, retrieve only a subset of the matching groups.
@@ -278,7 +281,7 @@ extract_all(@"(\w)(\w+)(\w)", dynamic([1,3]), content_type) == [["t", "t"],["c",
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%5Cn%7C%20project%20extract_match%20%3D%20extract_all(%40%5C%22(%5C%5Cw)(%5C%5Cw%2B)(%5C%5Cw)%5C%22%2C%20pack_array()%2C%20content_type)%22%2C%22queryOptions%22%3A%7B%22quickRange%22%3A%2230d%22%7D%7D)
-## format_bytes()
+## format_bytes
Formats a number as a string representing data size in bytes.
@@ -316,7 +319,7 @@ format_bytes(8000000, 2, "MB", 10) == "8.00 MB"
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27github-issues-event%27%5D%5Cn%7C%20project%20formated_bytes%20%3D%20format_bytes(4783549035%2C%20number%2C%20%5C%22%5B%27id%27%5D%5C%22%2C%20num_comments)%22%7D)
-## format_url()
+## format_url
Formats an input string into a valid URL. This function will return a string that is a properly formatted URL.
@@ -348,7 +351,7 @@ Formats an input string into a valid URL. This function will return a string tha
- These are all the supported keys when using the `format_url` function: scheme, host, port, fragment, user, password, query.
-## indexof()
+## indexof
Reports the zero-based index of the first occurrence of a specified string within the input string.
@@ -387,7 +390,7 @@ indexof ()
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27github-issues-event%27%5D%5Cn%7C%20project%20occurrence%20%3D%20indexof%28%20body%2C%20%5B%27id%27%5D%2C%2023%2C%205%2C%20number%20%29%22%7D)
-## isempty()
+## isempty
Returns `true` if the argument is an empty string or is null.
@@ -412,7 +415,7 @@ isempty([value])
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20empty%20%3D%20isempty%28num_comments%29%22%7D)
-## isnotempty()
+## isnotempty
Returns `true` if the argument isn’t an empty string, and it isn’t null.
@@ -435,7 +438,7 @@ notempty([value]) -- alias of isnotempty
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20not_empty%20%3D%20isnotempty%28num_comments%29%22%7D)
-## isnotnull()
+## isnotnull
Returns `true` if the argument is not null.
@@ -458,7 +461,7 @@ notnull([value]) - alias for `isnotnull`
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20not_null%20%3D%20isnotnull%28num_comments%29%22%7D)
-## isnull()
+## isnull
Evaluates its sole argument and returns a bool value indicating if the argument evaluates to a null value.
@@ -479,7 +482,7 @@ isnull(Expr)
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20is_null%20%3D%20isnull%28creator%29%22%7D)
-## parse_bytes()
+## parse_bytes
Parses a string including byte size units and returns the number of bytes
@@ -522,7 +525,7 @@ parse_bytes("bad data") == 0
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20parsed_bytes%20%3D%20%20parse_bytes%28%5C%22300%20KB%5C%22%2C%2010%29%22%7D)
-## parse_json()
+## parse_json
Interprets a string as a JSON value and returns the value as dynamic.
@@ -559,7 +562,7 @@ parse_json(json)
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20extend%20parsed%20%3D%20parse_json%28creator%29%5Cn%7C%20where%20isnotnull%28parsed%29%22%7D)
-## parse_url()
+## parse_url
Parses an absolute URL `string` and returns an object contains `URL parts.`
@@ -604,7 +607,7 @@ parse_url(url)
}
```
-## parse_urlquery()
+## parse_urlquery
Returns a `dynamic` object contains the Query parameters.
@@ -651,7 +654,7 @@ parse_urlquery(query)
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20parsed%20%3D%20parse_urlquery%28%5C%22https%3A%2F%2Fplay.axiom.co%2Faxiom-play-qf1k%2Fexplorer%3Fqid%3DfUKgiQgLjKE-rd7wjy%5C%22%29%22%7D)
-## replace()
+## replace
Replace all regex matches with another string.
@@ -678,7 +681,7 @@ replace(regex, rewrite, source)
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%5Cn%7C%20project%20content_type%2C%20Comment%20%3D%20replace%28%5C%22%5Bhtml%5D%5C%22%2C%20%5C%22%5Bcensored%5D%5C%22%2C%20method%29%22%7D)
-## replace_regex()
+## replace_regex
Replaces all regex matches with another string.
@@ -732,7 +735,7 @@ Backreferences match the same text as previously matched by a capturing group. W
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%20%7C%20project%20backreferences%20%3D%20replace_regex(%40'observability%3D(.%2B)'%2C%20'axiom%3D%241'%2C%20creator)%22%7D)
-## replace_string()
+## replace_string
Replaces all string matches with another string.
@@ -774,7 +777,7 @@ replace_string(lookup, rewrite, text)
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%20%22%5B%27sample-http-logs%27%5D%5Cn%7C%20extend%20replaced_string%20%3D%20replace_string%28%27github%27%2C%20%27axiom%27%2C%20%27The%20project%20is%20hosted%20on%20github%27%29%5Cn%7C%20project%20replaced_string%22%7D)
-## reverse()
+## reverse
Function reverses the order of the input Field.
@@ -806,7 +809,7 @@ project reversed = reverse("axiom")
moixa
```
-## split()
+## split
Splits a given string according to a given delimiter and returns a string array with the contained substrings.
@@ -841,7 +844,7 @@ project split_str = split("axiom_observability_monitoring", "_")
}
```
-## strcat()
+## strcat
Concatenates between 1 and 64 arguments.
@@ -885,7 +888,7 @@ strcat(argument1, argument2[, argumentN])
}
```
-## strcat_delim()
+## strcat_delim
Concatenates between 2 and 64 arguments, with delimiter, provided as first argument.
@@ -927,7 +930,7 @@ project strcat = strcat_delim(":", "axiom", "monitoring")
}
```
-## strcmp()
+## strcmp
Compares two strings.
@@ -974,7 +977,7 @@ project cmp = strcmp( "axiom", "observability")
}
```
-## strlen()
+## strlen
Returns the length, in characters, of the input string.
@@ -1008,7 +1011,7 @@ project str_len = strlen("axiom")
}
```
-## strrep()
+## strrep
Repeats given string provided amount of times.
@@ -1053,7 +1056,7 @@ project repeat_string = strrep( "axiom", 3, "::" )
}
```
-## substring()
+## substring
Extracts a substring from a source string.
@@ -1090,7 +1093,7 @@ project extract_string = substring( "axiom", 4, 5 )
}
```
-## toupper()
+## toupper
Converts a string to upper case.
@@ -1105,7 +1108,7 @@ toupper("axiom") == "AXIOM"
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20upper%20%3D%20toupper(%20body%20)%22%7D)
-## tolower()
+## tolower
Converts a string to lower case.
@@ -1120,7 +1123,22 @@ tolower("AXIOM") == "axiom"
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20low%20%3D%20tolower%28body%29%22%7D)
-## trim()
+## totitle
+
+Converts a string to title case.
+
+```kusto
+totitle("axiom") == "Axiom"
+```
+
+```kusto
+['github-issues-event']
+| project low = totitle(body)
+```
+
+[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'github-issues-event'%5D%5Cn%7C%20project%20low%20%3D%20totitle%28body%29%22%7D)
+
+## trim
Removes all leading and trailing matches of the specified cutset.
@@ -1158,7 +1176,7 @@ project remove_leading_matches = trim( "axiom", "observability")
}
```
-## trim_regex()
+## trim_regex
Removes all leading and trailing matches of the specified regular expression.
@@ -1192,7 +1210,7 @@ trim_regex(regex, source)
}
```
-## trim_end()
+## trim_end
Removes trailing match of the specified cutset.
@@ -1226,7 +1244,7 @@ trim_end(source)
}
```
-## trim_end_regex()
+## trim_end_regex
Removes trailing match of the specified regular expression.
@@ -1260,7 +1278,7 @@ trim_end_regex(regex, source)
}
```
-## trim_start()
+## trim_start
Removes leading match of the specified cutset.
@@ -1293,7 +1311,7 @@ trim_start(source)
}
```
-## trim_start_regex()
+## trim_start_regex
Removes leading match of the specified regular expression.
@@ -1327,7 +1345,7 @@ trim_start_regex(regex, source)
}
```
-## url_decode()
+## url_decode
The function converts encoded URL into a to regular URL representation.
@@ -1360,7 +1378,7 @@ url_decode(encoded url)
}
```
-## url_encode()
+## url_encode
The function converts characters of the input URL into a format that can be transmitted over the Internet.
@@ -1393,7 +1411,7 @@ url_encode(url)
}
```
-## gettype()
+## gettype
Returns the runtime type of its single argument.
@@ -1420,7 +1438,7 @@ A string representing the runtime type of its single argument.
| gettype(456.98) | **real** |
| gettype(parse_json('')) | **null** |
-## parse_csv()
+## parse_csv
Splits a given string representing a single record of comma-separated values and returns a string array with these values.
diff --git a/apl/scalar-functions/string-functions/base64-decode-toarray.mdx b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx
new file mode 100644
index 00000000..80da66b1
--- /dev/null
+++ b/apl/scalar-functions/string-functions/base64-decode-toarray.mdx
@@ -0,0 +1,123 @@
+---
+title: base64_decode_toarray
+description: 'This page explains how to use the base64_decode_toarray function in APL.'
+---
+
+Use the `base64_decode_toarray` function to decode a Base64-encoded string into an array of bytes. This is especially useful when you need to extract raw binary data from encoded inputs, such as network payloads, authentication tokens, or structured log fields. You can then transform or analyze the resulting byte array using additional APL functions like `array_slice`, `array_length`, or `array_index`.
+
+This function is useful in scenarios where logs or telemetry data include fields that store binary data encoded as Base64, which is common for compact transmission or obfuscation. By decoding these values into byte arrays, you gain visibility into the underlying structure of the data.
+
+## For users of other query languages
+
+If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.
+
+
+
+
+In Splunk SPL, decoding Base64 requires using `eval` with the `base64decode` function, which returns a string. If you need a byte array representation, you must manually transform it. In APL, `base64_decode_toarray` directly produces an array of bytes, allowing you to work with binary data more precisely.
+
+
+```sql Splunk example
+| eval decoded=base64decode(encodedField)
+````
+
+```kusto APL equivalent
+['my-dataset']
+| extend decoded = base64_decode_toarray(encodedField)
+```
+
+
+
+
+
+
+Standard ANSI SQL doesn’t include a native function to decode Base64 into byte arrays. You typically need to rely on a UDF or cast the result into `VARBINARY` if the engine supports it. APL provides a built-in function that directly yields an array of integers representing bytes.
+
+
+```sql SQL example
+SELECT CAST(FROM_BASE64(encodedField) AS BINARY) FROM my_table;
+```
+
+```kusto APL equivalent
+['my-dataset']
+| extend decoded = base64_decode_toarray(encodedField)
+```
+
+
+
+
+
+
+## Usage
+
+### Syntax
+
+```kusto
+base64_decode_toarray(base64_input)
+```
+
+### Parameters
+
+| Name | Type | Required | Description |
+| ------------- | ------ | -------- | --------------------------------------------------------------- |
+| base64_input | string | ✔️ | A Base64-encoded string. The input string must be valid Base64. |
+
+### Returns
+
+An array of integers representing the decoded byte values. If the input string is not valid Base64, the function returns an empty array.
+
+## Use case examples
+
+
+
+
+You want to decode a Base64-encoded field in logs to inspect raw payloads for debugging or transformation.
+
+**Query**
+
+```kusto
+['sample-http-logs']
+| extend raw = base64_decode_toarray('aGVsbG8gd29ybGQ=')
+```
+
+[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20extend%20raw%20%3D%20base64_decode_toarray('aGVsbG8gd29ybGQ%3D')%22%7D)
+
+**Output**
+
+| raw |
+| ------------------------------------------------------- |
+| [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] |
+
+This query decodes the Base64 string `'aGVsbG8gd29ybGQ='`, which represents the ASCII string `"hello world"`, into an array of byte values.
+
+
+
+
+You receive Base64-encoded trace IDs from an external system and want to decode them for low-level correlation.
+
+**Query**
+
+```kusto
+['otel-demo-traces']
+| extend trace_bytes = base64_decode_toarray(trace_id)
+| project trace_id, trace_bytes
+```
+
+[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D%20%7C%20extend%20trace_bytes%20%3D%20base64_decode_toarray(trace_id)%20%7C%20project%20trace_id%2C%20trace_bytes%22%7D)
+
+**Output**
+
+| trace_id | trace_bytes |
+| -------------------- | -------------------------------------------------------------- |
+| dHJhY2UtaWQtZGVtbw== | [116, 114, 97, 99, 101, 45, 105, 100, 45, 100, 101, 109, 111] |
+
+This query decodes the trace ID from Base64 into its byte-level representation for internal processing or fingerprinting.
+
+
+
+
+## List of related functions
+
+- [array_length](/apl/scalar-functions/array-functions/array-length): Returns the number of elements in an array. Use after decoding to validate payload length.
+- [array_slice](/apl/scalar-functions/array-functions/array-slice): Extracts a subrange from an array. Use to focus on specific byte segments after decoding.
+- [base64_encode_fromarray](/apl/scalar-functions/string-functions/base64-encode-fromarray): Converts a sequence of bytes into a Base64-encoded string.
diff --git a/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx
new file mode 100644
index 00000000..4effb618
--- /dev/null
+++ b/apl/scalar-functions/string-functions/base64-encode-fromarray.mdx
@@ -0,0 +1,103 @@
+---
+title: base64_encode_fromarray
+description: 'This page explains how to use the base64_encode_fromarray function in APL.'
+---
+
+Use the `base64_encode_fromarray` function to convert a sequence of bytes into a Base64-encoded string. This function is useful when you need to transform binary data into a textual representation for safe storage, logging, or transmission—especially over protocols that require plain-text formats.
+
+You can apply this function when working with IP addresses, file contents, or any byte array that needs to be encoded for use in logs or APIs. It accepts a byte array and returns the Base64-encoded string representation of that array.
+
+## For users of other query languages
+
+If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.
+
+
+
+
+Splunk doesn’t provide a native function to directly encode an array of bytes into Base64 in SPL. You would typically write a custom script using an external command or use `eval` with a helper function in an app context.
+
+
+```sql Splunk example
+| eval encoded=custom_base64_encode(byte_array_field)
+````
+
+```kusto APL equivalent
+datatable(bytes: dynamic)
+[
+ dynamic([192, 168, 1, 1])
+]
+| extend encoded = base64_encode_fromarray(bytes)
+```
+
+
+
+
+
+
+ANSI SQL doesn’t define a built-in standard for Base64 encoding from an array of bytes. This is usually handled via vendor-specific functions (e.g., `TO_BASE64()` in MySQL, or `encode()` in PostgreSQL).
+
+
+```sql SQL example
+SELECT TO_BASE64(BINARY 'data') AS encoded;
+```
+
+```kusto APL equivalent
+datatable(bytes: dynamic)
+[
+ dynamic([192, 168, 1, 1])
+]
+| extend encoded = base64_encode_fromarray(bytes)
+```
+
+
+
+
+
+
+## Usage
+
+### Syntax
+
+```kusto
+base64_encode_fromarray(array)
+```
+
+### Parameters
+
+| Name | Type | Required | Description |
+| ----- | ------- | -------- | ----------------------------------------------------------------------- |
+| array | dynamic | ✔️ | A dynamic array of integers between 0 and 255 representing byte values. |
+
+### Returns
+
+If successful, returns a string representing the Base64-encoded version of the input byte array. If the input is not a valid array of bytes, the result is an empty string.
+
+## Example
+
+Use this function to encode request metadata for logging or comparison with external systems that require Base64-encoded fields.
+
+**Query**
+
+```kusto
+['sample-http-logs']
+| extend ip_bytes = dynamic([192, 168, 0, 1])
+| extend encoded_ip = base64_encode_fromarray(ip_bytes)
+| project _time, id, method, uri, encoded_ip
+```
+
+[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20extend%20ip_bytes%20%3D%20dynamic(%5B192%2C%20168%2C%200%2C%201%5D)%20%7C%20extend%20encoded_ip%20%3D%20base64_encode_fromarray(ip_bytes)%20%7C%20project%20_time%2C%20id%2C%20method%2C%20uri%2C%20encoded_ip%22%7D)
+
+**Output**
+
+| _time | id | method | uri | encoded_ip |
+| -------------------- | ------- | ------ | --------- | ----------- |
+| 2025-06-25T08:00:00Z | user123 | GET | /api/data | wKgAAQ== |
+
+Encodes a hardcoded byte representation of an IP address into Base64 for easy string-based comparison or logging.
+
+## List of related functions
+
+- [array_concat](/apl/scalar-functions/array-functions/array-concat): Concatenates arrays of bytes or values. Use this when building byte arrays for Base64 encoding.
+- [base64_decode_toarray](/apl/scalar-functions/string-functions/base64-decode-toarray): Decode a Base64-encoded string into an array of bytes. Use this when decoding data received from external sources.
+- [format_ipv4_mask](/apl/scalar-functions/ip-functions/format-ipv4-mask): Formats a raw IPv4 address with an optional prefix into CIDR notation. Use when dealing with IP-to-string transformations.
+- [parse_ipv4](/apl/scalar-functions/ip-functions/parse-ipv4): Parses a string representation of an IP address into its numeric form. Use this before encoding or masking IP addresses.
diff --git a/docs.json b/docs.json
index 36323e36..8dca3a7b 100644
--- a/docs.json
+++ b/docs.json
@@ -369,6 +369,8 @@
"apl/scalar-functions/array-functions/array-shift-left",
"apl/scalar-functions/array-functions/array-shift-right",
"apl/scalar-functions/array-functions/array-slice",
+ "apl/scalar-functions/array-functions/array-sort-asc",
+ "apl/scalar-functions/array-functions/array-sort-desc",
"apl/scalar-functions/array-functions/array-split",
"apl/scalar-functions/array-functions/array-sum",
"apl/scalar-functions/array-functions/bag-has-key",
@@ -457,6 +459,8 @@
"group": "String functions",
"pages": [
"apl/scalar-functions/string-functions",
+ "apl/scalar-functions/string-functions/base64-decode-toarray",
+ "apl/scalar-functions/string-functions/base64-encode-fromarray",
"apl/scalar-functions/string-functions/indexof_regex",
"apl/scalar-functions/string-functions/parse_path",
"apl/scalar-functions/string-functions/regex_quote"
diff --git a/vale/styles/config/vocabularies/docs/accept.txt b/vale/styles/config/vocabularies/docs/accept.txt
index 12e65d0e..c3fccb3f 100644
--- a/vale/styles/config/vocabularies/docs/accept.txt
+++ b/vale/styles/config/vocabularies/docs/accept.txt
@@ -56,4 +56,5 @@ Axiom Processing Language
subpath
[Dd]atastore
[Tt]ooltip
-[Vv]iewport
\ No newline at end of file
+[Vv]iewport
+functionality
\ No newline at end of file