Data types
Every variable and every activity result has a data type. The type determines what you can do with that value: a text can be converted to uppercase, a number can be added, a table can be traversed row by row. Knowing the type of your variables is key to writing correct expressions.
Primitive types
Section titled “Primitive types”They are the simplest values: a text, a number, a yes/no.
| Type | Description | Examples |
|---|---|---|
string | Text | "Hello world", "INV-001" |
int / long | Whole number | 42, -7 |
double / decimal | Number with decimals (the decimal separator is the dot). Use decimal for money | 3.14, 1250.50m |
boolean | Logical value: true or false | true, false |
DateTime | Date and time | result of now(), today() |
TimeSpan | A duration | now() - start |
object | Any value | — |
The type selector in the variables panel groups them (Primitive, Collection, Data, Security, Session…) and has a search box. Composite type… builds types such as List<int> or Dictionary<string,string>.
string members
Section titled “string members”On a text you can call these methods (besides the built-in functions such as upper, trim…):
| Member | Returns | Description |
|---|---|---|
.Length | int | Number of characters |
.ToUpper() | string | Uppercase |
.ToLower() | string | Lowercase |
.Trim() / .TrimStart() / .TrimEnd() | string | Removes spaces |
.Contains(value) | bool | Does it contain the substring? |
.StartsWith(value) / .EndsWith(value) | bool | Does it start / end with? |
.Replace(old, new) | string | Replaces occurrences |
.Split(separator) | string[] | Splits into parts |
.Substring(start) / .Substring(start, length) | string | Extracts a portion |
.IndexOf(value) | int | Position of the first occurrence (-1 if not found) |
.PadLeft(width, char) / .PadRight(width, char) | string | Pads up to a width |
name.ToUpper()code.Substring(0, 3) // first 3 charactersemail.Split("@")[1] // email domainDateTime members
Section titled “DateTime members”| Member | Returns | Description |
|---|---|---|
.Year .Month .Day | int | Date parts |
.Hour .Minute .Second .Millisecond | int | Time parts |
.DayOfWeek | DayOfWeek | Day of the week |
.DayOfYear | int | Day of the year (1–366) |
.Date | DateTime | Date only (00:00:00) |
.ToString(format) | string | Formats it. E.g.: "yyyy-MM-dd", "dd/MM/yyyy HH:mm" |
.AddDays(n) .AddHours(n) .AddMinutes(n) | DateTime | Adds time (n can be negative) |
.AddMonths(n) .AddYears(n) | DateTime | Adds months / years |
.Subtract(otherDate) | TimeSpan | Difference between two dates |
today().AddDays(-7) // a week agonow().ToString("yyyy-MM-dd_HH-mm") // useful for naming filesdueDate.Subtract(today()).Days // days leftCollection types
Section titled “Collection types”They group several values. Indexes start at 0.
List — ordered list
Section titled “List — ordered list”A sequence of elements. It is declared with its element type, for example List<string>. It is created with the Create List activity, with new List<string>(), with the newList() or arr(…) functions, or as the result of functions such as split.
| Member | Returns | Description |
|---|---|---|
.Count | int | Number of elements |
.Add(item) | — | Adds an element at the end |
.Remove(item) / .RemoveAt(index) | — | Removes an element |
.Clear() | — | Empties the list |
.Contains(item) | bool | Is the element there? |
.IndexOf(item) | int | Position of the element |
.First() / .FirstOrDefault() | element | First one (FirstOrDefault returns null if empty) |
.Last() | element | Last one |
.Any() / .All(cond) | bool | Is there any / do all match? |
.Where(cond) | IEnumerable | Filters (LINQ — end with .ToList()) |
.Select(proj) | IEnumerable | Transforms (LINQ — end with .ToList()) |
.OrderBy(key) | IEnumerable | Sorts (LINQ) |
.ToList() / .ToArray() | List / array | Materializes the result |
products.Countproducts.Where(p => p > 100).ToList()names.Contains("Ana")Dictionary — key→value map
Section titled “Dictionary — key→value map”Associates a text key with a value. The most common one is Dictionary<string,object>. It is created with Create Dictionary, with newDict() or with new Dictionary<string, object>().
| Member | Returns | Description |
|---|---|---|
.Count | int | Number of keys |
.Keys / .Values | collection | All keys / values |
.ContainsKey(key) | bool | Does the key exist? |
.Add(key, value) | — | Adds a pair |
.Remove(key) | bool | Removes a key |
.GetValueOrDefault(key) | value | Value, or null if it doesn’t exist |
config["timeout"] // access by keyconfig.ContainsKey("proxy")config.GetValueOrDefault("language")DataTable — table of rows and columns
Section titled “DataTable — table of rows and columns”A table with named columns, like an Excel sheet. It is the common format shared by Excel, CSV, databases and Google Sheets: what you read from one source you can write to another without converting.
| Member | Returns | Description |
|---|---|---|
.Rows | DataRowCollection | The rows |
.Rows.Count | int | Number of rows |
.Columns | DataColumnCollection | The columns |
.Columns.Count | int | Number of columns |
.AsEnumerable() | IEnumerable<DataRow> | To use LINQ on the rows |
.Select(filter) | DataRow[] | Filters with an SQL-like expression (e.g. "Total > 1000") |
.NewRow() | DataRow | Creates an empty row with the same structure |
.Clone() | DataTable | Copies the structure without rows |
.Copy() | DataTable | Copies structure and rows |
Handy functions for tables: rowCount(dt), colCount(dt), firstRow(dt), asRows(dt), selectRows(dt, cond) (see Expressions).
DataRow — a table row
Section titled “DataRow — a table row”Each element of a For Each over a DataTable is a DataRow. You access its cells by column name with square brackets:
row["Customer"] // raw value (may be DBNull)str(row["Customer"]) // safe text (recommended)num(row["Total"]) // safe number| Member | Returns | Description |
|---|---|---|
row["column"] | object | Cell value |
.Table | DataTable | The table it belongs to |
.ItemArray | object[] | All cells as an array |
.IsNull("column") | bool | Is the cell empty? |
Editing collections by hand
Section titled “Editing collections by hand”When a parameter accepts a list, dictionary or table that you write yourself, the Properties panel shows an Edit… button with a visual editor, so you don’t have to write the structure by hand. The same applies to filter conditions.
All of the Designer’s visual editors are explained in Parameter editors.
Session types (open resources)
Section titled “Session types (open resources)”Some activities open a resource (a browser, an Excel workbook, a database connection) and return a session that represents that open resource. You pass that session to the other activities of the same package, and at the end you close it. It’s the same pattern across the platform: open → use → close.
| Type | Opened by | Closed by | Purpose |
|---|---|---|---|
ZoanPageSession | Open Browser / Attach Browser | Close Browser / Close Page | The browser and its page (Chrome/Edge) |
ZoanExcelSession | Excel Open / Excel Create | Excel Close | Excel workbook |
ZoanWordSession | Word Open / Word Create | Word Close | Word document |
ZoanDbSession | DB Connect | DB Close | Database connection |
ZoanSftpSession | SFTP Connect | SFTP Close | SFTP server |
ZoanGoogleSheetsSession | GoogleSheets Open | GoogleSheets Close | Google spreadsheet |
ZoanOutlookSession | (Outlook activities) | — | Outlook session |
ZoanDesktopSession | Open App / Win Attach | Win Close | Windows desktop application |
// Typical pattern: the output of "open" feeds the next activities// Open Browser → Save result in: page// Get Text → page: page → Save result in: title// Close Browser → session: pageActivity result types
Section titled “Activity result types”Other activities return an object with structured data that you do read through its properties.
ZoanHttpResponse — HTTP response
Section titled “ZoanHttpResponse — HTTP response”Result of the HTTP activities (GET, POST, PUT, PATCH, DELETE).
| Property | Type | Description |
|---|---|---|
.StatusCode | int | HTTP code (200, 404, 500…) |
.Ok | boolean | true if the code is 2xx |
.Body | object | Response body. If it is JSON, it is deserialized automatically |
.Headers | Dictionary | Response headers |
response.Okresponse.StatusCode == 200response.Body["token"] // if the body is JSONresponse.Headers["Content-Type"]ZoanMail — email
Section titled “ZoanMail — email”Result of the email reading activities (Outlook, IMAP, POP3).
| Property | Type | Description |
|---|---|---|
.Id | string | Unique identifier (use it to move/delete/get attachments) |
.Subject | string | Subject |
.From | string | Sender |
.To / .Cc / .Bcc | string[] | Recipients |
.Body | string | Body (plain text or HTML depending on IsHtml) |
.IsHtml | boolean | Is the body HTML? |
.SentAt | DateTime | Sent/received date |
.IsRead | boolean | Has it been read? |
.Attachments | ZoanAttachment[] | Attachments (if requested) |
email.Subjectemail.Fromcount(email.Attachments) > 0ZoanAttachment — attachment
Section titled “ZoanAttachment — attachment”| Property | Type | Description |
|---|---|---|
.Name | string | File name |
.ContentType | string | MIME type (e.g. application/pdf) |
.Content | byte[] | Binary content |
ZoanQueueItem — queue item
Section titled “ZoanQueueItem — queue item”Result of consuming a Zoan Cloud queue (Queue package).
| Property | Type | Description |
|---|---|---|
.Id | string | Item identifier |
.QueueId | string | Queue it belongs to |
.Reference | string? | Business reference (e.g. invoice number) |
.Priority | string | low / normal / high |
.Status | string | new / inProgress / success / failed… |
.SpecificContent | Dictionary | Item data (the fields you set when queuing it) |
.Output | Dictionary? | Result, once processed |
.Attempts | int | Number of attempts |
.CreatedAt | string | Creation date |
item.Referenceitem.SpecificContent["taxId"]ZoanError — captured error
Section titled “ZoanError — captured error”It is the object the errorVariable of Try / Catch receives when something in the Try lane fails.
| Property | Type | Description |
|---|---|---|
.Message | string | Error message |
.Type | string | Exception type (e.g. "HttpRequestException", "TimeoutException"); use it to tell errors apart |
.Source | string | Source of the exception |
.StackTrace | string | Stack trace |
error.Messageerror.Type == "TimeoutException" // branch on the error typeTo show the error in a log or an email, use error.Message.
Converting between types
Section titled “Converting between types”When a value arrives as text but you need a number (or the other way around), convert it explicitly:
toNumber(row["Total"]) // text → numbertoInt(quantityText) // text → integertoString(counter) // number → textparseDouble(replace(amount, ",", ".")) // "1234,56" with a decimal comma → numberSee the full list in Expressions › Type conversion.
Next steps
Section titled “Next steps”- Variables: declare variables with a type.
- Expressions: operate on these types.
- Activity catalog: which type each activity returns.