# Access Setup Best Practices Source: https://docs.elementum.io/administration/access-overview Plan domains, groups, roles, and data access before inviting users to your Elementum organization Access in Elementum is built around two ideas that drive every decision in this section: * **Roles and permissions determine what a user can *do*** -- create records, edit apps, run automations, invite other users. * **Object data access policies determine what a user can *see*** -- which specific records appear in lists, search, and reports. You can satisfy both by assigning permissions to individual users, but **roles, permissions, and data access are best managed at the group level**. Groups are easier to audit, faster to onboard new users into, and the only practical way to keep access aligned with your organization as it grows. *** ## Ways to Create Users Users can enter your Elementum organization through three paths. Pick the one that matches your operating model -- they all land users in the same access model, so the choice is about lifecycle automation, not capability. * **Manual creation in Organization Settings** -- An admin invites users from **Org Settings → Groups** (recommended) or **Org Settings → Users**. The user receives an email and self-completes registration. Best for small teams, ad-hoc invites, and external collaborators. See [Users](/administration/users). * **Single Sign-On (SSO)** -- Users authenticate through your Identity Provider. With **Auto Create Unknown Users** enabled, Elementum creates the user account on their first SSO login. Best for organizations that want centralized authentication without automated lifecycle management. See [SSO with SAML 2.0](/administration/sso-saml-setup). * **SCIM provisioning** -- Your IdP pushes user and group changes to Elementum, so accounts exist in Elementum *before* a user logs in. Best for organizations that need automated onboarding, profile syncing, and deactivation tied to identity-system membership. See [SCIM Provisioning](/administration/sso-saml-setup#scim-provisioning). *** ## Recommended Setup Order Set your organization up in this order before inviting users. Each step builds on the one before it, and skipping ahead almost always results in rework. Define the email domains that belong to your organization. Domains are the foundation for nearly everything that follows: they drive [dynamic groups](/administration/groups), gate the [User Invite Policy](/administration/roles-permissions#user-invite-policy), and identify users coming in through your [Identity Provider](/administration/sso-saml-setup). Get this list right first -- changes here ripple into every group and policy that references a domain. Build the [groups](/administration/groups) that mirror how your organization actually works -- typically by team, function, or location. * Use **dynamic groups** when membership can be derived from email domain (for example, "All Employees" or "All Contractors"). * Use **manually managed groups** for stable, intentional teams (for example, an approval committee or a small admin group). Plan for the groups you need first; do not create groups one role at a time. Assign each group to the [roles and permissions](/administration/roles-permissions) it needs. For every role, decide whether it belongs at the **organization level** or the **object level** -- see [Org-level vs Object-level Roles](#org-level-vs-object-level-roles) below. Granting a role to a group means every current and future member inherits the same capabilities, so changes to the group propagate automatically. Use [object data access policies](/workflows/object-data-access) to control which records each group can see. Policies are the right place to express "this team only sees their own records," "managers see their direct reports' records," or "external partners only see records they were invited to." Apply policies to **groups**, not individual users, so a user's visibility moves with their group membership. Now invite [users](/administration/users) and add them to the appropriate groups. Because roles and data access are already attached to those groups, every new user inherits the correct capabilities and visibility immediately, with no per-user configuration required. Following this order is the difference between onboarding a new hire in seconds (add to a group) and onboarding them over hours (configure roles, permissions, and data access on each individual account). *** ## Roles vs. Object Data Access These two systems work together but answer different questions. Configure both for every group. | | Roles & Permissions | Object Data Access | | -------------------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------- | | **What it controls** | What a user can do | What a user can see | | **Examples** | Create records, edit apps, run automations, invite users | Which specific records appear in lists, search, and reports | | **Where it is configured** | Org Settings → Roles & Permissions, or Roles & Permissions under an app's Security menu | App → Security → Data Access | | **Best assigned to** | Groups | Groups | A user with a powerful role but no data access policy can do a lot -- to nothing, because they cannot see any records. A user with broad data access but no role can see records but cannot act on them. You almost always want both. *** ## Org-level vs Object-level Roles When you assign or create a role, choose its scope deliberately. Picking the wrong scope is the most common cause of access drift over time. * **Organization-level roles** apply across **every** app, element, and task the user can reach. Use them for administrative oversight responsibilities -- IT admins, compliance officers, security operators, platform admins -- where the role *should* cascade everywhere. * **Object-level roles** (also called app-, element-, or task-level roles) apply only inside a single object. Use them for department- or workflow-specific responsibilities -- a vendor risk app's reviewers, a procurement app's buyers, an incident app's responders -- where the role only makes sense within that workflow. As a rule, default to **object-level** scope and only escalate to organization-level when the user genuinely needs the same capability across every app. Object-level custom roles also unlock [Auto Share Options](/administration/roles-permissions#auto-share-options), which are not available on organization-level roles. Organization-level roles cascade. Granting an org-level role increases a group's reach across every accessible app at once. Reserve org-level roles for the small set of users responsible for org-wide administration. *** ## Continue Reading Organize users into groups for scalable role and access assignment Decide what each group can do across the organization or within a specific object Control which records each group can see using dynamic policies Invite users into your organization and assign them to groups Create dedicated, auditable identities for automations and agents Centralize authentication through your existing Identity Provider Require periodic re-verification for users in the External Users group # Account Lockout Source: https://docs.elementum.io/administration/account-lockout How Elementum protects accounts from brute-force attacks and how locked users can restore access without contacting support. ## Overview After 5 consecutive failed login attempts, Elementum automatically locks the account and rejects all further login attempts. To restore access, the user must click **Forgot Password** on the login screen and complete a password reset. This unlocks the account -- no support ticket or admin intervention required. This policy applies to password-based login only. Users who authenticate through an Identity Provider via [SSO/SAML](/administration/sso-saml-setup) are governed by their IdP's own lockout and recovery policies. *** ## User recovery When locked out, go to the Elementum login page and click **Forgot Password**, then follow the password reset flow: 1. Enter the registered email address and click **Send Reset Link**. 2. Open the reset email and click the link. 3. Enter and confirm a new password, then click **Reset Password**. The account is unlocked immediately. No further action is required. Password reset links are single-use and expire after a short period. If the link has expired, return to the login page and request a new one. *** ## Admin visibility Org Admins can see when a user is locked from the **Users** page in Organization Settings. A lock icon appears in the **Locked** column next to any user whose account is currently locked. Locked accounts are visible for troubleshooting, but admins cannot manually unlock an account -- recovery is handled exclusively through the password reset flow to ensure the account owner is the one regaining access. *** ## Related features Add a second factor to login so a compromised password alone is not enough to gain access Centralize authentication through your Identity Provider, which manages its own lockout policies View and manage user statuses, including Locked accounts, from the admin console Require external users to periodically re-verify their identity via magic link # Activity Log Source: https://docs.elementum.io/administration/activity-log Review who changed what, when, and through which channel across your Elementum organization. ## Overview The Activity Log is an audit trail of actions in your Elementum organization. Entries are recorded automatically; you do not enable logging separately for each app or workflow. Typical uses include tracing changes to a specific user and time, supporting compliance and security reviews, and narrowing down causes when something goes wrong. *** ## What gets tracked You may see events such as: * Record and data changes, and workflow or automation runs * App configuration updates and agent-related actions * Organization settings updates * Activity from integrations and APIs Actions can come from the web interface, mobile app, API calls, or automations. Log entries generally include what changed, which account performed the action, when it occurred, and how the action was triggered. Users cannot edit or delete Activity Log entries. *** ## Where to find activity * **Record layouts** — Add the **Activity Log** component to your [layouts](/workflows/layouts) so activity appears on record detail pages. * **App, Element, or Task** — Open your object and navigate to **Security** → **Activity Log** in the left navigation menu to see activity scoped to that object. Activity appears in a searchable timeline, with user or system attribution where applicable. Expand an entry for full detail, including before-and-after values when available. *** ## Working with the log * **Filters** — Narrow by user, date range, activity type, or affected resources. * **Search** — Find specific activities, people, or resources. * **Detail** — Select an entry to see full context and links to related resources when available. *** ## Common scenarios Use the log to support reviews that require a record of data changes and which accounts performed them. Build a timeline of configuration and settings changes when investigating unexpected activity. Correlate configuration or automation changes with incidents or support cases. See what changed before an error or inconsistent data appeared, including failed or partial automation runs when logged. *** ## Best practices * Review logs periodically for operational and security visibility, according to your organization’s policies. * Restrict who can view Activity Logs to people who need that access for their role. * Clarify audit log retention requirements with your organization so they meet your compliance obligations. * Combine log review with notifications, reporting, and other tools you already use for operations. # CloudLink Overview Source: https://docs.elementum.io/administration/cloudlink-overview What CloudLink is, how it differs from your data warehouse, supported connection types, and the security model behind it. CloudLink is Elementum's secure connection mechanism. It's how Elementum reaches data and services that live outside the platform—your data warehouse (such as Snowflake) or an external REST API—so that workflows, apps, and automations can use that data where it already lives. ## CloudLink vs. Snowflake These are two different things that work together: | Term | What it is | Who owns it | | ------------- | ------------------------------------------------------------------------------- | ---------------------------- | | **Snowflake** | Your data warehouse. The system where your business data is stored. | Your organization | | **CloudLink** | The connection Elementum uses to reach Snowflake (or another supported system). | Elementum, configured by you | A CloudLink does **not** copy or move your data. Your data stays in Snowflake; CloudLink gives Elementum a governed, in-place way to read from and write to it. CloudLink uses **patented technology** for direct, in-place access to your warehouse data. That approach supports faster implementations and workflows that run against current data in your environment. ## What CloudLink provides * **Secure access** — Direct, encrypted connections with IP whitelisting and role-based access control. * **In-place data** — Your data stays in its source system. No data is copied or moved into Elementum. * **Centralized management** — One place in Elementum to configure, monitor, and rotate connections. * **Scalable architecture** — Supports small teams through enterprise-scale deployments. ## Common use cases A CloudLink to your warehouse is the foundation for processes that run on data you already own. Examples: * **Sales** — Opportunity routing, approvals, and pipeline monitoring from CRM or warehouse tables. * **Customer support** — Priority routing and response tracking from ticket and interaction history. * **Finance** — Reconciliation, spend monitoring, and reporting from ledger or transaction data. * **Supply chain** — Inventory, reorder, and supplier metrics from operational and logistics tables. ## Supported connection types A CloudLink connects to one of two kinds of systems. The setup steps differ for each, so pick the one that matches what you're connecting to. Connect Elementum to your Snowflake account using key-pair authentication. Required for Cortex AI features, change-tracking automations, and Snowflake stage workflows. Connect Elementum to an external REST API. Used primarily to power [API-powered dropdowns](/workflows/api-powered-dropdowns) and API Elements. Elementum also supports CloudLinks to [Google BigQuery](/guides/connect-bigquery-to-elementum) and [Databricks](/guides/connect-databricks-to-elementum). The concepts on this page apply to those platforms as well. **AI services require a data-warehouse CloudLink.** [AI Services](/ai-agents/ai-services) (LLMs, embeddings, Snowflake Cortex, etc.) cannot run on an API CloudLink. If you need AI services, choose a Snowflake (or other supported warehouse) CloudLink. ## Authentication CloudLink supports two authentication methods. Where the platform supports it, key-pair is required for full feature access. **Key-pair authentication (recommended)** Key-pair authentication uses an RSA key pair to secure the connection. Elementum holds the private key and gives you the public key to assign to your service account. Because the private key never leaves Elementum's infrastructure, there's no shared secret to leak or rotate manually. For Snowflake, key-pair authentication is **required** for change tracking, Cortex AI integration, and Cortex Agents. See [Connect Snowflake to Elementum](/administration/connect-snowflake-to-elementum#key-pair-authentication) for the full setup. **Password authentication** Password authentication is simpler to set up but is not recommended. If you use password authentication today, plan to migrate to key-pair using the Snowflake setup guide. ## The platform schema (critical concept) Every CloudLink to a data warehouse needs a small, dedicated schema (or dataset) that **Elementum uses for its own platform operations**. This is separate from your business data. **Do NOT enter your data schema in the CloudLink "Schema" field.** That field is for Elementum's internal platform operations only. **You must create a new, empty schema** (for example `ELEMENTUM_PLATFORM`) and enter that. Your actual data tables are selected separately after the connection is established. **If you enter your data schema here, it will be hidden from workflow building and you won't be able to access your data.** | What you enter | What happens | | ---------------------------------------------------------- | -------------------------------------------------------------------- | | ❌ Your data schema (for example `PUBLIC`, `SALES`) | Your data becomes inaccessible in Elementum | | ✅ Empty platform schema (for example `ELEMENTUM_PLATFORM`) | Elementum stores operational data here; your data remains accessible | **Critical:** The schema you choose for Elementum platform use is where Elementum creates and manages its own tables. That schema must be **used only by Elementum**. Do not store your own business tables in it or modify Elementum-managed objects there. External changes to those tables can cause Elementum to malfunction. ## Security model CloudLink is designed so that data access is secure, auditable, and revocable. RSA key-pair instead of passwords. Snowflake's dual-key support enables zero-downtime key rotation. IP whitelisting restricts inbound access to known Elementum IPs. All traffic uses TLS encryption. VPC/private network configurations are supported. Dedicated service account with minimal permissions. Each organization has separate access controls. Complete logging of all access and modifications. Contact your Elementum representative to discuss SOC 2, GDPR, HIPAA, and other compliance requirements. ### Security architecture **At rest** * Account data is encrypted using industry-standard algorithms. * Credentials are encrypted and never returned outside Elementum's internal systems. **In transit** * All traffic is encrypted using TLS. * Connections are supported over the public Internet or a VPN. * Application Firewall protects ingress traffic. * IP whitelisting restricts inbound access to known Elementum addresses. * VPN is supported with least-privilege network controls. * RSA key-pair authentication (recommended; required for full Snowflake feature support). * Role-based access control on the warehouse side. * Dedicated service account with minimal permissions per environment. * Each organization has separate access controls. * Complete logging of all data access and modifications. * All warehouse-side access is auditable through your warehouse's native audit logs (for Snowflake, query history and access history). ### Elementum IP addresses Whitelist these Elementum IPs in your data platform's network policy or firewall before attempting a connection. | Region | IP Addresses | | ----------- | --------------------------------------------------- | | **US East** | `44.210.166.136`, `44.209.114.114`, `52.72.254.246` | | **Europe** | `18.185.13.42`, `63.182.157.140`, `3.65.106.188` | The Snowflake setup guide includes copy-paste SQL for [creating a network policy](/administration/connect-snowflake-to-elementum#whitelist-elementum-ip-addresses) with these addresses. ## Keeping data fresh: real-time vs scheduled CloudLink supports two complementary mechanisms for keeping Elementum's view of your warehouse data current. You can use both, depending on the table. | Mechanism | What it does | Best for | | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | | **Real-time updates (change tracking)** | Elementum reacts to inserts and updates in your warehouse as they happen. Requires enabling change tracking on each Snowflake table. | Transactional data where workflows need to fire immediately on a new or changed row. | | **Scheduled updates** | Elementum re-reads the table on a configurable interval (default 20 minutes; minutes to days). | Analytical or slower-changing data, and resource-efficient batch processing. | For Snowflake, change tracking is enabled with an optional grant in the [setup script](/administration/connect-snowflake-to-elementum#step-4-grant-permissions-and-set-the-network-policy); the schedule is set during the [Elementum-side connection step](/administration/connect-snowflake-to-elementum#step-5-add-credentials-in-elementum). ## What you can do once connected After a CloudLink is set up, the same connection powers everything Elementum does with that warehouse: | Capability | Where to go next | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------- | | Bring warehouse tables into Elementum | [Tables](/data/tables) | | Build apps and workflows on warehouse data | [Build an app](/getting-started/build-an-app), [Flow](/getting-started/fundamentals/core-concepts) | | Detect new and changed data | [Data Mining](/data/data-mining) | | Trigger and run workflows on warehouse changes | [Automations](/workflows/automation-system) | | Process files stored in Snowflake stages | [Snowflake stages](/administration/snowflake-stages) | | Use Snowflake Cortex as your AI provider | [Snowflake Cortex setup](/ai-agents/snowflake-cortex-setup) | | Connect Snowflake Cortex Agents to apps | [Snowflake Cortex Agents](/ai-agents/snowflake-cortex-agents-setup) | | Run AI OCR on documents in Snowflake | [Snowflake AI OCR](/ai-agents/snowflake-ai-ocr) | ## Best practices 1. **Authentication** — Prefer key-pair authentication where supported; rotate credentials on your security schedule; limit who can change CloudLink settings. 2. **Platform schema** — Keep the Elementum platform schema dedicated and documented; never hand-edit Elementum-managed objects there. 3. **Data quality** — Use clear column names and consistent formats in source tables; keep data current for reliable workflows. 4. **Scope** — Connect only the tables you need; grant the minimum warehouse permissions required. 5. **Performance** — Plan refresh frequency for table size and cost; treat performance warnings seriously before production workflows depend on a table. 6. **External BI tools** — If you need warehouse data in BI tools such as Power BI or Tableau, **do not** point those tools at Elementum's platform schema. Use Elementum [Tables](/data/tables) to define views and exports that external tools can consume safely. ## Choose your connection type Step-by-step Snowflake setup: prerequisites, IP whitelisting, key-pair authentication, setup script, and Elementum-side credentials. Set up a CloudLink to an external REST API for use in API-powered dropdowns and API Elements. # Connect a REST API via CloudLink Source: https://docs.elementum.io/administration/connect-rest-api-cloudlink Set up a CloudLink to an external REST API for use in API-powered dropdowns and API Elements. In addition to data warehouses, Elementum can create a CloudLink to an external REST API. The primary use case for an API CloudLink is populating [API-powered dropdowns](/workflows/api-powered-dropdowns)—it stores the base URL and credentials in one place so dropdown fields and API Elements can call the API without re-entering connection details. If you're new to CloudLink, start with the [CloudLink Overview](/administration/cloudlink-overview) for the underlying concepts and security model. Before creating an API CloudLink, review [Populate Dropdown Fields from External APIs](/workflows/api-powered-dropdowns) to confirm this is the right setup for your use case and to see how the CloudLink is consumed downstream. **AI services are not supported on API CloudLinks.** [AI Services](/ai-agents/ai-services) (LLMs, embeddings, Snowflake Cortex, etc.) require a CloudLink configured against a supported data warehouse such as Snowflake. If you need AI services, set up a [Snowflake CloudLink](/administration/connect-snowflake-to-elementum) instead. ## Prerequisites Before creating an API CloudLink, gather: * **Admin access** to your Elementum organization (required to manage CloudLinks) * **Base URL** of the external API (for example, `https://api.example.com/v1`) * **Authentication details** for the API, depending on the method: * Basic — username and password * Bearer Token — a static API token * OAuth 2.0 — token URL, client ID, and client secret * **Network reachability** — confirm the API is reachable from the public internet. Elementum sends API requests server-side from its platform infrastructure. ## Create an API CloudLink In Elementum, open Settings icon **Organization Settings** and select **CloudLinks**. Click **+ CloudLink** in the upper right. In the **Create New CloudLink** dialog, select **API**. Fill out the API connection form: | Field | Description | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Name** | A descriptive name for the connection (for example, `Acme CRM` or `Internal Pricing API`). This is how the CloudLink appears in pickers across Elementum. | | **Base URL** | The root URL of the API. Endpoint paths configured later (on Elements or dropdown fields) are appended to this base URL. Use `https://` for production APIs. | | **Authentication** | The method used to authenticate requests. See [API authentication methods](#api-authentication-methods) below. | Select an authentication method from the dropdown and provide the required credentials. The fields displayed change based on the method you choose. Click **Save**. The new API CloudLink appears on the **CloudLinks** page and can be selected when configuring API Elements or API-powered dropdown fields. ## API authentication methods Choose the method supported by the external API: | Method | Required fields | Notes | | ---------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | **Basic** | Username, Password | Sent as a Base64-encoded `Authorization: Basic` header. Use only over HTTPS. | | **Bearer Token** | Token | Sent as `Authorization: Bearer ` on every request. | | **OAuth 2.0** | Token URL, Client ID, Client Secret (optional Scope) | Elementum runs the client credentials flow, caches the access token, and refreshes it automatically before expiration. | | **None** | — | No authentication header is sent. Use only for public, unauthenticated endpoints. | Avoid Basic authentication over non-HTTPS endpoints. Credentials are stored encrypted at rest in Elementum and are not displayed again in the UI after they're saved. ## Edit or rotate API credentials To update the URL or credentials on an existing API CloudLink: 1. On the **CloudLinks** page, click **Edit** next to the API connection. 2. Change the fields you need to update and click **Save**. For credential rotation, update the credentials in the external system first, then update them on the CloudLink to keep requests flowing without an outage. ## Using an API CloudLink After the API CloudLink is saved, use it to power dropdown fields. Continue with [Populate Dropdown Fields from External APIs](/workflows/api-powered-dropdowns), which walks through creating an API Element on top of this CloudLink, configuring the API Actions that fetch data from the external system, and adding a Dynamic Dropdown field that calls one of those API Actions to populate its options. ## Troubleshooting | Issue | Resolution | | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Save fails with an authentication error | Confirm the credentials work outside Elementum (for example, with `curl` or Postman). For OAuth 2.0, verify the token URL and that the client has access to the requested scope. | | Requests time out | Confirm the API is reachable from the public internet. If the API restricts inbound traffic, allow Elementum's outbound IP addresses (see [Elementum IP addresses](/administration/cloudlink-overview#elementum-ip-addresses)). | | Dropdown or Element returns no data | Verify the **Base URL** does not include a trailing endpoint path that conflicts with the path configured on the Element or dropdown. Endpoints are appended to the base URL. | | Need to change the auth method | Edit the CloudLink and select a different **Authentication** option. The credential fields update to match the new method. | ## Next steps Use this CloudLink to populate dropdown fields from external APIs. Review the CloudLink concept and security model. # Connect Snowflake to Elementum Source: https://docs.elementum.io/administration/connect-snowflake-to-elementum Step-by-step setup for a CloudLink between Snowflake and Elementum, in the order you'll execute it. This page is the chronological setup guide for a Snowflake CloudLink. Follow it top to bottom: prerequisites, IP whitelisting, key-pair authentication, the Snowflake setup script, the Elementum-side connection, and verification. If you're new to CloudLink or unsure how it differs from Snowflake itself, start with the [CloudLink Overview](/administration/cloudlink-overview). ## How it works Elementum connects directly to your Snowflake account using a dedicated service user, role, warehouse, and database. The connection is read/write where you grant it, and read-only where you don't. | Side | What it owns | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Your Snowflake account** | Your data (databases, tables, views). You grant access to a dedicated `ELEMENTUM` user/role with the exact permissions you choose. You can restrict access to known Elementum IP addresses. | | **Elementum platform** | A reader/writer service account that connects in-place to your Snowflake account. No data is copied or stored outside Snowflake; all operations execute in your Snowflake environment. | Both Internet and VPN traffic are encrypted with TLS. VPN provides additional security through least-privilege network controls. **Attachments and file uploads aren't stored in your Snowflake account.** File contents live in Elementum-managed cloud storage, not in a Snowflake table or blob column. Attachment metadata (name, media type, URL, size, and so on) is available through automations and the [REST API](/api-reference/api-introduction). See [Where attachments are stored](/workflows/file-uploads-attachments#where-attachments-are-stored) for the full picture. ## Prerequisites Before starting, confirm you have: * **`ACCOUNTADMIN`** role for setup * Tables/views with a primary key or unique identifier * Permission to create network policies * **Admin privileges** in Elementum to configure CloudLink connections * Your organization domain is already whitelisted on the Elementum side (`[your-org].elementum.io`) Identify which databases, schemas, and tables Elementum should access, and which need read/write vs read-only. ## Step 1: Whitelist Elementum IP addresses Configure your Snowflake network policy to allow connections from Elementum. | Region | IP Addresses | | ----------- | --------------------------------------------------- | | **US East** | `44.210.166.136`, `44.209.114.114`, `52.72.254.246` | | **Europe** | `18.185.13.42`, `63.182.157.140`, `3.65.106.188` | Whitelist **all IP addresses listed for your region** -- not just one. Elementum routes traffic across all addresses in the region's pool, so omitting any of them will cause intermittent connection failures. Use the SQL below for your region (or the combined option for multi-region). The network policy is applied to the `ELEMENTUM` user later in [Step 4](#step-4-grant-permissions-and-set-the-network-policy). ```sql US region theme={null} USE ROLE ACCOUNTADMIN; CREATE NETWORK POLICY IF NOT EXISTS ELEMENTUM_ACCESS_POLICY ALLOWED_IP_LIST = ( '44.210.166.136', '44.209.114.114', '52.72.254.246' ) COMMENT = 'Network policy for Elementum platform access'; ``` ```sql Europe region theme={null} USE ROLE ACCOUNTADMIN; CREATE NETWORK POLICY IF NOT EXISTS ELEMENTUM_ACCESS_POLICY ALLOWED_IP_LIST = ( '18.185.13.42', '63.182.157.140', '3.65.106.188' ) COMMENT = 'Network policy for Elementum platform access'; ``` ```sql Combined (US + Europe) theme={null} USE ROLE ACCOUNTADMIN; CREATE NETWORK POLICY IF NOT EXISTS ELEMENTUM_ACCESS_POLICY ALLOWED_IP_LIST = ( -- US Region '44.210.166.136', '44.209.114.114', '52.72.254.246', -- Europe Region '18.185.13.42', '63.182.157.140', '3.65.106.188' ) COMMENT = 'Network policy for Elementum platform access'; ``` Use the combined policy if your organization is configured for multi-region access or if you want to allow connections from both US and Europe. If your Elementum organization runs on AWS, you can use [AWS PrivateLink](/administration/snowflake-aws-privatelink) instead of public-internet IP whitelisting so CloudLink traffic between Elementum and your Snowflake account stays on the AWS network. ## Step 2: Get the public key from Elementum Elementum uses RSA key-pair authentication. The private key stays in Elementum's infrastructure; you assign the public key to your Snowflake service user. In Elementum, navigate to **Organization Settings** → **CloudLinks**. Click **+ CloudLink** and select **Snowflake** as the platform. The RSA public key is displayed in the connection setup dialog. Click **Copy Public Key** to copy it. You'll paste it into the Snowflake setup script in [Step 3](#step-3-run-the-snowflake-setup-script). Each Elementum environment generates its own unique key pair. If you're setting up [multiple environments](#multi-environment-setup), copy the public key separately from each environment's CloudLink settings. Leave the Elementum dialog open—you'll come back to it in [Step 5](#step-5-add-credentials-in-elementum). ## Step 3: Run the Snowflake setup script The script below creates the user, role, warehouse, database, and platform schema that Elementum needs. Run each step in order, replacing `` with the key you copied in Step 2. This script requires the `ACCOUNTADMIN` role. ```sql theme={null} USE ROLE ACCOUNTADMIN; CREATE ROLE IF NOT EXISTS ELEMENTUM; GRANT ROLE ELEMENTUM TO ROLE SYSADMIN; ``` ```sql theme={null} USE ROLE ACCOUNTADMIN; CREATE USER IF NOT EXISTS ELEMENTUM TYPE = SERVICE RSA_PUBLIC_KEY = ''; GRANT ROLE ELEMENTUM TO USER ELEMENTUM; ``` Paste the raw public key value without the `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----` header/footer lines. ```sql theme={null} USE ROLE SYSADMIN; CREATE WAREHOUSE IF NOT EXISTS ELEMENTUM WITH WAREHOUSE_SIZE = 'MEDIUM', MIN_CLUSTER_COUNT = 1, MAX_CLUSTER_COUNT = 10, AUTO_SUSPEND = 60; GRANT USAGE ON WAREHOUSE ELEMENTUM TO ROLE ELEMENTUM; ``` **Defaults:** Medium size, 1–10 clusters with auto-scaling, 60-second auto-suspend. Adjust based on your workload; see [Snowflake warehouses](/administration/snowflake-warehouses) for sizing guidance. ```sql theme={null} USE ROLE SYSADMIN; CREATE DATABASE IF NOT EXISTS ELEMENTUM; GRANT OWNERSHIP ON DATABASE ELEMENTUM TO ROLE ELEMENTUM; USE ROLE ELEMENTUM; USE DATABASE ELEMENTUM; CREATE SCHEMA IF NOT EXISTS ELEMENTUM_PLATFORM; ``` **Do not modify or add tables to the `ELEMENTUM_PLATFORM` schema.** It's reserved for Elementum's internal platform operations. See [The platform schema concept](/administration/cloudlink-overview#the-platform-schema-critical-concept). Use this only if you want a dedicated schema for tables built specifically for Elementum (such as data-exchange tables). Don't put these tables in `ELEMENTUM_PLATFORM`. ```sql theme={null} USE ROLE ELEMENTUM; USE DATABASE ELEMENTUM; CREATE SCHEMA IF NOT EXISTS PUBLIC; ``` ## Step 4: Grant permissions and set the network policy Apply the network policy you created in Step 1, then grant the `ELEMENTUM` role access to the data you want available in Elementum. ### Apply the network policy ```sql theme={null} USE ROLE ACCOUNTADMIN; ALTER USER ELEMENTUM SET NETWORK_POLICY = ELEMENTUM_ACCESS_POLICY; -- Verify DESC USER ELEMENTUM; ``` ### Grant data access The pattern is database usage → schema usage → table grants. Choose the access level you need. ```sql theme={null} USE ROLE SYSADMIN; -- Database and schema usage GRANT USAGE ON DATABASE TO ROLE ELEMENTUM; GRANT USAGE ON SCHEMA . TO ROLE ELEMENTUM; -- Table grants (fully qualified) GRANT INSERT, UPDATE, DELETE, SELECT ON TABLE .. TO ROLE ELEMENTUM; ``` ```sql theme={null} USE ROLE SYSADMIN; GRANT USAGE ON DATABASE SALES_DB TO ROLE ELEMENTUM; GRANT USAGE ON SCHEMA SALES_DB.PUBLIC TO ROLE ELEMENTUM; GRANT INSERT, UPDATE, DELETE, SELECT ON TABLE SALES_DB.PUBLIC.CUSTOMERS TO ROLE ELEMENTUM; GRANT INSERT, UPDATE, DELETE, SELECT ON TABLE SALES_DB.PUBLIC.ORDERS TO ROLE ELEMENTUM; ``` ```sql theme={null} USE ROLE SYSADMIN; GRANT USAGE ON DATABASE REFERENCE_DB TO ROLE ELEMENTUM; GRANT USAGE ON SCHEMA REFERENCE_DB.PUBLIC TO ROLE ELEMENTUM; GRANT SELECT ON TABLE REFERENCE_DB.PUBLIC.PRODUCTS TO ROLE ELEMENTUM; GRANT SELECT ON TABLE REFERENCE_DB.PUBLIC.CATEGORIES TO ROLE ELEMENTUM; ``` ```sql theme={null} USE ROLE SYSADMIN; GRANT USAGE ON DATABASE ANALYTICS_DB TO ROLE ELEMENTUM; GRANT USAGE ON SCHEMA ANALYTICS_DB.PUBLIC TO ROLE ELEMENTUM; GRANT SELECT ON ALL TABLES IN SCHEMA ANALYTICS_DB.PUBLIC TO ROLE ELEMENTUM; GRANT SELECT ON FUTURE TABLES IN SCHEMA ANALYTICS_DB.PUBLIC TO ROLE ELEMENTUM; ``` ### Optional grants The following grants are only needed if you plan to use the matching capability. Skip any that don't apply. Required if you want Elementum to start workflows when data is added or updated in Snowflake. ```sql theme={null} -- Enable change tracking on each table you want to monitor ALTER TABLE .. SET CHANGE_TRACKING = TRUE; ``` Example: ```sql theme={null} ALTER TABLE SALES_DB.PUBLIC.CUSTOMERS SET CHANGE_TRACKING = TRUE; ALTER TABLE SALES_DB.PUBLIC.ORDERS SET CHANGE_TRACKING = TRUE; -- Verify SHOW TABLES LIKE 'CUSTOMERS' IN SCHEMA SALES_DB.PUBLIC; ``` Required if you plan to use [Snowflake Cortex as your AI provider](/ai-agents/snowflake-cortex-setup), AI Search, AI Automations, or ML forecasting. ```sql theme={null} USE ROLE ACCOUNTADMIN; -- Enable cross-region Cortex access ALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'ANY_REGION'; -- Cortex user role GRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO ROLE ELEMENTUM; -- Cortex Search Service creation GRANT CREATE CORTEX SEARCH SERVICE ON SCHEMA ELEMENTUM_PLATFORM TO ROLE ELEMENTUM; -- ML model creation GRANT CREATE SNOWFLAKE.ML.ANOMALY_DETECTION ON SCHEMA ELEMENTUM.ELEMENTUM_PLATFORM TO ROLE ELEMENTUM; GRANT CREATE SNOWFLAKE.ML.CLASSIFICATION ON SCHEMA ELEMENTUM.ELEMENTUM_PLATFORM TO ROLE ELEMENTUM; GRANT CREATE SNOWFLAKE.ML.FORECAST ON SCHEMA ELEMENTUM.ELEMENTUM_PLATFORM TO ROLE ELEMENTUM; ``` **Capabilities enabled:** anomaly detection, classification, forecasting, LLM access (Cortex Complete), and Cortex Search. Required only if you plan to expose Elementum data to external BI tools (Power BI, Tableau, Looker) through Elementum's BI view feature. ```sql theme={null} USE ROLE ACCOUNTADMIN; GRANT USAGE ON DATABASE TO ROLE ELEMENTUM; GRANT USAGE ON SCHEMA . TO ROLE ELEMENTUM; GRANT CREATE VIEW ON SCHEMA . TO ROLE ELEMENTUM; ``` Example: ```sql theme={null} USE ROLE ACCOUNTADMIN; GRANT USAGE ON DATABASE ANALYTICS_DB TO ROLE ELEMENTUM; GRANT USAGE ON SCHEMA ANALYTICS_DB.BI_VIEWS TO ROLE ELEMENTUM; GRANT CREATE VIEW ON SCHEMA ANALYTICS_DB.BI_VIEWS TO ROLE ELEMENTUM; ``` Users and BI tools also need separate `SELECT` grants to query the views Elementum creates. See [Tables](/data/tables#snowflake-bi-view-permissions) for the full permission set. **Maintain view ownership:** the `ELEMENTUM` role retains ownership of any BI views it creates. Do not transfer ownership, or Elementum will lose the ability to update or manage the views. ## Step 5: Add credentials in Elementum Return to the CloudLink dialog you opened in Step 2. | Field | Value | | ------------------ | ------------------------------------------------------------------------------- | | **Name** | A descriptive name (for example, `Production Snowflake`) | | **Account URL** | Your Snowflake account URL (for example, `your-account.snowflakecomputing.com`) | | **Username** | `ELEMENTUM` | | **Authentication** | RSA Key Pair (configured automatically using the public key from Step 2) | | **Role** | `ELEMENTUM` | | **Warehouse** | `ELEMENTUM` | | **Schema** | `ELEMENTUM_PLATFORM` (Elementum's platform schema, **not** your data schema) | The **Schema** field must be the empty `ELEMENTUM_PLATFORM` schema, not your business data schema. See [The platform schema concept](/administration/cloudlink-overview#the-platform-schema-critical-concept). Click **Test Connection** to verify credentials, key-pair authentication, and network access end-to-end. A successful test confirms the IP whitelist, public key, role grants, and warehouse usage are all set correctly. Once connected, browse your Snowflake environment: 1. **Database** — Choose the database that contains your tables. 2. **Schema** — Pick the schema with your data. 3. **Table** — Choose the table(s) to bring into Elementum. Only databases, schemas, and tables that the `ELEMENTUM` role has access to will appear. **Performance check:** when you select a table, Elementum runs a test query to measure response time. If the table responds slowly, you'll see a warning before completing the connection. | Warning level | Query time | Recommendation | | ------------- | --------------- | ------------------------------------------------ | | Optimal | Under 3 seconds | Proceed | | Moderate | 3–5 seconds | Review optimization before proceeding | | Slow | Over 5 seconds | Strongly consider optimization before connecting | Slow tables affect workflow execution times, record load times, and automation reliability. See [Snowflake warehouses](/administration/snowflake-warehouses) and [Snowflake table types](/administration/snowflake-table-types) for optimization guidance. For each table, set: * **App name** — the application this data belongs to * **Table display name** — user-friendly name shown in Elementum * **Description** — optional context * **Primary key** — the unique identifier column * **Field mappings** — column-to-field-type, labels, and visibility Field types include: Text, Number, Date, Timestamp, Boolean, JSON, Array, Currency, Percentage, and References (for relationships). The default sync interval is **20 minutes**. Adjust based on data freshness needs: * Shorter intervals = fresher data, more Snowflake credits consumed. * Longer intervals = lower cost, suitable for slower-changing data. More frequent syncs consume more Snowflake credits. Balance freshness against cost. After the CloudLink is created, open its details by clicking the CloudLink name on the **CloudLinks** page in **Organization Settings**. In the **Query Profile Table** section, copy the provided DDL and run it in your Snowflake warehouse to provision the dynamic table that backs query-profile lookups. This improves query performance by giving Elementum fast, low-cost access to query execution metrics without scanning `ACCOUNT_USAGE` on every request. The DDL requires the `ACCOUNTADMIN` role and grants the `ELEMENTUM` role the permissions it needs to read `SNOWFLAKE.ACCOUNT_USAGE` and execute the scheduled task. Once provisioned, the **Query Profile Table** status updates to **Provisioned** in the CloudLink dialog. For more on what the table contains, why it's recommended, and verification and troubleshooting steps, see [Snowflake Query Profile Table](/administration/snowflake-query-profile-table). ## Step 6: Verify the connection Run these checks in Snowflake to confirm the role, warehouse, and data access work as expected. ```sql theme={null} USE ROLE ELEMENTUM; USE WAREHOUSE ELEMENTUM; USE DATABASE ELEMENTUM; SELECT CURRENT_ROLE(), CURRENT_WAREHOUSE(), CURRENT_DATABASE(); ``` Expected: `ELEMENTUM` for all three. ```sql theme={null} USE ROLE ELEMENTUM; USE WAREHOUSE ELEMENTUM; SELECT COUNT(*) FROM SALES_DB.PUBLIC.CUSTOMERS; ``` Replace with your actual database, schema, and table. ```sql theme={null} SHOW TABLES LIKE 'CUSTOMERS' IN SCHEMA SALES_DB.PUBLIC; -- Look for "change_tracking" = "ON" SELECT * FROM SALES_DB.PUBLIC.CUSTOMERS CHANGES(INFORMATION => DEFAULT) AT(TIMESTAMP => DATEADD(HOUR, -1, CURRENT_TIMESTAMP())) LIMIT 5; ``` ```sql theme={null} USE ROLE ELEMENTUM; USE DATABASE ELEMENTUM; USE SCHEMA ELEMENTUM_PLATFORM; SELECT SNOWFLAKE.CORTEX.COMPLETE( 'mistral-large', 'What is machine learning?' ) AS response; ``` A successful response confirms Cortex access is configured. 1. The connection shows as **Connected** on the CloudLinks page. 2. The integrated table loads correctly in Elementum. 3. Creating or updating a record (where write access was granted) syncs back to Snowflake. ## Use the connection After verification, use the connection from elsewhere in Elementum: * **Preview data** — On the CloudLinks page, click **Explore** next to the connection to preview rows from any table that connection can access. Useful for confirming the data and column names match what you expect before referencing the table in a workflow. * **Save Snowflake functions for automations** — Click **Functions** next to the connection, choose the database and schema that contain the function, and select the function to save it. Saved functions are available in the **Run Function** action in [automations](/workflows/automation-system). If a function doesn't appear, confirm the function is set up correctly in Snowflake (see Snowflake's [function reference](https://docs.snowflake.com/en/sql-reference-functions)) and that the `ELEMENTUM` role has the privileges it needs: ```sql theme={null} GRANT USAGE ON DATABASE DATABASE_NAME TO ROLE ELEMENTUM; GRANT USAGE ON SCHEMA DATABASE_NAME.SCHEMA_NAME TO ROLE ELEMENTUM; GRANT USAGE ON STAGE DATABASE_NAME.SCHEMA_NAME.STAGE_NAME TO ROLE ELEMENTUM; GRANT SELECT ON VIEW DATABASE_NAME.SCHEMA_NAME.VIEW_NAME TO ROLE ELEMENTUM; ``` For full capability docs, see [What you can do once connected](/administration/cloudlink-overview#what-you-can-do-once-connected) on the CloudLink Overview. ## Multi-environment setup If you use [organization environments](/administration/understand-organization-environments) for development, staging, and production, create separate Snowflake resources for each environment. Every CloudLink and environment combination needs a completely separate `USER`, `ROLE`, `DATABASE`, and `SCHEMA`. Users from one environment must not have access to another environment's database or schema. ### Required isolation | Environment | User | Role | Database | Schema | | ----------- | ------------------- | ------------------- | ------------------- | -------------------- | | Production | `ELEMENTUM_PROD` | `ELEMENTUM_PROD` | `ELEMENTUM_PROD` | `ELEMENTUM_PLATFORM` | | Staging | `ELEMENTUM_STAGING` | `ELEMENTUM_STAGING` | `ELEMENTUM_STAGING` | `ELEMENTUM_PLATFORM` | | Development | `ELEMENTUM_DEV` | `ELEMENTUM_DEV` | `ELEMENTUM_DEV` | `ELEMENTUM_PLATFORM` | ### Setup script for additional environments Run this for each environment, replacing `DEV` with your environment name. Copy the public key separately from each Elementum environment's CloudLink settings. ```sql theme={null} USE ROLE ACCOUNTADMIN; CREATE ROLE IF NOT EXISTS ELEMENTUM_DEV; GRANT ROLE ELEMENTUM_DEV TO ROLE SYSADMIN; CREATE USER IF NOT EXISTS ELEMENTUM_DEV TYPE = SERVICE RSA_PUBLIC_KEY = ''; GRANT ROLE ELEMENTUM_DEV TO USER ELEMENTUM_DEV; USE ROLE SYSADMIN; CREATE WAREHOUSE IF NOT EXISTS ELEMENTUM_DEV WITH WAREHOUSE_SIZE = 'MEDIUM', MIN_CLUSTER_COUNT = 1, MAX_CLUSTER_COUNT = 10, AUTO_SUSPEND = 60; GRANT USAGE ON WAREHOUSE ELEMENTUM_DEV TO ROLE ELEMENTUM_DEV; CREATE DATABASE IF NOT EXISTS ELEMENTUM_DEV; GRANT OWNERSHIP ON DATABASE ELEMENTUM_DEV TO ROLE ELEMENTUM_DEV; USE ROLE ELEMENTUM_DEV; USE DATABASE ELEMENTUM_DEV; CREATE SCHEMA IF NOT EXISTS ELEMENTUM_PLATFORM; ``` ### Sharing external data across environments (optional) You **can** grant multiple environment users access to the same external business data tables if you need realistic data for testing. ```sql theme={null} USE ROLE SYSADMIN; -- Grant the same business data to both PROD and DEV GRANT USAGE ON DATABASE BUSINESS_DATA TO ROLE ELEMENTUM_PROD; GRANT USAGE ON SCHEMA BUSINESS_DATA.PUBLIC TO ROLE ELEMENTUM_PROD; GRANT SELECT ON ALL TABLES IN SCHEMA BUSINESS_DATA.PUBLIC TO ROLE ELEMENTUM_PROD; GRANT USAGE ON DATABASE BUSINESS_DATA TO ROLE ELEMENTUM_DEV; GRANT USAGE ON SCHEMA BUSINESS_DATA.PUBLIC TO ROLE ELEMENTUM_DEV; GRANT SELECT ON ALL TABLES IN SCHEMA BUSINESS_DATA.PUBLIC TO ROLE ELEMENTUM_DEV; ``` When environments share access to external data, changes made in one environment are visible in all of them. This is usually fine for read-only reference data; be cautious with shared write access. ## Key rotation Snowflake supports two simultaneous public keys per user (`RSA_PUBLIC_KEY` and `RSA_PUBLIC_KEY_2`), enabling zero-downtime rotation. Elementum recommends rotating keys every 90 days. You can rotate the RSA signing key yourself from within Elementum, on your own schedule and without opening a support ticket. During a rotation, the current key and the new key are displayed side by side so it's clear which key is being swapped, and you can test the new key against a live connection before you apply it. In **Organization Settings → CloudLinks**, click **Rotate Key** for the connection. Copy the new public key from the dialog. ```sql theme={null} ALTER USER ELEMENTUM SET RSA_PUBLIC_KEY_2 = ''; ``` Click **Test Connection** in Elementum. ```sql theme={null} ALTER USER ELEMENTUM UNSET RSA_PUBLIC_KEY; ALTER USER ELEMENTUM SET RSA_PUBLIC_KEY = ''; ALTER USER ELEMENTUM UNSET RSA_PUBLIC_KEY_2; ``` Do not remove the old key before confirming the new key works. Use Snowflake's dual-key support to avoid disrupting active connections. ### Disable password authentication If the Snowflake user was previously created with a password, disable password-based login after key-pair authentication is confirmed: ```sql theme={null} ALTER USER ELEMENTUM SET DISABLE_DIRECT_LOGIN = TRUE; ``` This ensures the service account can only be accessed through key-pair authentication. ## Key-pair authentication reference For background on how key-pair authentication works (private vs public key, why it's required for Cortex features), see [Authentication on the CloudLink Overview](/administration/cloudlink-overview#authentication). ## Troubleshooting * Verify Elementum IP addresses are whitelisted in your Snowflake network policy. * Confirm the RSA public key was added correctly to the Snowflake user (run `DESC USER ELEMENTUM` and check `RSA_PUBLIC_KEY_FP`). * Check that the `ELEMENTUM` user has the `ELEMENTUM` role granted. * Verify the warehouse is not suspended and has available compute. * Ensure the user was created with `TYPE = SERVICE`. * Verify the user creation script ran successfully. * Check that `ACCOUNTADMIN` was the active role. * Verify the public key was copied completely from the Elementum UI without extra whitespace or line breaks. * Confirm the key was assigned to the correct user (`DESC USER ELEMENTUM` should show a value for `RSA_PUBLIC_KEY_FP`). * Ensure the key was pasted without the `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----` lines. The public key in Snowflake doesn't match the private key Elementum holds. Re-copy the public key from Elementum and re-assign: ```sql theme={null} ALTER USER ELEMENTUM SET RSA_PUBLIC_KEY = ''; ``` * Run `DESC USER ELEMENTUM` to see which key slots have values. * Ensure the current Elementum public key is in either `RSA_PUBLIC_KEY` or `RSA_PUBLIC_KEY_2`. * Follow the [key rotation procedure](#key-rotation) to safely rotate without downtime. * **Most likely cause:** you entered your data schema in the **Schema** field instead of `ELEMENTUM_PLATFORM`. * Verify `GRANT` statements include all required tables. * Confirm database and schema usage is granted on top of table grants. * Verify `GRANT` statements were executed for all required tables. * Check that the role has warehouse usage permission. * Confirm database and schema `USAGE` grants exist. * Verify `CORTEX_ENABLED_CROSS_REGION` is set to `'ANY_REGION'`. * Confirm `SNOWFLAKE.CORTEX_USER` database role is granted to `ELEMENTUM`. * Check that Cortex is available in your Snowflake region. * Verify `ACCOUNTADMIN` was used to grant Cortex permissions. * Ensure the connection uses key-pair authentication (Cortex features require it). * Increase warehouse size or cluster count. * Add clustering keys / partitioning on large tables. * Review sync interval—shorter intervals consume more credits. * See [Snowflake warehouses](/administration/snowflake-warehouses) and [Snowflake table types](/administration/snowflake-table-types) for tuning guidance. ## Security best practices * Grant only the permissions the `ELEMENTUM` role needs. * Use read-only access where write access isn't required. * Audit granted permissions regularly. * Remove access to tables no longer in use. * Whitelist Elementum IPs. * Use VPN for an additional security layer. * Monitor connection logs and set up alerts for suspicious activity. * Use RSA key-pair authentication, not passwords. * Rotate keys every 90 days. * Never share the service account credentials outside authorized personnel. * Review query history regularly. * Monitor warehouse credit consumption. * Set up cost alerts in Snowflake. * Track data access patterns. ## Next steps Size and configure your Snowflake warehouse for Elementum workloads. Choose Standard vs Hybrid tables for the right performance/cost balance. Process files stored in Snowflake stages with Elementum automations. Additional steps for License Patrol customers. Use Snowflake Cortex for AI services in Elementum. Create workflows that act on your Snowflake data. # Set Up Custom Email Domains Source: https://docs.elementum.io/administration/custom-email-domains Send email from your organization's domain using DNS verification and DKIM authentication ## Overview Custom email domains let your organization send email from your own domain so outgoing messages display your company in sender information. Configuration uses DNS records and DKIM authentication managed from **Organization Settings**. ## Prerequisites * **Elementum permissions**: Organization Admin access * **DNS**: Ability to create records at your DNS provider * **Domain**: You must own or control the domain you add ## Add and verify a domain ### Add the domain 1. Open **Organization Settings** 2. Select the **Email Domains** tab 3. Click **Add Domain** 4. Enter your domain (for example, `elementum.ai` or `app.elementum.ai`) ### Configure DNS Add the DNS records shown in the Elementum UI at your DNS provider. The UI lists the exact record types and values, including DKIM records used for authentication. ### Verification 1. After adding DNS records, click **Verify Configuration** 2. Verification can take up to 24 hours 3. Status indicators show configuration state: * ✅ Green: Properly configured * ⚠️ Yellow: Pending verification * ❌ Red: Configuration error ### Test sending Once the domain is verified: 1. Open an app that has an automation configured to send email (for example, [surveys](/workflows/survey-system) or [file attachments](/workflows/file-uploads-attachments#sending-files-via-email)) 2. Trigger the automation so it sends an email to a test address 3. Confirm the received message shows your domain in the **From** field ### Default domain 1. Select a verified domain 2. Click **Set as Default** 3. Confirm the selection ## Monitoring and notifications Elementum checks domain validity every six hours. If a configuration becomes invalid, the platform notifies configured recipients and **falls back to sending from elementum.io** until the domain is valid again. **Notification topics** include invalid domain configuration, failed email validation, and domain verification issues. To configure who receives system and error notifications: 1. Open **Organization Settings** 2. Open **Monitoring** 3. Add users or groups ## Best practices * Monitor domain status regularly, especially after DNS changes * Keep DNS records aligned with the values shown in Elementum * Maintain backup admin contacts for notifications * Review email sending logs periodically ## Troubleshooting If the domain shows errors: 1. Confirm DNS records match the UI exactly 2. Check for conflicting records at your DNS provider 3. Confirm you control the domain 4. Contact support if problems continue ## Technical reference * Outgoing mail uses **DKIM** for authentication (records are provided in the UI) * **Reply-To** continues to use an elementum.io address where applicable * Email sent using custom domains is logged for auditing # Deploy Apps between Environments Source: https://docs.elementum.io/administration/deploy-apps-between-environments Deploy apps from one organization environment to another, configure post-deployment data connections, and review deployment history **Labs feature.** Deployments depend on Environments, which is marked with the **Labs** badge in the Elementum UI because the feature is still being validated. Behavior, scope, and availability may change before the feature reaches General Availability, and not all Elementum customers have access yet. See [Upcoming Features](/release-notes/upcoming-features#labs-tag-in-the-platform) for what the Labs tag means. **Deployment** copies an app and its configuration from a source environment to a target environment. Before deploying, make sure both environments exist and have CloudLink configured. See [Understand and Configure Environments](/administration/understand-organization-environments) for the prerequisites. **Required Permission:** You must hold the **DEPLOY\_APPS** permission for the target environment to deploy an app to it. See [Who can deploy](#who-can-deploy) below. ## How deployment works You can deploy in any direction: from a non-production environment to Production, from Production into another environment to test changes, or between non-production environments. **What is included in a deployment** Automations; record layouts, related views, and form builder configuration; Flow definitions; approval processes; assignment rules; and report and analytics configuration for that app. In addition, any other objects your app depends on are included, recursively — see [Related objects included in deployment](#related-objects-included-in-deployment) below. **What is not included in a deployment** Role membership — which users and groups are assigned to a role — is **not** part of deployment. Elementum never modifies role membership during any deployment — initial or subsequent. When you deploy an app, element, or task into an environment for the first time, role membership from the source does not carry over. The owner of the deployed object is responsible for configuring role membership in the target environment after the first deploy, directly on the object's **Roles & Permissions** page in that environment. No future redeployment of that object will ever overwrite membership settings that have been configured in the target environment. **Phone numbers** are environment-specific and do not transfer with a deployment. A deployment copies the phone service configuration but leaves the target environment's copy without a live number, so each environment keeps its own phone number — see [Phone services](#phone-services). Deployment is different from environment creation. When an environment is first created, roles and role membership are cloned from Production into the new environment as its starting state. After that, deploying an app, element, or task into the environment does not carry membership with it — see [Environment-specific role membership](/administration/understand-organization-environments#environment-specific-role-membership). Deployment controls **what** an app does (configuration, automations, flows). **Who** can access it in each environment is always managed separately through [environment-specific role membership](/administration/understand-organization-environments#environment-specific-role-membership). Role membership is **not** part of the post-deployment **Configure** prompt. That prompt only handles Snowflake field mapping for Tables and Elements (see [Post-deployment configuration](#post-deployment-configuration)). Configure role membership separately on each object's **Roles & Permissions** page in the target environment. The deployment is tracked with status and history on the app's **Deployments** page. ## Related objects included in deployment When you deploy an app, you're not just deploying that app — you're deploying **everything the app needs to work**. If your app relies on another object for updates or information (another app, element, task, table, or similar), that object is included in the deployment and overwrites whatever version currently exists in the target environment. ### How dependencies are followed The system looks at your app and finds every object it references. Then it looks at *each of those* objects and finds *their* references. It keeps going — layer after layer — until no new objects are discovered. This is why deploying one app can bring in dozens or hundreds of objects: you're getting the app's dependencies, its dependencies' dependencies, and so on. For example, deploying a **Purchase Orders** app might pull in: ``` Purchase Orders → Vendors app (referenced by a dropdown) → Audit Log app (written to by a Vendors automation) → Compliance report (draws from Audit Log) ``` You deployed one app; four moved. Dependencies are directional. Deploying an app that depends on another object brings that object along, but the reverse is not true — deploying a shared object on its own does not automatically pull in the apps that reference it. ### What creates a dependency Anywhere one object points at another, that connection is followed during deployment. The most common sources of dependencies are: | Category | Examples | | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Connections between objects** | Relationships and related fields; dynamic dropdowns sourced from another object; calculated or lookup fields that read another object's data | | **Automations** | Actions that read or write another object (for example, create record, search records, search table); a datamine trigger pulls in its underlying table | | **Flows** | Any object referenced in a flow | | **Views and layouts** | Related views embedded in the app | | **Reports and analytics** | Reports that draw from another object | | **Agents' tools and skills** | Tools or skills that reference another object | | **Tables and their sources** | A table brought in via a Search Table action or datamine also brings the objects that table is built from | This table covers the most common sources of dependencies but is not exhaustive. As new features are added to Elementum, new kinds of references between objects can also become dependencies. The rule is the same in every case: any reference from one object to another is followed during deployment. ### In-progress work on shared objects is deployed too Because deployment always uses the **source environment's current version** of every dependent object, and always overwrites the target, in-progress work on a shared object can be promoted unintentionally. If a teammate has been editing an object your app depends on — for example, a shared Vendors app, a table used by a dropdown, or an automation your flow calls — the version they have in the source environment (including any work in progress) is what gets deployed to the target. Deploying your app can promote their changes even if that was not your intent. Before deploying an app that has dependencies, coordinate with the owners of any shared objects to confirm what's in source is ready to promote. ### Review dependencies before promoting Because dependencies are followed recursively, review the full set of objects that will move before you promote — especially to Production. Open each dependency in the source environment and confirm its current state is what you want in the target. To prevent a related object from deploying alongside your app, delete the reference that creates the dependency or edit it so the two objects no longer reference each other. Deactivating an automation or other configuration is not enough — the dependency still exists as long as the reference is in place. ## Who can deploy Promotion to each environment is gated by the **DEPLOY\_APPS** permission for **that environment**. Edit or admin rights on an app no longer imply the right to deploy it; users must hold DEPLOY\_APPS in the target environment to push an app there. | Behavior | What it means | | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Per-environment** | DEPLOY\_APPS is granted independently in each environment. A user with DEPLOY\_APPS in Staging cannot promote to Production unless they also hold it in Production. | | **Decoupled from app edit rights** | Granting someone the ability to update an app's configuration does not give them the ability to promote that app. Configure who can build apps and who can release them as separate decisions. | | **Granted through roles** | Admins assign DEPLOY\_APPS through a role (managed or custom) in the target environment. Role membership is environment-specific — see [Environment-specific role membership](/administration/understand-organization-environments#environment-specific-role-membership). | A user typically needs DEPLOY\_APPS in every environment they release to. For a `Dev → Stage → Prod` pipeline, the same release engineer commonly holds DEPLOY\_APPS in both Stage and Prod, while developers hold it only in Dev. ### Initial vs. subsequent deployments The first time you deploy an app to a target environment, settings are copied from the source. On later deployments to the same target, most configuration is updated to match the source, but the following **destination** values are left as you set them in that environment: | Configuration | Initial deployment | Later deployments | | ------------------------ | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------- | | **AI Search target lag** | Copied from source | Target environment's value is kept | | **Access policies** | Copied from source — only when the object does not already exist in the target | Target environment's policies are kept; deployment does not touch them | | **Role membership** | Not copied — must be configured manually | Never overwritten by Elementum | After the first deployment, you can set AI Search target lag and access policies per environment; later deployments will not overwrite those choices. Role membership is never part of any deployment and must always be set up independently in each environment. ### Access policy changes outside of a deployment Changes you make to a Data Access policy (outside of a deployment) are scoped to the environment you are signed in to. They do **not** propagate to other environments. * Removing a group's access to an app in one environment does not remove that group's access in any other environment. * To remove or change access across all environments, repeat the change in each environment separately. This is the same model used for role membership: the [environment indicator](/administration/understand-organization-environments#environment-categories) always shows which environment your change will apply to. ## Deploy an app Open the Apps icon **app** you want to deploy in its **source environment** (the environment where the app currently exists). For example, to deploy an app from Development to Production, open the app in the Development environment. In the app's left navigation, under the **Configuration** section, click **Deployments**. The Deployments page shows all available environments with their deployment status. Each environment is displayed as a card showing: * **Environment name** and description * **Status indicator**: Deployed (green), Deploying (yellow), Failed (red), or Not Deployed (gray) * **Deploy button** to initiate deployment The right panel shows **Deployment History**. For what each record includes, see [Deployment history](#deployment-history) below. Find the target environment (where you want to deploy the app) and click the **Deploy** button on its card. A confirmation modal appears: * Title: "Deploy App To Environment" * Message: "Deployment will copy all app configurations and associated objects to the target environment." * Visual showing the deployment flow from source to target * Summary: "Deploy App from \[Source] to \[Target]" Review the deployment details and click **Deploy** to proceed. The deployment process begins: * Status changes to "Deploying" (yellow) * Progress bar shows deployment progress * Upon completion, status changes to "Deployed" (green) Initial vs. subsequent deployments behave differently for some settings (for example AI Search target lag and Access Policies). See [Initial vs. subsequent deployments](#initial-vs-subsequent-deployments). Track deployment progress: | Status | Description | | ---------------- | --------------------------------------------- | | **Deploying** | Deployment is in progress | | **Deployed** | Deployment completed successfully | | **Failed** | Deployment encountered an error | | **Not Deployed** | App has not been deployed to this environment | View the **Deployment History** panel for the full deployment log, including outcome and any error details for failed deployments. ## Post-deployment configuration Apps whose Tables icon **Tables** or Elements icon **Elements** use Snowflake need extra steps in the **target** environment after deployment: pick database, schema, and table in that environment's CloudLink, and map fields. Apps with no Snowflake dependencies are ready once deployment finishes. ### Apps without external dependencies For apps that don't connect to Snowflake data: * Deployment completes immediately * Environment card shows green "Deployed" status * No additional configuration required * App is ready to use in the target environment ### Apps with Snowflake dependencies For apps with Tables icon **Tables** or Elements icon **Elements** linked to Snowflake, configure the data connections in the new environment. After deployment completes, the **Deploy** button changes to **Configure**. The card shows: * Green "Deployed" status pill * "Complete" progress indicator * **Configure** button Click **Configure** to open the target environment. The **Resolve Issues** modal appears with the message: "Review and resolve configuration issues before proceeding with deployment." The left panel lists all **Datasets** (Tables and Elements) that need configuration, each showing: * Dataset name * Configuration status ("Not configured") * Error count indicating fields needing mapping Click on a Dataset in the left panel to configure it. The right panel shows: * Dataset name and error count * "Configure data source connection and field mappings" * Valid fields count and errors count The CloudLink is pre-selected. Configure the data source: 1. **Database** - Select the database from the dropdown 2. **Schema** - Select the schema containing your data 3. **Table** - Select the table that corresponds to this dataset After selecting the table, map each field: | Target Field | Action | | --------------------------- | -------------------------------------------------------------------------- | | Field from the deployed app | Select the corresponding **Source Field** from the new environment's table | For each Target Field listed: * Use the dropdown to select the matching Source Field * Ensure data types align (TEXT to TEXT, NUMBER to NUMBER, etc.) * Repeat for all fields in the dataset After mapping all fields for all datasets: 1. Click **Configure Dataset** to save the configurations 2. Configured items are removed from the list 3. Continue until all items are configured 4. When the list is empty, the modal closes The app is now fully configured and ready to use in the target environment. ### Phone services Phone numbers are **environment-specific** and are **not** carried over by a deployment. A deployment copies the phone service itself — including its assigned agent and language settings — but the target environment's copy arrives **unconfigured**, without a live phone number. The source environment is untouched and keeps its existing number. This is by design: a phone number can only route calls to a single destination. If the same number were active in two environments (for example, QA and Production), there would be no way to determine which one should receive an incoming call. For that reason, each environment uses its own number, and dev and production numbers are different by default. After deploying, configure the phone service in the **target** environment before it can take calls: In the target environment, open the app and go to **App Details** → **Phone Services**. Edit the phone service that was deployed in an unconfigured state. Either provision a new number by area code or import an existing Twilio number for this environment. See [Configure a phone number in your app](/ai-agents/agents-phone-integration#configure-a-phone-number-in-your-app) for the full configuration steps. Save the phone service. The number is now live in the target environment only. To reuse the same number in a different environment, you must move it rather than copy it: release the number from the source environment first, then import it into the target environment. Removing a phone service in Elementum does **not** release the number from your Twilio account — release it in Twilio if you need to re-import it elsewhere. A single number cannot be active in two environments at the same time. Reserve your public-facing phone numbers for Production, and use separate test numbers in lower environments such as Development, QA, and Staging. This keeps live traffic from reaching a non-production build, avoids the need to move a number back and forth between environments, and lets you validate phone services safely before promoting an app to Production. ## Deployment history Each app keeps a log of deployments: who ran them, source and target environment, time, outcome (**Success** or **Failure**), and error details on failed runs. Error details stay on the record even after related background work is removed. Any user who can open the app can open **Deployments** and read this history. It is paginated and includes the full history, not only recent entries. | Field | Description | | ---------------------- | ------------------------------------- | | **Source environment** | Where the app was deployed from | | **Target environment** | Where it was deployed to | | **Initiated by** | User who started the deployment | | **Timestamp** | When the deployment started | | **Outcome** | **Success** or **Failure** | | **Error details** | On failures, shown on the same record | ## Deployments overview Before you deploy, run a **dry run** to preview the full process without writing any changes. The overview lists every App, Element, Task, and Table in scope, along with the admins responsible for each object, so you can confirm what a real deployment would touch. After a dry run or a real deployment completes, reopen that run from **Deployment History** to see exactly what it covered. Treating completed runs as an audit trail makes it easier to answer what shipped, when, and with which objects in scope. No extra configuration is required beyond access to the app's **Deployments** page. ## Example workflows 1. Add a Development environment from Production. 2. Deploy an app into Development and change it there. 3. When satisfied, deploy from Development to Production. 1. Add Staging (and optionally Development). 2. Move apps Development → Staging for review, then Staging → Production when approved. 1. Add a Training environment and deploy the apps users will see in Production so they can practice without touching live data. ## Troubleshooting **Possible Causes:** * CloudLink not configured in target environment * CloudLink credentials invalid or expired * Network connectivity issues **Solutions:** 1. Verify CloudLink is configured in the target environment 2. Test CloudLink connection in Settings icon **Organization Settings** 3. Check Snowflake service account permissions **Possible Causes:** * Environment not yet created * Insufficient permissions to view environments **Solutions:** 1. Verify the environment exists in Settings icon Organization Settings > Environments 2. Contact your administrator to check access permissions **Possible Causes:** * Table structure differs between environments * Missing columns in target environment's table * Data type mismatches **Solutions:** 1. Verify the target table exists and has the expected columns 2. Check that column names match or can be mapped correctly 3. Ensure data types are compatible between source and target **Possible Causes:** * Deployment still in progress * App has no external dependencies (no configuration needed) **Solutions:** 1. Wait for deployment to complete (status shows "Deployed") 2. If no Configure button appears after deployment, the app has no Snowflake dependencies and is ready to use **Scenario:** You need to use the same Snowflake user account with key-pair authentication for CloudLinks in environments that belong to **different organizations**. **Solution:** Snowflake supports key-pair rotation, which allows you to configure a second public key for the same user account. This enables environments in both organizations to authenticate simultaneously without disrupting existing connections. **Important:** Key-pair rotation is only required when using the same Snowflake user across environments in **different organizations**. If you are using the same Snowflake user across multiple environments within the **same organization**, key-pair rotation is not necessary because they share the same public key. **Steps:** 1. **Obtain the Public Key from the Organization You Are Adding the CloudLink To:** * Navigate to Settings icon **Organization Settings** > **CloudLinks** in the organization where you want to add the CloudLink * Start creating a new Snowflake CloudLink * Select **Key-pair authentication** as the authentication method * Copy the public key displayed 2. **Configure Key-Pair Rotation in Snowflake:** * Contact your Snowflake administrator to set the `RSA_PUBLIC_KEY_2` property for the Snowflake user * Provide the public key copied from the organization where you're adding the CloudLink * The Snowflake admin should run: ```sql theme={null} ALTER USER SET RSA_PUBLIC_KEY_2=''; ``` 3. **Complete CloudLink Setup:** * After the second public key is configured in Snowflake, complete the CloudLink setup in the organization * Both organizations will now be able to authenticate with the same Snowflake user * The existing CloudLink in the other organization continues to work without interruption For detailed information on configuring key-pair rotation in Snowflake, see [Snowflake's key-pair authentication documentation](https://docs.snowflake.com/en/user-guide/key-pair-auth#configuring-key-pair-rotation). ## Deployment practices * **Validate before Production** — Deploy and test changes in non-production environments before deploying to Production. * **Deploy one app at a time** when practical so failures are easier to trace. * **Use deployment history** to confirm what ran, when, and by whom. * **Restrict who can deploy to Production** — Grant **DEPLOY\_APPS** in Production only to release-managers; review that role membership periodically. Because role membership is environment-specific, removing DEPLOY\_APPS in Production does not affect a user's ability to deploy in Development or Staging. ## Next steps Environment concepts, categories, CloudLink requirements, and setup steps Detailed CloudLink configuration options Complete Snowflake setup guide with scripts Understanding apps and their components # Environments Secret Vault Source: https://docs.elementum.io/administration/environments-secret-vault Store keys and secrets in an environment-scoped vault so configuration values vary by environment without hardcoding, with write-only secrets, access policies, and reference by key name in automations The Vault is a secure, environment-scoped store for the keys and secrets your configuration depends on — API keys, endpoints, and other values that change from one environment to the next. Storing them in the Vault lets a single automation reference a value by key name and resolve to the right value in each environment, so you never hardcode secrets or rewrite configuration when you promote work between environments. Find it in **Organization Settings** under the **Platform** section, on the **Vault** page. ## Add a vault entry Organization Administrators create and manage vault entries. 1. Open **Organization Settings** > **Platform** > **Vault**. 2. Click **+ Add Entry**. 3. Enter the **Key**, **Value**, and **Description**. 4. Toggle on **Secret** if the value is sensitive, such as an API key. 5. Click **Create**. ## Keys across environments Each vault entry has a **key** and a **value**. The key is the name automations reference (for example, `API_KEY`). The value is what that key resolves to in the current environment. When you add an entry in one environment, Elementum automatically creates the same key in every other environment — without copying the value. Other environments show the entry as **Not configured** until you add a value there. That is intentional: Development, Staging, and Production typically need different credentials for the same key. For example, you add an API key in Production with the key `API_KEY` and the Production value. In Development you will see an unconfigured entry for `API_KEY` — the key is already there, but the value is empty. Set a Development value when you have a credential for that environment. ## Manage access policies Each entry has its own access policy that controls who can view or manage it. 1. On the **Vault** page, click the entry you want to manage. 2. Select the **Access Policies** tab, where you control who can view or manage the entry. The creator is automatically added as a User. ## Reference vault entries in automations Vault entries can be referenced by key name as values in automations. Because the reference resolves to the value stored for the current environment, promoting an automation across environments automatically points it to the right value, and updates to a value take effect immediately. ## Behavior notes * When an entry is marked as **Secret**, it becomes write-only — no one can read the value after it is set. * Adding an entry in one environment adds the key to every other environment. Values are never copied; each environment stays **Not configured** until you set its own value. See [Keys across environments](#keys-across-environments). * Access is controlled per entry through its **Access Policies** tab. # External User Re-Authentication Source: https://docs.elementum.io/administration/external-user-reauth Require external users to periodically re-verify their identity via magic link to maintain access to your organization. ## Overview External user re-authentication lets Org Admins set a periodic re-verification interval for users in the **External Users** group. When the interval expires, the user is blocked from accessing the organization until they confirm their identity via a magic link sent to their registered email. This setting applies only to external users and is configured per organization. Verifying in one organization does not extend access to any other. Before enabling, confirm that your **External Users** group and email domains are correctly configured. All users in the group will be subject to re-authentication immediately. *** ## Configure Email Verification Gate 1. Go to **Organization Settings** > **Access Management** > **Authentication** > **Email Verification Gate**. 2. **Enable** the feature. 3. Set the **Link Validity** -- how long the magic link remains active after it is sent. * Options: 5 minutes, 15 minutes, 30 minutes, 1 hour 4. Set the **Session Duration** -- how long a verified session lasts before the user must re-authenticate. * Options: 1 hour, 8 hours, 24 hours, 72 hours 5. Click **Save**. *** ## When access expires When an external user's interval expires, the next time they access the organization: * **Access is suspended** -- the user is redirected to a re-authentication page and cannot navigate the platform. A magic link is automatically sent to their registered email address. Clicking the link restores full access immediately. Magic links are single-use and short-lived. If the link has expired, the user can request a new one from the re-authentication page. The re-authentication page also allows the user to switch to another organization. Each organization's expiry is tracked independently. *** ## Notes * **Internal users are not affected** -- this policy applies only to the **External Users** group. Each organization manages its own interval independently. * **Access assignments are preserved** -- expiry does not remove group memberships, roles, or data access policies. All access is restored once the user re-authenticates. * **Email deliverability** -- ensure automated emails from Elementum are not blocked by the recipient's domain. See [Custom Email Domains](/administration/custom-email-domains) for guidance on sending from a verified domain. *** ## Related features Manage groups, including the External Users system group Add a second factor to login for all users Control what external users can do within the organization Configure a verified sending domain for outbound emails # Global Filters Source: https://docs.elementum.io/administration/global-filters Apply consistent filtering across all workspace widgets for unified cross-functional data analysis ## Overview Global Filters let you apply one set of criteria across all compatible widgets in a workspace, so you do not need to filter each widget separately. How it fits together: org admins define organization-level fields, app admins map those fields to fields in each app, and people using a workspace choose filter values from the global filter bar. **Prerequisites** * **Org Admin** access to create organization-level field definitions * **App Admin** access for each app you want included in global filtering * Agreement on which dimensions (for example company, region, or date range) should be shared across apps *** ## Organization-level field definitions Org admins create the global field definitions that other apps map to. **To open Organization Fields:** Settings icon **Organization Settings** > **Organization Fields** (under **Platform**) ### Create and manage fields 1. Click **Add Field**. 2. Enter a **Field Name** using clear, organization-wide terminology. 3. Add a **Description** that explains what the field represents and how teams should use it. 4. Select the **Type** (Text, Number, Date, Dropdown, or other supported type). 5. Click **Create** to save. The Organization Fields table lists each field’s name, type, description, and how many apps have mapped it. Use the search bar to find fields by name, description, or app. To edit a field, click the **Edit** icon on the row, change the name or description, and click **Apply**. Choose field types carefully. Changing a type after apps have created mappings can cause compatibility issues. ### Naming fields Use names that everyone in the organization will recognize, for example **Company**, **Region**, **Date Range**, **Fiscal Quarter**, **Status**, **Department**, **Product Category**. Avoid ambiguous or internal codes such as **Acct**, **DT**, **Stat**, or **Dept\_CD**—spell out the meaning others expect. Before adding many fields, list the common dimensions your org needs (for example company, region, date range, status) and align types (for example Dropdown vs Date) with how data is stored in your apps. *** ## App-level field mappings App admins connect each organization field to a field in their app. **To open Field Mapping:** In the app, under **Configuration**, click **Field Mapping**. The page lists organization fields; use the dropdown beside each to choose the matching app field. If the app field type does not match the organization field type, an **error icon** indicates the problem. Use the search bar to find a mapping, and pick a different app field from the dropdown to change an existing mapping. | Organization field | Example app field (Sales) | Example app field (Support) | | ------------------ | ------------------------- | --------------------------- | | Company | Account\_Name | Customer | | Region | Sales\_Territory | Support\_Region | | Status | Deal\_Stage | Ticket\_Status | | Date Range | Close\_Date | Created\_Date | A mismatch often means the organization field is one type (for example Date) while the mapped app field is another (for example Text). Filtering may not behave correctly until types align. After you save mappings, open a workspace that includes widgets from your app, set a global filter for a mapped field, and confirm the widgets update as expected. Try more than one value to verify behavior. *** ## Using global filters The global filter bar appears at the top of workspaces. It shows a control for each configured dimension (for example Company or Region). 1. Choose values for one or more dimensions. Within a single dimension you can often select multiple values (multi-select). 2. Filters combine with **AND** logic: records must satisfy all selected dimensions. 3. When you change a filter, compatible widgets refresh to match. Widgets that do not have a mapping for a given dimension are unchanged when you set that filter. To clear filters, remove individual criteria with the **X** on each pill, or use **Clear All** to reset everything. *** ## Troubleshooting **What you see:** Applying a global filter does not change widget data. **What to check:** 1. The app has a field mapping for that filter dimension. 2. Field Mapping shows no type mismatch for that mapping. 3. The widget’s data actually uses the mapped field. 4. You have permission to see the records you expect after filtering. **What you see:** An error icon next to a mapping in Field Mapping. **What to do:** 1. Compare the organization field type with the app field type. 2. Map to a different app field with a compatible type, or ask an org admin whether the organization field type should change. **What you see:** A dimension you expect does not appear in the filter bar. **What to check:** 1. An org admin created the organization field. 2. Apps used in that workspace have mapped that field. 3. If the field still does not appear, ask an org admin to confirm the field exists and that your apps are mapped. *** ## Related Features Learn about basic filtering concepts and operators Create dashboards that work with global filters Understand how data sources connect to global filtering Configure admin access for field mapping configuration # Groups Source: https://docs.elementum.io/administration/groups Organize users into groups to assign roles, data access, notifications, and approvals at scale Groups are the primary way to manage access in Elementum. Assigning roles, data access policies, and approval responsibilities to a group rather than to individual users keeps onboarding fast, makes audits straightforward, and ensures access stays aligned with how your organization actually works. Build the groups that mirror your organization first -- typically by team, function, or location -- then attach roles and data access to those groups before inviting users. *** ## Create a Group 1. Open Settings icon **Org Settings** → **Groups**. 2. Click **New Group** in the top right corner. 3. Enter the **Group Name**. 4. Select a **Group Type** to determine how members are added to the group: * **Add user to group individually** -- Add and remove members manually, one at a time. Best for small, stable groups where membership is intentional, such as a core project team, a leadership group, or an approval committee. * **Dynamically add users to group in bulk by email domain using auto assignment domains** -- Automatically includes every active user whose email address matches one of the organization's approved email domains. Membership updates automatically as users are added to or removed from the org. Best for broad, inclusive groups like "All Employees" or "All Contractors" where you want everyone in a given domain included without manual upkeep. 5. Select one or more **Group Visibility** options to control how the group can be referenced across Elementum. Each option is independent -- enable only the capabilities the group actually needs. Leaving an option **disabled** is the most effective way to prevent the group from being surfaced, notified, or granted access in contexts where it should not appear. * **Mentionable** -- Allows the group to be @-mentioned in comments. When enabled, mentioning the group sends a notification to every member. Disable this if the group contains sensitive stakeholders or has a large dynamic membership you do not want to broadcast notifications to. * **Watchable** -- Allows the group to be added as a watcher on records, tasks, and workflows. Watchers receive updates when the record changes. Disable this if group members should not automatically receive record-level activity notifications. * **Assignable** -- Allows the group to be assigned to work items or tasks that support group assignment. When a group is assigned, every member becomes an accountable assignee and can receive related notifications. Disable this to keep the group reference-only and prevent it from being placed on records as an owner or assignee. * **Approvers** -- Allows the group to be designated as an approver in an [approval process](/workflows/approval-processes). Any member can act on the approval on behalf of the group, which exposes them to the approval request and its context. Only enable this for groups whose members are authorized to approve on behalf of the organization. * **Data Access** -- Makes the group available for use in [object data access policies](/workflows/object-data-access). When disabled, the group will not appear as an option when configuring record-level access rules. 6. Click **Save**. 7. Add users to the group using the search field (for individually managed groups) or confirm the auto-populated list (for domain-based groups). 8. Optionally, add a photo to represent the group. Dynamic groups can grow quickly and may include users you did not intend to notify or grant access to. Review the **Group Visibility** settings carefully -- especially **Assignable** and **Approvers** -- before enabling them on a dynamic group. Each visibility option independently exposes a group to a different surface area in the product. As a general rule, enable only the visibility options the group needs to do its job, and pair restrictive visibility settings with an [object data access policy](/workflows/object-data-access) to control which records the group can see. *** ## Edit or Delete a Group The **Groups** page displays basic information about each group. * **Edit a group** -- Select a group on the Groups page to update its details or export a list of users in the group. * **Delete a group** -- Click the delete icon on the far right side of a group to permanently remove it. Deleting a group is permanent and cannot be undone. Users in the group will lose any permissions that were assigned through that group. System-managed groups (All Users, Internal Users, and External Users) cannot be deleted. The delete icon is not shown for these groups. *** ## System-managed Groups Elementum automatically creates three groups in every organization. Their membership is maintained automatically as users are added or removed -- you do not need to manage membership manually. | Group | Who it includes | | ------------------ | ---------------------------------------- | | **All Users** | Every active user in the organization | | **Internal Users** | Users with internal (non-guest) accounts | | **External Users** | Users with external or guest accounts | System-managed groups cannot be renamed, re-typed, or have their membership edited manually. The only properties Org Admins can change are the five **Group Visibility** checkboxes: Mentionable, Watchable, Assignable, Approvers, and Data Access. **To edit the visibility properties on a system-managed group:** 1. Open Settings icon **Org Settings** → **Groups**. 2. Select the system-managed group you want to configure (**All Users**, **Internal Users**, or **External Users**). 3. Select or clear the **Mentionable**, **Watchable**, **Assignable**, **Approvers**, and **Data Access** checkboxes as needed. 4. Click **Save**. These checkboxes affect all users in the group. Clearing **Assignable** on **All Users**, for example, removes the group from assignment lists across the entire organization. Review the impact before making changes to system-managed group visibility. Every new user is automatically added to the **All Users** group. This group is intended for organization-wide defaults only -- do not rely on it to grant sensitive or record-level access, since every active user is a member. *** ## Related Features Invite users into your organization and view their group memberships Assign permissions to groups through managed or custom roles Control which records each group can access with data access policies Configure organization, app, and user-level notification preferences # Multi-Factor Authentication (MFA) Source: https://docs.elementum.io/administration/multi-factor-authentication Add an extra layer of security to your Elementum account with time-based one-time passwords ## Overview Multi-Factor Authentication (MFA) adds an additional security layer to your Elementum account by requiring a time-based verification code during login. Even if your password is compromised, unauthorized users cannot access your account without the code from your authenticator app. **Key Benefits:** * **Reduced Risk**: Compromised passwords alone cannot grant account access * **Industry Standard**: Uses TOTP (Time-based One-Time Password) protocol supported by all major authenticator apps * **User Control**: Enable or disable MFA from your account settings at any time * **Simple Setup**: Configure in minutes with any compatible authenticator app *** ## Who Should Enable MFA * Users with access to sensitive business data * Organization administrators * Users managing automations and integrations * Anyone seeking enhanced account security * Accounts not protected by SSO/SAML * Users accessing Elementum from multiple devices * Accounts with elevated permissions * Compliance-sensitive environments If your organization uses SSO with an Identity Provider that already enforces MFA (such as Okta or Azure AD with MFA policies), you may already have multi-factor protection at the IdP level. *** ## Supported Authenticator Apps MFA works with any authenticator app that supports the TOTP standard, including: | App | Platforms | Notes | | --------------------------- | --------------------- | ------------------------------------ | | **Google Authenticator** | iOS, Android | Free, simple interface | | **Microsoft Authenticator** | iOS, Android | Includes backup and cloud sync | | **Okta Verify** | iOS, Android | Common in enterprise environments | | **1Password** | iOS, Android, Desktop | Integrated with password management | | **Authy** | iOS, Android, Desktop | Multi-device sync and backup | | **Duo Mobile** | iOS, Android | Enterprise-focused with push options | *** ## Set Up MFA Before enabling MFA, ensure you have: * An Elementum account with password-based authentication * A smartphone or device with an authenticator app installed * Access to scan a QR code or manually enter a setup key 1. Click your profile icon in the bottom-left corner of Elementum 2. Navigate to the **Security** tab 1. Locate the **Multi-Factor Authentication** section 2. Click **Enable MFA** to begin setup 3. A QR code will be displayed on screen 1. Open your authenticator app on your mobile device 2. Select the option to add a new account (usually a **+** icon) 3. Choose **Scan QR code** or **Scan barcode** 4. Point your device camera at the QR code displayed in Elementum If you cannot scan the QR code (e.g., using a desktop authenticator or camera issues): 1. Click **Can't scan? Enter code manually** below the QR code 2. Copy the secret key displayed 3. In your authenticator app, select **Enter setup key manually** 4. Enter: * **Account name**: Your Elementum email or "Elementum" * **Secret key**: Paste the copied key * **Type**: Time-based (TOTP) 1. Your authenticator app will display a 6-digit code that refreshes every 30 seconds 2. Enter the current code in the **Verification code** field in Elementum 3. Click **Verify and Enable** 4. You'll see a confirmation message that MFA is now active After successful verification: * The MFA section will show **Enabled** status * Your next login will require both password and authenticator code **Important**: Your authenticator app is now required for every login. Ensure you don't uninstall the app or lose access to your device without first disabling MFA or setting up the app on a new device. *** ## Log In with MFA Once MFA is enabled, your login process includes an additional verification step: 1. Navigate to the Elementum login page 2. Enter your email and password, then click **Log In** 3. When prompted, open your authenticator app and find your Elementum account entry 4. Enter the 6-digit code currently displayed and click **Verify** Codes refresh every 30 seconds. If your code is about to expire (timer nearly empty), wait for the next code to ensure you have enough time to enter it. *** ## Manage MFA ### View MFA Status To check your current MFA status: 1. Go to **Account Settings** > **Security** 2. The **Multi-Factor Authentication** section displays: * **Enabled**: MFA is active on your account * **Disabled**: MFA is not configured ### Disable MFA Disabling MFA reduces your account security. Only disable if necessary, and re-enable as soon as possible. To disable MFA: 1. Go to **Account Settings** > **Security** 2. In the **Multi-Factor Authentication** section, click **Disable MFA** 3. Enter your password or current authenticator code when prompted 4. Click **Confirm** to disable MFA *** ## Best Practices Choose an authenticator app that supports cloud backup or multi-device sync (Microsoft Authenticator, Authy, 1Password). This makes device transitions seamless and provides recovery options. The QR code contains your secret key. Never share, screenshot, or store QR codes in unsecured locations. Ensure your authenticator app is updated to the latest version for security patches and compatibility. Before switching phones or resetting your device: 1. Disable MFA in Elementum while you still have access 2. Set up your new device 3. Re-enable MFA with a fresh QR code scan TOTP codes depend on accurate time. Enable automatic time sync on your device to prevent code validation issues. *** ## Related Documentation Frequently asked questions about Multi-Factor Authentication Configure Single Sign-On with SAML 2.0 for centralized authentication *** *Last updated: January 2025* # Notifications Source: https://docs.elementum.io/administration/notifications Configure app-level and user-level notification preferences with multi-tier notification resolution ## Overview The Notifications feature provides a comprehensive system for managing when and how users receive notifications about activities in your apps. The platform uses a multi-level resolution system that checks both app-level permissions and individual user preferences before sending any notification. App-level and user-level notification settings apply to **email notifications only**. In-app notifications are not affected by these settings. Email notifications are batched and sent every 5 minutes rather than individually, reducing inbox noise while keeping users informed of recent activity. *** ## How Notification Resolution Works The platform uses a three-tier system to determine whether notifications are sent: 1. **Organization-Level Check**: The system checks if notifications are enabled organization-wide 2. **App-Level Check**: If allowed by the organization, the system checks if the notification type is enabled at the app level 3. **User-Level Check**: If allowed by both organization and app, the system checks the individual user's preferences 4. **Final Decision**: Notifications are only sent if all three levels approve the notification type **Resolution Flow:** ``` Notification Event Occurs ↓ Organization Settings: Are notifications enabled organization-wide? ↓ NO → Notification Blocked ↓ YES App Settings: Is this notification type enabled? ↓ NO → Notification Blocked ↓ YES User Settings: Does the user want this notification? ↓ NO → Notification Blocked ↓ YES Notification Sent (with Organization Branding) ``` If any level (organization, app, or user) blocks a notification type, the notification will not be sent, regardless of the other levels' settings. *** ## Organization-Level Notification Controls Before app and user settings take effect, organization-wide controls can override notification behavior. ### Enable Organization-wide Notifications Organization administrators can disable all notifications across the entire organization from Settings icon **Organization Settings** → **General**. * **Enable Notifications**: Controls whether email notifications are sent for the entire organization. * When disabled, no notifications are sent regardless of app or user settings * Useful for maintenance periods or organization-wide notification pauses When the Enable Notifications toggle is turned off, all app-level and user-level notification settings are overridden. No notifications will be sent until this toggle is re-enabled. ### Communication Customization Control how email notifications appear to users through Settings icon **Organization Settings** → **Communication**. * **Custom Organization Banner**: Enable branded email headers * **Banner Color**: Customize the banner color (e.g., #29b5e8) * **Banner Logo Position**: Control logo placement (Left, Right, Center) * **Banner Image**: Upload custom organization logo or image **Communication Preview:** The settings include a live preview showing how emails will appear to recipients, including: * Organization branding elements * Email layout and formatting * Banner positioning and colors * Logo integration and sizing Communication settings apply to all email notifications sent by the platform, including system notifications, automation emails, and user-generated communications. *** ## App-Level Notification Configuration App administrators control which notification types are available to users within their app. ### Access Notification Settings Open your app, element, or task and select Notifications icon **Notifications** under **Configuration** in the left navigation menu. Notification settings require admin permissions and control what notification types are available to all users of the app, element, or task. App notification settings are organized into three main categories: * **Users are assigned a record**: Notify when individual users are assigned to records * **Teams are assigned a record**: Notify when entire teams are assigned to records * **Users are added as watchers**: Notify when users are added to watch records * **Teams are added as watchers**: Notify when teams are added to watch records * **Users are mentioned in a comment**: Notify when individual users are @mentioned * **Teams are mentioned in a comment**: Notify when entire teams are @mentioned * **Assignee or Assignment Group is changed**: Notify when assignments change * **Watchers are added**: Notify when new watchers are added to records * **Comments are added**: Notify when new comments are posted * **All other updates**: Notify for any other record modifications Each notification type has a toggle to enable or disable it for the app. When a type is disabled at the app level, no users in the app receive that notification regardless of their personal preferences. Start with essential notifications enabled and add more based on user feedback and workflow needs. *** ## User-Level Notification Preferences Individual users control their personal notification preferences for notifications that are enabled at the app level. ### Access User Notification Settings Click your profile icon in the bottom-left corner of Elementum, then select Notifications icon **Notifications**. User notification settings only apply to notification types that are enabled at the app level. User notification preferences mirror the app-level categories. Each toggle can be enabled or disabled independently: * **You're now the assignee**: Notified when you are assigned to a record * **Your team is now the assignee**: Notified when your team is assigned to a record * **You're now a watcher**: Notified when you are added as a watcher on a record * **Your team is now a watcher**: Notified when your team is added as a watcher on a record * **You've been mentioned in a comment**: Notified when you are @mentioned in a comment * **Your team has been mentioned in a comment**: Notified when your team is @mentioned in a comment * **Assignee or Assignment Group is Changed**: Notified when the assignee or assignment group changes on a record you are associated with * **Watchers are added**: Notified when new watchers are added to a record you are associated with * **Comments are added**: Notified when new comments are posted on a record you are associated with * **All other updates**: Notified for any other changes to records you are associated with *** ## Best Practices ### App-Level Configuration **Start Conservative**: Begin with only essential notifications enabled and expand based on user needs and feedback. **Recommended Approach:** 1. **Enable essential notifications first** -- Assignment notifications for task management, mention notifications for communication, and comment notifications for collaboration. 2. **Monitor usage patterns** -- Track which notifications users find valuable, identify which cause noise or confusion, and adjust settings based on actual usage and feedback. 3. **Align with workflows** -- Match notification settings to your business processes, consider the roles and responsibilities of your users, and ensure notifications support rather than disrupt productivity. *** ## Troubleshooting ### Common Issues **Possible Causes:** * App-level notifications disabled for that type * User-level preferences blocking notifications * Email delivery issues (if using email notifications) * User not properly assigned or watching the record **Solutions:** 1. **Check App Settings**: Verify the notification type is enabled at the app level 2. **Check User Settings**: Confirm the user has enabled that notification type 3. **Verify Assignments**: Ensure the user is properly assigned or watching the record 4. **Test Delivery**: Send test notifications to verify delivery channels work **Possible Causes:** * Too many notification types enabled at app level * Users haven't customized their preferences * High activity levels generating excessive notifications * Lack of notification filtering or batching **Solutions:** 1. **Review App Settings**: Disable unnecessary notification types 2. **User Education**: Help users customize their preferences 3. **Workflow Optimization**: Reduce unnecessary activities that trigger notifications 4. **Batching Options**: Implement notification batching if available **Possible Causes:** * Mixed app and user settings across the organization * Different users having different preferences * System performance issues affecting delivery * Integration problems with external notification systems **Solutions:** 1. **Standardize Settings**: Establish consistent app-level notification policies 2. **User Guidance**: Provide clear recommendations for user settings 3. **System Monitoring**: Monitor notification system performance 4. **Integration Testing**: Regularly test external notification integrations ### Notification Debugging If notifications aren't working as expected, check each level of the resolution chain: 1. **Check Organization Settings** -- Verify the Enable Notifications toggle is turned on in Settings icon Organization Settings and that communication settings are properly configured. 2. **Verify App Settings** -- Confirm the notification type is enabled at the app level and review which notification categories are active. 3. **Check User Preferences** -- Verify the user has enabled the specific notification type and review their overall notification preferences. 4. **Test the Flow** -- Create a test scenario that should trigger the notification, then verify it is generated and delivered correctly. 5. **Review System Logs** -- Check system logs for notification generation events, monitor delivery attempts, and identify any patterns in notification issues. *** ## Feature-Specific Notification Behavior ### Automation Notifications * **Approval Processes**: Approval activities generate notifications that users cannot opt out of ### Communication Features * **Microsoft Teams**: Teams integration can extend notification delivery beyond email * **Public Attachment Links**: Attachments on records can be [made public](/workflows/file-uploads-attachments#public-attachment-links) so notification recipients can access them without logging in ### User Management * **Regional Settings**: User regional preferences may affect notification timing # Org Structure Source: https://docs.elementum.io/administration/org-structure Define your organization's employee hierarchy to enable dynamic manager-based approval routing Org Structure lets you define the reporting hierarchy within your organization. By mapping employees to their managers, departments, and job titles, you establish the relationships that drive dynamic approval chains and other manager-based workflows. ## Overview The Org Structure page is accessible from Settings icon **Org Settings** → **Org Structure** within the **Platform Administration** section. From here, you can review your organization's hierarchy, search for individual employees, and add or update entries. ## Adding Employees In most organizations, the Org Structure is populated automatically by your identity provider via SCIM. Manual entry and Excel import are available for organizations that don't use SCIM, or to make targeted adjustments alongside an automated sync. If your organization uses [SCIM provisioning](/administration/sso-saml-setup#scim-provisioning) with Microsoft Entra ID or Okta, the Org Structure page is populated automatically from your identity provider. Each user's **Department**, **Employee ID**, **Job Title**, and **Manager** sync into Elementum, so the hierarchy stays current as people join, change roles, or leave the organization — without manual maintenance in Elementum. To enable this: 1. Set up [SAML SSO with Microsoft Entra ID](/administration/sso-saml-setup#step-3-configure-your-identity-provider). 2. Configure [SCIM provisioning for Entra ID](/administration/sso-saml-setup#scim-provisioning) and ensure each user's **Job Information** in Entra ID includes at least one of **Department**, **Employee ID**, or **Manager**. 3. Start provisioning. Users and their reporting relationships will appear on the Org Structure page on the next sync. 1. Set up [SAML SSO with Okta](/administration/sso-saml-setup#step-3-configure-your-identity-provider). 2. Configure [SCIM provisioning for Okta](/administration/sso-saml-setup#scim-provisioning) and ensure the **Employee ID** field is populated for each user — this field is set via API from your identity system, not through the Okta admin UI. 3. Push the group and start provisioning. Users will appear on the Org Structure page on the next sync. Other identity providers (OneLogin, JumpCloud) can provision users and groups via SCIM, but Org Structure auto-population is currently supported only for Microsoft Entra ID and Okta. With other IdPs, populate Org Structure manually or via Excel import. To add an employee manually: 1. Click **+ Add** in the top right corner of the Org Structure page. 2. If the employee already has a user account in Elementum, select them from the **Add Existing User** dropdown. This pre-fills their name and email. 3. Fill in the **Employee Information** fields: * **First Name** and **Last Name** * **Email** * **Employee ID** * **Department** * **Job Title** * **Manager** — Search for and select the employee's direct manager 4. Click **Save**. To add employees in bulk: 1. Click **Import** in the top right corner of the Org Structure page. 2. Click the cloud download icon to download the Excel template pre-populated with your current org structure data. 3. Fill in or update the template with your employee information. 4. Upload the completed Excel file. 5. Review the import preview and confirm. Bulk import is useful for organizations that don't use SCIM, or as a one-time way to load historical data before enabling automated provisioning. ## Employee Fields Each employee record in the org structure contains the following information: * **First Name / Last Name** — The employee's full name. * **Email** — The employee's email address. If linked to an existing Elementum user, this connects the org structure entry to their platform account. * **Employee ID** — A unique identifier for the employee, typically matching your HR system's ID. * **Department** — The department or business unit the employee belongs to. * **Job Title** — The employee's role or position. * **Manager** — The employee's direct manager. This field establishes the reporting chain used by dynamic approval routing. The **Manager** field is what defines the hierarchical relationships in your org structure. Make sure every employee has an accurate manager assignment to ensure approval chains route correctly. ## Searching for Employees Use the search bar at the top of the Org Structure page to find employees by name. This is helpful for verifying reporting relationships or updating individual records. ## Using Org Structure with Approval Processes The primary use case for org structure is enabling **dynamic manager approval chains** in [Approval Processes](/workflows/approval-processes). When configuring an approval chain, you can select the **Dynamic Manager** option for any step. This automatically assigns the approver based on the requester's manager hierarchy as defined in the org structure. For example, if an approval chain requires three levels of management sign-off: 1. **Level 1** — The requester's direct manager 2. **Level 2** — The direct manager's manager 3. **Level 3** — The next manager up the chain The system traverses the org structure automatically, so you don't need to hard-code specific approvers for each step. This means approval routing stays accurate as employees change roles or managers without requiring updates to the approval process configuration. Combine dynamic manager approvals with [automated triggers](/workflows/automation-system) to create fully automated approval workflows that route through the correct management chain based on your org structure. ## Best Practices * **Automate with SCIM where possible** — When using Microsoft Entra ID or Okta, configure [SCIM provisioning](/administration/sso-saml-setup#scim-provisioning) so the Org Structure stays current automatically as employees join, change roles, or leave. * **Keep the hierarchy current** — If maintaining Org Structure manually, update it promptly when employees change managers, departments, or roles. Stale data leads to misrouted approvals. * **Use Excel import for initial setup** — When first building your org structure without SCIM, import from your HR system rather than adding employees one at a time. * **Verify manager chains** — After importing or after a SCIM sync, spot-check a few employees to confirm their manager assignments are correct, especially for multi-level approval scenarios. * **Link to existing users** — When adding employees manually who already have Elementum accounts, use the **Add Existing User** option to connect their org structure entry to their platform identity. # Platform Branding Source: https://docs.elementum.io/administration/platform-branding Customize the Elementum accent color and organization logos so the workspace matches your brand. ## Overview Platform Branding lets Organization Administrators customize how Elementum looks for everyone in the organization. Set a shared accent color that carries across primary buttons, links, active states in main and sub navigation, icon hover states, focus states, and the login flow, and add company and login-page logos so the workspace visually reflects your brand. Branding is especially useful when external collaborators use Elementum — a distinctive accent color and logo help them immediately recognize which customer's organization they're working in and reduce wrong-account mistakes. ## Prerequisites * **Elementum permissions:** Organization Administrator access. * **Assets:** A Company Logo used across the platform and a dedicated Login Page Logo displayed on the login screen. * **Accent colors:** Hex values (or a color picker selection) for both Light Mode and Dark Mode. ## Configure Platform Branding Platform Branding is managed alongside your organization's other identity settings. **Where to find it:** **Organization Settings** → **General** → **Platform Branding**. 1. Open **Organization Settings** and select **General**. 2. Scroll to the **Platform Branding** section. Check **Enable Custom Branding** to turn on your organization's custom accent color and login-page logo. Custom branding is off by default; toggling it on activates the accent color, Login Page Logo, and Live Preview controls described below. Upload the two logos used across Elementum: * **Company Logo** — Used across the platform, including the organization icon in the main navigation. The Company Logo is managed in **General Settings** just above the Platform Branding section and is reused everywhere your organization's logo appears in-app. * **Login Page Logo** — A dedicated logo displayed above the email field on the login screen. Set the **Accent Color** for both **Light Mode** and **Dark Mode** so users see a consistent look regardless of their theme. Choose colors with enough contrast against light and dark backgrounds so buttons, links, and focus states stay legible. Use the **Live Preview** on the right side of the page to confirm how your accent color appears across primary buttons, links, navigation states, and focus states in each theme. Adjust the accent color and logos as needed, then click **Save** when finished. ## Where custom branding appears When Custom Branding is enabled, the accent color and logos are applied globally so users see a consistent visual identity across: * Primary buttons * Links * Active states in main and sub navigation * Icon hover states * Focus states * The login flow * The Elementum organization icon The Company Logo lives in the General Settings section above Platform Branding and is reused throughout the platform. The Login Page Logo only affects the login screen, so you can use different assets for in-app branding and the login page if your visual identity calls for it. ## Update or turn off custom branding * **Update a color or logo:** Return to **Organization Settings** → **General** → **Platform Branding**, change the field, review the update in the Live Preview, and click **Save**. * **Turn off custom branding:** Uncheck **Enable Custom Branding** and click **Save**. Elementum reverts to the default accent color and logo experience. Uploaded logos remain saved and are reapplied the next time you enable custom branding. ## Best practices * **Set both themes.** Elementum honors each user's Light Mode or Dark Mode preference, so define an accent color for both modes to avoid falling back to the default in one theme. * **Match your style guide.** Pick accent colors your team already uses in other tools so Elementum feels like part of your platform. * **Keep logos current.** Upload updated logos when your brand changes so external collaborators still recognize your organization at a glance. * **Preview before saving.** Use the Live Preview on the settings page to confirm buttons, links, and focus states remain legible against your accent color before rolling out the change. # Profile Source: https://docs.elementum.io/administration/profile Manage your personal profile, notifications, security, and integrations in Elementum Every personal setting in Elementum -- your profile details, background tasks, notifications, regional preferences, security, approvals, and API tokens -- is managed from the **Profile** icon at the bottom of the left navigation bar. Because each of these settings is reached the same way, they are grouped together on this single Profile page. Use the options below to update your personal information and customize your experience: * **Profile photo** -- Add or change your avatar. * **Away status** -- Set an away status for a specific time period to exclude yourself from [automated assignments](/workflows/assignment-rules) and send [approvals](/workflows/approval-processes) to a delegate. * **Name and job title** -- Update your first name, last name, and job title. * **Phone number** -- Enter a phone number for [call agents](/ai-agents/agents-phone-integration) that require authentication. * **Key personalization** -- Configure your encryption key preferences. * **Appearance** -- Choose between light, dark, or system-default theme. If your administrator has enabled an [Agent Gateway](/ai-agents/agent-gateways) with the platform assistant turned on, you can also tailor the assistant to your role, goals, and most-used apps. See [Personalization](/ai-agents/agent-gateways#personalization) for details. ## Background Tasks Tasks that take longer to process and result in a downloadable file are listed here. Each entry shows the task name, action type, and current status. This is particularly useful for monitoring **Bulk Import via CSV** progress. If errors persist during an import, download the CSV report to identify what needs to be corrected in your source file. ## Notifications Use the toggles to control which notifications you receive via email. Notification delivery is also governed by organization-level settings (which can enable or disable all notifications globally), and certain notifications cannot be turned off—such as emails sent through a workflow automation or triggered manually. For more on how notification settings are resolved across organization, app, and user levels, see [Notifications](/administration/notifications). ## Regional Settings Set your preferred language and time zone. 1. Click your **Profile** icon at the bottom of the left navigation menu. 2. Click **Regional Settings**. 3. Select your language from the **Locale** dropdown. 4. Set your time zone using the **Time Zone** dropdown. Elementum also supports multi-language app content through AI-powered translations. See [Language Settings](/workflows/translations) for details on localizing your apps. ## Security Manage your account credentials and authentication methods. * **Last login** -- The date and time of your most recent successful login is displayed each time you sign in. * **Change your password** -- Update your account password. * **Set up MFA** -- Enable [multi-factor authentication](/administration/multi-factor-authentication) for an additional layer of login security. * **Set a PIN** -- Configure a PIN for phone authentication if a [call agent](/ai-agents/agents-phone-integration) requires one for access. ## Approvals Configure delegation for your [approval processes](/workflows/approval-processes). * **Set a delegate** -- Assign a delegate to handle your assigned approvals when your status is set to away. ## OAuth Manage API access tokens for your account. * **Elementum tokens** -- Set up tokens for [Elementum API](/api-reference/api-introduction) access. *** ## Related Features Manage the groups that organize users in your organization Configure organization, app, and user-level notification preferences Add an extra layer of security with time-based one-time passwords Route work for review and set delegates when you are away # Roles & Permissions Source: https://docs.elementum.io/administration/roles-permissions Manage access control through role-based permissions for secure enterprise workflows ## Overview Roles & Permissions is the foundation of Elementum's security model. Best practice is to assign permissions through roles rather than to individual users. This approach ensures consistent access control, simplifies management across large teams, and keeps role assignments audit-ready for compliance reviews. Elementum supports two permission scopes: * **Organization-level** -- Grants access across all apps the user can reach. Use for administrative oversight roles such as IT administrators or compliance officers. * **App-level** -- Grants access only to a specific app, element, or task and its related features. Use for department-specific or project-scoped roles. Organization-level permissions cascade down to all accessible apps. Assign org-level roles carefully and primarily for administrative oversight. *** ## Managed Roles Managed roles are predefined roles with standard permission sets. Permissions are fixed; you manage **membership** only (users and groups). Organization managed roles and app managed roles are different sets—use the tabs below to compare them. Open Settings icon **Org Settings** → **Roles & Permissions**, then select the **Organization roles** tab. The **Managed roles** list shows predefined organization roles; use **Manage membership** on each card to assign users and groups. * **Admin** -- Full access to Elementum Admin functions and organization settings, including company-wide configuration. Organization Admins also have view-only visibility into every App, Element, Task, and Table in the organization, and every record they contain, regardless of [object data access policies](/workflows/object-data-access) or per-record sharing. Edit, update, and delete permissions remain governed by the Admin's other role assignments. This org-wide visibility applies only to **Organization** Admins (assigned in **Org Settings**); Object-level admins (assigned in an individual App, Element, or Task) stay scoped to that Object. * **API Developer** -- Permissions to access and run Elementum APIs across the platform. * **App Admin** -- Create or edit apps, tasks, and elements at the organization level, within sharing and access policies that apply to what this user can reach. * **Bulk Import Admin** -- Use bulk import and bulk update from list views on apps, tasks, and elements. * **External Create** -- View, create, and update records; read and post to conversations on records the user can access (for external collaboration patterns). * **External Update** -- View and update records; read and post to conversations on accessible records according to access policies. * **Internal User** -- View, create, and update records, conversations, and attachments across apps, tasks, and elements the user can access. * **Service Requestor** -- Create service requests for users or groups that need to submit service requests through your workflows. **App Admin** at the organization level is not the same role as **App Admin** under **App roles**. Organization **App Admin** applies org-wide; app **App Admin** applies only within one app. Open **Roles & Permissions** under **Security** in the app menu, then select the **App roles** tab. * **App Admin** -- Full administrative access to all features and settings within that app. * **Content Editor** -- Can create and manage content but cannot change app settings. * **Content Viewer** -- Read-only access to content and basic features. Start with managed roles when they fit your needs before creating custom alternatives. *** ## Custom Roles Custom roles let you define any combination of permissions to match your organization's specific workflows. ### Create a Custom Role 1. Open Settings icon **Org Settings**. 2. Click **Roles & Permissions**. 3. Click **Create Custom Role**, enter a descriptive **Role Name**, and add a **Description** explaining the role's purpose. 4. Select the **Users** and **Groups** who should have this role. 5. Set permissions for each resource type. See [Permission Types](#permission-types) for the full list of granular options. Custom roles can also be created directly on an app, element, or task. Click **Roles & Permissions** under the **Security** section of the object's menu. Object-scoped custom roles also expose [Auto Share Options](#auto-share-options), which are not available on organization-level custom roles. ### Auto Share Options Auto Share Options are only available when creating or editing a **custom role scoped to an object** (an app, element, or task) via **Roles & Permissions** under the **Security** section of that object's menu. They do not appear on organization-level custom roles. When enabled, they automatically grant the custom role to a user the first time they interact with a record in one of the configured ways. The typical use case is making sure that someone who needs context on a record -- because they were assigned, mentioned, or added as a watcher -- has enough access to actually read and act on it, without an administrator manually sharing the record each time. Because the role is assigned to the **user** (not just to that single record), every permission the role grants will apply across that object's scope. If the role grants broad access within the object, a single interaction on one record can silently widen a user's access across every record that object covers. Auto Share Options can unintentionally widen a user's access. Before enabling any trigger, make sure the role's permissions are tightly scoped to what a newly-interacting user actually needs -- typically read-only access to the related record and its conversations. Avoid combining Auto Share with roles that grant **Update Records**, **Delete Records**, **Bulk Update Records**, **Create Record Sharing**, or administrative permissions unless you explicitly want every triggering interaction to grant that level of access. Each trigger controls a specific interaction. Enable only the triggers the role is designed for -- they are independent and additive. * **When user is added as a watcher** -- The role is granted when the user starts watching a record (manually, or via automation). Use this to give watchers enough access to read the record they chose to follow. Good fit for lightweight view-oriented roles. Leaving this disabled prevents watchers from gaining any new access beyond what they already had. * **When user is assigned to a record** -- The role is granted when the user becomes the assignee of a record. Use this to ensure assignees can actually work the record they own (view it, update required fields, post in its conversation). Pair with a role that grants the minimum editing permissions the assignee's job requires. * **When user is @mentioned** -- The role is granted when the user is @-mentioned in a conversation or comment on a record. Use this to let mentioned users read the record and the conversation they were pulled into. Because anyone who can comment can trigger this, keep the role as read-only as possible to prevent comment-based privilege escalation. * **When a record is shared with a user** -- The role is granted when a record is explicitly shared with the user via [record sharing](#relationships). Use this to give recipients of ad-hoc shares consistent access without every sharer having to reason about permissions. * **When a record is approved** -- The role is granted when a record moves through an [approval process](/workflows/approval-processes) and receives an approval. Use this to give approvers continuing access to records they have signed off on -- for example, for audit trail, follow-up, or handoff to the next stage of the workflow. Because many approvers only need access during the approval itself, avoid pairing this trigger with a role that grants long-lived edit access unless post-approval access is the intent. Auto Share Options layer on top of, but do not replace, your [object data access policies](/workflows/object-data-access). They are most effective when the auto-assigned role is narrowly scoped -- for example, a read-only role that grants **View Records**, **View Conversations**, **View Messages**, and **View Attachments** on the relevant object -- so that the trigger grants just enough access to do the work in front of the user. *** ## Permission Types Custom roles can include many granular permissions, grouped by resource type in the role editor. Use the **quick picker** at the top to apply common bundles (**View**, **Edit**, or **Admin** access) where available, then adjust individual permissions as needed. Most resources follow a consistent **View / Create / Update / Delete** pattern: * **View** -- Read-only access. Users can see the resource in the UI and reference it elsewhere, but cannot change it. * **Create** -- Users can add new instances of the resource. * **Update** -- Users can modify existing instances. * **Delete** -- Users can permanently remove instances. Deletions are typically irreversible, so grant this permission to the smallest audience possible. Follow the [principle of least privilege](#security-principles). Start by granting **View** only, then add **Create**, **Update**, or **Delete** as the role actually requires them. Administrative and configuration permissions -- especially those marked as sensitive below -- should be held by a narrow audience. Permissions for apps and their underlying building blocks -- **Objects** (apps, elements, and tasks), **Assignment Rules**, **Data Sources**, and **Tags**. These control who can see, build, or restructure apps in the organization or a specific app. * **Admin Access** -- Full administrative control within the scope of the role (org-wide for an organization role, app-wide for an app role). Grants every other permission in this category and overrides finer-grained settings. Assign only to users responsible for owning and configuring the scope. * **Create Objects**, **View Objects**, **Update Objects**, **Delete Objects** (Apps, Elements, Tasks) -- CRUD over the structural definitions of apps, elements, and tasks (fields, relationships, validations, and app configuration). **Create**, **Update**, and **Delete** are app-building permissions; grant them only to users who design or maintain apps. **View Objects** lets users see the structure without modifying it. * **View Apps** -- Lets users see which apps exist and open them, subject to other record- and access-level permissions. A prerequisite for most other app-scoped activity. * **Deploy Apps** -- Promote an app from one [environment](/administration/understand-organization-environments) to another. This is a separate permission from the **Update Objects** edit rights — a user with edit access on an app no longer automatically gains the ability to deploy it. Grant **Deploy Apps** in each environment that the user should be able to promote into, so deployment into Production can be controlled independently from deployment into Development or Staging. See [Deploy Apps between Environments](/administration/deploy-apps-between-environments) for the deployment workflow. * **Create Assignment Rules**, **View Assignment Rules**, **Update Assignment Rules**, **Delete Assignment Rules** -- Manage [assignment rules](/workflows/assignment-rules) that distribute work to users and groups. Mutating permissions can silently change how records are routed and who gets notified, so limit them to workflow owners. * **View Data Sources** -- See the data sources (such as [CloudLinks](/administration/setup-cloudlink)) configured for the scope. Required to reference those data sources when building apps or automations. * **Create Tags**, **Update Tags**, **Delete Tags** -- Manage the organization's tag library used to label and filter records. Permissions for files attached to records, conversations, and messages. Because attachments often contain the most sensitive data in a record (contracts, screenshots, PII), treat these permissions as record-data permissions. * **Create Attachments** -- Upload new files to records or conversations. * **View Attachments** -- Download and preview attached files. Grant only to audiences who should see the content of those files -- not everyone who can view a record needs attachment access. * **Update Attachments** -- Replace or modify attached files. * **Delete Attachments** -- Permanently remove attachments. Deletions cannot be undone. Permissions for **Conversations** (threaded discussions on records) and the individual **Messages** posted inside them. Conversations frequently contain the most candid commentary on a record, so handle view permissions with the same care as records. * **Create Conversations** -- Start a new conversation on a record. * **View Conversations** -- See that a conversation exists and open it. Does not imply permission to read individual messages if **View Messages** is withheld. * **Update Conversations** -- Modify conversation metadata (title, participants, status). * **Delete Conversations** -- Permanently remove a conversation and its messages. * **Create Messages** -- Post a new message in a conversation. * **View Messages** -- Read the content of messages. Withhold this to keep a user aware that a conversation exists without exposing its contents. * **Update Messages** -- Edit messages. Typically only the author or an admin should hold this. * **Delete Messages** -- Remove individual messages. Deletions are permanent. These permissions also govern [Conversations](/workflows/conversations) on a record — both the internal **Comments** channel and the external-facing **Customer Chat** channel. Permissions for the three automation surfaces: generated **Documents**, **Workflows** built in Flow, and **Data Mines** that watch warehouse data. **Documents** * **Create Documents**, **View Documents**, **Update Documents**, **Delete Documents** -- Manage document generation templates used by automations. Templates can embed record data and attachments in outbound files, so **Update** and **Delete** are configuration-level permissions. **Workflows** * **Create Workflows**, **View Workflows**, **Update Workflows**, **Delete Workflows** -- Manage [automation workflows](/workflows/automation-system) in Flow. Mutating permissions allow users to change business logic that runs without further approval, so grant them to workflow owners only. **Data Mines** * **Create Data Mines**, **View Data Mines**, **Update Data Mines**, **Delete Data Mines** -- Manage [Data Mines](/data/data-mining), the feature that watches CloudLink-backed tables on a schedule and triggers automations when row state changes. **Update** and **Delete** can silently change or stop downstream automations. Permissions for linking data together and for sharing individual records. * **Create Element Relations**, **Delete Element Relations** -- Add or remove relationships between elements so records can be linked and joined across objects. See [showing relationships](/data/showing-relationships). * **Create Record Sharing**, **Delete Record Sharing** -- Grant or revoke access to an **individual record** for specific users or groups, on top of the broader [object data access policies](/workflows/object-data-access). This is the fastest path to widen access to a single record, so limit **Create Record Sharing** to users who understand the data they are sharing. **Create Record Sharing** bypasses access-policy controls for the records it is used on. Grant it only to users who are expected to share data externally or with other teams. Permissions for the records themselves, along with the features that govern what records users can see (**Data Access Policies**) and who can read past activity (**Activity Logs**). * **Create Records**, **View Records**, **Update Records**, **Delete Records** -- Standard CRUD on records within the scope. Subject to any [object data access policies](/workflows/object-data-access) that restrict which records the user can see. * **Bulk Update Records** -- Make the same change to many records at once from a list view. Bulk operations are hard to reverse and harder to audit one row at a time; grant only to power users who are accountable for the data. * **Create Data Access Policies**, **View Data Access Policies**, **Update Data Access Policies**, **Delete Data Access Policies** -- Manage the rules that determine which records users and groups can access. Changes here directly change who can see which records -- treat these as security-critical. * **View Activity Logs** -- Read the [activity log](/administration/activity-log) for the scope. Because activity logs can reveal sensitive actions (who viewed what, when), limit this to auditors and administrators. * **Create Document Models**, **View Document Models**, **Update Document Models**, **Delete Document Models** * **View Tags** -- See tags applied to records. Pair with **Create/Update/Delete Tags** under **Apps** for users who maintain the tag library. **Data Access Policies** define who can see what. Mutating permissions in this group can widen record access across the organization in a single change. Keep **Create**, **Update**, and **Delete Data Access Policies** on a short list of administrators. Permissions for charts, dashboards, and the analytics building blocks that feed them. **Charts** and **Dashboards** can expose aggregated views of record data even when users cannot see the underlying records, so treat viewing permissions here as data-visibility permissions. * **Create Analytics Events**, **View Analytics Events** -- Manage analytics events, the telemetry and usage records captured by the platform. Each event includes an event name, platform, optional field/section/value context, device metadata (type, OS, manufacturer), session ID, user agent, and IP address. **View Analytics Events** lets a user query stored events (required to access event data via the API); **Create Analytics Events** controls the ability to record new events into the platform. Only available on **organization-level** custom roles. * **Create Charts**, **View Charts**, **Update Charts**, **Delete Charts** -- CRUD for individual charts. * **Create Dashboards**, **View Dashboards**, **Update Dashboards**, **Delete Dashboards** -- CRUD for dashboards that group charts together. Dashboards can be shared broadly, so deletion of a widely used dashboard should be limited to dashboard owners. * **View Metrics** -- See platform metrics surfaced in analytics. * **View Skills** -- See the [agent skills](/ai-agents/agents-skills) available in the Skills Directory. Required for users who build or audit agents that call skills. * **View Analysts**, **Update Analysts** -- Manage **Analysts**, predefined roles that encapsulate specific skills and responsibilities to standardize how certain types of work are scoped and assigned within an organization. **View Analysts** lets a user see Analyst role definitions; **Update Analysts** lets a user modify those definitions. Permissions for the authenticated connections to external AI model services (OpenAI, Anthropic, Google Gemini, Snowflake Cortex, Amazon Bedrock, and Custom OpenAI-compatible endpoints) and the connectors that route traffic to them. Providers hold credentials and drive AI spend, so treat these permissions as infrastructure-level. **Providers** hold the credentials for an external AI service. **Connectors** reuse a provider's credentials to bind a specific model or app to a specific feature without duplicating secrets. Separating the two permissions lets administrators own credential management centrally while still allowing other users to wire the same Snowflake, OpenAI, Anthropic, Bedrock, or custom-endpoint account into different models or features. **Providers** * **Create AI Provider** -- Register a new AI provider and its credentials. * **View AI Provider** -- See which providers are configured (credentials remain hidden). * **Update AI Provider** -- Modify a provider's configuration, including credentials and routing. * **Delete AI Provider** -- Remove a provider. Any agent, service, or automation pointing at the provider will stop working. **Connectors** * **Create AI Provider Connector**, **View AI Provider Connector**, **Update AI Provider Connector**, **Delete AI Provider Connector** -- Manage the connectors that reuse an existing provider's credentials to drive a specific model, app, or feature (for example, a CloudLink-backed Cortex provider bound to a specific feature). Connectors -- and the per-feature CloudLink binding they carry -- are where data residency, routing, and spend attribution are tuned, so they remain sensitive even for users who cannot create new providers. Creating or updating an AI provider stores credentials that the platform will use to make outbound calls that incur cost. Limit these permissions to administrators responsible for the AI spend budget and vendor relationships. **Create/Update AI Provider Connector** can redirect AI traffic and shift data residency or cost attribution without touching provider credentials, so scope those permissions just as carefully. Permissions for [AI agents](/ai-agents/ai-overview) -- the reusable AI components that execute tasks inside workflows. * **Create Agents** -- Build new agents. * **View Agents** -- See which agents exist and review their configuration. * **Update Agents** -- Modify an agent's prompt, tools, providers, or data sources. Because an agent's behavior is defined by its configuration, **Update Agents** effectively controls what the agent does at runtime. * **Delete Agents** -- Remove an agent. Any workflow, automation, or skill that depends on the agent will stop working. Administrative permissions for managing users, tokens, roles, org structure, service accounts, and SCIM. This is the highest-privilege category -- several of these permissions can be used to escalate access to the entire organization. * **Create Organization Users**, **Update Organization Users** -- Invite new users and modify existing user records. Subject to the [User Invite Policy](#user-invite-policy). **Update Organization Users** includes profile information and, for admins, role and group membership. * **Delete Groups** -- Permanently delete groups. (Other group CRUD is under the **Groups** category.) * **Create Roles**, **View Roles**, **Update Roles**, **Delete Roles** -- Manage the role definitions themselves. A user who can **Update Roles** can effectively grant themselves any permission. * **Create Object Level Roles**, **View Object Level Roles**, **Update Object Level Roles**, **Delete Object Level Roles** (Apps, Elements, Tasks) -- Manage roles that are scoped to a single app, element, or task. Useful for giving an app owner role-admin rights inside their app without org-wide role admin. * **Create Organization Structures**, **Update Organization Structures**, **Delete Organization Structures** -- Manage the organization's [reporting hierarchy](/administration/org-structure) (managers, departments, job titles). This data drives dynamic approval chains and manager-based routing, so incorrect values can misdirect approvals. * **Create OAuth Tokens**, **Delete OAuth Tokens** -- Manage API tokens issued against the user's account for [Elementum API](/api-reference/api-introduction) access. Tokens are bearer credentials: anyone who holds the token can act as the issuing user. * **Create Service Accounts**, **View Service Accounts**, **Update Service Accounts** -- Manage [service accounts](/administration/service-accounts) used by automations and integrations. Service accounts can hold powerful roles, so these permissions grant the ability to create and configure non-human principals. * **SCIM Integration** -- Configure and run [SCIM provisioning](/administration/sso-saml-setup#scim-provisioning), which synchronizes users and groups from your identity provider. A misconfigured SCIM connection can create, disable, or reassign accounts at scale. **Create Roles**, **Update Roles**, **Create Service Accounts**, **Update Service Accounts**, and **SCIM Integration** can each be used to escalate privileges across the organization. Reserve them for a small set of security administrators and review assignments regularly. Permissions for managing [org groups](/administration/groups) used to grant access and send notifications at scale. * **Create Groups** -- Add new groups and set their type and visibility. * **View Groups** -- See the groups that exist and their membership. * **Update Groups** -- Modify group settings (name, type, visibility, membership). **Update Groups** can silently add members to a group that grants access, so treat it as an access-granting permission. **Delete Groups** is listed under the [Users](#users) category. Permissions for [CloudLink](/administration/setup-cloudlink) -- the connection to external data warehouses such as Snowflake, BigQuery, and Databricks -- and the warehouse-backed **Elements** and **Procedures** used in Elementum. * **View Cloudlink Explore** -- Use the CloudLink Explore interface to browse warehouse schemas and sample data. This exposes raw warehouse content, so grant it only to users allowed to browse underlying data. * **Create Elements**, **View Elements**, **Update Elements**, **Delete Elements** -- CRUD on CloudLink-backed elements that project warehouse tables into Elementum. * **Create Procedures**, **View Procedures**, **Update Procedures**, **Delete Procedures** -- Manage warehouse stored procedures imported into Elementum so automations can call them. Permissions for [service requests](/workflows/tasks) -- work items submitted through request forms. * **Create Service Requests** -- Submit new service requests. * **View Service Requests** -- See requests visible to the user. * **Update Service Requests** -- Modify open requests. Typically held by fulfillment teams. * **Delete Service Requests** -- Permanently remove a request. Keep this narrow to preserve an audit trail. Permissions for publishing to and installing from the Elementum Marketplace. * **View Marketplace Apps** -- Browse the marketplace and see the apps available for installation. * **Create Marketplace Apps** -- Install marketplace apps into your organization. Permissions for [service level agreements](/workflows/service-level-agreements) that track response and resolution targets. * **Create Service Level Agreements**, **View Service Level Agreements**, **Update Service Level Agreements**, **Delete Service Level Agreements** -- Manage SLA definitions applied to records. Mutating SLAs retroactively can affect breach reporting, so limit **Update** and **Delete** to SLA owners. Users can hold multiple roles simultaneously -- permissions are additive across all assigned roles. When two roles disagree, the **most permissive** setting wins. There is no "deny" override and no role hierarchy: assigning a read-only role on top of an edit-granting role does not remove edit access. ### Enforce read-only access for specific users Because permissions are additive, simply adding a user to a read-only role does **not** restrict them if they also belong to a role that grants `Update Records` -- including the **Internal User** organization role or the **Content Editor** app role, which are commonly assigned to the system-managed **All Users** or **Internal Users** [groups](/administration/groups). System-managed groups cannot have their membership edited, so you cannot "remove" a user from All Users or Internal Users. To make a specific set of users read-only without affecting everyone else: 1. **Audit edit-granting roles.** In **Org Settings** → **Roles & Permissions**, identify which roles grant `Update Records` (or other write permissions) and which users or groups are members. Pay particular attention to roles whose membership includes the system-managed **All Users** or **Internal Users** groups. 2. **Scope edit access app-by-app instead of org-wide.** If the **Internal User** org role is granting edit access broadly, remove that role from the users who should be read-only, and grant edit access at the app level only -- through a custom group assigned to the **Content Editor** app role (or a custom app role with `Update Records`) on the specific apps where editing is intended. 3. **Create a custom "editors" group** for users who do need edit access on a given app, and assign the edit-granting app role to that group only. 4. **Leave read-only users with view-only roles.** Once read-only users are no longer members of any role that grants `Update Records`, the view-only role (for example, **Content Viewer** at the app level) takes effect. No further action on All Users or Internal Users is required. You cannot edit membership of **All Users**, **Internal Users**, or **External Users**. These groups are maintained automatically by Elementum. See [Groups](/administration/groups#system-managed-groups) for which group properties Org Admins can change. *** ## User Invite Policy The **User Invite Policy** is an organization-level setting that controls which users can invite new people into the organization. Find it in Settings icon **Org Settings** → **General**. The policy applies on top of the CREATE\_ORGANIZATION\_USERS permission. Users must first have this permission, and the policy then further restricts what they can do. Users with the **ADMIN** permission always bypass the policy and can invite anyone regardless of the setting. ### Policy Options The most restrictive setting. Only administrators can invite new users. **Behavior:** * **Admins**: Can invite any user (any email domain) * **Non-admins**: Cannot invite anyone, even if they have CREATE\_ORGANIZATION\_USERS permission. Requests are rejected with a validation error. **Use case**: Organizations that want centralized control over user provisioning. The most permissive setting. Any user with appropriate permissions can invite anyone. **Behavior:** * **Admins**: Can invite any user * **Non-admins** (with CREATE\_ORGANIZATION\_USERS): Can invite users from any email domain with no restrictions **Use case**: Organizations that want to let team members quickly onboard external collaborators. A balanced setting that allows delegation while maintaining domain restrictions. **Behavior:** * **Admins**: Can invite any user * **Non-admins** (with CREATE\_ORGANIZATION\_USERS): Can only invite users whose email domain is on the organization's approved managed domains list. Attempts to invite users from non-approved domains are rejected. **Use case**: Organizations that want to allow team members to invite colleagues while preventing invitations to external domains. The User Invite Policy only affects **inviting new users** into the organization. Adding existing organization users to resources like customer chat channels is controlled separately by the UPDATE\_CONVERSATIONS permission. *** ## Manage Roles 1. Open **Roles & Permissions** for the scope you need: **Org Settings** → **Roles & Permissions** for organization roles, or **Roles & Permissions** under **Security** in an app menu for that app’s roles. 2. Click **Manage Role** on any role to add or remove users and groups. 3. For custom roles, modify permissions and settings as business needs change. 4. Remove custom roles that are no longer needed. Managed roles cannot be deleted. For organizations with multiple [environments](/administration/understand-organization-environments), role membership is tracked per environment. See [Environment-specific role membership](/administration/understand-organization-environments#environment-specific-role-membership) for how to grant a role in a specific environment. *** ## Best Practices ### Security Principles * **Principle of least privilege** -- Grant only the minimum permissions necessary for users to perform their job functions. * **Separation of duties** -- Ensure critical functions require multiple roles or approvals. * **Regular audits** -- Periodically review role assignments and permissions to confirm they remain appropriate. * **Descriptive naming** -- Use clear, descriptive role names that indicate purpose and scope. ### Common Security Patterns Separate roles by function rather than hierarchy. Create roles based on job responsibilities, avoid overly broad permissions, and prefer multiple specific roles over one broad role. Use custom roles for temporary or project-based access. Create time-limited roles for contractors, remove access when projects complete, and regularly clean up unused roles. Plan for emergency access scenarios. Designate emergency administrators, document emergency procedures, and test emergency access regularly. # Service Accounts Source: https://docs.elementum.io/administration/service-accounts Create dedicated API users for agents and automations with managed permissions and security controls ## Overview Service accounts are dedicated API users that provide controlled access for agents and automations. Unlike regular user accounts, service accounts cannot be used for interactive login—they exist solely to execute automated tasks with specific, managed permissions. When you assign a service account to an automation or agent: * The automation or agent runs with the exact permissions granted to that service account * Data access policies assigned to the service account determine which records it can access * All actions are logged under the service account in the [Activity Log](/administration/activity-log), providing a clear audit trail Service accounts have no default access to your data. You must explicitly configure data access policies for any app, element, or table the service account needs to interact with. *** ## Create a Service Account 1. Go to your Elementum organization and select the app where you want to create the service account 2. In the app subnavigation, navigate to **Security** → **Service Accounts** 3. Click **Create Service Account** 4. Fill in the required information: * **First Name** and **Last Name**: The service account's display name * **Purpose**: A description explaining the intended use—this helps other administrators understand what the service account was created for * **Profile Photo** (optional): An avatar image that appears in agent conversations and activity logs 5. Save the service account, then configure its permissions and data access Use descriptive names and clear purpose statements. For example, name it "Support Bot" with purpose "Handles L1 support ticket creation and routing." *** ## Configure Permissions After creating a service account, configure its permissions from the service account row. ### Roles The **Roles** tab controls what actions the service account can perform within the app. Service accounts follow the same role-based permission model as regular users. 1. Click the **More** icon next to the service account 2. Select **Permissions**, then navigate to the **Roles** tab 3. Select the roles that grant the permissions your automation or agent needs 4. Save your changes * **Automation Service Account**: Assign roles with permissions for Create Records, Update Records, and Run Automations * **Agent Service Account**: Assign roles with permissions for Records, Comments, Attachments, and Agent access * **Read-Only Service Account**: Assign roles with only Read permissions for reporting or monitoring automations * **Least Privilege**: Grant only the minimum permissions required for the service account's intended purpose * **Separation of Concerns**: Create separate service accounts for different types of automations rather than reusing a single account for unrelated tasks * **Regular Audits**: Periodically review and remove unnecessary permissions ### User/Group Access The **User/Group Access** tab controls which users and groups are authorized to use this service account when configuring agents or automations. 1. Click the **More** icon next to the service account, then select **Permissions** 2. Navigate to the **User/Group Access** tab 3. Add individual users or user groups who should be able to use this service account *** ## Configure Data Access Service accounts follow the same data access model as regular users. To grant data access: 1. Navigate to **App Settings** → **Security** → **Data Access** 2. Create a new policy or edit an existing one 3. In the **Users and Groups** section, add the service account 4. Define which records the service account can access based on your security requirements Elementum will warn you when configuring agents and automations if your selected service account is missing required permissions or data access. Before publishing an automation that uses a service account, run [Validate Only](/workflows/automation-system#validate-access-before-publishing) from the **Publish** dropdown to confirm the service account has sufficient access to every object the automation touches. An automation that processes all records in an element needs a policy with no conditions (access to all records) assigned to the specific service account. An agent that should only access records in a specific status or category needs a policy with matching conditions (e.g., `Status` `is` `Open`). An automation that works across multiple apps needs data access policies configured in each app. *** ## Assign to Automations and Agents When creating or editing an automation or agent, you are prompted to select a service account. The process is similar for both: 1. Navigate to **Workflow** → **Automations** 2. Create or edit an automation 3. Select the service account that should execute the automation 4. Verify the service account has the necessary roles and data access for the automation's actions 1. Navigate to **Workflow** → **Intelligence** (Agents) 2. Create or edit an agent 3. Select the service account that should represent the agent 4. Verify the service account has the necessary roles and data access for the agent's tools When an agent uses a service account, the service account's profile photo and name appear as the agent's identity in conversations. This provides users with a consistent experience regardless of which agent variant they interact with. Once assigned, all actions performed by the automation or agent are attributed to the service account in the [Activity Log](/administration/activity-log). *** ## Troubleshooting Service accounts cannot currently generate OAuth tokens for A2A and API connections. **Symptom**: Automation fails or agent reports no records found 1. Verify data access policies include the service account 2. Check that policy conditions allow access to the expected records 3. Ensure policies exist in all apps/elements the automation needs **Symptom**: Actions fail with permission errors 1. Review roles assigned to the service account 2. Verify the required permissions are included in assigned roles 3. Check if the specific action requires additional permissions **Symptom**: Service account doesn't appear in dropdown when configuring an automation or agent 1. Verify you have been granted access in the User/Group Access tab 2. Check if the service account was created in the correct app 3. Contact the service account owner to request access **Symptom**: Actions show a different user than expected in Activity Log 1. Confirm the service account is properly assigned to the automation/agent 2. Check for any "Run as current user" settings that might override the service account 3. Verify the automation/agent configuration was saved after assigning the service account *** ## Related Features Service accounts use the same role-based permission system as regular users Configure data access policies to control which records service accounts can access Assign service accounts to automations for controlled, auditable execution All service account actions are tracked in the Activity Log # Set up Phone Integrations for Agents Source: https://docs.elementum.io/administration/set-up-phone-integrations-for-agents Configure phone providers, SIP trunking, and organization-wide voice telephony in Organization Settings ## Overview Organization Admins configure voice telephony in **Organization Settings** → **Voice**: phone providers (**Twilio** or **SIP Trunking**), SIP domains and ingress regions, and org-wide visibility into numbers and voice agents. After a provider is configured, app builders [build a voice agent and add a phone number](/ai-agents/agents-phone-integration) in each app. *** ## Prerequisites * **Organization Admin** access * For **Twilio**: a Twilio account with Account ID and Auth Token (you provision and pay for telephony on your Twilio account) * For **SIP Trunking**: credentials from your SIP trunk provider and access to configure a callback URL on that provider *** ## Choose a phone provider | | **Twilio** | **SIP Trunking** | | ------------ | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | **Best for** | Teams that want to provision numbers through a VoIP account connected to Elementum | Organizations with an existing enterprise phone system and carrier | | **Numbers** | Connect your Twilio account; platform provisioning creates **US toll-free** numbers | Bring your own numbers and point them at Elementum so calls route to the correct agent | | **Costs** | Telephony charges stay on your Twilio account when you use your own credentials | Telephony stays with your SIP/carrier provider; Elementum does not add pass-through telephony charges | Both paths use the same agent and phone service setup in your apps, including outbound **Initiate Call** automations. Voice usage also incurs model/LLM cost for the conversation, separate from telephony. *** ## Add a phone provider You must configure a phone provider before you can provision numbers or assign a provider to a phone service. 1. Go to **Organization Settings** → **Voice**. 2. Open the **Phone Providers** tab. 3. Click **+ Add Phone Provider**. 4. In the **Add Phone Provider** dialog, select a **Type** and complete the fields for that provider: * **Type**: **Twilio** * **Name**: A display name for this provider * **Account ID**: Your Twilio Account ID * **Auth Token**: Your Twilio Auth Token Elementum does not create or manage your Twilio account. For help locating or troubleshooting your Twilio credentials, see [Twilio's usage docs](https://www.twilio.com/docs/usage). * **Type**: **SIP Trunking** * **Name**: A display name for this provider * Enter the **username** and **password** credentials for your SIP trunk provider * Copy the **callback URL** Elementum provides and use it to finish setup on your provider's side When you add a phone number in an app, select this provider so calls route through your SIP trunk. See [Configure a phone number in your app](/ai-agents/agents-phone-integration#configure-a-phone-number-in-your-app). 5. Click **Save**. ### Multi-Region SIP Domains For SIP Trunking, Organization Admins can provision multiple SIP domains and select the ingress region closest to their SIP infrastructure. A nearer region lowers latency for voice calls and helps with global telephony deployments. 1. On the **Phone Providers** tab, open or add a SIP domain configuration. 2. Select the **ingress region** closest to your SIP infrastructure. Region options and setup instructions appear in the UI alongside the SIP domain fields. 3. Save your changes. Use a separate SIP domain when you need distinct routing or regional ingress for different parts of your telephony footprint. *** ## Organization voice management The **Voice** page has three tabs for org-wide management: View, add, and edit every provisioned number across the organization. Each number shows its provider, type, gateway, and language at a glance, and the list is searchable and sortable. Configure Twilio and SIP trunk providers. Manage SIP domains, ingress regions, and allowed IP addresses, with validation as you enter them. See [Add a phone provider](#add-a-phone-provider) and [Multi-Region SIP Domains](#multi-region-sip-domains). See every voice-enabled agent along with its app, gateway, and assigned phone numbers. Voice gateways show active or inactive status and their number counts, and configuration gaps — such as an agent with no assigned number or no app — are surfaced rather than hidden. *** ## Next steps Build the voice agent, add a phone number in the app, and configure caller access. Phone numbers are environment-specific and do not transfer with a deployment. # AWS PrivateLink for Snowflake CloudLink Source: https://docs.elementum.io/administration/snowflake-aws-privatelink Connect Elementum on AWS to your Snowflake account over AWS PrivateLink so traffic stays on the AWS network instead of the public internet. If your Elementum organization runs on AWS, you can connect to your Snowflake account over [AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/what-is-privatelink.html) instead of the public internet. PrivateLink creates a private connection between Elementum's AWS Virtual Private Cloud (VPC) and your Snowflake VPC, so CloudLink traffic stays on the AWS network. This is offered as an alternative to [IP whitelisting](/administration/connect-snowflake-to-elementum#whitelist-elementum-ip-addresses) for customers with stricter security or compliance requirements. ## How it works End users still reach Elementum over the public internet, but data traffic between Elementum and your Snowflake account is routed through an Amazon PrivateLink endpoint inside AWS. Elementum supports PrivateLink to customer Snowflake accounts in any AWS region with PrivateLink support. ## When to use PrivateLink PrivateLink is a good fit when: * Your Elementum organization is hosted on AWS. * Your Snowflake account is on AWS in a region with PrivateLink support and is on the **Business Critical** Snowflake edition (or higher). * Your security or compliance program requires data traffic to bypass the public internet. * You want to block all public access to Snowflake and only allow connections from your corporate network and Elementum. If any of these don't apply, the standard [IP-whitelisted CloudLink setup](/administration/connect-snowflake-to-elementum) is still secure (encrypted in transit with TLS) and is the simpler option. ## Prerequisites Confirm with your Elementum representative that your organization is deployed on AWS. PrivateLink is not available for Elementum organizations on other clouds. Your Snowflake account must be on AWS, in a region with PrivateLink support, and on the **Business Critical** edition or higher. PrivateLink is not available on Standard or Enterprise editions. You need a user with the `ACCOUNTADMIN` role to authorize PrivateLink and retrieve the configuration. PrivateLink replaces the IP whitelist on an existing or planned [Snowflake CloudLink](/administration/connect-snowflake-to-elementum) connection. The rest of the CloudLink setup — service user, role, warehouse, and key-pair authentication — is still required. ## Setup workflow The customer-side setup happens in your Snowflake account. Elementum handles the consumer-side AWS VPC endpoint, DNS, and CloudLink hostname configuration. Provisioning the Elementum-side VPC endpoint is handled by Elementum support. The steps below are the Snowflake actions you complete in your own account so Elementum can finish wiring up the connection. Open a request with your Elementum representative or [Elementum support](/support/resources). They will provide the **AWS account identifier** you authorize on your Snowflake account in the next step. Compare your Snowflake account's AWS region against [Elementum's hosting regions](#cross-region-considerations) and call out the mismatch in your request if your Snowflake account is in a different region, so the team can configure cross-region endpoint settings. `SYSTEM$AUTHORIZE_PRIVATELINK` requires a federated token from your AWS account. Generate one with the AWS CLI: ```bash theme={null} aws sts get-federation-token --name elementum-privatelink ``` Save the JSON output — you'll pass it to Snowflake in the next step. The federated token expires **12 hours** after it's generated. If authorization or verification fails because of an expired token, run `aws sts get-federation-token` again and re-issue the Snowflake command with the fresh token. Using the `ACCOUNTADMIN` role, call [`SYSTEM$AUTHORIZE_PRIVATELINK`](https://docs.snowflake.com/en/sql-reference/functions/system_authorize_privatelink) with the AWS account ID Elementum gave you and the federated token from the previous step: ```sql theme={null} USE ROLE ACCOUNTADMIN; SELECT SYSTEM$AUTHORIZE_PRIVATELINK( '', '' ); ``` Replace **ELEMENTUM\_AWS\_ACCOUNT\_ID** with the 12-digit AWS account ID Elementum provided, and **FEDERATED\_TOKEN\_JSON** with the full JSON output from `aws sts get-federation-token`. Confirm the authorization succeeded by calling [`SYSTEM$GET_PRIVATELINK`](https://docs.snowflake.com/en/sql-reference/functions/system_get_privatelink) with the same arguments: ```sql theme={null} SELECT SYSTEM$GET_PRIVATELINK( '', '' ); ``` A successful response returns `Account is authorized for PrivateLink.` Get your account's PrivateLink endpoint details by calling [`SYSTEM$GET_PRIVATELINK_CONFIG`](https://docs.snowflake.com/en/sql-reference/functions/system_get_privatelink_config): ```sql theme={null} SELECT SYSTEM$GET_PRIVATELINK_CONFIG(); ``` Share the JSON output with your Elementum contact. Elementum primarily needs: * `privatelink-account-url` — the private hostname for your Snowflake account * `privatelink-vpce-id` — the VPC endpoint service identifier * `privatelink-ocsp-url` — the OCSP cache server hostname Elementum uses these values to provision the VPC endpoint on the Elementum side and update the CloudLink hostname. After Elementum confirms the endpoint is provisioned, open **Settings > CloudLinks** in Elementum, edit the Snowflake connection (or create a new one following the [Connecting Snowflake to Elementum](/administration/connect-snowflake-to-elementum) guide), and click **Test Connection**. A successful test confirms traffic is flowing over PrivateLink. ## Block public access to Snowflake After PrivateLink is verified, you can tighten security further by restricting your Snowflake account to PrivateLink and your corporate network only. Add a Snowflake [network policy](https://docs.snowflake.com/en/user-guide/network-policies) that allows only your corporate CIDR ranges and activate it for the account. Once PrivateLink is in place for Elementum, the Elementum [public IP allow list](/administration/connect-snowflake-to-elementum#whitelist-elementum-ip-addresses) (`44.210.166.136`, `44.209.114.114`, etc.) is no longer required for Elementum traffic. You can safely remove those IPs from your Snowflake network policy after confirming the PrivateLink connection is healthy. ## Cross-region considerations Elementum hosts its production AWS environments in two regions: | Elementum environment | AWS region | Region name | | --------------------- | -------------- | ---------------------- | | PROD | `us-east-1` | US East (N. Virginia) | | PROD-EU | `eu-central-1` | EU Central (Frankfurt) | If your Snowflake account is in the same AWS region as the Elementum environment hosting your organization, no cross-region configuration is needed. If your Snowflake account is in a different region, AWS PrivateLink still supports the connection, but Elementum needs to enable cross-region endpoint settings during provisioning — flag the region mismatch in your initial request. Cross-region PrivateLink is not supported for some Snowflake platform-as-a-service traffic (for example, Amazon S3 internal stages) — see Snowflake's [AWS PrivateLink documentation](https://docs.snowflake.com/en/user-guide/admin-security-privatelink) for the current matrix. ## Troubleshooting `SYSTEM$AUTHORIZE_PRIVATELINK` and `SYSTEM$GET_PRIVATELINK` require a federated token that's still valid. The token from `aws sts get-federation-token` expires after 12 hours. Regenerate the token and re-run the Snowflake command. Confirm you used the same AWS account ID Elementum provided, with no extra whitespace or quoting issues in the JSON value. Verify Elementum has finished provisioning the VPC endpoint on its side and that the CloudLink **Account URL** has been updated to the `privatelink` hostname returned by `SYSTEM$GET_PRIVATELINK_CONFIG` (it should contain `.privatelink.snowflakecomputing.com`). If the CloudLink still points at the public account URL, traffic continues to use the public route. You can also call [`SYSTEM$ALLOWLIST_PRIVATELINK`](https://docs.snowflake.com/en/sql-reference/functions/system_allowlist_privatelink) in your Snowflake account to list the hostnames that should be reachable over the private endpoint. Generate a fresh federated token and call [`SYSTEM$REVOKE_PRIVATELINK`](https://docs.snowflake.com/en/sql-reference/functions/system_revoke_privatelink) with the same `aws_id` and `federated_token` arguments you used to authorize. Notify Elementum so the consumer-side endpoint can be removed and the CloudLink hostname can be reverted. Re-add the Elementum public IP allow list before revoking if you want to fall back to public-internet CloudLink connectivity. ## Additional resources Snowflake's reference documentation for AWS PrivateLink, including all supported system functions and limitations. AWS overview of PrivateLink concepts, security model, and VPC endpoint architecture. Complete CloudLink setup for Snowflake — service user, role, warehouse, and key-pair authentication. How CloudLink connections work across Snowflake, BigQuery, Databricks, and REST APIs. # License Patrol with Snowflake CloudLink Source: https://docs.elementum.io/administration/snowflake-license-patrol Additional setup steps for using License Patrol with your Snowflake CloudLink. If your organization uses License Patrol, complete the standard [Snowflake CloudLink setup](/administration/connect-snowflake-to-elementum) first, then follow these additional steps to grant the License Patrol native app access to your data. ## Prerequisites * Completed [Snowflake CloudLink setup](/administration/connect-snowflake-to-elementum), including the `ELEMENTUM` user, role, warehouse, and database. * `ACCOUNTADMIN` role in Snowflake. * Access to the [Snowflake Marketplace](https://app.snowflake.com/marketplace). ## Step 1: Install the License Patrol native app 1. In the Snowflake Marketplace, navigate to the **License Patrol** listing. 2. Select the app and click **Get** to install it. 3. Using the `ACCOUNTADMIN` role, select **Manage Access**. 4. Add the `ELEMENTUM` role to the app's access list. ## Step 2: Grant required permissions Run the following grants to give the License Patrol application access to the source tables it analyzes, and to give the `ELEMENTUM` role access to License Patrol's app data. ```sql theme={null} USE ROLE ACCOUNTADMIN; -- Grant database and schema access to the License Patrol application GRANT USAGE ON DATABASE TO APPLICATION LICENSE_PATROL; GRANT USAGE ON SCHEMA . TO APPLICATION LICENSE_PATROL; -- Grant access to relevant tables GRANT SELECT ON TABLE ..APPLICATION_LOGINS TO APPLICATION LICENSE_PATROL; GRANT SELECT ON TABLE ..EMPLOYEE_DATA TO APPLICATION LICENSE_PATROL; GRANT SELECT ON TABLE ..SOFTWARE_CONTRACTS TO APPLICATION LICENSE_PATROL; -- Grant Elementum access to License Patrol data GRANT SELECT ON TABLE LICENSEPATROL.APP_DATA.REVOCATION_EXCLUDE TO ROLE ELEMENTUM; ``` Replace `` and `` with the database and schema that contain your License Patrol source tables. ### Example with concrete values ```sql theme={null} USE ROLE ACCOUNTADMIN; GRANT USAGE ON DATABASE HR_DB TO APPLICATION LICENSE_PATROL; GRANT USAGE ON SCHEMA HR_DB.PUBLIC TO APPLICATION LICENSE_PATROL; GRANT SELECT ON TABLE HR_DB.PUBLIC.APPLICATION_LOGINS TO APPLICATION LICENSE_PATROL; GRANT SELECT ON TABLE HR_DB.PUBLIC.EMPLOYEE_DATA TO APPLICATION LICENSE_PATROL; GRANT SELECT ON TABLE HR_DB.PUBLIC.SOFTWARE_CONTRACTS TO APPLICATION LICENSE_PATROL; GRANT SELECT ON TABLE LICENSEPATROL.APP_DATA.REVOCATION_EXCLUDE TO ROLE ELEMENTUM; ``` ## Next steps For setup or access questions, contact Elementum Support or your account representative. Return to the main Snowflake setup guide. Review CloudLink concepts and security. # Snowflake Query Profile Table Source: https://docs.elementum.io/administration/snowflake-query-profile-table What the Query Profile Table is, why Elementum recommends provisioning it, and how to set it up in your Snowflake account. The Query Profile Table is a small, dedicated table in your Snowflake account that records performance metrics for queries Elementum runs on your behalf. It's part of the [Snowflake CloudLink setup](/administration/connect-snowflake-to-elementum) and is provisioned once, after the CloudLink itself is created. ## What the Query Profile Table is When you create a Snowflake CloudLink, Elementum generates a DDL script that creates a dynamic table in the `ELEMENTUM_PLATFORM` schema. That table is backed by `SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY` and a scheduled task that keeps it current. Once provisioned: * The table records execution time, warehouse usage, bytes scanned, and similar metrics **only for queries the `ELEMENTUM` role runs**. * It does not capture queries from your internal users, other applications, or third-party tools. * It lives entirely inside your Snowflake account—no data leaves Snowflake. * A scheduled task clears records older than 14 days, so the table stays small. | Property | Value | | --------- | --------------------------------------------------------------- | | Location | `ELEMENTUM.ELEMENTUM_PLATFORM` schema in your Snowflake account | | Source | Filtered view of `SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY` | | Scope | Queries executed by the `ELEMENTUM` role only | | Retention | 14 days, enforced by a scheduled task | | Owner | The `ELEMENTUM` role | Elementum reads the Query Profile Table to surface query-performance metrics. Without it, every metric lookup has to scan `SNOWFLAKE.ACCOUNT_USAGE` directly, which is slow and consumes credits. ## Why Elementum recommends provisioning it The Query Profile Table gives Elementum's support and engineering teams the visibility needed to diagnose performance issues in your environment, without granting access to anything beyond the queries Elementum itself ran. ### Faster diagnosis of performance issues When the table is provisioned, Elementum can diagnose and resolve issues directly rather than relying on support escalations and one-off `ACCOUNT_USAGE` queries. This applies to: * Timeouts and slow-running operations * Intermittent query failures * Warehouse scaling and credit-usage concerns ### Proactive performance monitoring With visibility into how operations perform over time, Elementum can: * Identify which operations are creating bottlenecks * Alert on emerging performance issues before they affect your workflows * Recommend configuration changes (such as warehouse sizing or scaling policy) when they would improve your experience ### Targeted optimization for your environment Using performance trends specific to your account, Elementum can recommend or apply targeted improvements such as: * Index recommendations * [Search optimization](https://docs.snowflake.com/en/user-guide/search-optimization-service) * Clustering keys on tables Elementum queries frequently ## Privacy and access scope The table is designed so Elementum only ever sees activity it generated: * The DDL filters `QUERY_HISTORY` by the `ELEMENTUM` role, so other users' queries are excluded. * The table is owned by the `ELEMENTUM` role and lives in the platform schema you already use for CloudLink. No additional access is granted outside that role. * Data older than 14 days is removed automatically by the scheduled task. You control access through your existing Snowflake roles and grants. If you ever revoke the `ELEMENTUM` role's privileges, the table and its task stop receiving data. ## Prerequisites Before provisioning the Query Profile Table, confirm: * The Snowflake CloudLink has been created and is showing as **Connected** in **Organization Settings → CloudLinks**. See [Connect Snowflake to Elementum](/administration/connect-snowflake-to-elementum) for the full setup. * You have a Snowflake user with the `ACCOUNTADMIN` role available to run the DDL. * The `ELEMENTUM` role, warehouse, database, and `ELEMENTUM_PLATFORM` schema created during CloudLink setup are in place. ## Provision the table Elementum generates the DDL for your specific CloudLink—it includes the right database, schema, warehouse, and role names for your environment. In Elementum, go to **Organization Settings → CloudLinks** and click the name of your Snowflake CloudLink to open its details. Scroll to the **Query Profile Table** section and click **Copy DDL**. The script is tailored to this CloudLink and includes the grants the `ELEMENTUM` role needs to read `SNOWFLAKE.ACCOUNT_USAGE` and run the scheduled task. Open a Snowflake worksheet as `ACCOUNTADMIN` and run the script. The DDL must be run by `ACCOUNTADMIN`. It grants `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE` and creates a scheduled task in `ELEMENTUM_PLATFORM`—both of which require account-level privileges. Return to the CloudLink dialog. The **Query Profile Table** status should change to **Provisioned**. If it still shows **Not provisioned**, see [Troubleshooting](#troubleshooting) below. ## Verify the table is working You can sanity-check the table and its scheduled task directly in Snowflake. ```sql theme={null} USE ROLE ELEMENTUM; USE DATABASE ELEMENTUM; USE SCHEMA ELEMENTUM_PLATFORM; SHOW DYNAMIC TABLES LIKE 'QUERY_PROFILE%'; ``` You should see the dynamic table created by the DDL. ```sql theme={null} SHOW TASKS LIKE 'QUERY_PROFILE%' IN SCHEMA ELEMENTUM.ELEMENTUM_PLATFORM; ``` The task `state` should be `started`. If it shows `suspended`, resume it: ```sql theme={null} USE ROLE ACCOUNTADMIN; ALTER TASK ELEMENTUM.ELEMENTUM_PLATFORM. RESUME; ``` Once the CloudLink has run a few queries (give it a few minutes after provisioning), the table should contain rows: ```sql theme={null} SELECT COUNT(*) FROM ELEMENTUM.ELEMENTUM_PLATFORM.; ``` The exact table and task names are in the DDL Elementum generated for your CloudLink. ## Troubleshooting * Re-run the DDL as `ACCOUNTADMIN`. The `IMPORTED PRIVILEGES` grant and task creation both require account-level privileges and will silently fail under other roles. * Confirm the CloudLink in the UI matches the one whose DDL you copied. Each CloudLink has its own DDL. * Click **Refresh** on the CloudLink details page; the status check runs against Snowflake on demand. * Verify you are running the script as `ACCOUNTADMIN`, not `SYSADMIN` or a custom admin role. * Confirm the `ELEMENTUM` role exists. If you set up the CloudLink before the role was created, the grants in the DDL will fail. * Check that the scheduled task is in the `started` state with `SHOW TASKS`. * Confirm the `ELEMENTUM` warehouse is not suspended; the task needs warehouse compute to run. * Allow up to the task's scheduled interval (typically a few minutes) for the first rows to land. * Verify the CloudLink has actually executed queries since provisioning. The table only captures activity from the `ELEMENTUM` role. If you need to remove the table—for example, before tearing down a CloudLink—drop the task first, then the table: ```sql theme={null} USE ROLE ACCOUNTADMIN; ALTER TASK ELEMENTUM.ELEMENTUM_PLATFORM. SUSPEND; DROP TASK ELEMENTUM.ELEMENTUM_PLATFORM.; DROP DYNAMIC TABLE ELEMENTUM.ELEMENTUM_PLATFORM.; ``` The CloudLink will continue to work without the table, but query-profile lookups will fall back to scanning `ACCOUNT_USAGE` directly. ## Related * [Connect Snowflake to Elementum](/administration/connect-snowflake-to-elementum) — full CloudLink setup, including the step where you provision this table. * [Snowflake warehouses](/administration/snowflake-warehouses) — sizing and scaling guidance Elementum can refine using Query Profile data. * [Snowflake table types](/administration/snowflake-table-types) — Standard vs. Hybrid tables and how table type affects query performance. # Accessing Files from Snowflake Stages Source: https://docs.elementum.io/administration/snowflake-stages Complete guide to accessing and processing files stored in Snowflake stages through Elementum automations ## Overview This workflow enables you to process external files automatically, extract data, and trigger workflows based on file content. The Snowflake stage file access workflow consists of six main steps: 1. **Create a Snowflake view** for stage files 2. **Import the view as an Elementum table** 3. **Build a Data Mine** to monitor for new or changed files 4. **Create an automation** triggered by the Data Mine 5. **Process files** using the presigned URLs in your automation 6. **Add additional actions** to your automation This workflow enables you to securely access and process files stored in Snowflake stages - without duplicating the data outside of Snowflake. By default, files are not persisted or stored outside of Snowflake; your data remains protected and centralized unless you explicitly configure otherwise. ## Prerequisites Before starting this workflow, ensure you have: * **Snowflake access** with permissions to create views and access stages * **Elementum CloudLink** configured and connected to your Snowflake instance * **Files uploaded** to a Snowflake stage (e.g., `@files_to_process`) * **Directory Table enabled on your Snowflake stage** for file listing and metadata access * **Understanding** of [Elementum Tables](/data/tables), [Data Mining](/data/data-mining), and [Automation System](/workflows/automation-system) The stage you use must have a [Directory Table](https://docs.snowflake.com/en/user-guide/data-load-dirtables) enabled. Enable it with: ```sql theme={null} ALTER STAGE SET DIRECTORY = (ENABLE = TRUE); ``` ## Step 1: Create Snowflake View from a Stage The first step is creating a Snowflake view that provides access to your stage files with presigned URLs for secure access. Execute this SQL in your Snowflake environment: ```sql theme={null} CREATE VIEW STAGE_FILES_VIEW AS SELECT RELATIVE_PATH, SIZE, LAST_MODIFIED, MD5, get_presigned_url(@files_to_process, RELATIVE_PATH, 3600) AS presigned_url FROM DIRECTORY(@files_to_process); ``` * **`RELATIVE_PATH`**: File path within the stage * **`SIZE`**: File size in bytes * **`LAST_MODIFIED`**: Timestamp of last file modification * **`MD5`**: File hash for integrity checking * **`presigned_url`**: Secure, time-limited URL for file access (valid for 3600 seconds = 1 hour) The `presigned_url` is automatically regenerated every time the Data Mine runs, ensuring that URLs are always fresh and valid. This means you never have to worry about URL expiration interrupting your automated file processing. ## Step 2: Import View as Elementum Table Once your Snowflake view is created, import it into Elementum as a table. 1. Navigate to **Tables** → **Explore Data** → **CloudLink** 2. Select your Snowflake connection and choose the view you created 3. Click **Create Table** and fill out the details ## Step 3: Build Data Mine for File Monitoring Create a Data Mine to automatically detect when new files arrive or existing files change. 1. In your table, go to **Data Mining** → **Create Data Mine** → **Logic-Based Rules Mining** 2. **Identifying Columns**: Select `RELATIVE_PATH`, `LAST_MODIFIED`, and `MD5` These columns work together to track individual files across Data Mine runs, detect when files are modified or replaced, and ensure accurate state management (ON/OFF transitions). 3. **Matching Criteria**: Set filters for file types or conditions (optional) 4. **Name and Schedule**: Give it a name and set check frequency ## Step 4: Create Automation with Data Mine Trigger Build an automation that processes files when the Data Mine detects them. Your automation will follow this logical flow: **Data Mine Trigger** → **Process File** → **Take Additional Actions** (e.g. AI Analysis) 1. Navigate to **Automations** → **Create Automation** 2. Add **Data Mine Trigger** and select your Data Mine 3. Set trigger option to **Trigger when data meets requirement** ## Step 5: Process Files Using API Request Action Add an API Request action to your automation to access files stored in the Snowflake stage. **API Request** action details: * **Request URL**: `$PRESIGNED_URL` * **Method**: `GET` * **Authorization**: `No Auth` * **Response Type**: `File` **Variable Reference**: The `$PRESIGNED_URL` variable comes from the Data Mine trigger, providing access to all fields from the matching stage file record. ## Step 6: Add Additional Actions After accessing the file via the API Request action, any additional actions you add will now have access to the file content. ## Summary This workflow enables you to automatically process files stored in Snowflake stages: 1. **Snowflake View** provides secure access to stage files 2. **Elementum Table** makes stage files accessible in your workspace 3. **Data Mine** automatically detects new or changed files 4. **Automation** provides access to the file content 5. **Additional Actions** enable AI analysis, data extraction, and workflow automation By following this guide, you can create an automated file processing system that uses your Snowflake stage as a workflow trigger so your business can respond to new data as it arrives. *** ## Appendix: Quick Test Setup in Snowflake Use the following SQL to create a stage in Snowflake for testing purposes. Replace the `ALL_CAPS` placeholders with your actual values. For complete configuration options, see Snowflake's [CREATE STAGE documentation](https://docs.snowflake.com/en/sql-reference/sql/create-stage). ```sql theme={null} USE DATABASE DATABASE_NAME; USE SCHEMA SCHEMA_NAME; -- Create internal stage with directory table enabled CREATE OR REPLACE STAGE STAGE_NAME; ALTER STAGE STAGE_NAME SET DIRECTORY = (ENABLE = TRUE); -- Create view with presigned URLs (1-hour expiration) CREATE OR REPLACE VIEW VIEW_NAME AS SELECT RELATIVE_PATH, SIZE, LAST_MODIFIED, MD5, get_presigned_url(@STAGE_NAME, RELATIVE_PATH, 3600) AS presigned_url FROM DIRECTORY(@STAGE_NAME); ``` Ensure your Elementum CloudLink role has the necessary permissions to access the stage and view. ```sql theme={null} GRANT USAGE ON DATABASE DATABASE_NAME TO ROLE CLOUDLINK_ROLE; GRANT USAGE ON SCHEMA DATABASE_NAME.SCHEMA_NAME TO ROLE CLOUDLINK_ROLE; GRANT USAGE ON STAGE DATABASE_NAME.SCHEMA_NAME.STAGE_NAME TO ROLE CLOUDLINK_ROLE; GRANT SELECT ON VIEW DATABASE_NAME.SCHEMA_NAME.VIEW_NAME TO ROLE CLOUDLINK_ROLE; ``` Upload a test file to verify the stage is working correctly: ```sql theme={null} -- Using SnowSQL CLI PUT file://path/to/test-file.csv @DATABASE_NAME.SCHEMA_NAME.STAGE_NAME OVERWRITE=TRUE AUTO_COMPRESS=FALSE; ``` You can also upload files through the Snowflake web interface by navigating to your stage and using the "Upload Files" option. # Snowflake Table Types Source: https://docs.elementum.io/administration/snowflake-table-types Essential guide for choosing between Standard and Hybrid tables to optimize Elementum's performance and cost efficiency ## Introduction Snowflake offers different types of tables that fundamentally affect how data is stored, accessed, and processed. For Elementum, choosing between Standard and Hybrid tables forms the essential foundation that shapes all workflow data operations and transaction processing capabilities. When Elementum processes business-critical workflows, every data write, state change, and query is ultimately influenced by the underlying table structure supporting these operations. The choice between Snowflake Standard tables and Hybrid tables is critical for optimizing both performance and cost for the platform's various data needs. For the purposes of this guide, we refer to any table not explicitly created as a Hybrid table as a "Standard table." **The fundamental rule for Elementum implementations:** * **Standard Tables**: Suitable for tables that are primarily read-only * **Hybrid Tables**: Use for any table with high read/write activity (transactional data) This choice directly impacts: * Query performance for time-sensitive operational workflows * Storage costs for large datasets with varying access patterns * Data freshness requirements for real-time decision making * System responsiveness for end users * Optimization of compute resources across the organization *** ## Quick Reference: Table Type Selection for Elementum **Data Pattern**: Primarily read-only data **Examples**:
  • Reference data
  • Configuration tables with infrequent updates
  • Historical archives
  • Lookup tables
  • Analytical datasets accessed for reporting
  • **Benefits**: Simplified management, consistent performance for analytical queries, lower maintenance overhead
    **Data Pattern**: High read/write transactional data **Examples**:
  • Active workflow instances
  • Transaction records
  • Status tracking tables
  • Data Exchange Tables
  • Any table requiring frequent updates or inserts
  • **Benefits**: Significantly faster performance for transactional workloads, improved concurrency, reduced latency
    *** ## Understanding Table Types in the Elementum Context ### Standard Tables Standard tables in Snowflake store data entirely in the persistent storage layer, providing consistent performance characteristics regardless of data age or access patterns. * Data is stored in micro-partitions in cloud storage with metadata cached for query optimization * Offers uniform performance across all data * Reference data, configuration data, and other read-primarily datasets For Elementum implementations, Standard tables work well for: * Master data that workflows reference (customers, products, locations) * Business rules and validation criteria used by workflows * Lookup tables providing decision parameters for workflow steps * Mapping and translation tables for data standardization * Configuration parameters that inform workflow behavior ### Hybrid Tables Hybrid tables combine both local (in compute layer) and remote storage (in cloud storage) to optimize for performance and cost, particularly for transactional data with frequent access. * Frequently accessed "hot" data is stored in the compute layer for ultra-fast access * Delivers significantly faster performance for transactional operations * Any table experiencing frequent reads and writes Hybrid tables are essential for Elementum's core transactional components: * Active workflow instance tables * Transaction processing tables * State tracking and status tables * Event logging with frequent updates * Any table supporting real-time operations *** ## Performance Benefits Comparison Choosing the right table type for different data workloads in Elementum provides significant performance advantages. **Query Performance**:
  • Reliable performance for analytical queries
  • Simplified query planning and optimization
  • Consistent execution times for reports and dashboards
  • **Maintenance Efficiency**:
  • Less complexity for tables with infrequent changes
  • Reduced need for monitoring and optimization
  • Simplified backup and recovery processes
  • **Write Operations**:
  • Up to **10x faster** inserts and updates for hot data
  • Reduced latency for transaction processing
  • Better handling of concurrent write operations
  • **Read Performance**:
  • Near-instant access to recently written data
  • Reduced query latency for operational workflows
  • Better cache utilization for frequently accessed records
  • **Concurrency**:
  • Better handling of simultaneous read/write operations
  • Reduced contention for actively used workflow data
  • Improved scalability for high-traffic implementations
  • These performance benefits directly translate to more responsive workflows, faster state transitions, and improved user experience for Elementum implementations. *** ## Cost Considerations Choosing the right table type impacts not just performance but also cost. **Costs**:
  • Higher storage costs for hot data (stored in both compute and storage layers)
  • Lower compute costs due to reduced query processing time
  • **Value Proposition**:
  • Better value for transactional tables where performance is critical
  • **Costs**:
  • Lower overall storage costs
  • More predictable cost model
  • **Value Proposition**:
  • Better value for read-primarily data
  • For Elementum's implementations, the cost/performance tradeoff typically favors hybrid tables for core transaction processing, as the performance benefits outweigh the modest increase in storage costs. *** ## Transitioning from Standard to Hybrid Tables Snowflake does not currently support direct conversion of an existing standard table to a hybrid table. Unlike other table property changes, changing the table type requires creating a new table and migrating the data. ### Post-Migration Optimization After migration to a hybrid table: Monitor performance to confirm improvement justifies the migration effort Adjust virtual warehouse sizing as hybrid tables may allow for more efficient compute utilization Migrating table types from hybrid to standard or standard to hybrid can only be performed by Elementum. Contact [Elementum support](/support/resources) to request a table type migration. For technical implementation details, refer to Snowflake's documentation on [Creating and Using Hybrid Tables](https://docs.snowflake.com/en/user-guide/tables-hybrid). *** ## Conclusion 1. **Use Hybrid Tables for all transactional data** with frequent reads and writes to maximize performance, responsiveness, and user experience. 2. **Keep Standard Tables for read-primarily data** to maintain cost efficiency and simplified management. 3. **Monitor usage patterns** and be prepared to migrate tables from standard to hybrid as your Elementum implementation evolves and usage patterns change. By following these guidelines, Elementum implementations can achieve optimal performance for transaction processing while maintaining cost efficiency across the entire data platform. # Snowflake Warehouses Source: https://docs.elementum.io/administration/snowflake-warehouses Essential guide for configuring Snowflake Virtual Warehouses to optimize Elementum's performance and cost efficiency ## Introduction Snowflake Virtual Warehouses are essential compute resources that execute queries and data manipulation operations. For Elementum, these warehouses are the critical backbone that powers all workflow and application interface queries. When users interact with Elementum's interface, every data request, workflow status check, and process automation is ultimately served by Snowflake warehouses processing these queries behind the scenes. Proper warehouse configuration is not just beneficial but crucial to Elementum's performance. Well-configured warehouses ensure: * Responsive user interfaces with minimal latency * Efficient execution of complex workflow logic and data transformations * Consistent performance during peak usage periods * Balanced resource allocation across various use cases * Optimized cost-to-performance ratio for production environments This guide outlines best practices for configuring Snowflake warehouses specifically tuned for Elementum's workload patterns and performance requirements. *** ## Quick Reference: Configuration Guidelines For quick implementation, follow these essential configuration guidelines based on environment type.
  • **Warehouse Size**: X-Small to Small
  • **Cluster Settings**: Single cluster
  • **Auto-Suspend**: 1-3 minutes
  • **Resource Monitoring**: Implement suspensions at 100% of budget allocation
  • **Use Case Isolation**: One warehouse per development department sufficient
  • **Scaling Policy**: Use Economy unless performance in development environments is a concern
  • **Warehouse Size**: Small to Medium for user-facing applications; Medium to Large for data processing and/or many concurrent users
  • **Cluster Settings**: Multi-cluster with minimum 1, maximum 10+ clusters
  • **Auto-Suspend**: Default 10 minutes for user-facing applications; 2-5 minutes for automated use cases
  • **Resource Monitoring**: Implement alerts without suspension
  • **Use Case Isolation**: Dedicate separate warehouses for each distinct workflow application
  • **Scaling Policy**: Standard for most workloads; Economy only for non-time-sensitive operations
  • *** ## Detailed Configuration While the quick reference above offers a starting point, these detailed guidelines will help you optimize warehouse performance for your specific Elementum deployment patterns and requirements. ### Determining Warehouse Size Warehouse sizing directly impacts query performance within Elementum's environment. Properly sized warehouses ensure the application remains responsive while delivering consistent query execution times. Begin with a smaller warehouse size (e.g., X-Small) and monitor performance. For Elementum's development environments, starting with X-Small or Small warehouses is typically sufficient for initial testing and non-intensive data operations. As you observe query performance metrics, especially for critical workflow paths, incrementally increase size to Medium or Large for production environments handling complex business critical operations or concurrent user sessions. [Learn more about warehouse considerations](https://docs.snowflake.com/en/user-guide/warehouses-considerations) Elementum's workflows involve varying levels of query complexity - from simple status lookups to complex multi-table joins for contextual workflow information. Analyze these patterns to select appropriate sizing: * **Dashboard and reporting interfaces**: Medium warehouses typically provide good balance * **Real-time workflow processing functions**: Medium to Large for sub-second response times * **Batch processing for large data sets**: Large warehouses during scheduled processing windows * **User-facing operational workflows**: Small to Medium with multi-cluster capability for concurrency When selecting size, consider both the computational intensity of typical Elementum queries and the peak concurrent user loads in your deployment. [Learn more about warehouse considerations](https://docs.snowflake.com/en/user-guide/warehouses-considerations) ### Warehouse Scaling and Concurrency Elementum's user traffic often follows predictable patterns with occasional unexpected surges. Proper scaling configuration ensures consistent performance regardless of user load variations. #### Multi-Cluster Warehouses For Elementum's production environments, multi-cluster warehouses are essential to handle varying concurrency demands. Configure these with: **1** for consistent baseline performance **10** for most implementations (adjust based on peak user load) Snowflake supports scaling maximum cluster counts up to **300** depending on warehouse size These configurations are particularly important for global deployments where users across different time zones create overlapping usage patterns. During critical business events or end-of-period reporting, multi-cluster warehouse scaling prevents performance bottlenecks that could impact workflow execution. [Learn more about multi-cluster warehouses](https://docs.snowflake.com/en/user-guide/warehouses-multicluster) #### Scaling Policies For Elementum workloads: Use 'Standard' policy for general application interfaces and dashboard rendering Consider 'Economy' only for non-time-sensitive automated operations The right scaling policy ensures that resources are allocated efficiently during peak usage periods like month-end reporting or during high-intensity workflow processing events. [Learn more about scaling policies](https://docs.snowflake.com/en/user-guide/warehouses-multicluster) ### Resource Management and Cost Optimization Balancing performance with cost considerations is crucial for maintaining Elementum's total cost of ownership while delivering exceptional user experiences. #### Auto-Suspend and Auto-Resume Elementum's usage patterns often include predictable periods of inactivity, particularly outside of business hours or between batch processing jobs. Configure warehouses with: **10 minutes** (Snowflake's default) Optimal balance between responsiveness and resource efficiency **2-5 minutes** For automated workflows and processing jobs **1-3 minutes** For testing and development work These settings optimize credit consumption while ensuring warehouses are immediately available when needed. [Learn more about warehouse tasks](https://docs.snowflake.com/en/user-guide/warehouses-tasks) #### Resource Monitors Implement a tiered resource monitoring strategy for Elementum deployments: Set daily and monthly thresholds at **80-90%** of expected usage Configure at **70%** threshold to provide advanced notification Apply to development and testing warehouses at **100%** of allocated budget For critical production environments supporting essential business operations, use alerting without suspension to prevent unexpected service interruptions. [Learn more about resource monitors](https://docs.snowflake.com/en/user-guide/resource-monitors) ### Performance Optimization Optimizing warehouse performance directly impacts Elementum user satisfaction and system responsiveness during critical workflow execution. #### Isolate Workloads by Use Case Elementum's architecture is designed to isolate warehouses by specific business use cases or "applications": Each distinct workflow application operates on its own warehouse High-demand applications can scale without affecting other organizational workflows Align warehouse configurations to the specific performance needs of each use case Prevents performance bottlenecks where intensive operations in one application would impact others This isolation strategy ensures consistent performance across all applications regardless of varying workload intensities. Administrators can configure warehouse assignments for each use case through Elementum's application administration interface, allowing for granular resource management based on business priorities. #### Query Optimization Elementum's complex AI workflow queries often involve: * Multi-table joins across workflow, task, and user data * Window functions for time-series analysis of workflow metrics * Aggregations across high-cardinality dimensions Regularly profile and optimize these patterns by: * Creating materialized views for commonly accessed tables * Implementing appropriate clustering keys on frequently filtered dimensions * Scheduling resource-intensive operations during off-peak hours Performance tuning should be an ongoing process, with particular attention to queries supporting critical dashboards and real-time alerts. [Learn more about query warehouse performance](https://docs.snowflake.com/en/user-guide/performance-query-warehouse) #### Query Acceleration Service For workloads with unpredictable data volume or queries with large scans and selective filters, consider enabling the Query Acceleration Service (QAS):
  • Improves warehouse performance by offloading portions of query processing to shared compute resources
  • Particularly beneficial for ad hoc analytics and queries with large scans
  • Reduces the impact of outlier queries that consume disproportionate resources
  • Configure with appropriate scale factors (1-10) based on workload requirements
  • QAS does not support hybrid tables - only standard tables can be accelerated
  • Performance improvements may fluctuate based on server availability
  • Additional credits are consumed when QAS is utilized
  • Before enabling QAS, identify eligible queries using the QUERY\_ACCELERATION\_ELIGIBLE view and monitor cost-performance tradeoffs after implementation. [Learn more about Query Acceleration Service](https://docs.snowflake.com/en/user-guide/query-acceleration-service) ### Monitoring and Maintenance Proactive monitoring ensures Elementum maintains optimal performance and prevents operational disruptions. #### Performance Monitoring Implement a multi-layered monitoring approach for Elementum warehouses: Track overall warehouse utilization, queue times, and concurrency Monitor execution times for critical queries supporting key workflows Correlate warehouse performance with application response times Establish baselines during normal operations and configure alerts for significant deviations. [Learn more about warehouse load monitoring](https://docs.snowflake.com/en/user-guide/warehouses-load-monitoring) #### Adjust Configurations Elementum's warehouse requirements evolve with: * User growth and changing usage patterns * New workflow capabilities * Integration with additional data sources * Seasonal business fluctuations Assess warehouse configurations against current needs using historical performance data, user feedback, and cost metrics During reviews, optimize: * Warehouse sizes and cluster limits * Scaling policies and auto-suspend times * Resource allocation across different functions * Workflow optimization opportunities For global or high-growth Elementum deployments, consider more frequent reviews to stay ahead of changing requirements [Learn more about performance optimization](https://docs.snowflake.com/en/guides-overview-performance) *** ## Conclusion 1. **Size warehouses appropriately** based on workload complexity and user concurrency, starting small and scaling up as needed. 2. **Implement multi-cluster warehouses** for production environments to handle varying concurrency demands and prevent performance bottlenecks. 3. **Configure auto-suspend settings** based on usage patterns to optimize credit consumption while maintaining responsiveness. 4. **Isolate workloads by use case** to ensure consistent performance across all applications regardless of varying workload intensities. 5. **Establish a regular review cycle** to continuously optimize warehouse configurations as your Elementum implementation evolves. By following these guidelines, Elementum implementations can achieve optimal performance for workflow processing while maintaining cost efficiency across the entire platform. # Single Sign-On (SSO) with SAML 2.0 Source: https://docs.elementum.io/administration/sso-saml-setup Configure SAML 2.0-based Single Sign-On and SCIM provisioning for secure, centralized authentication in Elementum ## Overview Single Sign-On (SSO) via SAML 2.0 allows your organization to manage user authentication through your existing Identity Provider (IdP), such as Okta, Azure AD, or OneLogin. This centralizes user access control, improves security, and streamlines the login experience. Once configured, users can sign in to Elementum using their organization credentials, and you can enforce SSO-only authentication to ensure all access goes through your IdP. For organizations that need automated user and group provisioning, Elementum also supports [SCIM](#scim-provisioning) to keep accounts in sync with your IdP. ## How Users Are Provisioned How users land in Elementum -- and how they leave -- depends on whether you use SSO alone or pair it with SCIM. ### SSO Only When SSO is enabled without SCIM: * **First-login creation** -- With [Auto Create Unknown Users](#step-4-configure-saml-in-elementum) enabled, Elementum creates the user account the first time someone authenticates via your IdP. No record exists in Elementum until that first login. * **Manual pre-creation** -- If you need a user to exist in Elementum before their first SSO login -- for example, to @-mention them, assign them to a record, or add them to a group in advance -- create them manually from [Org Settings → Groups](/administration/users#invite-a-user-through-a-group) or [Org Settings → Users](/administration/users#invite-a-user-directly). On their first SSO login they are matched to the existing account by email. * **Removal does not deactivate** -- If you remove a user from your IdP, they can no longer authenticate, but their Elementum account continues to display as **Active**. Manually [deactivate the user](/administration/users#user-status) to reflect the change in Elementum. Their history is preserved either way. ### SSO with SCIM When SSO is paired with [SCIM provisioning](#scim-provisioning): * **Pre-login creation** -- SCIM syncs users from your IdP into Elementum on a schedule, so accounts exist in Elementum before the user's first login. You can mention, assign, and add them to groups immediately. * **Profile and group sync** -- Profile changes (name, job title) and group membership push from your IdP to Elementum without manual intervention. * **Automatic deactivation** -- When a user is removed from your IdP -- or unassigned from the SCIM application -- SCIM deactivates them in Elementum, provided your IdP's SCIM application is configured to send deactivation events. If you need every user to exist in Elementum before they can log in -- and you want IdP changes to flow through automatically -- use SCIM. SSO alone is simpler to configure but leaves user lifecycle and deactivation as manual operations. ## Prerequisites Before configuring SAML SSO, ensure you have: * **Elementum permissions**: Organization Admin access * **IdP access**: Administrator access to your Identity Provider (Okta, Azure AD, OneLogin, etc.) * **IdP configuration details**: * SSO URL from your IdP * Issuer/Entity ID from your IdP * X.509 signing certificate from your IdP * **User attributes**: Ensure your IdP sends `firstName` and `lastName` attributes in SAML assertions (and optionally `jobTitle` for job title syncing) Elementum provides Service Provider (SP) metadata URLs that your IdP will need. These are displayed in the configuration interface and include the Assertion Consumer Service (ACS) URL and Audience URI. ## Configuration Steps ### Step 1: Navigate to SSO Settings 1. Log into Elementum as an Organization Admin 2. Navigate to **Organization Settings** 3. Select the **Single Sign-On** tab 4. Locate the **SAML Configuration** section ### Step 2: Gather Elementum SP Metadata Before configuring your IdP, you'll need the Service Provider information from Elementum: 1. Copy the **Assertion Consumer Service URL** * Example: `https://se.elementum.io/api/v1/saml/callback` * This is where your IdP will send SAML responses 2. Copy the **Audience URI (SP Entity ID)** * Example: `https://se.elementum.io/api/v1/saml/metadata` * This uniquely identifies your Elementum instance to your IdP Keep these URLs handy - you'll need to enter them into your Identity Provider configuration in the next step. ### Step 3: Configure Your Identity Provider Configure a new SAML application in your Identity Provider. While specific steps vary by provider, you'll typically need to: 1. In Okta Admin Console, go to **Applications** → **Create App Integration** 2. Select **SAML 2.0** and click **Next** 3. Enter application name (e.g., "Elementum") 4. Configure SAML settings: * **Single sign on URL**: Paste your Elementum ACS URL * **Audience URI**: Paste your Elementum Audience URI * **Name ID format**: EmailAddress * **Application username**: Email 5. Add attribute statements: * `firstName` → `user.firstName` * `lastName` → `user.lastName` * `jobTitle` → `user.title` (optional) 6. Click **Next** and complete setup 7. Navigate to **Sign On** tab and click **View SAML setup instructions** 8. Copy the **Identity Provider Single Sign-On URL**, **Identity Provider Issuer**, and download the **X.509 Certificate** 1. In Azure Portal, go to **Azure Active Directory** → **Enterprise Applications** 2. Click **New application** → **Create your own application** 3. Enter name (e.g., "Elementum") and select **Integrate any other application you don't find in the gallery (Non-gallery)** 4. Go to **Single sign-on** → Select **SAML** 5. Edit **Basic SAML Configuration**: * **Identifier (Entity ID)**: Paste your Elementum Audience URI (SP Entity ID) * **Reply URL (Assertion Consumer Service URL)**: Paste your Elementum ACS URL 6. Edit **Attributes & Claims**: * **Unique User Identifier (Name ID)**: Select `user.mail` (if using email for Identity Connection) * If not using email, select **Persistent** in the Name Identifier Format field * Add Additional Claims (ensure you **remove the NameSpace values** or the integration will fail): * `firstName` → `user.givenname` * `lastName` → `user.surname` * `jobTitle` → `user.jobtitle` (optional) * `Email` → `user.mail` 7. In **SAML Certificates** section, download **Certificate (Base64)** 8. In **Set up Elementum** section: * Copy the **Login URL** * Copy the **Azure AD Identifier** 1. In OneLogin portal, go to **Applications** → **Add App** 2. Search for "SAML Custom Connector (Advanced)" and select it 3. Enter display name (e.g., "Elementum") and save 4. Go to **Configuration** tab: * **Audience (Entity ID)**: Paste your Elementum Audience URI * **ACS (Consumer) URL**: Paste your Elementum ACS URL * **ACS (Consumer) URL Validator**: `^https://se\.elementum\.io/api/v1/saml/callback$` 5. Go to **Parameters** tab and add custom fields: * `firstName` → First Name * `lastName` → Last Name * `jobTitle` → Title (optional) 6. Go to **SSO** tab: * Copy the **SAML 2.0 Endpoint (HTTP)** * Copy the **Issuer URL** * Click **View Details** under X.509 Certificate and copy the certificate 7. Save and assign users 1. In JumpCloud Admin Portal, go to **SSO** → **Applications** 2. Click the **+** button to add a new application 3. Select **Custom SAML App** 4. Configure general info: * **Display Label**: Enter "Elementum" 5. Click **Next** and configure **SSO** settings: * **IdP Entity ID**: Enter `JumpCloud` * **SP Entity ID**: Paste your Elementum Audience URI (SP Entity ID) * **ACS URL**: Paste your Elementum Assertion Consumer Service URL * **SAMLSubject NameID**: Select `email` * **SAMLSubject NameID Format**: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress` 6. Configure **Attribute Mapping**: * Add attribute: `firstName` → `firstname` * Add attribute: `lastName` → `lastname` * (Optional) Add attribute: `jobTitle` → `jobTitle` if available in user profiles 7. Click **Activate** to save the application 8. On the SSO configuration page, copy the following: * **IdP URL** (e.g., `https://sso.jumpcloud.com/saml2/elementum`) * Download the **X.509 Certificate** 9. Assign users or user groups to the application The exact field names and navigation may vary depending on your IdP version. Consult your IdP's documentation if you need specific guidance. ### Step 4: Configure SAML in Elementum Return to Elementum's SSO configuration page and enter the information from your Identity Provider: 1. **Enable SAML Authentication** * Toggle the **Enable** switch to activate SAML 2. **Identity Provider SSO URL** * Paste the SSO/Login URL from your IdP * This is where Elementum redirects users for authentication 3. **Identity Provider Issuer** * Paste the Issuer/Entity ID from your IdP * This identifies your IdP in SAML exchanges 4. **Identity Connection** * Select **Email** from the dropdown * This maps IdP users to Elementum users via email address 5. **Identity Provider X.509 Certificate** * Paste the complete X.509 certificate from your IdP * Include the `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` headers * Remove any extra whitespace or line breaks that may cause issues 6. **Configure Inactive User Logout** (optional but recommended) * **Desktop Users**: Set hours of inactivity before automatic logout (default: 24 hours) * **Mobile Users**: Set days of inactivity before automatic logout (default: 30 days) 7. **Auto Create Unknown Users** (optional) * Enable this toggle if you want Elementum to automatically create user accounts when someone authenticates via SSO for the first time * Requires `firstName` and `lastName` attributes in the SAML assertion * If enabled and `jobTitle` is provided, the user's job title will also sync 8. Click **Save** to apply the configuration **Do not enable "Enforce SSO-only authentication" yet.** Test SSO thoroughly first to ensure it works correctly before enforcing it organization-wide. ### Step 5: Test SSO Authentication Before enforcing SSO, verify it works correctly: 1. **Open an incognito/private browser window** * This ensures you're testing a fresh login flow 2. **Navigate to your Elementum login page** * You should now see a **Sign in with SSO** button 3. **Click "Sign in with SSO"** * You'll be redirected to your IdP's login page 4. **Log in with your organization credentials** * Enter your IdP username and password 5. **Verify successful authentication** * You should be redirected back to Elementum and logged in * Confirm your user profile shows correct information (name, email, job title if configured) 6. **Test with multiple users** * Have several team members test the SSO flow * Verify different user roles authenticate correctly If you enabled **Auto Create Unknown Users**: 1. Have a user who doesn't yet exist in Elementum attempt to log in via SSO 2. Verify they can successfully authenticate 3. Check that their user account was automatically created 4. Confirm their profile contains: * Email address (from SAML NameID) * First and last name (from SAML attributes) * Job title (if configured in SAML attributes) 5. Assign appropriate roles and permissions to the new user Auto-created users will have minimal default permissions. Ensure you have a process to assign proper roles after their first login. The **Identity Connection** setting determines how Elementum matches IdP users to existing accounts: * **Email**: Matches users based on email address (recommended) * This means the email in your IdP must match the email in Elementum To verify: 1. Check that the SAML NameID or email attribute matches existing Elementum user emails 2. Test login with users who have accounts 3. Verify they log into their existing accounts (not new ones) ### Step 6: Enforce SSO-Only Authentication (Optional) Once you've thoroughly tested SSO and confirmed it works for all users: 1. Return to **Organization Settings** → **Single Sign-On** 2. Enable the **Enforce SSO-only authentication** toggle 3. Click **Save** **Critical**: Once enabled, users will **only** be able to log in via SSO. Standard username/password authentication will be disabled. Ensure all users can access SSO before enforcing this setting. Even with SSO enforcement enabled, Organization Admins can access a backup login method in case of IdP issues. Contact Elementum support for emergency access procedures. ## Local Password Policy For users who are not on SSO or before SSO is enforced organization-wide, passwords must meet these requirements: * **Minimum length**: 12 characters * **Complexity** (must contain at least one of each): * Lowercase character (a-z) * Uppercase character (A-Z) * Number (0-9) * Symbol (e.g., `!@#$%^&*()_+-=[]{}|;:'",.<>?`) * **Restrictions**: * May not contain the user's name * May not contain the user's email address Once SSO is enforced, these local password requirements no longer apply as all authentication goes through your Identity Provider. ## User Experience ### End User Login Experience The login experience varies depending on your SSO configuration: **What users see:** The login page displays a split interface giving users two options: 1. **Top Section: "Log In With Email"** * Traditional username/password login * Available for users with local accounts * Subject to local password policy requirements 2. **Bottom Section: "Log In With Single Sign On"** * Clickable button that redirects to your IdP * Users authenticate using their organization credentials * Recommended for all organization users **Use case**: This configuration is ideal during the SSO testing and migration period, allowing users to choose their authentication method while you verify SSO works correctly. **What users see:** The traditional "Log In With Email" section is removed, and users see: 1. **Single email input field** * Users enter their email address * No password field is shown 2. **Automatic redirect on login** * Upon clicking "Log In", the system detects the user's domain * Users are immediately redirected to the IdP for authentication * No local password authentication available 3. **Seamless experience** * If users are already authenticated with your IdP, they may be logged in automatically * Single sign-on across all applications **Use case**: This configuration is recommended once SSO testing is complete and you want to enforce centralized authentication for all users. ### Session Management Session timeouts are configured in Step 4 under **Configure Inactive User Logout** and apply regardless of SSO enforcement. If users are already logged into your IdP, they may experience automatic single sign-on without re-entering credentials. ## Security Best Practices * Enable SSO enforcement after successful testing * Configure automatic logout for inactive sessions * Regularly rotate your X.509 certificates * Enable Multi-Factor Authentication (MFA) in your IdP * Use Auto Create Unknown Users only if you have proper onboarding processes * Regularly audit user access in both your IdP and Elementum * Monitor failed SSO authentication attempts * Document your SSO configuration for your IT team ### Certificate Management * **Validity**: X.509 certificates typically expire after 1-3 years * **Rotation**: When your IdP issues a new certificate: 1. Download the new certificate from your IdP 2. Update it in Elementum SSO settings before the old one expires 3. Test authentication to confirm the update worked * **Monitoring**: Set calendar reminders to check certificate expiration ### User Provisioning **Pros:** * New users can access Elementum immediately * No manual account creation required * Scales easily for large organizations **Cons:** * Users created with default minimal permissions * Requires post-login role assignment process * May create accounts for users who shouldn't have access **Best for:** Organizations with automated onboarding workflows and clear role assignment processes **Pros:** * Full control over who has access * Pre-configured roles and permissions * No surprise account creation **Cons:** * Manual account setup required * User must be created before first SSO login * Doesn't scale as easily **Best for:** Organizations preferring explicit user provisioning and tighter access control ## Troubleshooting **Cause**: SAML may not be enabled or configuration hasn't been saved **Solution**: 1. Verify the **Enable** toggle is turned on 2. Ensure you clicked **Save** after configuration 3. Try clearing your browser cache 4. Try a different browser or incognito mode **Cause**: Incorrect IdP configuration or user not assigned to the application **Solution**: 1. Verify the user is assigned to the Elementum app in your IdP 2. Check that the IdP application is active/enabled 3. Confirm the SSO URL and Issuer are correct in Elementum 4. Verify required attributes (`firstName`, `lastName`) are configured in your IdP **Cause**: Certificate mismatch, incorrect ACS URL, or missing required attributes **Solution**: 1. Verify the X.509 certificate is correctly copied (including headers) 2. Confirm the ACS URL in your IdP matches exactly what Elementum provided 3. Check that your IdP sends required SAML attributes (`firstName`, `lastName`) 4. Review browser developer console and network tab for specific error messages 5. Contact Elementum support with error details **Cause**: Email mismatch between IdP and Elementum, or Identity Connection misconfigured **Solution**: 1. Verify **Identity Connection** is set to **Email** 2. Confirm user emails in Elementum match emails in your IdP exactly 3. Check that IdP sends email in SAML NameID or as an attribute 4. Temporarily disable SSO enforcement to allow testing **Cause**: Auto Create Unknown Users is disabled, or required attributes are missing **Solution**: 1. Verify **Auto Create Unknown Users** toggle is enabled 2. Confirm your IdP sends `firstName` and `lastName` attributes in SAML assertions 3. Check attribute name spelling matches exactly (case-sensitive) 4. Review IdP logs to see what attributes are being sent **Cause**: Malformed certificate, expired certificate, or whitespace issues **Solution**: 1. Verify certificate includes begin/end markers: ``` -----BEGIN CERTIFICATE----- [certificate content] -----END CERTIFICATE----- ``` 2. Remove any extra spaces or line breaks 3. Check certificate hasn't expired in your IdP 4. Download a fresh certificate from your IdP 5. Use a text editor (not Word) to copy/paste the certificate **Cause**: SAML claims from IdP are overwriting Elementum user data **Solution**: * Claims sent by the IdP take precedence and will overwrite user-defined parameters in Elementum (such as Name, Last Name, and Job Title) * Update the values in your IdP user profiles instead of in Elementum * Verify the correct attributes are being mapped in your IdP configuration * Check IdP logs to confirm what values are being sent **Cause**: Configuration mismatch between IdP and Elementum **Solution**: Check these three common issues: 1. **URL Configuration**: Ensure the ACS URL and Entity ID are not inverted or swapped 2. **Unique Identifier**: Verify the unique identifier (Name ID) is set to the user's email address 3. **Required Claims**: Ensure all required claims (`firstName`, `lastName`, `email`) are being sent and properly formatted 4. Clear browser cookies and try in an incognito window 5. Check browser developer console for specific error messages **Cause**: Missing or incorrectly named `jobTitle` attribute. **Solution**: 1. Verify the `jobTitle` attribute is configured in your IdP 2. Check that the attribute name is exactly `jobTitle` (case-sensitive) — sending `JobTitle` instead is a common mistake 3. Verify the IdP user profile contains job title data to send 4. Test with a user who has a job title populated in the IdP If you continue experiencing issues after reviewing the items above: 1. **Gather diagnostic information**: * Browser console errors * Network tab showing SAML request/response * IdP logs (if available) * Exact error messages 2. **Contact Elementum support** with: * Your organization name * Identity Provider being used * Steps to reproduce the issue * Diagnostic information collected above ## Advanced Configuration ### Attribute Mapping Elementum supports these SAML attributes: | Attribute | Required | Purpose | Example Value | | ----------------- | -------- | -------------------------------- | ------------------- | | `email` or NameID | Yes | User identification and matching | `user@company.com` | | `firstName` | Yes\* | User's first name | `John` | | `lastName` | Yes\* | User's last name | `Doe` | | `jobTitle` | No | User's job title | `Software Engineer` | | `externalId` | No\*\* | External user identifier | `EMP-12345` | \*Required when Auto Create Unknown Users is enabled. \*\*Required only if you select "External Identifier" as the Identity Connection in Elementum. Attribute names are **case-sensitive**. Ensure they match the exact casing shown above (e.g., `jobTitle`, not `JobTitle`). For Azure AD / Entra ID, you must **remove the NameSpace values** from Additional Claims or the integration will fail. ### IdP-Initiated vs SP-Initiated Login Both flows are supported. IdP-initiated login requires no additional configuration beyond the standard setup. 1. User starts at the Elementum login page 2. Clicks "Sign in with SSO" 3. Redirected to IdP for authentication 1. User starts at the IdP dashboard 2. Clicks the Elementum app tile 3. Directly authenticated into Elementum ### SCIM Provisioning SCIM (System for Cross-domain Identity Management) automates user and group provisioning between your Identity Provider and Elementum. Instead of manually creating users or relying on first-login auto-creation, SCIM keeps user accounts, group memberships, and profile data in sync automatically. SCIM provisioning requires a working SAML SSO configuration. Complete the SAML setup steps above before configuring SCIM. **Elementum prerequisites:** 1. In **Organization Settings** > **Domains** > **Managed Domains**, confirm the desired domains are configured and SSO is enabled for each 2. In **Organization Settings** > **Single Sign-On**, verify that SAML authentication is enabled and configured (see Configuration Steps above) 3. In the **SCIM Instructions** section on the Single Sign-On page, copy the following values: * **SCIM URL** — the endpoint your IdP will use to provision users * **SCIM Secret** — the bearer token for authenticating SCIM requests **Set up users:** 1. In the Okta Admin Console, go to **Directory** > **People** 2. Click **Add person** and fill in the required fields: **First Name**, **Last Name**, and **Username** (the user's email address) 3. Click **Save** (or **Save and Add Another** for additional users) To support [Org Structure](/administration/org-structure) in Elementum — the hierarchy that drives dynamic manager-based approval routing — the Employee ID field must be populated via API from your identity system. Once SCIM provisioning runs, each user's Org Structure entry syncs automatically. **Set up groups:** 1. Go to **Directory** > **Groups** and click **Add group** 2. Enter a name (e.g., "Elementum") and click **Save** 3. Open the new group, go to the **People** tab, and click **Assign people** 4. Click **+** for each user to add, then click **Done** **Create and configure the application:** 1. Go to **Applications** > **Applications** and click **Browse App Catalog** 2. Search for **SCIM 2.0 Test App**, select **SCIM 2.0 Test App (OAuth Bearer Token)**, and click **Add Integration** 3. Update the application label if desired, click **Next**, then **Done** 4. Open the application and go to the **Provisioning** tab 5. In **Settings** > **Integration**, click **Configure API Integration** 6. Check **Enable API Integration** and enter: * **SCIM connector base URL**: Paste the SCIM URL from Elementum * **OAuth Bearer Token**: Paste the SCIM Secret from Elementum 7. Click **Test API Credentials** to verify the connection, then click **Save** 8. Go to **Provisioning** > **Settings** > **To App** and click **Edit** 9. Enable the following, then click **Save**: * Create Users * Update User Attributes * Deactivate Users **Assign groups and provision:** 1. In the **Assignments** tab, click **Assign** > **Assign to Groups** 2. Click **Assign** next to the group you created, then click **Done** 3. Go to the **Push Groups** tab, click **Push Groups** > **Find Groups by Name** 4. Select the group, click **Create Group**, then **Save** 5. On the Push Groups page, click **Active** on the group and select **Activate Push Group** For subsequent syncs after the initial push, select **Push Now** instead of Activate Push Group. **Set up users:** Ensure each user in Entra ID has the following fields populated: * **Identity**: First Name (required), Last Name (required) * **Job Information**: Job Title (optional) * **Contact Information**: Email — the domain must match the domain enabled for SSO in Elementum To populate [Org Structure](/administration/org-structure) in Elementum — the hierarchy that drives dynamic manager-based approval routing — include at least one of the following in **Job Information**: Department, Employee ID, or Manager. These fields sync to each user's Org Structure entry on the next provisioning run. **Set up groups:** Create a new security group (e.g., "Elementum") or use an existing security group. **Create and configure the enterprise application:** 1. Go to **Enterprise Applications** > **Create your own application** 2. Enter a name and select **Integrate any other application you don't find in the gallery (Non-gallery)** 3. In the application, click **Users and Groups** > **Add user/group** and assign the security group (or individual users) 4. Click **Provisioning** and configure: * **Provisioning Mode**: Select **Automatic** * **Tenant URL**: Paste the SCIM URL from Elementum * **Secret Token**: Paste the SCIM Secret from Elementum 5. Click **Test Connection** to verify, then click **Save** **Provision users:** 1. Click **Provisioning** in the left pane 2. To test first, click **Provision on Demand**: * Select the group, choose **View Members only**, select desired members, and click **Provision** * Verify the group and users appear in Elementum 3. To enable ongoing sync, click **Start Provisioning** **Auto-provisioning behavior:** Once automatic provisioning is enabled, actions in Entra ID trigger corresponding changes in Elementum: | Entra ID Action | Elementum Result | | ---------------------------------------------- | --------------------------------------------------------------------------- | | Add a user to a provisioned group | User is created (if new), reactivated (if inactive), and added to the group | | Remove a user from a group | User is removed from the group and deactivated if not in any other groups | | Remove a group assignment from the application | Group is removed; users deactivated if not in any other groups | | Remove a user assignment from the application | User is deactivated | | Delete a group | Group is removed; users deactivated if not in any other groups | | Delete a user | User is removed from associated groups and deactivated | For more details, see [Microsoft's provisioning documentation](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/how-provisioning-works). # Trace Forwarding Source: https://docs.elementum.io/administration/trace-forwarding Configure OpenTelemetry (OTEL) endpoints to stream OTLP trace data from Elementum to your observability and AI evaluation platforms. ## Overview Trace Forwarding lets your organization push OpenTelemetry (OTEL) trace data from Elementum environments to external platforms — observability tools, AI evaluation suites, or any system that accepts the OpenTelemetry Protocol (OTLP) over gRPC or HTTP. You can configure multiple endpoints per channel to route traces to different teams or platforms in parallel. **OTEL vs. OTLP.** OpenTelemetry (OTEL) is the open standard for generating and collecting trace, metric, and log data. The OpenTelemetry Protocol (OTLP) is the wire format OTEL uses to transmit that data over gRPC or HTTP. Elementum produces OTEL trace data and exports it using OTLP, so your endpoints must accept OTLP. Go to Settings icon **Organization Settings** > **Platform** > **Trace Forwarding**. Only **Organization Administrators** can view and modify these settings. ## Trace channels Two independent channels are available: | Channel | What it forwards | Default protocol | Example destinations | | ------------------ | ------------------------------------------------------- | ---------------- | ----------------------------------- | | **General Traces** | Operational telemetry from all Elementum activities | gRPC | Datadog, Grafana, Jaeger, Honeycomb | | **GenAI Traces** | Detailed LLM and agent spans from AI-powered operations | HTTP | Weave (W\&B), LangSmith, Arize | ## Quick start: add your first endpoint 1. Go to Settings icon **Organization Settings** > **Platform** > **Trace Forwarding**. 2. Click **Add General Endpoint** or **Add GenAI Endpoint** depending on the type of traces you want to forward. 3. Enter a **Name**, your **Endpoint URL**, and confirm the **Protocol** matches what your destination platform expects. 4. Select an **Authorization Type** and fill in the required credentials. 5. Optionally, add **Resource Attributes** to tag every span with metadata such as `environment` or `team`. 6. Click **Save & Test**. A green *Message delivered* result confirms the endpoint is reachable. 7. Click **Enable** to activate the endpoint. 8. Go to **Organization Settings** > **Platform** > **Environments**, click **Configure** on an environment card, then click **Edit Environment**, select your endpoint under **Trace Forwarding**, and click **Save Changes**. ## Add or edit an endpoint Click **Add General Endpoint** or **Add GenAI Endpoint** to open the endpoint dialog. To edit an existing endpoint, click the pencil icon in its row. Both actions open the same dialog. ### Connection | Field | Required | Details | | ---------------- | -------- | --------------------------------------------------------------------------------------------------------------------- | | **Name** | Yes | A human-readable label used to identify the endpoint in the list. | | **Endpoint URL** | Yes | The full URL of your OTLP receiver. Must be a valid HTTP or HTTPS URL. | | **Protocol** | Yes | **gRPC** (binary, efficient) or **HTTP** (REST-based). Defaults to gRPC for General Traces and HTTP for GenAI Traces. | ### Authentication Select one of four options from the **Authorization Type** dropdown: | Type | Behavior | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | | **None** | No authentication headers are sent. Use only for internal or open endpoints. | | **Bearer Token** | Sends an `Authorization: ` header. Requires a **Bearer Token**; **Bearer Scheme** is optional and defaults to `Bearer`. | | **Basic Auth** | Sends an `Authorization: Basic ` header. Requires **Username** and **Password**. | | **Custom Headers** | Sends one or more arbitrary request headers. Add as many **Header Key** / **Header Value** pairs as needed. | Secret values (tokens, passwords, header values) are encrypted at rest. When you reopen an endpoint for editing, existing secrets are masked as `****`. Click **Overwrite** to replace a secret, or leave it masked to keep the current value. ### Optional fields * **Additional headers** — Extra HTTP headers attached to every trace export request beyond those required for authentication. Click **+ Add Header** to add key-value pairs. * **Resource attributes** — Key-value pairs added to the OTLP resource on every exported span. Use these to tag trace data with environment, team, or deployment metadata that your external platform can filter on (e.g. `environment = production`, `team = ai-platform`). Click **Save & Test** to save the endpoint and verify connectivity immediately. General Trace endpoints also offer a **Save** option that skips the connection test. GenAI endpoints require **Save & Test** — connectivity must be verified before the endpoint is saved. ## Manage endpoints ### Test a connection A connection test sends a sample OTLP trace to the configured endpoint. You can run a test two ways: * Click **Save & Test** when creating or editing an endpoint. * Click the **send icon** (Test Connection) in the endpoint list row. The test times out after 30 seconds. A result modal shows latency, HTTP status code, trace ID, and span ID on success, or an error message and guidance on failure. From the modal you can **Edit Connection**, toggle **Enable** / **Disable**, or **Cancel** to close. ### Assign to an environment After configuring and enabling an endpoint, assign it to one or more environments. Traces are only forwarded from environments where an endpoint is assigned. 1. Go to Settings icon **Organization Settings** > **Platform** > **Environments**. 2. Find the environment you want to forward traces from and click **Configure** on its card, then click **Edit Environment**. 3. In the **Trace Forwarding** section, select your configured endpoint from the list. 4. Click **Save Changes**. Repeat for each environment you want to forward traces from. ### Delete an endpoint 1. Click the **trash icon** in the endpoint list row. 2. Confirm the deletion in the dialog that appears. ## Continuing an existing trace Include a W3C `traceparent` header on a request to signal trace propagation for the traces Elementum exports. The exported spans are tied back to the information you provide, placed under the same trace using the span ID you supply as their parent, so in your platform the request appears as a single connected trace with Elementum's spans nested under your calling span. This requires a Trace Forwarding endpoint that is enabled and [assigned to the environment](#assign-to-an-environment); without one, there is nowhere to export the spans. If no `traceparent` is sent, the exported spans are not tied to an external trace. ### Add the header Set the `traceparent` header on the request your system sends to Elementum. If your calling application is instrumented with OpenTelemetry, its HTTP client adds this header automatically. Otherwise, add it manually, populated from the calling span in your tracing system. ``` traceparent: 00---01 ``` | Field | Length | Value | | ---------------- | ------ | ------------------------------------------------------------ | | `trace-id` | 32 hex | The overall trace ID. Elementum's spans adopt this. | | `parent-span-id` | 16 hex | The span in your system that Elementum's spans attach under. | The leading `00` (version) and trailing `01` (flags) are fixed parts of the W3C format; you normally leave them as shown, and if your caller uses OpenTelemetry they are set automatically. Example: `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01` You may also send a `tracestate` header; Elementum preserves it. ### Verify Open the trace by the `trace-id` you sent. You should see your originating span with Elementum's spans nested beneath it as one connected trace. Propagation is opt-in per request. Without a `traceparent`, exported spans are not tied to an external trace. ## Troubleshooting The credentials are invalid or expired. Re-enter the token or password and ensure the API key has the correct scopes. The endpoint URL is likely incorrect. Double-check the URL and, for HTTP endpoints, confirm the path includes `/v1/traces` or the equivalent path required by your platform. A network or firewall issue is preventing the connection. Verify the endpoint host is reachable from the Elementum backend and check any applicable firewall rules. Check that the endpoint is **Enabled** and assigned to the environment you are testing from. A passing test only confirms connectivity, not that traces are being produced — trigger an AI operation in Elementum to generate spans. ## GenAI attribute reference ### LLM call spans These attributes appear on spans representing a single call to a language model. Span names follow the pattern `chat `. | Attribute | Type | Description | | -------------------------------- | ------------- | ------------------------------------------------------------- | | `gen_ai.system` | string | The LLM provider (e.g. `aws.bedrock`, `openai`, `anthropic`). | | `gen_ai.request.model` | string | The model name that was requested. | | `gen_ai.response.model` | string | The model name that actually responded. | | `gen_ai.usage.input_tokens` | integer | Number of tokens in the prompt. | | `gen_ai.usage.output_tokens` | integer | Number of tokens in the completion. | | `gen_ai.prompt` | string (JSON) | Input messages as a JSON array of `{role, content}` objects. | | `gen_ai.completion` | string (JSON) | Output messages as a JSON array of `{role, content}` objects. | | `gen_ai.operation.name` | string | Always `"chat"` for LLM call spans. | | `gen_ai.response.finish_reasons` | string\[] | Why the model stopped generating (e.g. `["stop"]`). | | `gen_ai.response.id` | string | The provider's unique response identifier. | ### Tool execution spans These attributes appear on spans representing an agent executing a tool. Span names follow the pattern `execute_tool `. | Attribute | Type | Description | | ----------------------- | ------ | --------------------------------------------------------- | | `gen_ai.tool.name` | string | The function name of the tool that was called. | | `gen_ai.tool.call.id` | string | Links this execution back to the LLM's tool call request. | | `gen_ai.operation.name` | string | Always `"execute_tool"` for tool execution spans. | ### Span tree structure Traces from Elementum AI operations are organized into a span hierarchy: | Interaction type | Span structure | | ---------------------------------- | --------------------------------------------- | | Single LLM call | `root → chat` | | Tool-calling agent (one round) | `root → chat → tool → chat` | | Multi-step agent (multiple rounds) | `root → chat → tool → chat → tool → chat → …` | # Understand and Configure Environments Source: https://docs.elementum.io/administration/understand-organization-environments How environments isolate development and testing from production, plus how to create environments and configure CloudLink for each one **Labs feature.** Environments are marked with the **Labs** badge in the Elementum UI because the feature is still being validated. Behavior, scope, and availability may change before the feature reaches General Availability, and not all Elementum customers have access yet. See [Upcoming Features](/release-notes/upcoming-features#labs-tag-in-the-platform) for what the Labs tag means. An **organization environment** is a separate Elementum workspace tied to your production organization. You can build and test changes without affecting live workflows, then copy app configurations to another environment when you are ready. ## Organization environments Each environment: * Uses its own subdomain (for example `dev-yourorg.elementum.io`) * Needs its own CloudLink configuration to reach your data warehouse * Holds its own copies of apps you deploy into it * Runs independently of other environments Your organization begins with **Production**—the default, live environment. You can add environments for purposes such as **Development**, **Testing**, **Staging**, and **Training**. Environments do not share app configuration by default; you move configuration between them using **deployment**. See [Deploy Apps between Environments](/administration/deploy-apps-between-environments) for how that works. **Why teams use multiple environments** * Develop and change apps without risking production data or workflows * Validate behavior with realistic configuration before go-live * Let several people work in parallel in separate workspaces * Release changes in a controlled way after review ## Environment categories Every environment belongs to one of four categories. The category determines the color and icon shown on the persistent indicator visible throughout the platform. | Category | Color | Icon | Description | | --------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------- | | **Development** | Orange | Triangle | An environment to build and experiment with new ideas without affecting anyone else. | | **Test** | Yellow | Square | An environment to review your work and make sure everything clicks before moving forward. | | **Stage** | Green | Pentagon | An environment to host demos or beta users and verify everything is perfect before the final release. | | **Production** | Blue | Circle | An environment to host the finished, live version of your app where your actual users interact with your work. | Every authenticated user sees the same indicator regardless of role — there is no permission gate on viewing it. **Production is locked.** The Production category is reserved for the default Production environment. It cannot be selected when creating a new environment, and the Production environment's category cannot be changed after creation. **Pre-existing environments.** When this feature is enabled, the Production environment is automatically assigned the Production category. All other existing environments are assigned Development by default. Org Admins can update those assignments afterward. ## CloudLink and platform data Each environment needs its own CloudLink configuration. Set up credentials in the environment before deployed apps can use Snowflake-backed data there. Isolated environments need separate warehouse connections. Plan Snowflake users, roles, databases, and schemas before you connect CloudLink; then verify the connection works before relying on deployments. ### Isolating platform data **Critical:** Each environment's CloudLink **must** use distinct Snowflake **USER**, **ROLE**, **DATABASE**, and **SCHEMA** values for Elementum **platform** data. Sharing these across environments risks security issues and data integrity problems. | Component | Requirement | | ------------ | ---------------------------------------------------------------------------------- | | **User** | One Snowflake user per environment (for example `ELEMENTUM_DEV`, `ELEMENTUM_PROD`) | | **Role** | One role per environment | | **Database** | One database per environment for platform data | | **Schema** | A dedicated platform schema in that database | This separation limits cross-environment access to platform data and supports auditing. **External** (non-platform) tables can be shared across environment users if your governance allows it; changes to those shared tables are visible in every environment that uses them. **Example** | Environment | User | Role | Platform database | Platform schema | | ----------- | ------------------- | ------------------- | ------------------- | -------------------- | | Production | `ELEMENTUM_PROD` | `ELEMENTUM_PROD` | `ELEMENTUM_PROD` | `ELEMENTUM_PLATFORM` | | Development | `ELEMENTUM_DEV` | `ELEMENTUM_DEV` | `ELEMENTUM_DEV` | `ELEMENTUM_PLATFORM` | | Staging | `ELEMENTUM_STAGING` | `ELEMENTUM_STAGING` | `ELEMENTUM_STAGING` | `ELEMENTUM_PLATFORM` | ## Create an Environment Create a new environment from your production organization to start developing and testing in isolation. 1. Go to Settings icon **Organization Settings** > **Platform** > **Environments**. You will see a list of all environments in your organization, with Production marked as the default. 2. Click **+ Create Environment** in the upper right. A modal appears with the message: "Create an environment that allows you to safely build, test, and release changes without affecting your live app." 3. Fill in the required fields: | Field | Description | Example | | -------------------- | ----------------------------------------------------------------------------- | -------------------------------------------- | | **Environment name** | A descriptive name for the environment | `Development`, `Testing`, `Staging` | | **Subdomain** | The URL prefix for this environment | `dev`, `test`, `staging` | | **Description** | Optional description of the environment's purpose | `For testing new features before production` | | **Category** | The environment type that controls its color and icon throughout the platform | `Development`, `Test`, `Stage` | The subdomain creates the environment's URL: `[subdomain]-[yourorg].elementum.io` 4. Click **Create Environment**. The new environment appears in the list with its own card showing the name, description, and domain. When a new environment is created, Elementum clones the **roles and role membership** from Production into that environment as its starting state. The user who creates the environment is also added to the **Admin** role so they can configure CloudLink and adjust membership without an additional access request. Admin is one of the managed roles in Roles & Permissions — every organization has it by default, and it cannot be deleted or have its permissions modified. After environment creation, role membership becomes environment-specific — see [Environment-specific role membership](#environment-specific-role-membership) for details. ## Change an Environment's Category You can update an environment's category at any time after creation. The Production environment's category is locked and cannot be changed. 1. Go to Settings icon **Organization Settings** > **Platform** > **Environments**. 2. Find the environment and click **Edit** on its card. 3. In the edit environment panel, select a new value for the **Category** field. 4. Click **Save**. The Production category cannot be assigned to any environment other than the default Production environment, and the Production environment's category cannot be changed. ## Configure CloudLink After creating an environment, configure CloudLink to connect the environment to your data warehouse. CloudLink must be configured before you can deploy apps that use Snowflake-connected Tables icon **Tables** or Elements icon **Elements**. Apps deployed without a valid CloudLink connection cannot access data. Create dedicated Snowflake users, roles, databases, and schemas per environment before you connect CloudLink. Full isolation rules and examples are in [Isolating platform data](#isolating-platform-data) above. From the Environments list, find your new environment and click the **Configure** button on its card. This opens the environment configuration page showing the environment name, status, and domain configuration. Click the **Manage CloudLink Credentials** button. This opens the new environment in a new tab/window, navigating directly to the CloudLinks settings page. On the CloudLinks page, click the **Edit** button on the CloudLink entry. The Edit CloudLink modal appears with the following fields: **Connection Settings:** * **Name** - Identifier for this CloudLink connection * **Username** - Snowflake service account username * **URL** - Your Snowflake account URL (for example, `your-account.snowflakecomputing.com`) * **Authentication Method** - Select Password or Key-pair authentication * **Password** - Service account password (if using password authentication) **Resource Scheduler:** * **Interval** - Sync frequency (default: 20 minutes) * **Time unit** - Minutes, Hours, or Days The default sync interval is 20 minutes. Shorter intervals provide faster data updates but increase Snowflake credit consumption. After entering valid credentials, additional fields become available: * **Role** - Select the Snowflake role for this connection * **Warehouse** - Select the Snowflake warehouse to use * **Database** - Select the database where Elementum stores platform data The Database field is where Elementum creates its platform tables. Select or create a dedicated schema for Elementum. Do not use your business data schema here. Click **Save** to apply the CloudLink configuration. The connection is tested automatically. Once successful, the environment is ready for app deployments. For detailed Snowflake configuration including IP whitelisting and permissions, see the [Connecting Snowflake to Elementum](/administration/connect-snowflake-to-elementum) guide. ## Environment-specific role membership There are two distinct concepts when it comes to roles and environments: * **Role definitions** (what permissions a role grants, creating or deleting roles) — these changes are mirrored across all environments. When you modify a role's permissions, create a new role, or delete a role in any environment, that change applies everywhere. * **Role membership** (who belongs to a role) — at environment **creation**, roles and role membership are cloned from Production into the new environment as its starting state. After that, membership is tracked **per environment**: changes you make in one environment do not propagate to others, so granting a user a role in Development does not also grant the same role in Staging or Production. "Role changes" in the context of environments refers to the role itself — its permissions, creation, or deletion — not who belongs to it. Membership is mirrored once at environment creation, then managed separately in each environment afterward. | Behavior | What it means | | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Cloned at environment creation** | When you create a new environment, the roles **and** role membership from Production are cloned into it as the starting state. After creation, membership changes are environment-specific. | | **Per-environment assignments** | A user or group must be added to a role in each environment where the access is needed. The same role exists in every environment, but its members are stored independently. | | **Creator gets the Admin role** | The user who creates a new environment is also added to the **Admin** role for that environment so they can configure CloudLink and grant access to others. Admin is one of the managed roles in Roles & Permissions — every organization has it by default, and its permissions cannot be modified or deleted. | | **Same role management UI** | Admins manage membership through the existing **Roles & Permissions** screens. The screen always edits the role in the **environment you are currently signed in to**. | | **Groups governed in Production** | Groups and group membership are managed in the Production environment and remain consistent across all environments. You will not see Group Admin options in non-production environments. | | **Membership is independent of deployment** | Deploying an app, element, or task into an environment does not carry over role membership from the source environment. After the first deployment, configure role membership for those objects on the object's **Roles & Permissions** page in the target environment. No future redeployment will overwrite membership settings you have configured. | | **Data Access policies are environment-specific** | Access policy changes you make outside of a deployment apply only to the environment you are signed in to. Removing a group's access to an app in one environment does not remove it elsewhere — to change access across all environments, repeat the change in each one. See [Initial vs. subsequent deployments](/administration/deploy-apps-between-environments#initial-vs-subsequent-deployments) for how access policies behave during a deployment. | ### Add or remove users and groups in a specific environment 1. Sign in to the environment whose membership you want to change. The persistent environment indicator confirms which environment you are working in. 2. Open Settings icon **Org Settings** > **Roles & Permissions** for organization roles, or open **Roles & Permissions** under **Security** in an app menu for that app's roles. 3. Click **Manage Membership** on the role you want to change. 4. Add or remove the relevant users and groups, then save. The change applies **only** to the current environment. To grant the same access in another environment, repeat the steps after switching to that environment. For role definitions, the difference between managed and custom roles, and the full permission list, see [Roles & Permissions](/administration/roles-permissions). ## Practices to follow * **Naming and category** — Use clear names (`Development`, `QA`, `Staging`, `Training`) and assign the matching category so the purpose of each environment is obvious to every user at a glance; keep both consistent across your organization. * **CloudLink** — Prefer separate Snowflake service accounts per environment; document which databases and schemas each environment uses; confirm connections stay healthy. * **Access** — Restrict who can create environments and deploy apps; review role membership in each environment separately, since assignments are not shared across environments; use non-production accounts for testing where appropriate. ## Next steps Move app configuration from one environment to another and complete post-deployment setup Configure CloudLink connections for your environments Detailed guide for connecting Snowflake to Elementum Learn about apps and how they organize your business processes # Users Source: https://docs.elementum.io/administration/users Invite users into your Elementum organization and review their group memberships Once your [groups](/administration/groups), [roles](/administration/roles-permissions), and [data access policies](/workflows/object-data-access) are in place, inviting users is the last step. New users inherit their access from the groups you add them to, so a complete invite is just an email plus group membership -- no per-user permission configuration required. For organizations that authenticate through an Identity Provider, see [SCIM Provisioning](/administration/sso-saml-setup#scim-provisioning) to automate user creation from your IdP instead of inviting users manually. Your ability to invite users depends on the organization's **User Invite Policy**, which controls who can send invitations and which email domains are allowed. The policy applies to both invite paths below. See [User Invite Policy](/administration/roles-permissions#user-invite-policy) for details. *** ## Invite a User Through a Group Inviting users from inside a group is the recommended path. The user lands in the right group as soon as they complete registration, with no extra step required to grant the access that group provides. 1. Open Settings icon **Org Settings** → **Groups**. 2. Select the group the user should belong to. 3. Click **Add User** in the top right corner. 4. In the popup, select **Invite User**. 5. Enter the user's information: * **Email Address** * **First Name** * **Last Name** 6. Click **Invite User**. The invite is sent to the user's email inbox, and the user must create their account to complete registration. When registration finishes, the user is already a member of the group, with all roles and data access policies attached to that group applied automatically. If a user belongs in multiple groups, repeat these steps from each group, or add them to additional groups after registration from **Org Settings** → **Users**. *** ## Invite a User Directly Use this path only when the user is not yet associated with a group, or when you want to invite first and decide on group membership later. Users invited this way have **no access** until they are added to a group, assigned a role, or granted object-specific permissions. 1. Open Settings icon **Org Settings** → **Users**. 2. Click **New User** in the top right corner. 3. Enter the user's information: * **Email Address** * **First Name** * **Last Name** 4. Click **Invite User**. The invite is sent to the user's email inbox. From there, the user must create their account to complete registration. *** ## Grant Additional Access After Registration If you invited the user through a group, they already have the access that group provides. To grant more -- additional groups, direct role assignments, or object-specific permissions -- use one or more of the following after registration completes: * **Org Groups** -- Add the user to additional [groups](/administration/groups) they should belong to. Groups are the most scalable way to manage access because permissions assigned to a group apply to every member automatically. * **Roles** -- Assign [managed or custom roles](/administration/roles-permissions) directly to the user to grant org-wide or app-level capabilities. * **Object-specific permissions** -- For access to a specific app, record, or workflow that is not covered by a group or role, grant permissions directly on the object. Use this sparingly, as direct assignments are harder to audit and maintain than group- or role-based access. Every new user is automatically added to the built-in **All Users** group. This group is intended for organization-wide defaults only -- do not rely on it to grant sensitive or record-level access, since every active user is a member. *** ## View a User's Groups To see which groups a user belongs to: 1. Open Settings icon **Org Settings** → **Users**. 2. Select the user's profile. The user profile displays all groups the user is a member of. *** ## Last Login The Users page displays a **Last Login** timestamp for each user showing the date and time of their most recent successful login. Use this to identify inactive accounts or spot unexpected access patterns across your organization. A blank value means the user has never completed a login -- typically a newly invited user who has not yet registered. *** ## User Status The Users page in Organization Settings displays a status next to each user. Status controls how much of the platform a user can reach without removing the user record itself, so mentions, assignments, approvals, and history are preserved no matter the status. | Status | What it means | | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Active** | Full platform access, scoped by the user's roles and data access policies. | | **Limited** | No platform visibility. The user can only interact with Elementum updates through email -- for example, replying to a notification or completing an emailed form. | | **Locked** | The account was automatically locked after 5 consecutive failed login attempts. The user must complete a password reset to restore access. See [Account Lockout](/administration/account-lockout) for details. | | **Inactive** | The user has been deactivated and cannot sign in. Their update history is preserved and continues to appear in the [Activity Log](/administration/activity-log). | ### Change a User's Status 1. Open Settings icon **Org Settings** → **Users**. 2. Click the **More** icon next to the user. 3. Choose the action that matches your goal: * **Downgrade** or **Upgrade** -- Move the user between **Active** and **Limited**. The label reflects the user's current status, so an Active user shows **Downgrade** and a Limited user shows **Upgrade**. * **Deactivate** -- Move the user to **Inactive** and revoke all platform access. On an inactive user, this same action is labelled **Activate User** and restores the user's previous status. Deactivation preserves the user's record, mentions, and activity history. If your organization uses [SCIM Provisioning](/administration/sso-saml-setup#scim-provisioning), removing the user from your Identity Provider will trigger deactivation automatically. *** ## Related Features Organize users into groups for scalable role and access assignment Decide what users in each group can do across the organization or within an app Control which records users can see using dynamic policies Centralize authentication and automate user provisioning through your Identity Provider # Agent Gateways Source: https://docs.elementum.io/ai-agents/agent-gateways Set up unified entrypoints to all agents in your organization ## Overview Agent Gateways provide a single entrypoint to multiple agents across your organization. Instead of users navigating to individual agents in different apps, a gateway consolidates them behind one interface. Users interact with the gateway, which routes their requests to the appropriate agent based on context. When enabled as the front door, the gateway becomes the primary assistant in the **Action Center** on the Home page — giving every user in the organization a consistent starting point for AI-powered assistance. Agent Gateways require at least one configured [AI Provider](/ai-agents/ai-services#prerequisites) with an available LLM. See [AI Services](/ai-agents/ai-services) to set up providers and models. *** ## Create a Gateway 1. Open Settings icon **Org Settings** → **Agent Gateways** in the **Platform** section. 2. Click **New Gateway**. 3. Enter a **Name** and **Description** for the gateway. 4. Select an **AI Provider**. 5. Click **Create Gateway**. The gateway is created in a disabled state. Click on it to configure settings and add agents before making it available. *** ## Configure the Gateway Click on a gateway to open its configuration. Use the toggle at the top of the page to make the gateway available to users. ### Agents Select the **Agents** tab to manage which agents are accessible through the gateway. * Add agents from across your organization to make them available through this gateway * Toggle the **Platform Assistant** on if you want to include Elementum's built-in assistant alongside your custom agents. See [Platform Assistant (Elementum Edge)](#platform-assistant-elementum-edge) to configure it first. ### Platform Assistant (Elementum Edge) **Elementum Edge** is the built-in platform assistant for an Agent Gateway. It provides general AI help to gateway users when no specific process agent is the right fit. The assistant tailors its responses to each user based on their [Personalization](#personalization) settings in the gateway. To enable and configure the platform assistant: 1. Click the Settings icon **Settings** icon in the top-right corner of the gateway. 2. In the **Platform Assistant** tile, click **Configure Platform Assistant**. 3. Toggle on **Elementum Edge**. 4. Configure the agent: * **Name** -- Display name for the assistant. Defaults to *Elementum Edge*. * **Model** -- Select the LLM that powers the assistant. 5. Click **Save**. 6. On the **Gateway Settings** page, toggle on the platform assistant. If you changed the name, the new name appears here in place of *Elementum Edge*. Once enabled, gateway users can call the platform assistant from the gateway chat for generic help when no other process agent is appropriate. ### Rules Select the **Rules** tab to define how the gateway routes incoming requests to specific agents. To create a rule: 1. Click **+ Add Rule**. 2. Choose your rule type: * **Deterministic** -- Add a name, description, and conditions to filter the rule. Use for structured requests that are easy to filter (for example, channel, user, or department). * **Probabilistic** -- Add a name, description, and conditional description (AI prompt) for the LLM to use, then choose the desired routing from the dropdown. Use for natural language requests that are evaluated by AI to select the correct route. 3. Click **Update Rule**. After a rule is created, return to the **Rules** tab to toggle it on or off, Edit icon **edit** it, or Delete icon **delete** it. Deterministic rules are evaluated before probabilistic rules during a chat with a user. ### Settings Select the **Settings** tab to update the gateway's core configuration. * **Name and Description** -- Update the gateway's display name and description. * **AI Provider** -- Change the AI provider used by the gateway. * **Front Door** -- Enable this toggle to set the gateway as the primary assistant in the **Action Center** on the Home page. This makes the gateway the default AI interaction point for all users in your organization. Once the gateway is enabled as the front door, you can still return to your workspaces from the gateway. Click the Workspaces icon **Workspaces** icon in the left sidebar, then select a workspace to switch to it. ### Voice Connect one or more phone numbers to the gateway so a single inbound entry point can route callers to multiple voice agents. Inbound calls flow through a pre-agent pipeline that authenticates the caller, detects the spoken language, and classifies intent before routing to the right agent based on the gateway's [Rules](#rules). **Prerequisites:** * A gateway with at least one agent added on the **Agents** tab and routing rules defined on the **Rules** tab. * A configured phone provider (for example, Elementum Twilio or a SIP trunk-enabled provider). **Connect a phone number:** 1. Open the gateway and select the **Settings** tab. 2. In the **Voice** section, click **+ Add phone number**. 3. In the **Create Phone Service** dialog, configure: * **Number Type** — Select how the number is provisioned (for example, **Create Number**). * **Area Code** — Enter a U.S. toll-free area code (for example, 833, 866, 877, or 888). * **Phone Provider** — Select the telephony provider that will host the number. * **Caller Access** — Choose who can reach the gateway (for example, **Allow All Callers**). * **Default Language** — Set the primary language used for caller interactions. * **Additional Supported Languages** — Optionally add languages the gateway can detect and respond in mid-call. * **Generate First Message** — Toggle on to have the gateway automatically generate the opening message when a call connects. 4. Click **Save**. Connected phone numbers are listed under the **Voice** section. Add more than one phone number to give the gateway multiple inbound entry points. **Voice overrides per agent:** Each agent routed through the gateway can have its own voice persona. Configure voice overrides on the individual agent so callers hear a distinct voice when they're handed off to that agent. **Behavior notes:** * Inbound calls are authenticated, language-detected, and intent-classified by the gateway before being routed to the right voice agent. * When a caller's intent shifts mid-call, the gateway transfers them to a different agent without re-authentication and carries the full transcript across the handoff. * The same multi-agent orchestration available in chat applies on the phone — gateway rules govern both channels. ### Test Select the **Test** tab to verify the gateway is working as intended before enabling it for your organization. Send messages and confirm that requests are routed to the correct agents. *** ## Personalization Personalization is available to **all users** of an Agent Gateway, not just administrators. Each user configures their own personalization independently, and it only affects their own experience with the gateway. Personalization tailors the [Platform Assistant (Elementum Edge)](#platform-assistant-elementum-edge) to each user's role, goals, and the apps most relevant to their work. The assistant uses this information to deliver responses informed by each user's context. To configure your personalization: 1. From the gateway **Home** page, click the Settings icon **Settings** icon in the bottom-left corner. 2. Select **Personalization**. 3. Configure the following: * **User Info** -- Details about your role, team, or other identifying information. * **Goals** -- Personal goals and responsibilities the assistant should consider when responding. * **Relevant Apps** -- Apps that contain the data and processes most relevant to your work. If this is your first time, follow the **Onboarding Setup** guidance to walk through each section. *** ## Related Features Configure providers and models that power your gateway Create and configure the agents available through your gateway Multi-agent coordination and the A2A protocol for agent-to-agent communication Define reusable skill modules that gateway agents can use # Agent Architecture & A2A Protocol Source: https://docs.elementum.io/ai-agents/agents-a2a-protocol How Elementum agents are structured internally, coordinate with external agents via the A2A protocol, and integrate into deterministic workflows Elementum agents operate at two levels: each agent has an internal architecture that balances AI reasoning with deterministic controls, and agents coordinate across organizational boundaries using the Agent-to-Agent (A2A) protocol. This page covers the internal component model, A2A discovery and authentication, the JSON-RPC messaging interface, streaming, and multi-turn conversations. ## Individual Agent Architecture ### Core Agent Components Each Elementum agent follows a standardized internal architecture that balances AI capabilities with deterministic control structures: Elementum Agent Architecture - Light Mode ### Agent Component Functions * **System Prompts**: Define agent behavior, expertise domain, and operational constraints * **Orchestrator**: Manages execution flow, tool calls, and contextual state * **LLM Engine**: Provides natural language understanding and generation capabilities * **Memory Systems**: Maintain context, conversation history, and learned patterns * **Tool Registry**: Catalog of functions and integrations the agent can invoke * **Customer Data Access**: Secure, governed access to relevant business data ### Deterministic Control Mechanisms The agent orchestrator enforces deterministic behavior through: * **Workflow Action Constraints**: Predefined actions that limit agent behavior to approved operations * **Data Access Controls**: Strict boundaries around what data the agent can access and modify * **Tool Invocation Rules**: Defined conditions for when and how external tools can be used * **Escalation Triggers**: Automatic handoff to human oversight based on confidence thresholds or business rules ## Multi-Agent Coordination via A2A Protocol ### Agent2Agent (A2A) Protocol Implementation The A2A protocol enables standardized communication between Elementum agents and external agent systems. The protocol operates through several key mechanisms: For complete A2A protocol specification and additional resources, see the [A2A Project Documentation](https://a2aproject.github.io/A2A/latest/). #### Direction of A2A Communication Elementum agents act as A2A **receivers** (servers), not A2A clients. External systems — other AI agents, automation platforms, or custom applications — connect *to* an Elementum agent: they retrieve its [Agent Card](#agent-card-structure), authenticate, and send it messages. See [Connecting to an Elementum Agent via A2A](#connecting-to-an-elementum-agent-via-a2a) for the receiver-side setup. Elementum does not act as an A2A client. There is no way to install, import, or register an external agent's Agent Card in Elementum, and an Elementum agent cannot call out to another system's A2A endpoint to discover or consume its capabilities. To use an external, third-party agent's capabilities inside an Elementum workflow, connect a **managed agent** through [App Intelligence](./agents-tools-and-deployment#external-agents-via-app-intelligence) rather than A2A. Elementum supports two managed agent runtimes: * [Snowflake Cortex Agents](./snowflake-cortex-agents-setup) — agents that run on your Snowflake data warehouse. * [AWS Bedrock Agents](./bedrock-agents-setup) — agents built in your own AWS account. Managed agents are configured per App and invoked from automations using **Run Agent Task**. | A2A direction | Supported? | How | | -------------------------------------------------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | External system → Elementum agent | Yes | Enable A2A on the agent, then the caller retrieves the Agent Card and sends messages. See [Connecting to an Elementum Agent via A2A](#connecting-to-an-elementum-agent-via-a2a). | | Elementum agent → external A2A agent (install or consume an external Agent Card) | No | Not supported over A2A. Use [App Intelligence](./agents-tools-and-deployment#external-agents-via-app-intelligence) with a Snowflake Cortex or AWS Bedrock managed agent instead. | #### Agent Card Structure Each agent publishes a standardized Agent Card that serves as both a discovery mechanism and capability contract. The Agent Card includes: * **Identity and Capabilities**: Unique agent identifier and list of specific functions the agent can perform, such as document analysis, compliance checking, or data transformation. * **Communication Endpoints**: Technical connection details including A2A protocol endpoints and health check URLs for establishing secure communication channels. * **Authentication Requirements**: Security specifications covering authentication methods, required permissions, and access scopes needed for interaction. * **Data Schemas**: Structured definitions of expected input formats and guaranteed output formats to ensure compatible data exchange between agents. * **Governance Metadata**: Compliance and operational requirements including audit trails, data residency constraints, and regulatory certifications that govern agent interactions. #### A2A Authentication Elementum supports two authentication methods for A2A communication: **OAuth Client Credentials Flow** Standard OAuth 2.0 client credentials grant for machine-to-machine authentication. External agents obtain access tokens from an authorization server and include them in A2A requests. **Self-Signed JWT Authentication** For scenarios where external agents issue their own JWTs, Elementum validates tokens using the following configuration: | Field | Description | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | **Header Name** | The HTTP header containing the JWT token (typically `Authorization`) | | **Email Address Claim Name** | The JWT claim containing the user identifier (e.g., `sub`, `email`). When configured, the agent runs with the permissions of the identified user. | | **JWKS URL** | URL to the JSON Web Key Set endpoint for public key retrieval and token verification | | **PEM Key** | Alternative to JWKS—paste the plaintext public key directly for JWT verification | **Required Claims** You can enforce additional JWT claims that must be present with specific values. This is useful for restricting access to particular clients or tenants: | Field | Description | | --------------------- | ----------------------------------------------------------------- | | **Claim Name** | The JWT claim to validate (e.g., `client_id`, `aud`, `tenant`) | | **Acceptable Values** | Comma-separated list of values that satisfy the claim requirement | Use required claims to scope A2A access—for example, require `client_id` to match your partner's registered client identifier, or validate `aud` contains your agent's expected audience. #### A2A Communication Flow ```mermaid theme={null} sequenceDiagram participant B as Business Process participant O as Workflow Engine participant A1 as Lead Agent participant A2 as Specialist Agent participant AW as Approval Workflow B->>O: Initiate Complex Request O->>A1: Assign Primary Task A1->>A1: Analyze Requirements A1->>A2: Request Specialist Capability A2->>A1: Provide Agent Card & Context A1->>A2: Collaborate on Subtask A2->>A1: Return Specialized Results A1->>O: Complete Primary Task O->>AW: Execute Approval Workflow AW->>AW: Human Review & Validation AW->>O: Approval Decision O->>B: Deliver Business Outcome ``` ### Inter-Agent Communication Patterns * Direct agent-to-agent calls for immediate responses * Timeout handling and circuit breaker patterns * Used for validation, lookup, and simple transformations * Long-running operations with callback notifications * Status polling and progress updates * Used for analysis, document processing, and complex workflows * Agents subscribe to relevant business events * Reactive processing based on data changes * Used for monitoring, alerting, and automated responses ## Workflow Integration Architecture ### Deterministic Structure Around Non-Deterministic Agents Agents operate within workflow frameworks that provide governance and predictability: ```mermaid theme={null} graph TB subgraph "Elementum Ecosystem" W[Workflow Engine] A1[Data Analysis Agent] A2[Communication Agent] H1[Human Review Step] H2[Approval Process] A3[Compliance Agent] end subgraph "External Partners" E1[Customer System Agent] E2[Supplier Portal Agent] E3[Regulatory Reporting Agent] end W --> A1 W --> H1 W --> A2 W --> H2 W --> A3 A1 -.->|A2A Protocol| E1 A2 -.->|A2A Protocol| E2 A3 -.->|A2A Protocol| E3 W --> R[Business Results] ``` ### Workflow-Agent Integration Points * **Task Assignment**: Workflow engine determines when and where to invoke agents * **Context Provision**: Agents receive structured context and constraints from workflow state * **Result Validation**: Agent outputs are validated against business rules before proceeding * **Exception Handling**: Failed or low-confidence agent responses trigger defined escalation paths ## Connecting to an Elementum Agent via A2A External systems can connect to Elementum agents that have been configured for A2A access. The connection follows the standard A2A handshake pattern. A2A is one-directional in Elementum: your agent is the receiver, and the external system is the caller. An Elementum agent cannot consume or install another system's Agent Card. To bring an external agent's capabilities into a workflow, connect a managed agent through [App Intelligence](./agents-tools-and-deployment#external-agents-via-app-intelligence) (Snowflake Cortex or AWS Bedrock). See [Direction of A2A Communication](#direction-of-a2a-communication). To turn on A2A capabilities for your agent, select the agent and click the **Connections** tab. Toggle on **A2A Streaming** to enable A2A protocol communication. For additional conversation settings such as automatic record creation and inactivity timeouts, see [A2A Conversation Settings](#a2a-conversation-settings). Elementum implements A2A protocol **version 0.3.0** with streaming support. The A2A protocol is an evolving standard. The examples in this documentation reflect Elementum's current implementation. Contact your Elementum representative if you have questions about integration. ### Configure A2A Authentication Configure how external systems authenticate when calling your agent from the **Authentication** section of the agent's **Configure** page. Elementum supports two authentication methods: * **OAuth** — Standard OAuth 2.0 client credentials grant for machine-to-machine access. No additional fields are required in the Agent Configuration page. * **JWT** — Self-signed JSON Web Tokens issued by an external system and validated by Elementum. Requires the configuration below. The **Authentication** section controls how callers prove their identity to the agent. Streaming behavior is configured separately on the **Connections** tab; see [A2A Conversation Settings](#a2a-conversation-settings). #### JWT Authentication Click **+ Add Authentication** in the JWT section to open the configuration dialog. Elementum validates incoming tokens against a public key you provide. | Field | Description | | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Header Name** | The HTTP header that carries the JWT token on incoming requests. Defaults to `Authorization`. | | **Email Address Claim Name** | The JWT claim that contains the caller's email address (commonly `sub` or `email`). Elementum extracts this value from the validated token and runs the agent as that user, applying that user's permissions. | | **JWKS URL** / **Plain Text** | Toggle between providing a JWKS endpoint or pasting a public key directly. Choose **JWKS URL** when your identity provider exposes a JSON Web Key Set endpoint, or **Plain Text** to paste a PEM-formatted public key. | | **Required Claims** | Optional. Click **+ Add Claim** to require specific claims with specific values in the token — for example, restricting access by `client_id`, `aud`, or `tenant`. Tokens missing the claim or carrying an unaccepted value are rejected. | The caller signs each request with their private key, and Elementum verifies the signature using the configured public key. Because only the private key holder can produce a valid signature, a successful verification confirms the request's authenticity. If JWT-authenticated requests appear to run as the agent's publisher instead of the calling user, check the following: * JWT authentication is enabled in the **Authentication** section. * The **Email Address Claim Name** matches the claim actually present in the token. * The configured JWKS URL is reachable, or the pasted public key is current and correctly formatted. For the protocol-level specification—including required claim semantics and authentication flow details—see [A2A Authentication](#a2a-authentication) below. ### Discover Agent Capabilities Each Elementum agent has a unique A2A endpoint URL in the format: ``` https://agent-{agentId}-{orgDomain}.elementum.io/a2a/v1 ``` Retrieve the Agent Card to understand the agent's capabilities, supported input/output modes, and available skills: ``` GET https://agent-{agentId}-{orgDomain}.elementum.io/a2a/v1/.well-known/agent.json ``` The Agent Card response includes: * Agent name and description * Supported protocol versions * Available skills and their descriptions * Authentication requirements * Capability flags (streaming, push notifications) ### Send a Message to Initiate a Task Use the `message/send` method to start an interaction: ```json theme={null} { "jsonrpc": "2.0", "method": "message/send", "params": { "message": { "role": "user", "parts": [ { "kind": "text", "text": "Create a support ticket for login issues" } ] } }, "id": 1 } ``` **Sending Attachments** Messages can include file attachments alongside text content. To send an attachment, add a `file` part to the `parts` array with the file's `name`, `contentType`, and a `uri` pointing to the file location: ```json theme={null} { "jsonrpc": "2.0", "method": "message/send", "params": { "message": { "role": "user", "parts": [ { "kind": "text", "text": "Help me with my orders" }, { "kind": "file", "name": "orders.csv", "contentType": "text/csv", "uri": "https://example.com/files/orders.csv" } ] } }, "id": 1 } ``` Each file part requires the following fields: | Field | Description | | ------------- | -------------------------------------------------------------------------------------------------------------------- | | `kind` | Must be `"file"` to indicate an attachment | | `name` | The filename including extension (e.g., `"orders.csv"`) | | `contentType` | The MIME type of the file (e.g., `"text/csv"`, `"application/pdf"`, `"image/png"`) | | `uri` | A URL where the file can be retrieved. The file must be accessible at this URI at the time the message is processed. | You can include multiple file parts in a single message, and they can be combined with text parts in any order. Both `message/send` and `message/stream` support attachments. The file referenced by `uri` must be publicly accessible or reachable by the Elementum platform at the time the agent processes the message. If the file cannot be retrieved, the agent may not be able to process the attachment. ### Receive Task Response The agent returns a JSON-RPC response containing a Task object. The response includes a `contextId` that you can use for follow-up messages: ```json theme={null} { "jsonrpc": "2.0", "id": "1", "result": { "id": "8f1dfa7f-76c3-4368-8799-3116df7f7992", "contextId": "7584685c-e711-4e91-8d8e-e11484bff7b5", "status": { "state": "completed" }, "history": [ { "role": "user", "parts": [{"kind": "text", "text": "Create a support ticket for login issues"}], "taskId": "8f1dfa7f-76c3-4368-8799-3116df7f7992", "contextId": "7584685c-e711-4e91-8d8e-e11484bff7b5" } ], "artifacts": [ { "artifactId": "6299dcdc-0774-41a7-b35c-0018b1fbbba3", "parts": [{"kind": "text", "text": "Support ticket #12345 created successfully."}] } ], "kind": "task" } } ``` ## Streaming Responses Elementum agents support streaming responses via `message/stream` using [Server-Sent Events (SSE)](https://a2a-protocol.org/v0.3.0/specification/#72-messagestream). This delivers real-time updates as tasks are processed — useful for long-running operations or when you want to display incremental progress to users. **Initiating a Streaming Request** Use the `message/stream` method instead of `message/send`: ```json theme={null} { "jsonrpc": "2.0", "method": "message/stream", "params": { "message": { "role": "user", "parts": [ { "kind": "text", "text": "Analyze the quarterly sales data" } ] } }, "id": 1 } ``` ### Event Types Every streaming response contains two event kinds, per the [A2A spec](https://a2a-protocol.org/v0.3.0/specification/#72-messagestream): | Kind | Purpose | | ----------------- | ---------------------------------------------------- | | `status-update` | Agent lifecycle and tool execution notifications | | `artifact-update` | The agent's response content, streamed incrementally | ### TaskStatusUpdateEvent Status updates track what the agent is doing. The `status.state` field progresses through `submitted` → `working` → `completed`. A `status-update` with `state: "working"` and **no** `message` means the agent is processing but has not called a tool yet. When the agent executes a tool, it emits an additional `status-update` with `state: "working"` and a `status.message` containing a description of the tool being executed: ```json theme={null} { "taskId": "97fa3b19-...", "contextId": "4638cf82-...", "status": { "state": "working", "message": { "role": "agent", "parts": [ { "kind": "text", "text": "Executing tool: Creating item..." } ] } }, "kind": "status-update", "final": false } ``` If the agent calls multiple tools during a single request, each tool execution produces its own `status-update` event in sequence. The final event in every stream is a `status-update` with `state: "completed"` and `final: true`. ### TaskArtifactUpdateEvent Artifact updates carry the agent's text response, streamed token-by-token. Each event includes `append: true` and contains one text chunk. The last chunk in the sequence has `lastChunk: true`. ```json theme={null} { "taskId": "97fa3b19-...", "contextId": "4638cf82-...", "artifact": { "artifactId": "12c26a10-...", "parts": [ { "kind": "text", "text": "Here" } ] }, "append": true, "lastChunk": false, "kind": "artifact-update" } ``` ### Event Sequences The order of events in a stream depends on whether the agent calls any tools while processing the request. The simplest case — the agent responds directly without executing any tools: ``` status-update → state: submitted status-update → state: working artifact-update → first token (append: true) ... artifact-update → last token (append: true, lastChunk: true) status-update → state: completed (final: true) ``` The agent calls one tool before generating a response. The tool execution appears as an additional `working` status with a message: ``` status-update → state: submitted status-update → state: working status-update → state: working, message: "Executing tool: Creating item..." artifact-update → first token (append: true) ... artifact-update → last token (append: true, lastChunk: true) status-update → state: completed (final: true) ``` The agent calls several tools in sequence. Each tool execution produces its own `status-update` event: ``` status-update → state: submitted status-update → state: working status-update → state: working, message: "Executing tool: Searching available skills..." status-update → state: working, message: "Executing tool: Loading skill..." status-update → state: working, message: "Executing tool: Creating record..." artifact-update → first token (append: true) ... artifact-update → last token (append: true, lastChunk: true) status-update → state: completed (final: true) ``` ### Key Fields | Field | Description | | ----------- | -------------------------------------------------------------- | | `taskId` | Unique identifier for the task | | `contextId` | Context identifier for multi-turn conversations | | `kind` | Event type: `status-update` or `artifact-update` | | `final` | `true` when the stream is complete | | `append` | `true` indicates content should be appended to previous chunks | | `lastChunk` | `true` when this is the final chunk of an artifact | ### Stream Handling Requirements * Events are delivered in order and must not be reordered * The stream ends when you receive a `status-update` event with `"final": true` * Terminal states include: `completed`, `failed`, `canceled`, `rejected` * Capture the `contextId` from the response for follow-up messages in [multi-turn conversations](#multi-turn-conversations) ## Task States A2A tasks progress through defined lifecycle states: | State | Description | | ---------------- | ---------------------------------------------- | | `submitted` | Task has been created and acknowledged | | `working` | Task is actively being processed | | `input-required` | Agent needs additional information to proceed | | `completed` | Task finished successfully (terminal) | | `failed` | Task encountered an error (terminal) | | `canceled` | Task was canceled before completion (terminal) | | `rejected` | Agent declined to perform the task (terminal) | ## Multi-Turn Conversations The A2A protocol supports multi-turn conversations through the `contextId` field. When you send an initial message, the server generates a `contextId` in the response. Include this `contextId` in subsequent messages to continue the conversation. **Initial Request:** ```json theme={null} { "jsonrpc": "2.0", "method": "message/send", "params": { "message": { "role": "user", "parts": [ { "kind": "text", "text": "Hi, I need help with a support ticket" } ] } }, "id": 1 } ``` **Follow-up Request (using contextId from response):** ```json theme={null} { "jsonrpc": "2.0", "method": "message/send", "params": { "message": { "role": "user", "parts": [ { "kind": "text", "text": "The issue is with login authentication" } ], "contextId": "a269e867-fe40-4588-a381-c2596aeb3557" } }, "id": 2 } ``` The `contextId` groups related messages, enabling the agent to maintain conversational continuity across multiple interactions. When an agent requires additional input, it returns a task with `input-required` status—use the same `contextId` to provide the requested information. ## A2A Conversation Settings Configure conversation behavior for A2A agents on the **Connections** tab of the agent detail page. ### A2A Streaming Enable streaming responses for A2A protocol communication with the agent. When turned on, external systems can use the `message/stream` method to receive real-time, incremental responses. See [Streaming Responses](#streaming-responses) for protocol details. ### Create a Record When enabled, Elementum automatically creates a record when a conversation is initiated via the A2A protocol. This requires a conversation inactivity timeout to be configured. ### Conversation Inactivity Timeout Set the duration of inactivity (in minutes) before a conversation is automatically closed. When a conversation times out or completes, it can trigger follow-up automations. Enable **Create a Record** and set a **Conversation Inactivity Timeout** to use the [Agent Conversation Ended](/workflows/automation-triggers-reference#record) trigger in an App's automation. This lets you run follow-up workflows — such as summarizing transcripts, updating CRM records, or generating reports — after an A2A conversation wraps up. ## Testing A2A Connections To test your A2A integration with Elementum agents, use the official A2A Inspector tool: **A2A Inspector**: [github.com/a2aproject/a2a-inspector](https://github.com/a2aproject/a2a-inspector) The inspector allows you to: * Fetch and validate Agent Cards * Send test messages and view responses * Monitor streaming events in real-time * Debug authentication and protocol issues ## Protocol Version Elementum currently implements A2A protocol version **0.3.0** with streaming support. The examples in this documentation reflect the current implementation. For the complete A2A protocol specification, see [a2a-protocol.org](https://a2a-protocol.org/latest/specification/). ## Next Steps * [Building Agents](./agents-experience) — Create an agent, configure tools, and add it to your app * [Agent tools, deployment, and integrations](./agents-tools-and-deployment) — Tool types, deployment channels, and external agents via App Intelligence * [Help & Resources](/support/resources) — Support and additional documentation # Test Agent Behavior Source: https://docs.elementum.io/ai-agents/agents-evaluations Define repeatable evaluation suites and scenarios to verify agent behavior and catch regressions before they reach production Agent Evaluation Suites give you a repeatable way to verify that an agent still behaves the way you expect after prompt, model, tool, or skill changes. You define evaluations that score responses, then attach them to scenarios on individual agents so each scenario produces a pass/fail result you can review over time. Use evaluation suites to: * Define reusable test suites on agents with conversation scenarios. * Assert specific behavior, such as the tools and skills that should load during a conversation. * Score agent responses with LLM-as-judge evaluations against a passing threshold. ## Concepts * **Evaluation** — A reusable LLM-as-judge definition. An evaluation has a name, a prompt that tells the model what to score (for example, whether the agent followed the right instructions, avoided hallucinations, or used the correct tone), a passing threshold, and the model used to score. * **Scenario** — A test case attached to a specific agent. A scenario describes a conversation prompt to run, an assertion (for example, that a particular tool or skill should load), and one or more evaluations that score the response. * **Run** — A single execution of a scenario. Each run produces results for the assertion and every attached evaluation, and is recorded in run history for that scenario. ## Create an evaluation App Administrators create evaluations once and reuse them across any number of agents and scenarios. 1. Open **Intelligence** → **Evaluations** in your app. 2. Click **New Evaluation** in the top-right corner. 3. Enter the evaluation details: * **Name** — A descriptive name (for example, *Hallucination Judge* or *Tone Check*). * **Prompt** — Instructions that tell the model what to score. Be specific about what counts as passing and failing behavior. * **Passing Threshold** — The score the response must meet or exceed to pass. 4. Choose a **Model** from the dropdown to act as the judge. 5. Click **Save**. Reuse the same evaluation across multiple agents and scenarios to standardize scoring — for example, a shared hallucination judge or a tone judge that every customer-facing agent should pass. ## Attach an evaluation to an agent scenario Scenarios live on the agent and pair a test prompt with the assertions and evaluations that should run against it. 1. Open **Intelligence** → **Agents** and select the agent you want to evaluate. 2. Open the **Scenarios** tab on the agent page and click **+ Scenario**. 3. Configure the scenario: * **Name** and **Description** — Identify the scenario and what it covers. * **Prompt** — The user message or conversation that drives the scenario. * **Timeout** — How long the scenario is allowed to run before failing. * **Model** — The model the agent should use for this run. * **Assertion** — A required behavior to verify, such as which tool or skill should load. * **Evaluations** — Select one or more evaluations to score the response. 4. Click **Save**. ## Run a scenario and review results 1. From the scenario configuration page, click **Run Scenario**. 2. Watch the live response in the panel and review the assertion result and each evaluation's score. 3. Open the **Run history** section on the same page to compare the latest run against previous runs over time. Because run history is preserved per scenario, you can use evaluation suites as a regression check: rerun a scenario after changing a prompt, model, tool, or skill to confirm the agent still meets your expectations before promoting the change. # Building Agents Source: https://docs.elementum.io/ai-agents/agents-experience Create, configure, and test conversational AI agents in your app You create and manage agents under **Intelligence** in your app. This page walks through creating an agent, configuring its instructions, controlling Skill access, adding the agent to workflows, and reviewing past conversations. Once your agent is created, you can: * Add tools so it can take action—see [Agent tools, deployment, and integrations](./agents-tools-and-deployment). * Deploy it to a channel—see [Microsoft Teams](./agents-teams-integration), [Slack](./agents-slack-integration), or [phone](./agents-phone-integration). * Expose it to external callers via the A2A protocol—see [Agent Architecture & A2A Protocol](./agents-a2a-protocol). *** ## Create an Agent 1. Within your app, click **Intelligence** in the left navigation menu. 2. Click **+ Agent** in the top right corner. 3. Enter a name and description in the respective fields. 4. Select an LLM from the dropdown. If none are available, click **Set up AI Service**. 5. Choose the permissions level. * **Run as publisher:** The agent always has the same level of access, regardless of the user interacting with the agent. * **Run as current user:** Permissions change with the user interacting with the agent. * **Run as service account:** Set up a dedicated account with specific permissions for the agent. This is ideal for integrations or automations that require consistent, controlled access. 6. Select the **Agent type** — **Native Agent** or **Browser Use Agent**. See [Agent Types](#agent-types). 7. Click **Create Agent**. *** ## Agent overview When you open an agent under **Intelligence**, the detail page lands on **Agent Overview**. The overview shows the agent's configuration settings at a glance in a read-only summary that matches the design of the gateway page. Click into any section to edit that area of the agent's configuration. *** ## Agent Types When you create an agent, choose the agent type that matches your use case: * **Native Agent** — A fully customizable agent with configurable data sources, tools, and skills. Best for complex workflows and specific business requirements. * **Browser Use Agent** — An agent that interacts with web browsers and applications, pre-configured with browser automation capabilities. Choose a model and provide instructions. ### Browser Use Agents Browser use agents automate document-driven workflows on external websites from end to end — for example, reading a document, filling out a government form, and returning proof of submission — without a person touching a browser. * **Input attachments** — Feed documents such as PDFs, spreadsheets, and images to the agent so it can read and act on their contents. * **Output attachments** — The agent captures confirmation artifacts such as screenshots, downloaded PDFs, and confirmation numbers, and returns them to the calling action. * **Bring your own model** — Power the browser use agent with any model you choose, including Snowflake Cortex models. To create one, follow [Create an Agent](#create-an-agent), choose **Browser Use Agent** as the agent type, complete the remaining configuration, and click **Create Agent**. *** ## Configure Agent Settings Test the agent in the chat panel as you update the settings. 1. Click the **Configure** button on the agent profile. 2. Add the first message you want the user to see or hear when using the agent. 3. Add instructions. This is the prompt the agent will follow. Make sure to include the agent's overall purpose, core responsibilities, guidance on using specific tools, and any constraints. Use an LLM to help refine the agent's prompt for clarity and completeness. *** ## Instruction Version History Every time you save agent instructions, Elementum keeps a versioned snapshot. You can compare any previous version side-by-side with the current instructions and revert instantly if a change causes unexpected behavior. 1. Click **Intelligence** in your app's left navigation menu. 2. Select the agent whose history you want to review. 3. Click **Configure**. 4. In the **Instructions** section, click **History**. 5. Select the version you want to view. 6. Review the side-by-side comparison with the current instructions. 7. Click **Revert To This Version** to restore the selected version, or click **Cancel** to return to the configuration page. Reverting to a previous version saves it as the new current version, so nothing is lost. *** ## Add Tools Add tools so the agent can search, create, or update records, run automations, delegate to other agents, or call external services. Tools are configured from the **Configure** page of the agent. For configuration steps and field-by-field details for each tool type—including Search Records, AI Search, Create Record, Update Record, Run Automation, Run Agent, MCP, and the Ask User Question system tool—see [Agent tools, deployment, and integrations — Configure Agent Tools](./agents-tools-and-deployment#configure-agent-tools). *** ## Skill Access Control which Skills the agent can discover and use at runtime. Skill Access is configured in the **Configure** page under the Skills section. | Mode | Behavior | | ------------ | ------------------------------------------------------- | | **None** | Agent has no access to Skills (default for new agents) | | **All** | Agent can discover and use all active Skills in the app | | **Selected** | Choose specific Skills the agent can use from a list | For full setup details, including preloaded Skills and runtime behavior, see [Agent Skills](./agents-skills). *** ## Voice Properties When an agent is used through a phone integration, additional **Voice Properties** appear in the **Configure** page that control idle messages, timeouts, and the voice LLM. For the full field reference and setup steps, see [Agent Phone Integration — Voice Properties](./agents-phone-integration#voice-properties). *** ## Authentication and Connections External systems can call your agent over the [Agent-to-Agent (A2A) protocol](./agents-a2a-protocol). The agent's **Configure** page exposes: * An **Authentication** section to choose between OAuth and self-signed JWT and to configure the JWT verification settings. See [A2A Authentication (UI configuration)](./agents-a2a-protocol#configure-a2a-authentication) for field-level details. * A **Connections** tab where you enable **A2A Streaming**, automatic record creation, and the conversation inactivity timeout. See [A2A Conversation Settings](./agents-a2a-protocol#a2a-conversation-settings). *** ## Starting Actions You can configure **Starting Actions**—clickable chips that appear below the agent's greeting before the user's first message. Each action has a name, icon, and prompt template; optional `{{variable}}` placeholders open an inline form to collect inputs (Text, Number, or Dropdown) before sending. Actions without variables send immediately. For full setup and variable options, see [Agent Starting Actions](./agents-starting-actions). *** ## Start Conversation Hook App Administrators can run an on-demand automation before the first message in a conversation. Outputs from the automation are captured as a message sent to the agent before the first turn, so the agent has the context it needs on turn one. **Where to find it:** **App** → **Intelligence** → select the agent → Settings icon **Settings** → **Hooks**. 1. Within your app, open **Intelligence**. 2. Select the agent. 3. Click the Settings icon **Settings** icon. 4. In the **Hooks** section, click **Add Start Conversation Hook**. 5. Select an automation. 6. Map the **Inputs**, and optionally add a progress message users see while the automation runs. 7. Click **Next**. 8. Review the configuration and click **Save**. The progress message is optional. The hook runs at the start of each conversation, before the first user message. *** ## Add Your Agent to Your App Workflow Once your Agent is created and configured, you can edit and test by returning to **Intelligence** in your app. The Agent can now be added to Automations. You can also open the Agent wherever you see the **Agent** button in Elementum, or use it through [Microsoft Teams](./agents-teams-integration), [Slack](./agents-slack-integration), and [phone integrations](./agents-phone-integration). *** ## Embed an Agent in a Managed View Attach an agent to any [managed view](/workflows/managed-views) so users can chat with the agent in context of the records they are viewing. You can either add an agent to an existing List, Kanban, Calendar, or Dashboard view — which renders a chat box above the records — or create an **Agent** view type for a full-page embedded chat experience. Agents embedded in a view respect the permissions of the viewing user, so responses only reference records that user can access. For configuration steps, see [Attach an Agent to a View](/workflows/managed-views#attach-an-agent-to-a-view). *** ## Conversation History App admins can review past agent conversations to understand how the agent is performing and where it can be improved. 1. Click **Intelligence** in your app's left navigation menu. 2. Select the agent you want to review. 3. Click the **Conversation History** tab. 4. Select a conversation to view. The transcript shows what the user typed, how the agent responded, and which tool calls were made. 5. Click **Waterfall** in the top-right corner to switch to a time-based breakdown of the conversation. Each step displays an estimated duration, making it easy to identify which parts of the conversation are taking the longest. **Context management via summarization:** When a conversation approaches the model's token limit, Elementum automatically summarizes earlier messages so the conversation can continue without interruption. Compaction happens transparently in the background — no user action is required — keeping agents responsive and contextually aware across longer, more complex interactions. *** ## Agent Update History To see a full history of updates made to an agent, including which user made each change, open the agent under **Intelligence** in your app and click the **History** tab. *** ## Related documentation * [Interact with Configured Agents](./agents-interacting) — What end users see when chatting with an agent, including file inputs and in-chat forms * [Agent tools, deployment, and integrations](./agents-tools-and-deployment) — Tool types, deployment channels, and external agents * [Agent Architecture & A2A Protocol](./agents-a2a-protocol) — Internal architecture, A2A discovery, authentication, streaming, and multi-turn conversations * [Agent Skills](./agents-skills) — Skills and automatic tool discovery; see [When to Use Skills vs Tools](./agents-skills#when-to-use-skills-vs-tools) * [AI Services](./ai-services) — AI providers and models used by Agents # Interact with Configured Agents Source: https://docs.elementum.io/ai-agents/agents-interacting How users chat with Elementum agents in apps, Microsoft Teams, Slack, and over the phone, including starting actions, file inputs, and in-chat forms Elementum agents are conversational AI assistants you can chat with to get answers, take actions, and move work forward. When you interact with an agent, you'll want to know where to find one, how to start a conversation, the ways an agent can collect information from you, and what it can see and do on your behalf. If you are creating or configuring an agent, see [Building Agents](./agents-experience) instead. *** ## Where you can chat with an agent An agent is reachable from any of the following surfaces, depending on how an admin has set it up: * **In your Elementum app** — Chat from a [managed view](/workflows/managed-views) (a chat box above the records, or a full-page Agent view), or from an **Assign an Agent** button on a record. * **Microsoft Teams** — One-on-one chats with the Elementum bot. After your Teams admin has added the app, find **Elementum** in Teams and start a conversation. * **Slack** — In channels where the Elementum app has been added. Each channel can use a different agent. * **Phone (Twilio)** — Call the phone number assigned to the agent and hold a voice conversation. *** ## Starting a conversation When you open an agent, it greets you with a first message. From there you can: * **Click a Starting Action** — a clickable chip below the greeting — to begin a common task with one click. * **Type a message** to ask anything. In Microsoft Teams, an Elementum app record is created for your session so the conversation can be associated with your user details and reviewed later. In Slack, behavior depends on how the channel is configured — some channels reply to every message, others only to questions or only to high-confidence matches. *** ## Starting Actions **Starting Actions** are clickable prompt chips that appear directly under an agent's opening message before you've sent your first message. They are a fast way to kick off common tasks without typing. * **Actions without variables** send the prompt as soon as you click the chip. * **Actions with variables** open a short inline form that collects values (text, number, or dropdown) before sending the prompt. Starting Actions disappear after you send your first message in a conversation, whether you sent it by clicking a chip or by typing. For the full reference, see [Agent Starting Actions](./agents-starting-actions). *** ## Sharing files in a conversation You can attach a file to a message so the agent can read and reason over the contents. * **In your Elementum app** — Use the attachment button in the agent chat interface. * **Microsoft Teams** — Drag, drop, paste, or use the attachment button in the 1:1 Elementum bot chat. See [Sending File Attachments](/ai-agents/agents-teams-integration#sending-file-attachments). * **Slack** — Attach files as you would in any Slack message. Agents on **multimodal-capable models** can interpret the file content; other agents receive the message text only. Agents accept `.xlsx`, `.docx`, and `.tiff` files directly in conversation with no manual conversion required. The platform converts each file into a format that preserves embedded images, signatures, and content structure before passing it to the AI model. File content remains available for the rest of the active conversation — you do not need to re-upload for follow-up questions. Files do not carry over to new conversations. ### Agent Chat vs Run Agent Task Attaching a file in Agent Chat and passing a file through [Run Agent Task](/workflows/agent-task-automation#file-inputs) produce different behavior because the agent operates in different modes: | | Agent Chat | Run Agent Task | | ---------------------- | ----------------------------------------------- | ---------------------------------------------------------- | | **Input method** | Attach in the chat interface | Pass via the **Files** section in the action configuration | | **Conversation style** | Interactive — agent can ask follow-up questions | Headless — no user present to answer clarifying questions | | **Context available** | File + full conversation history | File + task description and value references | Because Run Agent Task is headless, the agent cannot ask for clarification. A vague task description (e.g., "Look at this file") forces the agent to guess, which often produces different results from an interactive chat. To get consistent output, put the same specific question you would ask in chat into the **Task Description** field. The Run Agent Task **Test & Preview** screen may not handle attachments the same way as Agent Chat. If you see different results, try providing a more specific Task Description. See [Run Agent Task — File Inputs](/workflows/agent-task-automation#file-inputs) for configuration details. *** ## Answering in-chat forms Some agents use the **Ask User Question** tool to collect input with a structured form instead of asking multiple back-and-forth questions. When the agent invokes the form: * A form is rendered inside the chat with the questions, fields, and any required selections. * Fields can be single-select, multi-select, or free text. * **Dynamic dropdown** fields populate their options from live platform data — for example, a list of vendors or projects — and let you search within long option lists. * Submitting the form sends your answers back to the agent so the conversation can continue. Form wording, options, and field layout are generated by the model at runtime, so they may vary slightly between invocations. *** ## Understanding what the agent is doing While the agent works, live status messages appear in chat — for example, "Searching knowledge base…" — that indicate when a tool is running. When an agent uses several tools back-to-back, each one appears as its own status message so you can follow what it is doing. *** ## Long conversations Elementum automatically summarizes earlier messages when a conversation approaches the model's context limit, so you can keep chatting through long sessions without the agent losing track. Compaction happens transparently in the background — no action is required on your part. *** ## What the agent can see and do as you How an agent acts on your behalf depends on the permissions mode an admin set when creating it: * **Run as current user** — The agent acts under *your* permissions. It can only see and modify records you can access. Agents attached to managed views always respect the viewing user's permissions in this way. * **Run as publisher** — The agent acts with a fixed level of access regardless of who is chatting. Two users may see the same answers because the agent reads and writes the same set of records. * **Run as service account** — The agent uses a dedicated controlled account configured by an admin. Common for integrations or processes that require consistent access independent of any one person. If you are not sure which mode an agent uses, ask the agent's admin — it affects what data the agent can return to you. *** ## Channel-specific notes ### Microsoft Teams * Conversations are **one-on-one** with the Elementum bot, not in channels or group chats. * Only one active conversation per user at a time. * After a period of inactivity, the conversation closes and the next message starts a new conversation. * Agents may end a session themselves once the request is complete. See [Agent Microsoft Teams Integration](./agents-teams-integration) for the full reference. ### Slack * Each Slack channel is configured separately and can use a different agent. * Some channels operate in **Quick Answers** mode (short replies, no multi-turn state) and others in **Full Conversations** mode (full transcript and context). * The agent replies to messages according to the **Channel messages** rule set for the channel — all messages, only questions, or only high-confidence matches. * Idle conversations close after a configured timeout; the next message starts a new conversation. See [Agent Slack Integration](./agents-slack-integration) for the full reference. ### Phone * You speak with the agent over a regular phone call. * The agent reads its responses aloud using a voice model selected by an admin. * If you go quiet for too long, the agent plays an idle message and may end the call after a configured timeout. * Some agents restrict who can call. If the caller's phone number is not recognized, the agent plays a message explaining that they could not be matched to a user. See [Agent Phone Integration](./agents-phone-integration) for the full reference. *** ## Conversations are recorded App admins can review the transcript and tool activity of past conversations from the agent's **Conversation History** tab in **Intelligence**. They can also see a step-by-step **Waterfall** breakdown of how long each part of the conversation took. *** ## Related documentation * [Agents Overview](./agents-overview) — What agents are and how they fit with the rest of AI in Elementum. * [Agent Starting Actions](./agents-starting-actions) — Full reference for starting-action chips. * [Microsoft Teams](./agents-teams-integration), [Slack](./agents-slack-integration), and [Phone](./agents-phone-integration) integrations. * [Building Agents](./agents-experience) — Create, configure, and test an agent (for admins and builders). # Agents Overview Source: https://docs.elementum.io/ai-agents/agents-overview What Elementum agents are, what they can do, and where they fit in your business processes Agents are conversational AI components that operate within your apps. Unlike one-shot AI actions in automations, agents maintain context across a conversation, use tools to read and write data, and follow policies you define. A first-line support assistant is a typical starting point, but the same patterns apply to onboarding, sales qualification, request intake, or any process where a guided conversation speeds up routine work. ## What agents can do * **Tools and data access** — Agents can query Elements, update records, trigger automations, and call external APIs. * **Skills** — Modular, reusable capabilities that agents discover and execute at runtime. * **Starting actions** — Pre-configured action chips that guide users toward common tasks without typing. * **Multi-channel deployment** — Run agents in your Elementum app, Microsoft Teams, Slack, or over the phone via Twilio. * **Multi-agent coordination** — Agents communicate using the Agent-to-Agent (A2A) protocol to hand off tasks and share context across workflows. ## How agents fit with the rest of AI in Elementum Agents sit on top of the same provider and AI service layer as the rest of the platform. Before you build an agent, make sure you have: 1. At least one configured [AI provider](/ai-agents/ai-overview#ai-providers). 2. An [LLM service](/ai-agents/ai-services) the agent can use as its model. 3. (Optional) An [embedding service](/ai-agents/ai-services) if you want the agent to perform [AI Search](/ai-agents/ai-search) over your records. Once those prerequisites are in place, the rest of the **Build agents** group walks through creating, configuring, and deploying an agent end-to-end. ## Where to go next Create, configure, and test agents in your apps Tool types, deployment options, and external agents via App Intelligence Define reusable skill modules that agents discover and execute at runtime Add clickable prompt chips that guide users toward common tasks Create a unified org-wide entry point that routes requests to the right agent Internal component model, A2A discovery, authentication, streaming, and multi-turn conversations ## Deploy agents to channels Agents can operate beyond the Elementum interface. Connect them to the communication channels your teams already use, or trigger agent conversations directly from automation workflows. Run agents as bots in Teams conversations Deploy agents in Slack channels for team collaboration Enable voice conversations with agents over the phone Trigger agent interactions from automation workflows ## External agents In addition to building agents inside Elementum, you can connect specialized agents that run on external platforms. These external agents are configured at the App level through Intelligence settings and invoked from automations via the AI Provider you connected. Use Cortex Agents that run on your Snowflake data warehouse Invoke Bedrock Agents hosted in your own AWS account # Agent Phone Integration Source: https://docs.elementum.io/ai-agents/agents-phone-integration Connect agents to phone numbers for inbound and outbound calls ## Overview Before you connect agents to phone numbers, an Organization Admin must configure a phone provider (**Twilio** or **SIP Trunking**) in **Organization Settings** → **Voice**. See [Set up Phone Integrations for Agents](/administration/set-up-phone-integrations-for-agents). After a provider is in place, Agent Phone Integration lets callers reach an agent by phone and lets automations place outbound calls. Use this order in your app: 1. **Build a voice agent** (the agent must exist before a number can be routed to it). 2. **Configure a phone number in your app** — add a phone service under **App Details**, provision or import the number, and assign the agent. 3. Optionally add **Initiate Call** automations for outbound calls (same process for Twilio and SIP). This page covers building the agent, configuring the app phone number, testing, outbound calls, and caller authentication. *** ## Prerequisites * A phone provider (**Twilio** or **SIP Trunking**) configured in **Organization Settings** → **Voice** by an Organization Admin — see [Set up Phone Integrations for Agents](/administration/set-up-phone-integrations-for-agents) * An agent in your app, or a plan to create one under [Build a voice agent](#build-a-voice-agent) before you assign a phone number * Optional: an existing number to import (Twilio number, or a number on your SIP trunk) instead of platform provisioning The app hosting your phone-enabled agent must not have its **Status** field set to **Required**. Inbound calls automatically create records, and this creation fails when a required Status value is enforced. Remove the Required constraint from the Status field before enabling phone services on the app. *** ## Build a voice agent Create and train the agent before you assign a phone number. For general agent creation (instructions, tools, permissions), see [Building Agents](./agents-experience). 1. In your app, click **Intelligence** in the left navigation menu. 2. Create or select the agent that will handle phone calls. 3. Configure phone-specific behavior: * **Training Instructions**: State that this is a phone agent, and keep guidance concise for spoken conversation * **First Message**: Custom greeting if you are not using auto-generation on the phone service * **End Call Training**: Instructions for how the agent should end conversations 4. Click **Configure**, set [Voice Properties](#voice-properties) (idle messages, timeouts, model, background sound), and click **Save**. Prefer **GPT-4o Mini** for low-latency voice unless you need another available model. See [Best Practices](#best-practices) for phone agent training guidance. ### Voice Properties Voice Properties control how the agent behaves during phone calls. They appear in **Configure** for any agent used with a phone service. | Setting | Description | | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Idle Message** | Message the agent speaks when the caller has not responded within the idle message timeout period. | | **Idle Message Timeout (seconds)** | How long the agent waits for a response before speaking the idle message. Default is 12 seconds. | | **Inactivity Timeout Message** | Message the agent speaks before ending the call due to prolonged inactivity. | | **Inactivity Timeout (seconds)** | How long the agent waits after the idle message before ending the call. Default is 60 seconds. | | **Unrecognized Phone Number Message** | Message spoken when the caller's phone number cannot be matched to a user in the system. Used when caller access is restricted to known callers. | | **LLM Model** | The AI model that powers the voice conversation. Available options include **GPT-4o Mini** (recommended for low-latency voice) and **Grok 4 Fast Non-Reasoning**. | | **Background Sound** | Turn ambient call background sound on or off. Default is **On**. | Voice Properties only apply when the agent is used through a phone service. ### EndConversation tool Agents have access to an **endConversation** tool for phone interactions. Train the agent to use it when the caller's request is resolved so calls close cleanly. You configure tools while you [build the agent](/ai-agents/agents-experience). Train your agents on when and how to use the endConversation tool. ```text Example Training Instructions theme={null} You are a phone agent. Keep spoken responses short and clear. When you have fully resolved the caller's question or completed the requested task, use the endConversation tool to end the call. Always provide a brief summary of what was accomplished and any next steps before ending the conversation. ``` Use the endConversation tool when: * Support issue has been fully resolved * Caller's question has been completely answered * Required information has been collected * Follow-up actions have been clearly communicated * Caller confirms satisfaction with the resolution *** ## Configure a phone number in your app After you have a voice agent and an Organization Admin has [configured a phone provider](/administration/set-up-phone-integrations-for-agents), add a phone service under **App Details** → **Phone Services**. Each service is a phone number tied to an agent, with language and caller access options. ### Provision a phone number 1. Open your App in Elementum. 2. Click **App Details**. 3. In the **Phone Services** section, add a new service. Choose how the number is sourced: Let Elementum provision a new number through your Twilio integration: 1. Start adding a phone service and select provisioning a new number. 2. Complete the service fields (see [Phone service fields](#phone-service-fields)). Platform provisioning through Twilio creates **US toll-free** numbers. Twilio configuration for the new number is handled automatically when your organization Twilio provider is connected. Use a number you already have (for example, in Twilio) or bring numbers via [SIP Trunking](/administration/set-up-phone-integrations-for-agents#add-a-phone-provider): 1. Start adding a phone service and choose to use an existing number. 2. Enter the number. 3. Complete the remaining service fields (see [Phone service fields](#phone-service-fields)). For Twilio, the number must be available and not in use by other Twilio applications. ### Phone service fields When you add or edit a phone service, set: * **Number Type**: New number (platform-provisioned) or existing number * **Area Code**: Geographic area code when provisioning a new number (where applicable) * **Phone Provider**: Your organization's configured provider (**Twilio** or **SIP Trunking**) * **Agent**: The agent that handles calls on this service (must already exist) * **Default Language**: Primary language for calls on this service * **Additional Supported Languages**: Optional extra languages beyond the default. See [Supported Languages](#supported-languages). Enabling many languages may reduce performance. Select the LLM for the voice agent on the phone service if shown. Options match [Voice Properties](#voice-properties) (**GPT-4o Mini** and **Grok 4 Fast Non-Reasoning**). Models use platform-level configuration; custom credentials are not configured here. When enabled, the platform generates an initial greeting the agent speaks when a call connects. You can also set a custom first message on the agent instead. Click **Save** when finished. ### Configure caller access Control who can interact with your voice agent by setting caller access on each phone service. Open **App Details**, click **Edit** next to the phone service you want to configure, and select a **Caller Access** option: * **Open**: Any caller can reach the agent (default). * **Known Callers Only**: Only callers whose phone number matches a number listed in your organization's user profiles can connect. * **Known Caller with PIN Verification**: Callers must enter a PIN at the beginning of the call. Users set their PIN in **User Settings** → **Security** → **Phone Authentication PIN**. See [Phone Authentication PIN](#phone-authentication-pin). * **Employee ID with OTP Authentication**: Any caller can reach the agent without a pre-registered phone number. The caller provides their employee ID, receives a one-time password by email, and speaks or types the OTP to authenticate. See [Employee ID with OTP Authentication](#employee-id-with-otp-authentication). Click **Save**. For **Known Callers Only** and **Known Caller with PIN Verification**, make sure phone numbers are added to personal user profiles within User Settings. See [Profile](/administration/profile). ### Manage phone services From **App Details** → **Phone Services**: See provisioned numbers, which agent is assigned, service status, and call activity or logs. Open the service you want to change, update the fields above (including voice model or first-message options if shown), then click **Save**. Remove a service from the list when you no longer need it. Confirm if prompted. Removing a service in Elementum does not release the number from your Twilio account. Release numbers in Twilio if needed. Organization Admins can also review numbers and mappings across apps in [Set up Phone Integrations for Agents](/administration/set-up-phone-integrations-for-agents#organization-voice-management). *** ## Test your phone integration 1. Dial your provisioned phone number. 2. Confirm the call connects and the agent responds. 3. Interact with the agent to verify it follows training instructions. 4. Review call logs in your app to confirm data is captured correctly. ### Troubleshooting * Verify the phone provider is active in [Set up Phone Integrations for Agents](/administration/set-up-phone-integrations-for-agents) * Check that the phone number is properly registered on the phone service * For Twilio, ensure your Twilio account has sufficient credits * Confirm the app's **Status** field is not set to **Required** — phone calls create records automatically, and a required Status field blocks that creation * Verify the agent is properly configured and active * Check that the LLM model is available * Review training instructions for phone-specific guidance * Reduce **Additional Supported Languages** if not needed * Review agent training to keep responses concise and tools fast * Check Twilio or SIP provider service status * For SIP, choose a nearer [ingress region](/administration/set-up-phone-integrations-for-agents#multi-region-sip-domains) * Some locales may require firewall configuration on your network or carrier side * Use [E.164](https://www.twilio.com/docs/glossary/what-e164) format for destination numbers (for example, `+15551234567`), especially for international calls * When reporting problems with international calls, include the locale and destination country * Confirm the phone service and agent are configured and the provider supports the destination region *** ## Voice call handoff Voice agents on **SIP-based phone numbers** can transfer a live call to a human or another destination without dropping the caller. SIP-based numbers are customer-provided and connected through the SIP protocol. Add a **Handoff** tool to the voice agent when you need to escalate a call—for example, routing a support caller to a human agent. The **Handoff** tool uses the same **Tool Name**, **Tool Description**, and **Tool Start Message** fields as other agent tools. The agent decides when to invoke the handoff based on the conversation. 1. Open the voice agent under **Intelligence** in your app. 2. Click **Configure**. 3. Click **+ Tool** in the **Tools** section and select **Handoff**. 4. Enter the tool name, description, and start message. 5. Set the **Destination** to the SIP URI where the call should be transferred. 6. Optionally set the **Context Key Header Name** for a warm transfer. The agent can pass call context in this header, and you can customize the header name to match what your SIP system expects. 7. Add **Headers** as needed. Combine **dynamic** headers the agent supplies at runtime with **static** headers you define on the tool. 8. Save the tool and deploy the agent on a SIP-based phone service. When the agent escalates a call, Elementum passes the configured header information, signals the transfer, and redirects the caller to the SIP destination—typically a human agent or another location in your telephony system. SIP Trunking must be configured in **Organization Settings** → **Voice** before you can use SIP-based phone numbers and handoff destinations. See [Set up Phone Integrations for Agents](/administration/set-up-phone-integrations-for-agents). *** ## Outbound calls and workflows Use the **Initiate Call** automation action to place outbound calls from a configured agent and phone service. The same outbound setup applies whether you use Twilio or SIP Trunking. The action is fire-and-forget: the workflow continues without waiting for the call to finish. Use the **Agent Conversation Ended** trigger in a separate automation to act on outcomes, and prefer post-call automations for heavy processing so the live call stays low latency. Outbound calling to China is not supported by default. To place China outbound calls, use a China-compliant telephony provider connected through [SIP Trunking](/administration/set-up-phone-integrations-for-agents#add-a-phone-provider); that provider relationship is managed entirely by your organization. ### How it works 1. An automation reaches an **Initiate Call** action. 2. The system starts a phone call to the specified number asynchronously. 3. The configured agent handles the conversation while the workflow continues. 4. A separate automation with **Agent Conversation Ended** can process results. ### Configure the Initiate Call action **Required:** * **Action Name** — Identifies the action in the workflow * **AI Agent** — Agent that conducts the call (must be trained for phone) * **Phone Service** — Phone service/number used to place the call * **Phone Number to Call** — Recipient number in E.164 format when possible (record field, previous task output, or static value such as `+15551234567`) * **Default Language** — Primary language for the call **Optional:** * **Related Record** — Associates the call with a record for context and record keeping * **Additional Context** — Instructions for the agent (for example, ticket number or callback reason). Keep this focused; large context increases latency. Common automation triggers for outbound calls include record created or updated, scheduled events, approval completed, and time-based follow-ups. You cannot reference call outcomes in the same workflow as **Initiate Call**. Create a separate automation with **Agent Conversation Ended**. Example outcome automation: ```text theme={null} TRIGGER: Agent Conversation Ended → IF conversation.type = "Voice" → Post Comment (on related record) → Comment: "Call completed: {{conversation.summary}}" → IF conversation contains "needs follow-up" → Create Record (Follow-up Task) ``` ### Call data and transcripts When a phone call is received or initiated, a record is created in your app with: * Phone number (caller or recipient) * Call start time * Call duration * Call direction (inbound or outbound) * Agent assigned to the call Call recordings are not available. Open the call record and use **Chat/Conversation** to view the **Voice** conversation type, direction, and full transcript. ### Agent Conversation Ended Use the **Agent Conversation Ended** trigger to process outcomes for inbound and outbound calls. The trigger provides the transcript, duration and metadata, call direction, and resolution status. Common follow-ups include posting a summary on the related record, creating tasks, sending notifications, or building call metrics (volume by direction, resolution rates, and similar). For building automations, see [Automations](/workflows/automation-system#building-your-first-automation). ### Outbound training tips Train outbound agents to introduce themselves, state the purpose of the call, confirm they have the right person, then complete the objective. Pass only the context needed for that call, respect time zones and calling hours, and use **Agent Conversation Ended** for no-answers and follow-ups. ```text Example Outbound Agent Instructions theme={null} You are a phone agent making an outbound call. Start by: 1. Introducing yourself and the company 2. Stating the purpose of your call clearly 3. Confirming you're speaking with the right person 4. Proceeding with the conversation objective Keep the call focused and respect the customer's time. If they're unavailable, offer to call back at a better time or provide alternative contact methods. Use the endConversation tool when you've completed the call objective or if the customer requests to end the call. ``` *** ## Supported Languages Set **Default Language** on each phone service. Use **Additional Supported Languages** when you need more than one language on that service. Enabling additional languages can reduce performance; enable only if your use case requires it. ### Available Languages * Arabic * Chinese (Mandarin) — Simplified and Traditional * Chinese (Cantonese) — Traditional * Dutch * English * French * German * Hindi * Hungarian * Indonesian * Italian * Japanese * Korean * Portuguese * Russian * Spanish * Thai * Turkish * Vietnamese When using multiple languages, test thoroughly, monitor call quality and response times, and prefer single-language mode when possible. *** ## Security and caller authentication Caller access settings restrict who can interact with your voice agent. Configure these on each phone service in **App Details**. See [Configure caller access](#configure-caller-access). ### Run As Current User When an agent is configured with **Run As Current User** permissions, the agent operates with the same data access and permissions as the caller. For this to work with voice agents, callers must have a phone number added to their personal user profile within User Settings so the platform can identify them. If a caller's phone number is not listed in their user profile, the platform cannot match the caller to a user and the call will not authenticate. ### Phone Authentication PIN Users who call an agent configured with **Known Caller with PIN Verification** must enter a PIN at the start of the call. To set up a PIN: 1. Go to **User Settings** → **Security**. 2. Set a **Phone Authentication PIN**. See also [Profile](/administration/profile). Admins can guide users to this setting when enabling PIN-protected phone services. ### Employee ID with OTP Authentication **Employee ID with OTP Authentication** opens a voice agent to any employee calling from any phone, without a pre-registered phone number, using two-factor verification: the caller's employee ID plus a one-time password (OTP) delivered by email. An admin selects **Employee ID w/ OTP** as the caller authentication type on the phone service (see [Configure caller access](#configure-caller-access)). When a caller reaches the agent: 1. The caller provides their employee ID. 2. Elementum emails a one-time password to the address on that employee's profile. 3. The caller speaks or types the OTP to the agent to authenticate. Because callers authenticate by employee ID rather than a recognized phone number, employees can reach the agent from any phone while still passing secure verification. ### Data protection and compliance * All phone conversations are processed according to your data retention policies * Sensitive information handling follows your organization's security guidelines * Call content is available as transcripts on the call record; call recordings are not available (see [Call data and transcripts](#call-data-and-transcripts)) * Ensure your phone interactions comply with local regulations * Consider consent requirements for call data and transcripts * Review data processing agreements with Twilio or your SIP provider * For China outbound limitations, see [Outbound calls and workflows](#outbound-calls-and-workflows) *** ## Best Practices * **Say it is a phone agent**: State in training that the agent is speaking on a phone call * **Be Concise**: Keep instructions and spoken responses short; large context and long tool outputs hit limits faster on voice * **Confirm Information**: Always repeat back important details * **Use Verbal Cues**: Include phrases like "Let me help you with that" or "I understand" * **Provide Clear Next Steps**: End calls with specific action items * **Phone-specific training**: Keep phone training separate from chat training when the agent is used in both channels * **Use endConversation**: Train agents to close calls with the endConversation tool when resolution is complete * **Prefer GPT-4o Mini** for voice unless you need another available model * **Fast tools only**: Use tools sparingly during the call and favor low-latency actions * **Post-call processing**: Avoid long-running work during the live call; use **Agent Conversation Ended** * **Single Language**: Prefer one language on the phone service unless multilingual support is essential * **Regular Review**: Check call logs and agent performance regularly * **Update Training**: Refine agent training based on call outcomes * **Two cost lines**: Telephony (Twilio or SIP) and model/LLM usage are separate * **Provider Management**: Monitor your Twilio or SIP provider usage and billing * **Backup Numbers**: Consider backup phone numbers for high-availability scenarios # Agent Skills Source: https://docs.elementum.io/ai-agents/agents-skills Create and manage modular, reusable Skills that agents discover and execute at runtime ## What Are Skills? Skills are reusable capability modules that agents can discover and run at runtime. Each Skill has a name, description, prompt instructions, and one or more configured tools. Instead of wiring every tool into each agent manually, you build Skills once in the Skills Directory; agents then find and use them dynamically based on context. *** ## When to Use Skills vs Tools Agents can take action through both [tools](./agents-tools-and-deployment#configure-agent-tools) and Skills. The right choice depends on how tightly coupled the capability is to a single agent versus how broadly it needs to be shared. | Consideration | Tools | Skills | | --------------- | ------------------------------------------------- | -------------------------------------------------------------- | | **Scope** | Configured directly on one agent | Created once in the Skills Directory, available to many agents | | **Setup** | Admin adds and configures each tool on the agent | Admin builds the Skill once; agents discover it at runtime | | **Reusability** | Must be recreated on every agent that needs it | Shared across any agent with Skills enabled | | **Maintenance** | Update each agent individually when logic changes | Update the Skill once and all agents pick up the change | | **Best for** | Capabilities specific to a single agent's purpose | Common capabilities used across multiple agents or apps | Start with tools when an agent needs a one-off capability. Promote a tool to a Skill when you find yourself configuring the same automation on multiple agents. *** ## Create a Skill App admins create and manage Skills under **Intelligence → Skills**. 1. Open **Intelligence** in your app. 2. Click the **Skills** tab at the top of the page. 3. Enter a name, description, prompt instructions, and one or more tools. 4. Click **Create Skill**. **Skill fields:** * **Name** and **Description** — How the Skill is identified and when it should be used * **Prompt instructions** — Instructions the agent follows when executing the Skill * **Tools** — One or more tools that implement the Skill's behavior. Skills support the same tool types as agents: Run Automation, Create Record, Update Record, Search Records, AI Search, and Run Agent. Configuring tools on a Skill follows the same workflow as configuring tools on an agent — for field-by-field setup steps for each tool type, see [Configure Agent Tools](./agents-tools-and-deployment#configure-agent-tools). Skills that use Create Record, Update Record, Search Records, AI Search, or Run Agent run natively in Elementum — you don't need to build a separate automation to wrap them. Use **Run Automation** when you want the Skill to trigger an existing On-Demand automation. **Lifecycle status:** | Status | Behavior | | ------------ | ------------------------------------------------- | | **Draft** | Not available to agents; use for work-in-progress | | **Active** | Available to agents when Skills are enabled | | **Disabled** | Temporarily hidden from agents; can be re-enabled | Only **Active** Skills appear when agents search or use Skills at runtime. **Draft** Skills never appear in search. *** ## Custom Inputs and Outputs on Automation Tools Automation-type Skill tools support custom inputs and outputs, the same interface controls already available on agent automation tools. When you define custom inputs, the agent uses them as its interface for the tool; tools without custom inputs continue to behave as before. App Administrators configure custom inputs and outputs from the tool details on a Skill. 1. Open **Intelligence → Skills** in your app and select the Skill. 2. On an automation-type tool in the **Tools** tile, click the More icon **More** icon to open the tool details. 3. Under **Configuration**, select the **App** and the **Automation** the tool runs. 4. Under **Inputs**, choose which automation parameters the AI can fill. For each input, set the **Name for AI**, enter a **Description for AI**, and toggle **Required** as needed. Leave the section empty to expose all parameters. 5. Under **Outputs**, choose which automation outputs the AI can read. For each output, set the **Name for AI**. Leave the section empty to expose all outputs. 6. Save the tool. **Behavior notes:** * When custom inputs are configured, the agent uses them as its interface for the tool. Tools without custom inputs continue to behave as before. * Leaving **Inputs** or **Outputs** empty exposes all of the automation's parameters or outputs to the AI. * A **Name for AI** accepts letters, numbers, and underscores only; spaces are converted to underscores. *** ## Skill Tool Execution Permissions Skill tools support execution permissions so each tool can run under a distinct identity, matching the permission behavior already available on agent tools. Set a permission per tool to control which identity the tool runs as. App Administrators configure execution permissions from the tool details on a Skill. 1. Open **Intelligence → Skills** in your app. 2. Click on a Skill. 3. Within the **Tools** section, click the More icon **More** icon on the tool you want to configure. 4. Select **Edit Skill Tool**. 5. In the permissions section, select the desired setting: * **Agent default** * **Run as publisher** * **Run as current user** * **Run as service account** 6. Save your changes. **Behavior notes:** * New Skill tools default to **Agent default**, and existing Skill tools continue working unchanged. * Each tool can run under a distinct identity, matching the permission behavior already available on agent tools. *** ## Configure Access Policies Access policies control which users can have a Skill discovered for them at runtime. When a user interacts with an agent, the agent only sees Skills the user is authorized to use. 1. Open **Intelligence → Skills** and select the Skill. 2. Open the **Access Policy** section. 3. Add the users or groups that should be able to access the Skill. 4. Save your changes. **Behavior notes:** * If no access policies are configured, the Skill is available to every user in your organization. * Access policies are evaluated per user at runtime, so the same agent may discover different Skills for different users. *** ## Tune Skill Discovery Discovery properties tell an agent when a Skill is the right fit for a request. The agent combines all configured properties into a weighted score and ranks candidate Skills, so well-tuned Skills surface ahead of weaker matches as your catalog grows. 1. Open **Intelligence → Skills** and select the Skill. Use the status filter at the top of the page to narrow the list to **Draft**, **Active**, or **Disabled** Skills. 2. Open the **Discovery** section. 3. Configure any of the following properties: * **Routing Priority** — Increase the weight of this Skill when multiple Skills could apply to the same request. * **Aliases** — Add alternate names the agent should recognize for this Skill. * **Example Utterances** — Add sample phrases a user might say when this Skill should be selected. * **Positive Keywords** — Add words and phrases that should make the Skill more likely to be discovered. * **Negative Keywords** — Add words and phrases that should make the Skill less likely to be discovered. 4. Save your changes. Small tuning changes can shift which Skill wins for a given request. Adjust one property at a time and re-test so you can see the impact. ### Test a Skill Test how an agent ranks Skills against a sample request before exposing the Skill to users. 1. On the Skill page, click **Test Skills** in the top-right corner. 2. Enter a **Query** that represents what a user might ask. 3. Select the **Agent** to test against. 4. Optionally select one or more **Users** so the test honors the Skill's access policy for those users. 5. Click **Run Query** to see which Skills are returned and how they are ranked. Use the test results to refine the discovery properties or access policy until the right Skill consistently surfaces for the right users. *** ## Add Skills to an Agent 1. In **Intelligence**, select an agent. 2. Click **Configure**. 3. Choose the Skills you'd like the agent to have access to (including **All App Skills**). 4. Click **Save**. If you know an agent will always need a specific Skill, add up to 3 preloaded Skills the agent can access immediately — skipping the runtime search step. The **Skill Access** setting controls the agent's access level: | Mode | Behavior | | ------------ | --------------------------------------------------------------------------------------- | | **None** | Agent has no Skills (default for new agents) | | **All** | Agent can discover and use all active Skills in the agent's own app | | **Selected** | Admin picks specific Skills from a checkbox table within the agent's own app | | **Custom** | Admin picks specific Skills from any app in the organization, including the agent's own | In **Selected** mode, use the checkbox table to choose exactly which Skills the agent can use. This gives fine-grained control when you have many Skills but want each agent to use only a subset. ### Share Skills Across Apps Use **Custom** access when you want an agent to use Skills that live in other apps. Build a Skill once in the app that owns the data or process, then make it available to agents elsewhere in your organization without duplicating configuration. To configure cross-app Skills: 1. Open the agent and click **Configure**. 2. Expand the **Skill Access** section. 3. Under **Access Mode**, select **Custom** and click the settings icon to edit the **Custom skills available** list. 4. Search for and select active Skills from any app in your organization. 5. Click **Done**, then click **Save**. **Behavior notes:** * Agents discover and execute cross-app Skills the same way they use local Skills — no additional setup is required at runtime. * Only **Active** Skills surface in the Custom picker; **Draft** and **Disabled** Skills are excluded. * When an agent is deployed, the apps that provide its configured Skills are automatically included in the deployment so the Skills remain accessible. *** ## Runtime Behavior When Skills are enabled (any mode other than **None**), the agent automatically receives discovery tools — no manual tool setup is required. At runtime, the agent uses Skills in three steps: 1. **Search** — The agent calls the Skill search tool to find Skills relevant to the user's request. 2. **Details** — For a chosen Skill, the agent retrieves the name, description, instructions, and configured tools. 3. **Execute** — The agent runs the Skill's behavior by invoking its configured tools. Create Record, Update Record, Search Records, AI Search, and Run Agent tools execute natively in Elementum; Run Automation tools trigger the linked On-Demand automation. *** ## Operational Notes * Only **Active** Skills surface at runtime; **Disabled** Skills do not. * New agents default to **None**; enable Skills explicitly if you want the agent to use them. * After changing a Skill's status or an agent's **Enabled Skills** mode, allow a moment for the agent to see the updated set. *** ## Troubleshooting If an agent isn't using the Skill you expect, work through the checks below. ### Confirm the Skill is Active Skills must be **Active** to surface at runtime. Open **Intelligence → Skills** and confirm the Skill's status reads **Active**. If it doesn't, select the Skill and click **Activate** in the top right corner. ### Make the Name and Description Discoverable Agents discover Skills by searching the name and description. If either is too generic, the agent may not find the Skill — or it may pick up the wrong one. Use specific, task-oriented wording that reflects when the Skill should be used. ### Review the Conversation History Open the agent's conversation history and check what happened during the request: * **Is the agent trying to discover Skills at all?** If the agent answers without searching, it may not realize a Skill is relevant. Adjust the agent's prompt to point it toward the Skills Directory for the kind of request you're testing. * **Is the agent running the Discover Skills tool?** If the tool isn't being called, prompt the agent differently so it knows to search for an existing Skill before attempting to act on its own. * **Are the wrong Skills coming back?** Look at the query the agent used to search. Either refine the Skill's name and description to better match how the agent phrases the request, or update the agent's instructions to guide it toward better search queries. *** ## Related Documentation * [Agent tools, deployment, and integrations](./agents-tools-and-deployment) — Tools reference, deployment, and external agents; includes how Skills fit into agent tools * [Building Agents](./agents-experience) — Create and configure agents, including tools and channels # Agent Slack Integration Source: https://docs.elementum.io/ai-agents/agents-slack-integration Deploy your conversational AI agents directly in Slack channels for intelligent team collaboration ## Overview Agent Slack Integration lets conversational agents work in Slack channels. Messages are handled in Slack, and conversation data is tracked in your Elementum app where you configure permissions and workflows. Slack is configured **per channel**, with a different agent per channel if you want. The Microsoft Teams integration instead uses one-on-one conversations and a single agent configuration. *** ## Prerequisites Organization admin access is required for the initial Slack app installation. Ensure you have proper permissions before starting. You also need: * **Active agent:** At least one agent in your app, with training appropriate for the channel * **Slack access:** Ability to install or request apps in your workspace (see your workspace’s app policies) * **Channel access:** Permission to add apps to the channels where the agent should run *** ## Setting Up Slack Integration Begin by adding the Elementum AI app to your Slack workspace through the official Slack App Directory. If you need help with Slack app installation permissions or approval flow, see [Add apps to your Slack workspace](https://slack.com/help/articles/202035138-Add-apps-to-your-Slack-workspace). **Installation Process:** 1. Click **Add to Slack** to install the Elementum app 2. Review the permissions the app is requesting 3. Click **Allow** to proceed with the installation The Elementum app requires standard permissions to read messages, post responses, and manage threaded conversations. These permissions are necessary for the agent to function properly within your Slack channels. After you install the app in Slack, you are redirected to Elementum to link the workspace to an organization. **Organization selection** 1. On the Elementum setup page, select the organization to associate with this Slack installation. 2. Click **Complete Installation**. 3. Wait for the **Installation Successful** confirmation. The organization you select determines which app data and agents are available when you configure channels. To confirm the installation: in Slack, open **Apps** and verify **Elementum Intelligence** is listed. In Elementum, verify the integration appears as installed for the correct organization. After installing the Elementum app, add it to the specific channel where you want the agent to operate. **How to Add:** **Option A: Using /invite command** 1. Type: `/invite @Elementum Intelligence` 2. Press Enter to add the bot to the channel **Option B: Using @ mention** 1. Simply mention the Elementum bot (`@Elementum Intelligence`) in a message 2. The app will automatically be added to the channel **Option C: Through channel settings** 1. Click the channel name at the top of the channel 2. Click the **More** icon, then select **Open channel details** 3. Select **Integrations** → **Add an app** 4. Search for and select the Elementum app you installed Wait for confirmation that the Elementum bot has joined the channel before proceeding. In the channel where the agent should run, type `/elementum setup` and press Enter. The configuration dialog opens. The following steps mirror the sections in the dialog: Agent Selection, Conversation Settings, then Channel Messages. **Select an app to configure for this channel:** * Choose the Elementum app that contains the agent you want to use * This determines which app environment the agent operates within **Choose an agent** * Select the specific agent that will respond to messages in this channel * Different channels can use different agents based on their purpose Continue in the dialog to **Conversation Settings** when you are ready. **Select conversation timeout:** * Choose how long conversations remain active before automatically expiring * Options range from minutes to hours depending on your needs * Helps manage agent workflows and conversation context **Include timeout reminder messages:** * Enable to send users warnings before conversations expire * Provides better user experience by setting clear expectations **Interaction Options:** * **Quick Answers:** Brief, direct responses to questions without creating app records. * **Full Conversations:** Multi-turn conversations with full context. Creates an app record to store the conversation and maintain workflow state across interactions. Continue in the dialog to **Channel Messages** when you are ready. **Channel message handling** controls how the agent responds to messages: **Behavior:** Agent responds to every message posted in the channel **Best for:** * Dedicated agent support channels * Low-traffic channels where agent participation is expected * Channels specifically created for agent interactions **Considerations:** May be overwhelming in high-traffic channels **Behavior:** Agent only responds to messages containing a '?' question mark **Examples:** * **Responds:** "What is our current inventory status?" * **Does not respond:** "Please update the inventory report" **Best for:** * General team channels where selective agent participation is desired * Channels with mixed conversation types * On-demand agent assistance **Considerations:** Users must explicitly ask questions for agent engagement **Behavior:** Agent only responds when it has high confidence in providing accurate answers **Best for:** * Channels requiring high accuracy standards * Reducing agent noise in busy channels * Ensuring quality over quantity of responses **Considerations:** Some valid questions may not receive responses if confidence is below threshold **Behavior:** Agent is present in the channel but does not respond to any messages **Best for:** * Temporarily disabling the agent without removing it * Testing other configuration options * Maintaining agent presence while troubleshooting **Note:** Alternatively, you can remove the bot from the channel entirely with `/remove @Elementum Intelligence` 1. Review all settings in the dialog (Agent Selection, Conversation Settings, and Channel Messages). 2. Click **Next** to finalize the agent setup 3. Wait for confirmation that the agent has been successfully configured *** ## Using Slack Integration ### Channel-Based Agent Deployment Each channel has its own agent, timeout, and **Channel messages** behavior. Match agent training to the channel’s purpose (for example, support vs. general questions). Example combinations appear in [Managing multiple channel configurations](#managing-multiple-channel-configurations). ### Starting Conversations **For end users:** 1. Open the channel where the Elementum agent is present. 2. Post according to the channel’s **Channel messages** setting (any message, questions with `?`, or other rules you configured). 3. The agent replies in the channel or a thread; context lasts for the active conversation. In **Full Conversations** mode, the user’s Slack identity is associated with the conversation record in your app. ### Conversation Management **Quick Answers** and **Full Conversations** are set in `/elementum setup` in the **Conversation Settings** step (see [Setting up Slack integration](#setting-up-slack-integration)). In short: * **Quick Answers:** Short replies, no app record, no multi-turn state between questions. * **Full Conversations:** App record per conversation, full transcript and context, suitable for automations and follow-up. **Timeouts** close idle conversations after the time you set; optional reminders warn users first. After a timeout, the next message starts a new conversation (new record in Full Conversations mode). *** ## Configuration Best Practices ### Matching Settings to Channel Purpose **Recommended Configuration:** * **Interaction Mode**: Full Conversations * **Channel Messages**: Interact with all messages * **Timeout**: 30-60 minutes for extended support interactions **Rationale:** Users expect comprehensive help and continuous engagement in dedicated support channels. **Recommended Configuration:** * **Interaction Mode**: Quick Answers * **Channel Messages**: Interact with questions only * **Timeout**: 15 minutes **Rationale:** Minimizes agent noise while providing on-demand assistance in busy channels. **Recommended Configuration:** * **Interaction Mode**: Full Conversations * **Channel Messages**: High confidence answers only * **Timeout**: 45 minutes **Rationale:** Ensures accuracy and reduces risk of misinformation in sensitive contexts. **Recommended Configuration:** * **Interaction Mode**: Quick Answers * **Channel Messages**: High confidence answers only * **Timeout**: 10 minutes **Rationale:** Provides quick, accurate answers to common questions without extended conversations. ### Agent Training for Slack Train agents for **public or semi-public channels**: shorter replies, Slack formatting when it helps, threaded replies for long exchanges, and clear guidance to move sensitive topics to DM or email when appropriate. ```text Example Training Instructions theme={null} You are operating in a Slack channel with multiple participants. Keep responses concise and professional. For sensitive information, suggest the user contact you via direct message or email. Always acknowledge other participants' contributions when relevant. ``` ### Conversation Timeout Strategy **Timeout Duration Recommendations:** **10-15 minutes** Simple question/answer interactions **30-45 minutes** Typical support conversations with multiple exchanges **60+ minutes** Technical troubleshooting or detailed consultations In busy channels, prefer shorter timeouts and stricter **Channel messages** settings so conversations do not pile up. *** ## Integration with Workflows ### Automatic Record Creation (Full Conversations Mode) In **Full Conversations** mode, starting a conversation creates an app record that typically holds Slack user details, start time, assigned agent, and channel or thread context. Use that record for review and downstream automations. ### Workflow Triggers Use the **Agent Conversation Ended** trigger in your automations to process Slack conversation outcomes. The trigger exposes the transcript, user details, timing and counts, messages, and channel metadata. **Automation Examples:** * Create follow-up tasks based on unresolved issues * Send summary notifications to relevant team members * Update CRM or support systems with interaction details * Generate analytics reports on agent performance * Route urgent matters to appropriate departments * Trigger approval workflows for agent recommendations ### Viewing Slack Conversations After a Slack conversation ends (in Full Conversations mode), you can view the complete interaction: **Conversation Interface:** 1. Navigate to the automatically created record in your app 2. Access the **Chat/Conversation** interface in record details 3. View the conversation marked as a **Slack** conversation type 4. Review complete transcript with timestamps and participant details 5. See channel context and threading information *** ## Managing Multiple Channel Configurations ### Channel-Specific Agent Strategy Pilot in low-traffic or internal channels before wider rollout. **Strategic Agent Deployment:** * **Specialized Agents**: Deploy domain-specific agents to relevant channels * **Consistent Agents**: Use the same agent across related channels for consistency * **Hybrid Approach**: Mix specialized and general-purpose agents based on needs **Example Multi-Channel Setup:** | Channel | Agent | Mode | Interaction | | ------------------ | ----------------- | ------------------ | -------------------- | | #customer-support | Support Agent | Full Conversations | All messages | | #product-questions | Product Expert | Quick Answers | Questions only | | #general | General Assistant | Quick Answers | High confidence only | | #engineering | Technical Agent | Full Conversations | Questions only | | #sales | Sales Assistant | Full Conversations | All messages | ### Reconfiguring Channels To modify agent configuration for a channel: 1. Navigate to the channel where the agent is configured 2. Type `/elementum setup` to open the configuration dialog 3. Update any settings (agent selection, timeout, interaction mode) 4. Click **Next** to save the new configuration 5. The agent immediately adopts the new settings Configuration changes take effect immediately without needing to remove or re-add the bot to the channel. ### Monitoring Channel Performance * **Response Rate**: How often the agent responds to messages * **Conversation Duration**: Average length of agent conversations * **User Satisfaction**: Feedback on agent helpfulness * **Channel Activity**: Volume of messages and agent interactions * **Timeout Frequency**: How often conversations expire before natural completion * Adjust interaction mode if response rate is too high or too low * Modify timeouts based on average conversation duration * Refine agent training based on user feedback * Change confidence thresholds based on response quality *** ## Troubleshooting ### Common Issues * Verify the agent is properly configured using `/elementum setup` * Check interaction mode settings (agent may be set to **Do not interact**) * For **Questions only** mode, ensure messages include `?` question marks * Confirm the agent is active and functioning in your Elementum app * Verify the bot has been added to the channel successfully * Review the **Channel messages** setting and adjust interaction mode * Consider switching from **All messages** to **Questions only** or **High confidence only** * Refine agent training to better identify relevant questions * Check if multiple agents are configured in the same channel (may cause conflicts) * Verify you're using **Full Conversations** mode (Quick Answers doesn't create records) * Check that the target app is active and accessible * Ensure proper permissions for record creation * Review field mappings and data capture configuration * If conversations expire too quickly, increase timeout duration * If timeouts are too long, reduce duration to better match actual usage * Enable timeout reminder messages to improve user experience * Monitor actual conversation patterns to optimize timeout settings * Ensure you have proper permissions to configure the channel * Verify the selected app and agent are valid and active * Check that all required fields are completed * Try removing and re-adding the bot to the channel if issues persist ### Performance Optimization * Use **Questions only** or **High confidence only** interaction modes * Implement shorter conversation timeouts (10-15 minutes) * Consider Quick Answers mode to reduce overhead * Monitor agent load and adjust configuration as needed * Switch to **All messages** or **Questions only** mode to increase engagement * Reduce confidence threshold if using high confidence mode * Review agent training to improve question detection * Adjust timeout to match actual interaction patterns See [Agent Training for Slack](#agent-training-for-slack). Tune prompts for channel noise, when to stay silent, and when to escalate to a person. *** ## Security and Compliance * **User Information**: Slack user data is handled according to your data retention policies * **Conversation Storage**: All interactions are stored securely within your Elementum environment * **Access Control**: Conversations are only accessible to authorized users within your organization * **Channel Privacy**: Agents respect Slack channel privacy settings (public vs private channels) * **Organization Control**: Aligns with who can install apps in your workspace (see [Prerequisites](#prerequisites)) * **User Permissions**: Follows your organization's Slack app installation policies * **Data Residency**: Conversations remain within your configured data boundaries * **Channel Permissions**: Agents only access channels they're explicitly added to * All agent interactions are logged and auditable * Conversation transcripts available for compliance review * Agent responses can be configured to meet regulatory requirements * Configure retention policies for conversation records * Archive or delete conversations according to company policies * Export conversation data for compliance reporting *** ## File Attachment Support File attachment support for Slack agents is available on the Enterprise track. Slack users can attach files to messages the same way as any Slack message. Agents on **multimodal-capable models** can use the attachment content in their reply; other agents still receive the message text but do not interpret the file. *** ## See Also Slack-side install and approval behavior # Agent Starting Actions Source: https://docs.elementum.io/ai-agents/agents-starting-actions Configure clickable action chips that greet users and kick off common tasks without typing ## What Are Starting Actions? Starting Actions are pre-configured prompt chips that appear in the chat UI **before the user sends their first message**. They sit below the agent’s greeting and let users start common tasks with one click instead of typing. Admins define each action with a name, icon, prompt template, and optional variables. *** ## Where They Appear Starting Actions render as clickable chips in the agent chat interface, directly under the agent’s opening message. After the user sends their first message, the chips are no longer shown for that conversation. *** ## Create Starting Actions 1. In **Intelligence**, select the agent. 2. Click **Configure**. 3. Click **+ Add Starting Action** in the Starting Actions section. 4. Add an icon, name, and prompt template. Use `{{variableName}}` placeholders for any inputs you want to collect from users. 5. Configure each detected variable. In the **Detected Variables** section, click a variable chip to open its **Configure Variable** dialog. See [Configure Detected Variables](#configure-detected-variables) below for the available settings. 6. The action is automatically enabled. Toggle it off if you want to wait before enabling it for users. 7. Click **Add Starting Action**. **Per-action settings:** * **Name** – Label shown on the chip * **Icon** – Icon for the chip * **Prompt template** – The text sent when the user clicks the action; can include `{{variableName}}` placeholders * **Enabled** – Toggle to show or hide the action * **Display order** – Order of chips; reorder via drag-and-drop Actions can be reordered with drag-and-drop and individually enabled or disabled. ### Configure Detected Variables Every `{{variableName}}` placeholder in the prompt template is auto-detected and listed under **Detected Variables**. Each variable must be configured before the Starting Action can collect input from users. Click a variable chip to open its **Configure Variable** dialog, set the following, then click **Save**: * **Display Label** – The label shown to users when filling in the variable. * **Placeholder Text** – Hint text shown inside the input field. * **Input Type** – How users enter the value: **Text**, **Number**, or **Select from Options** (dropdown). * **Required** – Toggle on to require a value before the form can be submitted. * **Options** (Select from Options only) – Add each dropdown choice as a value/label pair. Options are static and entered manually. Variable settings — particularly **Select from Options** lists — must be updated manually. They are not populated dynamically from Element field values or other underlying data. When the source data changes (for example, when new records are added to a referenced Element), edit the Starting Action and update the affected variable's options to match. *** ## Variable Support Use **`{{variableName}}`** in the prompt template to collect input before sending. * Placeholders are **auto-detected** from the template and can be configured individually. * **Variable types** — Text, Number, and Dropdown are supported. * **Validation** — Optional rules such as pattern, min/max length, and custom error messages. Actions without variables send the prompt immediately when clicked. Actions with variables display an inline form to collect values before sending. *** ## Runtime Behavior | Action type | Behavior | | ------------------ | ------------------------------------------------------------------------------------------------------------------ | | **No variables** | Clicking the chip sends the prompt immediately. | | **With variables** | Clicking the chip expands an inline form; after the user fills it, the prompt is sent with the values substituted. | Chips disappear after the user sends their first message (whether from a Starting Action or by typing). *** ## Related Documentation * [Building Agents](./agents-experience) – Agent creation, configuration, and chat experience, including Starting Actions in the UI # Agent Microsoft Teams Integration Source: https://docs.elementum.io/ai-agents/agents-teams-integration Run conversational agents in Microsoft Teams with conversations tracked in your Elementum app ## Overview Conversational agents can interact with users in Microsoft Teams. Messages stay in Teams; conversation data is stored and managed in your Elementum app according to your routes and permissions. Teams conversations are **one-to-one** with the bot (not channel-based). You configure **routes** in Organization Settings to choose which app and agent handle Teams chats and how user fields map to records. *** ## Prerequisites Organization admin access is required for the initial Teams app connection. Ensure you have proper permissions before starting. You need: * **Organization admin access** — to connect the Elementum Teams app to Microsoft Teams * **Active agent** — at least one agent in your app with training appropriate for Teams * **Microsoft Teams access** — permission to install or use apps in your tenant, per your organization’s policies *** ## Permissions & Data Access The Elementum Intelligence Teams app requests **minimal permissions** so the bot can chat with users and connect to Elementum. ### Required Permissions **What it means:** The app can be used in 1:1 chats with individual users **Why we need it:** To provide direct assistance to team members **What we DON'T access:** Team channels, group chats, or organization-wide data **What it means:** The app can send notifications to users' devices **Why we need it:** To deliver responses and updates **Your control:** Users can manage notification settings in Teams **What it means:** When you interact with the bot, we receive: * Your display name * Your Teams user ID * Your email address * Your organization's tenant ID **Why we need it:** To identify you and connect your Teams identity to your Elementum account **Note:** This is automatic—Microsoft Teams provides this information to all bots **What it means:** The app connects to `*.elementum.io` domains **Why we need it:** To communicate with your Elementum backend and return responses **Security:** All connections use encrypted HTTPS ### What We Don't Access The Elementum Teams app does **not** have access to: * Team or channel conversations * Files or documents stored in Teams, OneDrive, or SharePoint (only files a user explicitly attaches to a message in the 1:1 chat are delivered to the agent) * Calendar or email * Call or video data * Contacts beyond the current conversation * Any Microsoft Graph data without explicit authentication *** ## Setting Up Microsoft Teams Integration Install the Elementum Teams app in your Microsoft Teams environment. This step requires uploading a custom app package to Microsoft Teams. Your organization's Teams administrator must have permissions to upload custom apps. **Installation Process:** 1. **Receive App Package**: Your Elementum contact will provide a ZIP file containing the Teams app package 2. **Upload to Microsoft Teams**: Follow Microsoft's documentation to upload the custom app to your Teams environment: * [Upload an app package to Microsoft Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/deploy-and-publish/apps-upload) * You can upload the app for yourself, your team, or your entire organization 3. **App Availability**: Once uploaded, the Elementum bot will be available in your Teams environment 4. **Receive Verification Code**: When you first open the Elementum app in Teams, you will receive a **verification code** as the first message. **Copy this code**—you will need it in the next step. Keep the verification code handy. You'll enter it in Elementum to complete the connection between your Teams environment and Elementum. Organization administrators complete the connection between Elementum and Microsoft Teams using the verification code from the previous step: **How to Access:** 1. Navigate to **Organization Settings** → **Integrations** → **Microsoft Teams** → **Configuration** **Configuration Process:** 1. Select an **AI Service** from the dropdown * This determines which model powers agent responses in Teams * If no AI services are available, use the **AI Services** link to set up a new service first (see [AI Services](/ai-agents/ai-services)) 2. Configure the **Default Conversation Timeout** (e.g., 15 minutes) * This sets how long conversations remain active before automatically closing * After timeout, users receive a warning before the conversation closes 3. Click **Save** to apply the configuration 4. Once saved, the **Verification Code** field will appear 5. Enter the verification code you received in Teams when you installed the app 6. Click **Verify** to validate the connection 7. Once verified, click **Save** to complete the setup 8. Verify the connection status shows as **Active** on the page This step only needs to be completed once per organization by an administrator. Routes determine which agents handle Teams conversations and how user data is captured: **How to Access:** 1. In the Microsoft Teams integration page, locate the **Routes** section 2. Click **Create Route** to open the route configuration dialog Fill in: * **App Selection** — The app that will receive and manage conversations * **Route Name** — A descriptive name (e.g., "Support Team Route") * **Agent Assignment** — The agent that will handle conversations for this route * **Route Responsibility** — Short description of what this route handles (e.g., "Route conversations from Teams") Configure how user information from Teams is captured in your app records: * **Country**: User's country information * **Email**: Teams user email address * **First Name**: User's first name from Teams profile * **Id**: Teams user ID * **Last Name**: User's last name from Teams profile * **Locale**: User's locale/language setting * **Name**: Full display name * **Platform**: Always "Microsoft Teams" * **Timezone**: User's timezone setting 1. **Source Field**: Select which Teams user data to capture 2. **Target Field**: Choose where to store this data in your app 3. **Add Field Mapping**: Click to add additional field mappings as needed 4. Map essential fields like Email, First Name, and Last Name for proper user identification Start with **one route** unless you have a clear need for multiple routes (for example, different apps or agents for different teams). Multiple routes add complexity; the platform works most reliably with a single primary route. **Configuration Steps:** 1. Fill in **Route Name** and **Route Responsibility** 2. Select the **Agent** that will handle Teams conversations 3. Configure field mappings to capture relevant user information 4. Click **Save** to create the route *** ## Using Microsoft Teams Integration ### Starting Conversations After an administrator has installed the app and completed integration setup, users can open the Elementum app in Teams: 1. **Find the App**: Search for "Elementum" in Microsoft Teams apps or your organization's app catalog 2. **Add the App**: Install the Elementum app if it is not already installed 3. **Start Chatting**: Open the app and send a message to begin interacting with your agent 4. Chat as you would with any other Teams contact **During a conversation:** * Messages are processed by the agent assigned on the route * Responses appear in Teams in real time * Context is maintained for the active session * User fields are populated according to your route mappings ### Sending File Attachments Users can share files with the agent directly inside the 1:1 Teams chat — no need to switch over to the Elementum UI to upload them. Attach a file to your message the same way you would in any other Teams conversation (drag and drop, paste, or the attachment button), and the file is delivered to the agent as part of the active conversation. **How it works:** * Attach one or more files to a message in the Elementum bot chat, with or without accompanying message text. * The file is passed to the agent alongside the message and is available for the agent to read and reason over for the rest of the active session. * File attachment support follows the same platform rules as files shared elsewhere in Elementum — including native handling of `.xlsx`, `.docx`, and `.tiff` files. See [Sharing files in a conversation](/ai-agents/agents-interacting#sharing-files-in-a-conversation) for the cross-channel reference. The Elementum bot only receives files you explicitly attach to a message in the chat. It does not have access to files stored elsewhere in Teams, OneDrive, or SharePoint. ### Conversation Behavior and Records When a user starts a conversation in Teams, the system **creates a record** in the app selected on the route, captures mapped user information, associates the conversation with that record, and tracks the interaction for workflows. **Session rules:** * **Single active conversation**: Only one active conversation per user at a time * **Timeout**: Conversations close after the configured timeout; users get a warning before closure * **After timeout**: New messages start a new conversation and new record *** ## Agent Tools for Teams You configure agent tools—including **endConversation**—while you [build and configure the agent](/ai-agents/agents-experience). The behavior below applies to Teams. ### EndConversation Tool Agents can use the **endConversation** tool to close a Teams session when the interaction is complete. **Purpose:** * Allows agents to end conversations when appropriate * Provides clear closure for support-style interactions * Avoids leaving sessions open when no longer needed Train your agents on when and how to use the **endConversation** tool so users are not left in ambiguous session states. ```text Example Training Instructions theme={null} When you have fully resolved the user's question or completed the requested task, use the endConversation tool to close the session. Always provide a brief summary of what was accomplished before ending the conversation. ``` *** ## Managing Teams Integration ### Viewing and Editing Routes In the **Routes** section of the Microsoft Teams integration settings you can see all routes, which agent each route uses, and edit mappings or assignments. Use the **Edit** action (pencil icon) on a route to change configuration, then **Save**. *** ## Integration with Workflows ### Agent Conversation Ended Trigger When a conversation ends (timeout, **endConversation**, or equivalent), you can run automations with the **Agent Conversation Ended** trigger. The trigger exposes data such as the transcript, captured user fields, timing, and agent messages—similar to other agent channels. Use it to create tasks, send email, update records, or call other actions your organization needs. **Add this to an automation:** In your app, open [Automations](/workflows/automation-system#building-your-first-automation) and create an automation whose trigger is **Agent Conversation Ended**. Set **Conversation Type** to **Teams** when you only want Microsoft Teams conversations. For trigger options, variables, and examples, see [**Agent Conversation Ended**](/workflows/automation-triggers-reference#agent-conversation-ended) in the triggers reference. Nothing is sent to Teams automatically when a conversation ends unless **you** add an automation that posts to Teams (for example **Send Message to Teams**). ### Viewing Teams Conversations After a conversation ends: 1. Open the record that was created for the session 2. Use the **Chat/Conversation** area in record details 3. Confirm the conversation type is **Microsoft Teams** and review the transcript and metadata *** ## Troubleshooting * Verify your Teams administrator has uploaded the Elementum app package (ZIP file) to your Teams environment * Ensure users have permission to install apps in Teams * Contact your Teams administrator if app installation is restricted or if the app package has not been uploaded yet * Confirm that you entered the verification code correctly in **Organization Settings** → **Integrations** → **Microsoft Teams** → **Configuration** * The verification code is provided as the first message when you open the Elementum app in Teams * Check that the integration status shows as **Active** in your organization settings * Verify the agent is configured and active * Check that the AI service is available * Review agent training for Teams-appropriate tone and closure behavior * Ensure the route is saved and points at the correct app and agent * Verify source fields map to existing target fields with compatible types * Confirm the target app is accessible to the integration * Verify the route includes the correct app selection * Check that field mappings are saved * Ensure the target app allows record creation for the integration identity * Adjust **Default Conversation Timeout** to match typical interaction length (shorter for high volume, longer for complex support) * Prefer concise, workplace-appropriate replies; train agents when to use **endConversation** *** ## Security and Compliance * **User Information**: Teams user data follows your organization’s retention and access policies in Elementum * **Conversation Storage**: Interactions are stored in your Elementum environment with your usual access controls * **Microsoft Teams**: App installation follows your tenant’s policies; the initial org connection requires an administrator *** ## Best Practices * **Routes**: Prefer one primary route until you need separate apps or agents for different audiences * **Timeouts**: Revisit timeout values after you see real conversation patterns * **Automations**: Use **Agent Conversation Ended** for follow-up work (tasks, notifications, CRM updates)—include a Teams notification only where it helps your process * **Training**: Align agent tone with your organization; use **endConversation** when the thread is done # Agent tools, deployment, and integrations Source: https://docs.elementum.io/ai-agents/agents-tools-and-deployment Configure agent tools, deploy agents to workflows and channels, use external agents from App Intelligence, and integrate via the A2A protocol AI agents in Elementum are conversational assistants tied to your apps. They interpret what people ask for, use tools to work with records and automations, and reach users on channels such as Microsoft Teams or phone calls. First-line support is a typical starting point; the same patterns apply to onboarding, sales, or any process where a guided conversation speeds up routine work. For creating an agent, adding it to an app, and configuring models and instructions in the UI, see [Building Agents](./agents-experience). *** ## Tools Agents use tools to take action during conversations — creating or updating records, running searches, triggering automations, delegating to sub-agents, or calling external services through MCP. Each tool has a name, description, permissions mode (Run as publisher, Run as current user, or Run as service account), and type-specific configuration. Available tool types: * **Create Record** — Create new records in a specified App, Element, or Task * **Record Search** — Search for existing records based on a query (returns up to 100 results) * **Update Record** — Update fields on an existing record identified by record ID * **AI Search Records** — Semantic search using AI to retrieve records based on natural language * **Run Automation** — Execute an automation with an On-Demand trigger, passing input and receiving output values * **Run Agent** — Delegate a task to a sub-agent in a new conversation * **MCP** — Connect to an external MCP server and invoke its tools * **Skills** — Dynamically discover and run reusable [Skills](./agents-skills) at runtime (no manual tool setup required) *** ## Configure Agent Tools Add and configure tools so agents can perform actions like creating or searching records, running automations, delegating to sub-agents, or connecting to external MCP services. 1. In the Agent profile page, click the **Configure** button. 2. Click **+ Tool** in the Tools section. 3. Select the tool type. 4. Complete the configuration. Follow the specific instructions below for the tool type you're creating. 5. Save the tool. Every tool type includes a **Tool Start Message** field, which controls the live status message users see in chat while the tool is running (e.g., "Searching knowledge base…"). Setting a clear, tool-specific message helps users understand what the agent is doing. Multiple back-to-back tool calls appear as separate messages, and this behavior is supported in both the agent builder preview and deployed app agents. Agent tool permissions override the agent permissions unless set to agent default. *** ### Search Records Enables the Agent to search for existing records based on a query. Configuration uses a three-step wizard: **Basic Info**, **Filter Conditions**, and **Output Fields**. **Step 1: Basic Info** * **Tool Name:** Enter a name with no spaces or special characters. * **Tool Description:** Describe when and how the Agent should use this tool. This helps the Agent understand when to invoke it. * **Tool Start Message:** Customize what the user sees or hears when the tool runs. * **Permissions:** Select the execution permissions for the tool. Defaults to agent default. * **Select Object:** Choose the record object to search. * **Max Results:** Set the maximum number of results returned per search (default is 10). Keeping this low prevents overwhelming the Agent. * **Sort Configuration:** Define the default sort order for search results returned by this tool. Click **Add Sort** and select a field to sort by. **Step 2: Filter Conditions** * **Filter Variables:** Define variables the Agent fills in at runtime. Click **+ Add Variable** and provide a variable name, a description with valid values, and whether it is required. Use the link button on a filter row to set a variable as the filter value. * **Filter Conditions:** Add static filter conditions to narrow results. Build rules using a field, operator, and value. Click **+ Condition** to add a row or **+ Condition Group** to add grouped conditions. **Step 3: Output Fields** * **Output Fields:** Toggle on the fields from the search results that should be returned to the Agent. The search returns results similar to a list view search. If more than 100 records are found, the Agent receives a failure message indicating the need for a more refined query. *** ### AI Search Provides advanced search capabilities using AI, allowing the Agent to understand and retrieve related data based on natural language. Configuration uses a five-step wizard: **Basic Info**, **Select Source**, **Configure Fields**, **Output Fields**, and **Review and Save**. **Step 1: Basic Info** * **Tool Name:** Enter a name with no spaces or special characters. * **Tool Description:** Describe when and how the Agent should use this tool. This helps the Agent understand when to invoke it. * **Tool Start Message:** Customize what the user sees or hears when the tool runs. * **Permissions:** Select the execution permissions for the tool. Defaults to agent default. **Step 2: Select Source** * **Select Object:** Choose the record object to search. * **Search Service:** Select the AI search service to use for this tool. * **Max Results:** Set the maximum number of results returned per search (default is 10). Keeping this low prevents overwhelming the Agent. **Step 3: Configure Fields** * **Search Field Description:** Describe how the Agent should use the search functionality. * **Filter Variables:** Define variables the Agent can fill in at runtime. Click **+ Add Variable** to create a variable, then use the link button on a filter row to reference it as the filter value. * **Configure Search Filters:** Add filters to narrow down search results. Build filter conditions using a field, operator, and value. Click **+ Condition** to add a row or **+ Condition Group** to add grouped conditions. **Step 4: Output Fields** * **Output Fields:** Toggle on the fields the Agent can return. Available fields are specific to the record object chosen in Step 2. Only enable fields relevant to the Agent's task. **Step 5: Review and Save** Review your configuration across all steps before saving. Once saved, the tool will be available for the Agent to use. *** ### Create Record Allows the Agent to create new records in the system. * **Tool Name:** Enter a name with no spaces or special characters. * **Tool Description:** Describe when and how the Agent should use this tool. This helps the Agent understand when to invoke it. * **Tool Start Message:** Customize what the user sees or hears when the tool runs. * **Permissions:** Select the execution permissions for the tool. Defaults to agent default. * **Record Object:** Choose the record object the Agent will create. * **Fields to Create:** Click **+ Field** to add fields the Agent will populate when creating a record. A record object must be selected before fields can be configured. Each field can be given a name, a description to guide the Agent on what value to provide, and toggled as required. **If the Create Record tool fails — especially when creating in a different App** — check the following in order: 1. **Permissions / Run As identity.** The tool's **Permissions** setting (Run as publisher, Run as current user, or Run as service account) determines whose access is used. Confirm that identity has Create access on the target Element. Tool permissions override the agent's permissions unless set to agent default. 2. **Data access policies.** If running as a service account, ensure the service account is included in the data access policies on the target App/Element and that policy conditions allow the action. 3. **Required fields and field descriptions.** Every required field on the target Element must either be configured as a tool field or have a default. Vague field descriptions can cause the Agent to omit or mis-populate values, which surfaces as a validation error from the platform. 4. **Cross-App references.** When fields reference records in other Elements (lookups, parent records), the Run As identity also needs read access to those referenced Elements. Failures are returned to the Agent with the underlying reason, which is visible in the conversation transcript and the agent's activity log. *** ### Update Record Allows the Agent to update existing records. * **Tool Name:** Enter a name with no spaces or special characters. * **Tool Description:** Describe when and how the Agent should use this tool. This helps the Agent understand when to invoke it. * **Tool Start Message:** Customize what the user sees or hears when the tool runs. * **Permissions:** Select the execution permissions for the tool. Defaults to agent default. * **Record Object:** Choose the record object the Agent will update. * **Identifier Description:** Help the Agent understand the unique identifier of the record to update (e.g., record ID or name). * **Fields to Update:** Click **+ Field** to add fields the Agent will update on the record. Each field can be given a name, a description to guide the Agent on what value to provide, and toggled as required. The Agent is notified whether the update was successful or not, along with reasons for failure, allowing it to attempt corrections. *** ### Run Automation Allows the Agent to execute existing automations that have an On-Demand trigger, enabling complex workflows to be triggered conversationally. * **Tool Name:** Enter a name with no spaces or special characters. * **Tool Description:** Describe when and how the Agent should use this tool. This helps the Agent understand when to invoke it. * **Tool Start Message:** Customize what the user sees or hears when the tool runs. * **Permissions:** Select the execution permissions for the tool. Defaults to agent default. * **Automation:** Choose an existing on-demand automation to run. * **Input Values:** Click **+ Input** to define the values the Agent will pass to the automation. Each input can be given a name and a description to guide the Agent on what value to provide. * **Output Values:** Click **+ Output** to define the values the Agent will receive back from the automation. Each output can be given a name and a description so the Agent understands how to use the returned data. *** ### Run Agent Allows the Agent to delegate tasks to another agent (sub-agent) for specialized processing. Each execution creates a new conversation between the main agent and the sub-agent. * **Tool Name:** Enter a name with no spaces or special characters. * **Tool Description:** Describe when and how the Agent should use this tool. This helps the Agent understand when to invoke it. * **Tool Start Message:** Customize what the user sees or hears when the tool runs. * **Permissions:** Select the execution permissions for the tool. Defaults to agent default. * **App:** Choose the App containing the target agent. * **Target Agent:** Choose the sub-agent to delegate tasks to. * **Worker Task Prompt:** Instructions for how this agent should delegate tasks to the worker agent. Each tool execution starts a new conversation with the sub-agent. The main agent can provide context and instructions, and results from the sub-agent are returned for continued processing. *** ### MCP Tool The MCP (Model Context Protocol) Tool allows the Agent to connect to external MCP servers and use custom tools, extending the Agent's capabilities beyond the platform's built-in tools. Configuration follows a three-step wizard: **Connect to MCP Server**, **Select Tool**, and **Configure Tool**. **Step 1: Connect to MCP Server** * **MCP Server URL:** Enter the base URL of the MCP server (e.g., `https://api.example.com/mcp`). * **Authentication:** Select the authentication method — Bearer Token, Basic Auth, API Key, or None. * Click **Connect** to discover available tools on the server. **Step 2: Select Tool** * Browse and select from the tools available on the MCP server. **Step 3: Configure Tool** * **Tool Name:** Enter a name with no spaces or special characters. * **Tool Description:** Describe when and how the Agent should use this tool. This helps the Agent understand when to invoke it. * **Tool Start Message:** Customize what the user sees or hears when the tool runs. * **Permissions:** Select the execution permissions for the tool. Defaults to agent default. The Agent communicates with the external MCP server to execute the tool. Authentication is handled automatically based on the configured method. Results are returned to the Agent for use in the conversation. *** ### Ask User Question Tool Enable the **Ask User Question** tool in agent settings to let agents surface structured forms mid-conversation to collect user input. Use agent instructions to control when the tool is called and what questions, options, and required fields are generated. When invoked, a UI form is rendered for the user to complete and return to the agent. Forms are generated by the LLM at runtime, so some variation in wording, options, and field layout is expected between invocations. **Enable the tool:** 1. In the **System Tools** section, click the **Edit** icon next to **Ask User Question**. 2. Toggle on **Enable**. 3. Click **Save**. 4. Update the agent instructions (prompt) to describe the form, including: * The questions to ask. * The desired answer format for each question (for example, single-select, multi-select, or free-text). * Whether each answer is required. 5. Click **Save**. 6. Use the **Chat Preview** to confirm the experience works as desired. **Example instructions:** ```text theme={null} Always use the askUserQuestion tool when gathering information from the user. Make sure you ask for: 1. The service. Required. Zoom, Cursor, or Figma, no custom input. 2. The platform. Required. Web, iOS, Android, Windows, Mac. Multiple allowed. No free entry. 3. The business use case. Text input. Optional. DO NOT put the text (optional) in the question text. ``` Avoid instructing the agent to include words like "optional" in the rendered question text—set the required/optional behavior through the instructions instead. #### Dynamic Dropdowns Pair the Ask User Question tool with **Dynamic dropdowns** so the agent can populate dropdown options from live platform data instead of static lists defined in instructions. This keeps choices current as records are added, updated, or removed and lets users search within long option lists. To add a dynamic data source: 1. When configuring an agent on an object, open the **Ask User Question** system tool. 2. In the **Dynamic dropdowns** section of the popup, click **+ Add Source**. 3. Choose the target object from the **Records to Show** dropdown. 4. Choose the field that is rendered to users in the dropdown. 5. Choose whether the prompt accepts a single-select or multi-select response. 6. To add another source, click **+ Add Source** in the top-right corner of the **Dynamic dropdowns** tile. 7. Click **Save**. **User experience:** When the agent surfaces a question that uses a dynamic dropdown, users see a searchable picker populated from the configured object. The selected value (or values) is returned to the agent and can be used in the next step of the conversation or written to a record. Use dynamic dropdowns when the answer must match an existing record (for example, "Which project?" or "Which vendor?"). Use the standard instruction-driven options when the choices are fixed and unrelated to platform data. *** ### Copy or Duplicate a Tool Reuse existing tool configurations instead of rebuilding them from scratch. **Copy a tool to another agent in the same app:** 1. Open the agent that has the tool you want to copy. 2. Hover over the tool and click the **More** icon. 3. Click **Copy Tool to Agent**. 4. Choose the target agent from the dropdown. 5. Click **Copy Tool**. 6. Navigate to the target agent to manage the copied tool. **Duplicate a tool within the same agent:** Hover over the tool, click the **More** icon, and select **Duplicate Tool**. This creates a copy on the same agent with an auto-generated name to avoid conflicts — giving you a pre-built starting point to modify rather than configuring from scratch. *** ## Deploying Agents Once configured, agents can run in several contexts: * **Workflow buttons** — Add an "Assign an Agent" button in record details so users can start a conversation with the agent from any record. See [Building Agents — Add Your Agent to Your App Workflow](./agents-experience#add-your-agent-to-your-app-workflow). * **Microsoft Teams** — Run agents in one-on-one Teams chats. See [Agent Microsoft Teams Integration](./agents-teams-integration). * **Slack** — Run agents in Slack channels. See [Agent Slack Integration](./agents-slack-integration). * **Phone calls** — Connect agents to phone numbers via Twilio. See [Agent Phone Integration](./agents-phone-integration). *** ## External Agents via App Intelligence In addition to creating and managing internal agents, Elementum supports integration with external agents configured at the App level through Intelligence settings. You can connect specialized AI capabilities from external providers such as Snowflake Cortex and AWS Bedrock while keeping data access governed by your provider configuration. *** ### External Agent Configuration External agents are configured at the **App level** through Intelligence settings, not centrally. This approach ensures: * **App-Specific Context**: Agents access only the data relevant to their App * **Scoped Permissions**: Security controlled through AI Provider credentials * **Independent Configuration**: Each App can configure agents according to its needs * **Flexible Deployment**: Different Apps can select different providers and agents **Key Concepts:** * **Native agents**: Built and hosted in Elementum * **Managed agents**: External agents (for example Cortex or Bedrock) integrated through App Intelligence * **App Intelligence**: Configuration area where external agents are discovered and connected * **AI Provider**: Provider configured with appropriate credentials for agent discovery and invocation *** ### Supported external agent runtimes Elementum supports two external agent runtimes, each documented end-to-end on its own page: Run Cortex Agents on your Snowflake data warehouse and invoke them from App automations Connect a Bedrock Agent built in your AWS account via the Agent Alias ARN Both runtimes use the same App-level configuration pattern: select the AI Provider you've already connected, register the external agent, then invoke it from automations using **Run Agent Task**. For the full setup, security model, and integration architecture for each runtime, follow the links above. *** ## Agent-to-Agent Protocol (A2A) Elementum supports the Agent-to-Agent (A2A) protocol, an open standard that enables external systems to communicate with Elementum agents programmatically. This allows other AI agents, automation platforms, or custom applications to interact with your Elementum agents as remote collaborators. A2A is one-directional: Elementum agents act as **receivers** (servers) that external systems call. Elementum does not act as an A2A client, so you cannot install or consume an external agent's Agent Card in Elementum. To bring an external agent's capabilities into a workflow instead, connect a managed agent through [App Intelligence](#external-agents-via-app-intelligence) (Snowflake Cortex or AWS Bedrock). For the full A2A reference — architecture, authentication, Agent Cards, JSON-RPC examples, streaming, task states, and multi-turn conversations — see [Agent Architecture & A2A Protocol](./agents-a2a-protocol#multi-agent-coordination-via-a2a-protocol). *** ## Next Steps * [Building Agents](./agents-experience) — Create an agent, configure tools, and add it to your app * [Agent Architecture & A2A Protocol](./agents-a2a-protocol) — Internal architecture, A2A discovery, authentication, streaming, and multi-turn conversations * [Snowflake Cortex Agents Setup Guide](/ai-agents/snowflake-cortex-agents-setup) — Step-by-step Snowflake configuration * [AWS Bedrock Agents Setup Guide](/ai-agents/bedrock-agents-setup) — Step-by-step AWS Bedrock configuration * [Help & Resources](/support/resources) — Support and additional documentation # AI in Automations Source: https://docs.elementum.io/ai-agents/ai-automations Intelligent automation actions that analyze, classify, and transform data using artificial intelligence Elementum's AI-powered automation actions process unstructured information, make classification decisions, and transform data within your automation workflows. Each AI action receives data through variables and produces structured outputs that subsequent actions in your sequence can reference. For a full list of every available automation action (including AI actions), see the [Automation Actions Reference](/workflows/automation-actions-reference). For trigger configuration, see the [Automation Triggers Reference](/workflows/automation-triggers-reference). ## Adding AI Actions to an Automation AI actions are added the same way as any other action in the automation builder. If you haven't built an automation before, start with the [Automation System](/workflows/automation-system#building-your-first-automation) guide. 1. Open an App, Element, or Task and navigate to **Automations** under **Workflows & Processes** 2. Create a new automation or edit an existing one 3. Add a trigger (or use the existing one) to define when the automation runs 4. Click **Add Action** at the point in the sequence where you want AI processing 5. Select an AI action from the action list -- **AI Classification**, **AI Summarization**, **Transform Data with AI**, or **AI File Analysis** 6. Configure the action's input by mapping variables from the trigger or previous actions 7. Use the action's output variables in subsequent steps for routing, record updates, or notifications Start with a single AI action before chaining multiple together. Validate that its output matches your expectations using the automation history, then build on it. ## AI Actions ### AI Classification AI Classification analyzes content and assigns categories, tags, or labels based on patterns and context. It returns a classification result along with a confidence score that you can use to route workflows or flag low-confidence results for human review. **Common applications:** * Categorize support tickets by type, priority, and department * Qualify leads as hot, warm, or cold based on form data * Classify uploaded documents by type (contract, invoice, report) * Analyze customer feedback for sentiment and topic **Example flow:** ``` Support Email Received → AI Classification → IF category = "Bug" → Route to Engineering ``` **Output variables:** ``` ai_classification.category = "Bug Report" ai_classification.confidence = 0.92 ai_classification.priority = "High" ``` ### AI Summarization AI Summarization condenses long-form content into key points and insights. It extracts the most relevant information from text fields, documents, or conversation histories. **Common applications:** * Convert detailed reports into executive summaries * Extract action items and decisions from meeting notes * Summarize customer feedback to identify recurring themes * Create digests of lengthy documents for quick review **Example flow:** ``` Monthly Report Generated → AI Summarization → Send Email to Executive Team ``` **Output variables:** ``` ai_summarization.summary = "Key project milestones achieved with 15% budget savings" ai_summarization.key_points = ["Budget savings achieved", "Timeline on track", "Resource optimization"] ai_summarization.sentiment = "Positive" ``` ### Transform Data with AI Transform Data with AI cleans, normalizes, and standardizes data by recognizing patterns and applying context-aware corrections. This is especially useful when ingesting data from external sources with inconsistent formatting. **Common applications:** * Standardize addresses: `"123 main st, NYC, ny"` becomes `"123 Main Street, New York, NY"` * Format phone numbers: `"5551234567"` becomes `"+1 (555) 123-4567"` * Normalize company names: `"Microsoft Corp"` becomes `"Microsoft Corporation"` * Enrich records with consistent formatting and structure **Example flow:** ``` Customer Data Imported → Transform Data with AI → Update Customer Records ``` **Output variables:** ``` transform_data.standardized_address = "123 Main Street, Suite 200, New York, NY 10001" transform_data.formatted_phone = "+1 (555) 123-4567" transform_data.confidence_score = 0.95 ``` ### AI File Analysis AI File Analysis extracts structured information from uploaded documents by understanding the content and context of different document types. It identifies key data points automatically based on the document format. **Common applications:** * Extract parties, dates, terms, and obligations from contracts * Pull vendor information, line items, and due dates from invoices * Parse skills, experience, and education from resumes * Identify key metrics and trends from business reports **Example flow:** ``` Contract PDF Uploaded → AI File Analysis → Create Contract Record → Set Renewal Reminders ``` **Output variables:** ``` ai_file_analysis.contract_parties = ["Company A", "Company B"] ai_file_analysis.effective_date = "2024-01-15" ai_file_analysis.contract_value = "$50,000" ai_file_analysis.renewal_date = "2025-01-15" ``` ## Model Availability Across AI Actions Each AI action has its own model dropdown, and the list may differ between actions even within the same organization. This is intentional: Elementum enables models per action based on task fit, so only models suited to a given task (for example, classification vs. open-ended transformation) appear in that action's dropdown. The list is not filtered by your LLM Service's temperature or other advanced settings, and enablement is managed by Elementum at the platform level -- admins control which providers and models are connected in [AI Services](/ai-agents/ai-services), not which of them appear inside a given action. Elementum is working to keep the lists largely consistent across the four AI actions, with occasional differences remaining only where a model is a poor fit for a specific task. If a model you expected is missing from an action, confirm it's configured on the **AI Services** page; if it's configured but still not listed, contact Elementum Support. ## Combining AI Actions You can chain multiple AI actions within a single automation for more comprehensive processing. Each action's output variables are available to all subsequent actions in the sequence. **Sequential processing** -- Process a document through multiple AI stages: ``` Document Uploaded → AI File Analysis → AI Classification → AI Summarization → Create Record ``` **Conditional routing** -- Use AI results to branch your workflow: ``` Customer Email → AI Classification → IF category = "Complaint" → AI Summarization → Route to Manager OTHERWISE → Standard Response → Route to Support Team ``` **Multi-action enrichment** -- Combine classification with transformation: ``` Lead Form Submitted → Transform Data with AI → AI Classification → IF quality = "Hot" → Immediate Follow-up IF quality = "Warm" → Add to Nurture Campaign ``` ## Example: Document Processing Pipeline This example shows how multiple AI actions work together in a single automation to process an incoming invoice end-to-end. **Scenario:** A vendor emails an invoice PDF. The automation extracts the data, standardizes it, classifies the invoice for routing, and creates a record. ``` Email Received (invoice PDF attached) → AI File Analysis → Transform Data with AI → AI Classification → Create Record → IF amount > $5,000 → Start Approval Process OTHERWISE → Update Record Fields (auto-approved) ``` **Step-by-step data flow:** 1. **AI File Analysis** extracts raw data from the PDF: * `ai_file_analysis.vendor_name` = `"ACME corp."` * `ai_file_analysis.amount` = `"$2,450.00"` * `ai_file_analysis.due_date` = `"3/15/2026"` 2. **Transform Data with AI** standardizes the extracted values: * `transform_data.vendor_name` = `"ACME Corporation"` * `transform_data.amount` = `"$2,450.00"` * `transform_data.due_date` = `"2026-03-15"` 3. **AI Classification** categorizes the invoice: * `ai_classification.category` = `"Office Supplies"` * `ai_classification.department` = `"Operations"` * `ai_classification.confidence` = `0.89` 4. **Create Record** uses all three outputs to populate an invoice record with clean, classified data -- then routing logic handles approval based on the amount. ## Tips for AI Actions These tips apply specifically to AI actions in automations. For general automation design guidance, see [Automation Best Practices](/workflows/automation-best-practices). **Provide sufficient context in inputs.** AI actions produce better results when they receive relevant background information. When configuring an AI Classification action for support tickets, pass the full email body and subject line rather than just a snippet -- the additional context improves categorization accuracy. **Use confidence scores to gate decisions.** AI actions return a confidence score with their results. Use IF conditions to check confidence before acting on the output. For example, route results with confidence above 0.85 through the automated path, and send lower-confidence results to a human reviewer. ``` AI Classification → IF ai_classification.confidence > 0.85 → Automated routing OTHERWISE → Make Assignment (manual review queue) ``` **Validate outputs before writing to records.** Add IF conditions to verify that AI action outputs contain expected values before using them in Update Record Fields or Create Record actions. This prevents empty or malformed data from entering your system when an AI action produces an unexpected result. **Match the action to the task.** Each AI action is designed for a specific type of processing: | Task | Action | | ------------------------------------------- | ---------------------- | | Categorize data into groups | AI Classification | | Condense long content | AI Summarization | | Standardize or clean data | Transform Data with AI | | Extract data from documents | AI File Analysis | | Research, reasoning, or multi-step judgment | Run Agent Task | ## Agent Tasks in Automations Beyond the four AI actions above, you can assign tasks to AI agents directly within automations using the **Run Agent Task** action. This bridges structured automation steps with autonomous, reasoning-based task completion -- the automation gathers context and the agent handles analysis, research, or decision-making that goes beyond predefined rules. **Example flow:** ``` Order Approved → Search Records (customer history) → Run Agent Task ("Research customer industry") → Update Record Fields → Send Email ``` The agent works autonomously in a headless environment (no user interaction), then returns structured output that subsequent automation actions can reference as variables. ### AI Actions vs. Agent Tasks AI actions and agent tasks serve different purposes within an automation. Use this as a quick guide for choosing between them: **Use AI actions when:** * The task fits a well-defined pattern (classify, summarize, transform, extract) * You need fast, deterministic processing * The expected output structure is consistent across runs **Use Run Agent Task when:** * The task requires reasoning, judgment, or synthesis of multiple data points * You need the agent to research or evaluate something that doesn't fit a predefined template * The output depends on contextual interpretation rather than pattern matching You can combine both approaches in a single automation -- for example, use AI File Analysis to extract contract data, then hand the extracted data to an agent task for risk assessment that requires business judgment. For a complete guide on configuring agent tasks, writing task definitions, designing structured output fields, and best practices for headless operation, see [Agent Task Automation](/workflows/agent-task-automation). ### Agent Conversation Ended Trigger The **Agent Conversation Ended** trigger fires when an AI agent completes a conversation, making the conversation context available for further automation processing. Use it to generate conversation summaries, create follow-up tasks, update customer records, or trigger post-conversation workflows. ``` Agent Conversation Ended → AI Summarization → Create Follow-up Tasks → Update Customer Record ``` When this trigger fires, your automation can access the full conversation transcript (`trigger.transcript`), conversation type (Teams, Voice), and all field values from the record the conversation is associated with. Pass the transcript to AI Summarization or AI Classification to extract structured insights for downstream actions. For trigger configuration details including conversation type filtering, timeout settings, and where conditions, see [Agent Conversation Ended](/workflows/automation-triggers-reference#agent-conversation-ended) in the Triggers Reference. ## Next Steps Full configuration details and variable outputs for every action, including AI actions In-depth guide to bridging structured automation with agent intelligence Understand the event-driven framework that powers all automations Design principles, performance strategies, and proven patterns # AI Models Source: https://docs.elementum.io/ai-agents/ai-models Comprehensive guide to available AI models, their capabilities, and when to use them Elementum supports a wide range of AI models across multiple providers. Models are accessed through configured AI providers -- you'll select your provider first, then choose from the models available through that provider. To use a model in your workflows, create an [AI Service](/ai-agents/ai-services) that references the provider and model you want. ## Available Providers * **Snowflake** -- Claude, OpenAI (Cortex), Llama, Mistral, DeepSeek, embedding models * **OpenAI** -- GPT models * **Anthropic** -- Direct access to Claude models. Primary provider supported on Studio Agents. See the [Anthropic setup guide](/ai-agents/anthropic-setup) for configuration details. * **Gemini** -- Multimodal Gemini models * **Bedrock** -- Claude models via AWS Bedrock. See the [AWS Bedrock Setup](/ai-agents/bedrock-setup) guide to configure the provider, or [AWS Bedrock Agents Setup](/ai-agents/bedrock-agents-setup) to connect a Bedrock Agent built in AWS. * **Custom** -- Any OpenAI-compatible endpoint, including LLM gateways, proxies, and self-hosted models. See [Configure a Custom Provider](/ai-agents/ai-services#configure-a-custom-provider) for setup details. **Important:** Models are accessed through providers you configure in Organization Settings. Claude models, for example, can be accessed directly through the Anthropic provider or through the Snowflake or Bedrock providers, depending on your data residency and compliance needs. Model availability varies by provider configuration, account tier, and region. Not all models listed below may be available in your environment. Check your provider's [service creation screen](/ai-agents/ai-services#creating-ai-services) for the models currently accessible to your organization. **Per-feature availability**: Even when a model is configured in your organization, it may not appear in every AI feature's dropdown. Elementum enables models per feature based on task suitability, so the model list inside **AI Classification** can differ from the list inside **Transform Data with AI**, **AI Summarization**, or **AI File Analysis**. See [Model Availability Across AI Actions](/ai-agents/ai-automations#model-availability-across-ai-actions) for details. For models scheduled to leave the supported list, see [Upcoming Model Deprecations](/ai-agents/upcoming-model-deprecations). ## Quick Reference: Model Capabilities This table shows which capabilities each model category supports: | Model | Provider | Multimodal | Structured Output | Reasoning | Agents | Best Use Case | | ------------------------ | ----------------------------- | ---------- | ----------------- | ---------- | ------ | ---------------------------------------------------- | | **GPT-5 Series** | OpenAI | No | Yes | Yes | Yes | Complex reasoning, demanding applications | | **GPT-4.1 Series** | OpenAI | No | Yes | No | Yes | Production deployments, reliable automation | | **GPT-4o Series** | OpenAI | Yes | Yes | No | Yes | General-purpose, document analysis | | **o3-mini / o1-mini** | OpenAI | No | No | Yes (req.) | No | Mathematical reasoning, logic problems | | **GPT-4 / GPT-3.5** | OpenAI | No | Partial | No | No | Legacy applications | | **Claude 4.5 Sonnet** | Anthropic, Snowflake, Bedrock | No | No | No | Yes | Advanced reasoning, detailed analysis, Studio Agents | | **Claude 4 Opus** | Anthropic, Snowflake, Bedrock | No | No | No | Yes | Highest-capability reasoning | | **Claude 4 Sonnet** | Anthropic, Snowflake, Bedrock | No | No | No | Yes | Balanced performance | | **Claude Haiku 4.5** | Anthropic, Snowflake, Bedrock | No | No | No | Yes | Fast, efficient processing | | **Claude 3.7 / 3.5** | Anthropic, Snowflake, Bedrock | No | No | No | Yes | Cost-effective reasoning | | **Cortex GPT-5** | Snowflake | No | Yes | Yes | Yes | OpenAI through Snowflake | | **Cortex GPT-4.1** | Snowflake | No | Yes | No | Yes | Production OpenAI via Snowflake | | **Cortex o4-mini** | Snowflake | No | No | Yes (req.) | Yes | Reasoning through Snowflake | | **Gemini 3 Pro** | Gemini | Yes | No | No | Yes | Latest multimodal | | **Gemini 2.5 Pro/Flash** | Gemini | Yes | No | No | Yes | Production multimodal | | **Gemini 2.0 Flash** | Gemini | Yes | No | No | No | Cost-effective multimodal | | **Gemini 1.5 Pro** | Gemini | Yes | No | No | No | Established multimodal | | **DeepSeek R1** | Snowflake | No | No | No | No | Open-source reasoning | | **Llama 3.3 70B** | Snowflake | No | No | No | No | Open-source, balanced | | **Llama 3.1 Series** | Snowflake | No | Partial | No | No | Open-source, structured output | | **Llama 3 Series** | Snowflake | No | No | No | No | Open-source, function calling | | **Mistral Large 2** | Snowflake | No | No | No | No | Multilingual, European focus | | **Mistral 7B / Mixtral** | Snowflake | No | No | No | No | Efficient small models | | **Snowflake Arctic** | Snowflake | No | No | No | No | Data cloud native | | **Arctic Embeddings** | Snowflake | N/A | N/A | N/A | N/A | Semantic search | **Legend:** * **Multimodal**: Processes text and images together * **Structured Output**: Guaranteed JSON/XML format responses * **Reasoning**: Advanced reasoning mode (req. = required, always on) * **Agents**: Supports Elementum agent workflows ## Models by Provider ### Snowflake Cortex Snowflake Cortex provides access to multiple AI model families through your Snowflake data cloud. **Data Residency**: All Snowflake Cortex models run within your Snowflake environment, keeping data in your cloud. #### Anthropic Claude (via Snowflake) **claude-sonnet-4-5** * **Best for:** Complex reasoning and analysis tasks * **Capabilities:** Strong reasoning, nuanced understanding, extensive context windows * **Use cases:** Complex research, detailed analysis, advanced automation, agent workflows * **Temperature range:** 0.0 - 1.0 (default: 0.7) * **When to use:** Demanding applications requiring deep understanding and analysis **Claude 4 Opus** (claude-4-opus) * **Best for:** Highest-capability reasoning tasks * **Use cases:** Strategic decisions, complex research, mission-critical analysis * **When to use:** Tasks where quality matters more than cost **Claude 4 Sonnet** (claude-4-sonnet) * **Best for:** Balanced performance and cost for demanding tasks * **Use cases:** Business automation, production workflows, detailed analysis * **When to use:** Production workloads needing strong reasoning **Claude Haiku 4.5** (claude-haiku-4-5) * **Best for:** Fast, efficient processing * **Use cases:** High-volume operations, real-time interactions, simple automation * **When to use:** Speed and cost-efficiency are priorities **Claude 3.7 Sonnet** (claude-3-7-sonnet) * **Best for:** Daily tasks requiring strong reasoning at lower cost * **Use cases:** Standard business automation, customer support, content generation * **When to use:** Cost-effective production deployments **Claude 3.5 Sonnet** (claude-3-5-sonnet) * **Best for:** Reliable production performance * **Use cases:** Established workflows, production automation * **When to use:** Stability and consistent performance matter #### OpenAI via Cortex Access OpenAI models through your Snowflake environment: **openai-gpt-5** - Advanced reasoning **openai-gpt-5-mini** - Efficient reasoning **openai-gpt-5-nano** - Maximum efficiency **openai-gpt-5-chat** - Optimized for conversations * **Capabilities:** Structured output, reasoning mode, through Snowflake * **Use cases:** Complex analysis, conversations, classification, intelligence features, agents * **When to use:** Need OpenAI capabilities with Snowflake data residency **openai-gpt-4.1** * Production-ready OpenAI through Snowflake * Structured output, reliable reasoning **openai-o4-mini** * Reasoning model through Snowflake * Required temperature: 1.0 (not adjustable) * System role not supported **When to use:** Production OpenAI workloads within Snowflake environment #### Open Source Models (via Snowflake) **deepseek-r1** * **Best for:** Advanced reasoning with open-source flexibility * **Capabilities:** Strong reasoning, open-source architecture * **Use cases:** Research, academic applications, cost-conscious deployments * **When to use:** Open-source requirements or research projects **Llama 3.3 Series** * **Llama 3.3 70B** (llama3.3-70b): Latest generation, balanced performance **Llama 3.2 Series** * **Llama 3.2 3B** (llama3.2-3b): Efficient, compact * **Llama 3.2 1B** (llama3.2-1b): Maximum efficiency for simple tasks **Llama 3.1 Series** * **Llama 3.1 405B** (llama3.1-405b): Largest, most capable * **Llama 3.1 70B** (llama3.1-70b): Production-ready, structured output support * **Llama 3.1 8B** (llama3.1-8b): Cost-effective, structured output support **Llama 3 Series** * **Llama 3 70B** (llama3-70b): Function calling, reliable * **Llama 3 8B** (llama3-8b): Efficient operation **Llama 2 Series** * **Llama 2 70B Chat** (llama2-70b-chat): Conversational focus **When to use:** Open-source requirements, cost optimization, specific model sizes **Mistral Large 2** (mistral-large2) * Advanced capabilities, multilingual support, European markets **Mistral Large** (mistral-large) * Previous generation, reliable performance **Mistral 7B** (mistral-7b) * Compact, efficient, cost-effective **Mixtral 8x7B** (mixtral-8x7b) * Mixture-of-experts architecture, balanced performance **When to use:** International applications, multilingual needs, small model requirements **Snowflake Arctic** (snowflake-arctic) * Data cloud native processing, integrated with Snowflake infrastructure * **When to use:** Data-intensive workflows within Snowflake **Gemma 7B** (gemma-7b) * Lightweight Google-developed model * **When to use:** Efficient processing on smaller tasks **Jamba Instruct** (jamba-instruct) * Instruction-following optimization * **Note:** Not recommended for JSON/YAML parsing **Reka Core / Flash** (reka-core, reka-flash) * Advanced processing or fast operation #### Snowflake Embedding Models * **Arctic L V2.0** (`snowflake-arctic-embed-l-v2.0`) -- High-quality embeddings for semantic search. Use for new AI search implementations. * **Arctic M V1.5** (`snowflake-arctic-embed-m-v1.5`) -- Balanced performance and quality. Use for production search systems. ### Anthropic Direct Access Claude models directly through the Anthropic API. The Anthropic provider is the primary provider supported on Studio Agents and gives organizations a direct path to Claude without routing requests through Snowflake or AWS Bedrock. **Studio Agents**: Anthropic is the primary provider supported on [Studio Agents](/ai-agents/studio-agents). Configure an Anthropic provider before using Studio Agents to build automations, agents, and flows. **claude-sonnet-4-5** * **Best for:** Complex reasoning, detailed analysis, and Studio Agents * **Capabilities:** Strong reasoning, nuanced understanding, extensive context windows, agent support * **Use cases:** Studio Agents, advanced automation, conversational agents, complex research * **When to use:** Demanding applications that benefit from direct Anthropic access **Claude 4 Opus** (claude-4-opus) * **Best for:** Highest-capability reasoning tasks * **Use cases:** Strategic decisions, complex research, mission-critical analysis * **When to use:** Tasks where quality matters more than cost **Claude 4 Sonnet** (claude-4-sonnet) * **Best for:** Balanced performance and cost for demanding tasks * **Use cases:** Business automation, production workflows, detailed analysis * **When to use:** Production workloads needing strong reasoning **Claude Haiku 4.5** (claude-haiku-4-5) * **Best for:** Fast, efficient processing * **Use cases:** High-volume operations, real-time interactions, simple automation * **When to use:** Speed and cost-efficiency are priorities **Claude 3.7 Sonnet** (claude-3-7-sonnet) * **Best for:** Daily tasks requiring strong reasoning at lower cost * **Use cases:** Standard business automation, customer support, content generation * **When to use:** Cost-effective production deployments **Claude 3.5 Sonnet** (claude-3-5-sonnet) * **Best for:** Reliable production performance * **Use cases:** Established workflows, production automation * **When to use:** Stability and consistent performance matter **Note**: Embeddings for AI Search are handled exclusively through Snowflake Cortex. Anthropic models are used for LLM services only. Specific model availability depends on your Anthropic account access. ### OpenAI Direct Access OpenAI models directly through OpenAI API. **GPT-5** (gpt-5) * **Best for:** Complex reasoning and demanding applications * **Capabilities:** Structured output, reasoning mode, advanced problem-solving * **Use cases:** Complex analysis, strategic planning, research tasks **GPT-5 Mini** (gpt-5-mini) * **Best for:** Daily reasoning at lower cost * **Capabilities:** Structured output, reasoning mode, balanced performance * **Use cases:** Standard business logic, moderate analysis, automation **GPT-5 Nano** (gpt-5-nano) * **Best for:** Simple reasoning requiring efficiency * **Capabilities:** Structured output, reasoning mode, cost-effective * **Use cases:** Basic classification, simple analysis, high-volume operations **GPT-5.1** (gpt-5.1) * **Best for:** Enhanced reasoning with improved accuracy * **Use cases:** Business intelligence, detailed analysis, critical decisions **GPT-5.2** (gpt-5.2) * **Best for:** Highest-tier reasoning * **Use cases:** Complex problem-solving, research, mission-critical applications **All GPT-5 models support:** Prompts, conversations, classification, intelligence features, agents **GPT-4.1** (gpt-4.1) * **Best for:** Production applications requiring consistent performance * **Capabilities:** Structured output, reliable reasoning * **Use cases:** Customer-facing applications, production workflows **GPT-4.1 Mini** (gpt-4.1-mini) * **Best for:** Cost-effective production deployments * **Use cases:** High-volume automation, chatbots, content generation **GPT-4.1 Nano** (gpt-4.1-nano) * **Best for:** Maximum efficiency for simple tasks * **Use cases:** Real-time interactions, simple classification, quick responses **All GPT-4.1 models support:** Prompts, conversations, classification, intelligence features, agents **GPT-4o** (gpt-4o) * **Best for:** Balanced performance and capability * **Capabilities:** Structured output, multimodal support (text + images) * **Use cases:** General-purpose applications, document analysis, versatile automation * **Supports:** Prompts, conversations, email analysis, classification, intelligence, agents **GPT-4o Mini** (gpt-4o-mini-2024-07-18) * **Best for:** Cost-effective general-purpose tasks * **Capabilities:** Structured output, multimodal support, efficient operation * **Use cases:** Standard automation, customer support, content processing * **Supports:** Prompts, conversations, email analysis, translation, classification, intelligence, agents **o3-mini** (o3-mini) * **Best for:** Latest reasoning-focused tasks requiring deep analysis * **Capabilities:** Advanced reasoning mode (required temperature: 1.0) * **Use cases:** Mathematical problems, logical analysis, complex problem-solving * **Note:** System role not supported; fixed temperature requirement **o1-mini** (o1-mini) * **Best for:** Previous-generation reasoning tasks * **Capabilities:** Reasoning mode (required temperature: 1.0) * **Use cases:** Logic puzzles, analytical tasks, structured problem-solving * **Note:** System role not supported; fixed temperature requirement **When to use:** Tasks requiring explicit step-by-step reasoning, math, logic **GPT-4 Turbo Preview** (gpt-4-turbo-preview) * Function calling, extended context * **Recommendation:** Consider upgrading to GPT-4.1 or GPT-5 series **GPT-4** (gpt-4) * Structured output, reliable performance * **Supports:** Prompts, conversations, summarization, email analysis, classification **GPT-3.5 Turbo** (gpt-3.5-turbo, gpt-3.5-turbo-1106) * Function calling, basic capabilities * **Recommendation:** Upgrade to GPT-4.1 Mini for better performance ### Google Gemini Access Google's multimodal Gemini models directly. **Gemini 3 Pro Preview** (gemini-3-pro-preview) * **Best for:** Latest multimodal capabilities * **Capabilities:** Multimodal processing (text, images, audio), advanced reasoning * **Use cases:** Document analysis with images, multimedia processing, complex automation * **Temperature range:** 0.0 - 1.0 (default: 0.7) * **Supports:** Prompts, translation, classification, file analysis, agents **Gemini 2.5 Pro** (gemini-2.5-pro) * **Best for:** Complex multimodal tasks requiring high performance * **Capabilities:** Multimodal, large context windows, detailed analysis * **Use cases:** Document understanding, comprehensive analysis, advanced automation **Gemini 2.5 Flash** (gemini-2.5-flash) * **Best for:** Fast multimodal processing * **Capabilities:** Multimodal, efficient operation, quick responses * **Use cases:** Real-time document analysis, responsive automation **Both support:** Prompts, translation, classification, file analysis, agents **Gemini 2.0 Flash** (gemini-2.0-flash) * **Best for:** Cost-effective multimodal processing * **Use cases:** Standard document processing, general automation **Gemini 2.0 Flash Lite** (gemini-2.0-flash-lite) * **Best for:** Lightweight multimodal tasks * **Use cases:** Simple document analysis, high-volume operations **Both support:** Prompts, translation, classification, file analysis **Gemini 1.5 Pro** (gemini-1.5-pro) * **Best for:** Established multimodal performance * **Capabilities:** Multimodal processing, reliable operation * **Use cases:** Production workloads, established workflows * **Supports:** Prompts, translation, classification, file analysis ### AWS Bedrock Access Claude models through your own AWS Bedrock account. Bedrock-hosted models run within your AWS infrastructure, keeping AI workloads inside your cloud compliance boundaries. Claude models available through Bedrock mirror the Anthropic Claude family. Availability depends on your AWS region and account access. * **Best for:** Organizations that need Claude capabilities within their own AWS environment * **Use cases:** Automations, agents, content generation, classification, reasoning * **When to use:** AWS compliance requirements, existing AWS infrastructure, data residency needs **Model Availability**: Available Claude models depend on your AWS region and Bedrock model access grants. Check the Amazon Bedrock console for current availability. ### Custom Providers Connect any OpenAI-compatible endpoint as an AI provider in Elementum. This includes LLM gateways, proxies, internally hosted inference servers, and self-hosted models. Once configured, custom-provider models appear in the model dropdown alongside built-in providers and can be used in the same agents and automations. * **Best for:** Standardizing on internal infrastructure, routing through an enterprise LLM gateway, or adopting models that aren't yet supported natively * **Use cases:** Self-hosted open-source models, proxied access to multiple upstream providers, region- or compliance-specific deployments * **When to use:** You need a model or routing path that isn't covered by the built-in providers, or your organization requires all model traffic to flow through a managed endpoint **Capability availability**: Multimodal input, structured output, reasoning mode, and other advanced features are only available if the underlying custom endpoint supports them. Test each model against your use case before relying on a specific capability. See [Configure a Custom Provider](/ai-agents/ai-services#configure-a-custom-provider) for connection details. ## Model Selection Guide ### By Use Case **Recommended Models:** 1. **GPT-4o Mini** - Best balance of cost and performance 2. **Claude 3.7 Sonnet** - Strong reasoning at reasonable cost 3. **Gemini 2.5 Flash** - Fast multimodal conversations 4. **GPT-5 Mini** - Advanced reasoning for complex interactions **Why these models:** * Support structured output for reliable responses * Handle context well for conversation continuity * Cost-effective for high-volume interactions * Consistent reliability in production **Recommended Models:** 1. **Gemini 2.5 Pro** - Complex multimodal analysis 2. **Gemini 3 Pro Preview** - Latest document understanding 3. **GPT-4o** - Strong multimodal processing 4. **Gemini 2.5 Flash** - Fast multimodal analysis **Why these models:** * Multimodal support for images and text together * Large context windows for lengthy documents * Strong reasoning for extracting insights * Handle charts, diagrams, and visual elements **Recommended Models:** 1. **GPT-4.1 Nano** - Fast, cost-effective 2. **GPT-4o Mini** - Structured output for consistency 3. **Claude Haiku 4.5** - Quick, efficient 4. **GPT-4.1 Mini** - Production-ready reliability **Why these models:** * Structured output ensures consistent categorization * Cost-effective for high-volume operations * Fast response times for real-time classification * Reliable accuracy for business logic **Recommended Models:** 1. **o3-mini** - Specialized reasoning mode for logic 2. **Claude 4 Opus** - Highest-capability reasoning 3. **GPT-5** - Advanced problem-solving 4. **Claude Sonnet 4.5** - Detailed analysis **Why these models:** * Advanced reasoning capabilities * Handle multi-step logic effectively * Understand complex relationships * Provide detailed explanations **Recommended Models:** 1. **Claude Sonnet 4.5** - High-quality writing 2. **GPT-5** - Creative and coherent content 3. **Gemini 2.5 Pro** - Long-form content 4. **Claude 4 Sonnet** - High-quality balanced output **Why these models:** * Natural, fluent writing style * Good creativity control via temperature * Handle various content types well * Consistent quality and tone **Required Models:** 1. **Snowflake Arctic L V2.0** - Latest, highest quality 2. **Snowflake Arctic M V1.5** - Reliable production **Why these models:** * Optimized for semantic similarity * Consistent vector representations * Efficient processing at scale * **Note:** Must use Snowflake provider for embedding models ### By Budget **Lowest Cost Models:** * **GPT-4.1 Nano**: Minimal cost, simple tasks * **Claude Haiku 4.5**: Fast and efficient * **Gemini 2.0 Flash Lite**: Lightweight multimodal * **Llama 3.2 1B/3B**: Maximum efficiency * **Mistral 7B**: Small but capable **Best for:** High-volume operations, simple automation, basic classification **Best Value Models:** * **GPT-4o Mini**: Strong cost-performance ratio * **GPT-4.1 Mini**: Production-ready efficiency * **Claude 3.7 Sonnet**: Strong reasoning, moderate cost * **Gemini 2.5 Flash**: Fast multimodal, reasonable cost * **GPT-5 Mini**: Advanced capabilities, acceptable cost **Best for:** Production applications, customer-facing features, standard automation **High-Performance Models:** * **GPT-5.2**: Highest OpenAI performance * **Claude 4 Opus**: Highest-capability reasoning * **Claude Sonnet 4.5**: Latest advanced capabilities * **GPT-5**: Advanced reasoning and quality * **Gemini 3 Pro Preview**: Latest multimodal **Best for:** Mission-critical applications, complex analysis, high-performance features ### By Provider Strengths **Strengths:** * Data residency in your cloud * Wide model selection * Claude and OpenAI access * Native data processing **Choose when:** Data security, Snowflake integration, diverse model needs **Strengths:** * Latest GPT models first * Structured output * Mature ecosystem * Reliable performance **Choose when:** Latest OpenAI features, production performance **Strengths:** * Direct access to the full Claude lineup * Primary provider supported on Studio Agents * Strong reasoning and natural writing quality * Simple API-key setup without a data warehouse **Choose when:** Building Studio Agents, expanding model choice beyond OpenAI/Gemini, or you want direct Anthropic access without Snowflake or Bedrock **Strengths:** * Multimodal capabilities * Large context windows * Fast processing * Latest multimodal features **Choose when:** Document analysis with images, large contexts, latest AI **Strengths:** * Claude models within your AWS account * Data stays in your cloud infrastructure * Leverages existing AWS security and compliance * Bedrock Agent orchestration **Choose when:** AWS compliance requirements, existing AWS infrastructure, data residency within your own cloud **Strengths:** * Any OpenAI-compatible endpoint (gateways, proxies, self-hosted) * Bring models that aren't natively supported * Route all traffic through internal infrastructure * Flexible authentication via API key or OAuth Client Credentials **Choose when:** Standardizing on an internal LLM gateway, hosting your own models, or adopting new models ahead of native support ## Key Model Capabilities ### Multimodal Processing **What it is:** Process text and images together in the same request **Supported Models:** * All Gemini models (2.0+) * GPT-4o, GPT-4o Mini **Use cases:** * Document analysis with charts/diagrams * Image-based data extraction * Visual content understanding * OCR and form processing ### Structured Output **What it is:** Guaranteed JSON/XML format responses for reliable automation **Supported Models:** * All GPT-4o, GPT-4.1, GPT-5 series * Cortex GPT models * GPT-4 (partial) * Llama 3.1 8B, 70B **Use cases:** * Data extraction to databases * Automated classification * API integrations * Workflow automation ### Reasoning Mode **What it is:** Extended thinking for complex problems with step-by-step reasoning **Supported Models:** * o1-mini, o3-mini (dedicated reasoning, always on) * GPT-5 series (configurable) * Cortex o4-mini (dedicated reasoning) **Use cases:** * Mathematical problems * Logic puzzles * Complex analysis * Multi-step problem-solving **Note:** Dedicated reasoning models (o1/o3/o4-mini) require temperature = 1.0 and don't support system roles ### Agent Support **What it is:** Optimized for Elementum agent workflows and multi-step tasks **Supported Models:** * GPT-4o, GPT-4.1, GPT-5 series * All Claude models (via Anthropic, Snowflake, or Bedrock) * Cortex OpenAI models * Gemini 2.5+, Gemini 3 Pro **Use cases:** * Conversational agents * Multi-turn interactions * Complex workflows * Autonomous task execution ## Temperature Settings All models except dedicated reasoning models support customizable temperature. Temperature is configured at the **LLM Service level** in Organization Settings. * **0.0 - 0.3**: Deterministic, consistent (classification, data extraction) * **0.4 - 0.7**: Balanced creativity (conversation, general tasks) * **0.8 - 1.0**: Creative, diverse (content generation, brainstorming) **Default:** 0.7 for most models **Special cases:** o1-mini, o3-mini, Cortex o4-mini require temperature 1.0 (not adjustable) ## Best Practices ### Model Selection 1. **Identify your use case** -- Determine if you need conversation, classification, analysis, generation, or search. 2. **Check required capabilities** -- Verify if you need multimodal, structured output, or reasoning capabilities. 3. **Consider your provider** -- Choose based on data residency, integration, and model access requirements. 4. **Balance cost and performance** -- Select the smallest model that meets your quality requirements. 5. **Test before committing** -- Compare 2-3 models with your actual use cases. 6. **Monitor and optimize** -- Track quality, cost, and speed metrics to refine your selection. ### Cost Optimization **Choose right-sized models:** * Use Nano/Mini for simple tasks * Reserve Pro/Opus for complex analysis * Test if smaller models meet needs **Optimize prompts:** * Write concise, clear instructions * Remove unnecessary context * Set appropriate max tokens * Use structured output formats **Consider provider costs:** * Snowflake Cortex models cost \~4.5x base rate (includes infrastructure and data residency) * Direct provider access may be more cost-effective for high-volume, simple tasks * Snowflake provides value through data residency and unified platform ### Performance Optimization **For speed:** * Use Mini/Nano/Haiku models * Lower max tokens * Choose geographically close providers **For quality:** * Use Pro/Opus/Sonnet tier models * Provide detailed context * Test with real examples **For consistency:** * Use low temperature (0.0-0.2) * Enable structured output * Choose models with structured output support ## Next Steps Set up your AI provider connections Configure specific model instances for your workflows Create conversational AI assistants using these models Use AI models in automation workflows # AI Overview Source: https://docs.elementum.io/ai-agents/ai-overview How Elementum integrates AI providers, services, and agents into your workflows Elementum embeds AI directly into your business workflows. Rather than operating as a standalone tool, AI in Elementum connects to your data cloud infrastructure and works within the same apps, automations, and processes your teams already use. This means AI actions run on live data without copying or moving it between systems. There are three layers to AI in Elementum: **providers** supply the models, **services** make those models available to your workflows, and **capabilities** (agents, search, and automation actions) put them to work. ## AI Providers AI providers are authenticated connections to external model services. Each provider gives your Elementum environment access to a different set of language models and capabilities. GPT and reasoning models for language processing, classification, and generation Direct access to Claude models for agents, automations, and Studio Agents AI that runs natively in your Snowflake environment with LLM functions, embeddings, and search Multimodal models through Vertex AI for text, image, and document processing Claude models hosted in your own AWS account (Bedrock Agents are a separate setup) Connect any OpenAI-compatible endpoint, including LLM gateways, proxies, and self-hosted models Compare supported models, capabilities, and provider-specific features You need at least one configured AI provider before you can create AI services or use AI capabilities in your workflows. You can configure multiple providers simultaneously to use different models for different tasks, implement failover strategies, or optimize costs by routing to the most efficient provider. See [AI Models](/ai-agents/ai-models) for a detailed breakdown of available models across providers. Only verified domain users can configure AI Providers. Elementum employees cannot create or modify AI Providers or Models in any customer org. In addition to the built-in providers, you can connect a **Custom Provider** to bring in any OpenAI-compatible endpoint—useful for internal LLM gateways, proxies, or self-hosted models. Custom providers support **API Key** and **OAuth Client Credentials** authentication, and once configured behave like any other provider in agents and automations. ## AI Services AI services sit between your providers and your workflows. They define which model to use, how it behaves, and where it can be applied. There are two types: * **LLM services** -- Configure a language model for use in automation actions, agents, and other AI-driven tasks. Each service specifies the provider, model, and default parameters. * **Embedding services** -- Configure an embedding model for [AI Search](/ai-agents/ai-search), which converts your data into vector representations for semantic querying. Create and manage LLM and embedding services for your environment Enable semantic search across Elements and Tables using embedding services ## AI in Automations AI actions are available as steps within Elementum's automation system. They operate on record data and return structured results that your automation can act on. * **Classification** -- Categorize records by analyzing field content and assigning labels with confidence scores * **Summarization** -- Generate concise summaries from long-form text fields, comments, or attached documents * **Data transformation** -- Restructure, normalize, or enrich field values using language model processing * **File analysis** -- Extract structured data from PDFs, invoices, contracts, and other uploaded documents Each AI action returns results that downstream automation steps can use for routing, field updates, notifications, or further processing. Learn how to configure AI-driven automation actions Understand the triggers, conditions, and actions that power Elementum automations ## AI Agents Agents are conversational AI components that operate within your apps. Unlike one-shot AI actions in automations, agents maintain context across a conversation, use tools to read and write data, and follow policies you define. What agents are, what they can do, and where they fit in your processes Create, configure, and test agents in your apps ## Data Cloud Architecture AI processing in Elementum runs within your data cloud environment. This architecture has several practical implications: * **No data movement** -- AI actions query and process data where it already lives. Records stay in your data warehouse; only prompts and results move between systems. * **Inherited security** -- AI capabilities respect your existing access controls, role-based permissions, and audit logging. No separate security layer is required. * **Real-time data** -- AI operates on current record states, not cached snapshots. When an agent queries an Element, it reads the latest data. ## Getting Started Setting up AI in Elementum follows a consistent sequence. Complete each layer before moving to the next. 1. **Connect a provider** -- Configure at least one AI provider ([OpenAI](/ai-agents/openai-setup), [Anthropic](/ai-agents/anthropic-setup), [Snowflake Cortex](/ai-agents/snowflake-cortex-setup), [Google Gemini](/ai-agents/gemini-setup), [Amazon Bedrock](/ai-agents/bedrock-setup), or a [Custom OpenAI-compatible endpoint](/ai-agents/ai-services#configure-a-custom-provider)) with your API credentials. 2. **Create AI services** -- Set up [LLM services](/ai-agents/ai-services) for the models you want to use in automations and agents. If you plan to use semantic search, create an [embedding service](/ai-agents/ai-services) as well. 3. **Enable AI search** *(optional)* -- Configure [AI Search](/ai-agents/ai-search) on Elements and Tables where you want natural language querying. 4. **Add AI actions to automations** -- Use [AI automation actions](/ai-agents/ai-automations) to classify, summarize, transform, or analyze data within your existing workflows. 5. **Build and deploy agents** -- Start with the [Agents Overview](/ai-agents/agents-overview), then create [agents](/ai-agents/agents-experience) with tools, skills, and policies tailored to your business processes. Deploy them in-app or across [Teams](/ai-agents/agents-teams-integration), [Slack](/ai-agents/agents-slack-integration), or [phone](/ai-agents/agents-phone-integration). Start with a single use case -- like classifying incoming requests or summarizing documents -- before building multi-step agent workflows. This lets you validate your provider configuration and service setup with minimal complexity. # AI Search Source: https://docs.elementum.io/ai-agents/ai-search Enable intelligent semantic search across your data using AI embeddings AI Search lets you find information by meaning and context rather than exact keyword matches. It uses embeddings to convert text into vector representations and then compares semantic similarity, so a search for "delivery delays" can surface records about "shipping bottleneck" even when no words overlap. You can configure multiple search fields per table and choose between semantic search and keyword search for each field. AI Search is available on **Elements** and **Tables**. You can also use it as an action step in automations or as a tool that agents can call at runtime. ## Requirements **Snowflake Cortex only.** AI Search is exclusively powered by Snowflake Cortex embedding services. OpenAI and Gemini providers cannot be used for AI Search. Before configuring AI Search, confirm the following: * **Snowflake Cortex provider** configured with an embedding service — see [Snowflake Cortex Setup](/ai-agents/snowflake-cortex-setup) * **Standard Snowflake table** — transient, temporary, hybrid, external, and dynamic tables are not supported * **Change tracking enabled** on all underlying Snowflake tables — this can be enabled at any time, even after connecting an Element to Elementum. Run `ALTER TABLE SET CHANGE_TRACKING = TRUE;` if it is not already on. * **At least one text field** containing the content you want to search * **A unique identifier field** (primary key) on each record For automation triggers like "Record is updated" on Snowflake tables, change tracking must be enabled **before** configuring the trigger. ## How It Works 1. **Content processing** — Your text data is converted into high-dimensional vectors (embeddings) that represent semantic meaning. 2. **Query understanding** — When you search, your query is converted into an embedding using the same model. 3. **Similarity matching** — The system finds content whose embeddings are closest to your query, regardless of exact word overlap. 4. **Results ranking** — Results are ordered by semantic similarity so the most relevant records appear first. ## Setting Up AI Search There are two ways to set up AI Search: create a new search table from scratch, or link an existing Cortex Search service that already lives in Snowflake. ### Create a New Search Table In the Intelligence tab, select **AI Search** from the menu. Click **+ Search Table** to begin configuring a new searchable table. * **Standard Table** — Select a Standard Snowflake table * **Unique Identifier** — Specify the field that uniquely identifies each record * **Fields to Search** — Add one or more text fields to search. For each field, choose a search type: * **Semantic search** — Finds results by meaning and context using embeddings, even when wording differs from the query * **Keyword search** — Matches results based on exact terms in the query * **Attribute Fields** — Select additional fields to return alongside search results (e.g., category, status, date) * **Service** — Choose your configured Snowflake Cortex embedding service * **Archival Service** — Select the Snowflake Cortex service to use when running search queries * **Target Lag** — Set how frequently the search index updates (`1` = daily) Click **Create** to build the search index. Initial indexing may take time depending on data volume. After clicking **Create**, track the configuration status on the AI Search page. The table displays a status indicator that moves from **Loading** to **Ready** once the search index is fully built and available for queries. If an error occurs during creation, click **Retry** to reattempt the search table setup. ### Link an Existing Cortex Search Service If you already have a Cortex Search service running in Snowflake, you can link it directly to an App or Element without recreating it in Elementum. The linked service becomes available for AI Search queries immediately. Open the App or Element where you want to use the existing search service. In the Intelligence tab, select **AI Search** from the menu. Click **+ Search Table** and select the option to link an existing Cortex Search service. Provide the following information to locate the service in Snowflake: * **Provider** — Select the Snowflake Cortex provider configured in your organization * **Database** — Choose the Snowflake database where the service resides * **Schema** — Select the schema that contains the Cortex Search service * **Search Table Name** — Enter the name of the existing Cortex Search service Click **Create** to link the service. Once linked, the search table is available for AI Search queries on the App or Element. Removing a linked Cortex Search service from Elementum only removes the reference — it does not delete the underlying service in Snowflake. Your Cortex Search service continues to run independently in your Snowflake environment. #### What you can configure on a linked service When you link an existing Cortex Search service, Elementum only stores the pointer to the service (provider, database, schema, and service name). Configuration of the service itself lives in Snowflake. **Managed in Elementum:** * Referencing the linked service in AI Search queries on the App or Element * Using the service in Automations (via the [AI Data Search](/workflows/automation-actions-reference#ai-data-search) action) and as an Agent tool * Removing the link (which does not affect the underlying Snowflake service) **Managed in Snowflake, not in Elementum:** * Search fields and search types (semantic vs. keyword) * Attribute fields returned with results * Embedding service and index refresh cadence (Target Lag) * Scoring profiles and any other Cortex Search service properties To change any of these on a linked service, update the service definition in Snowflake. To manage these from Elementum, create a new search table with **Standard Table** instead of linking (see above). ## Using the Search Interface Once a search table is configured, you can query it directly from the AI Search interface. **Natural language queries** — Type questions in plain language. AI Search understands meaning, so queries like "issues with payment processing" or "customer complaints about delivery" return semantically relevant results even when records use different phrasing. **Filtering** — Combine semantic search with attribute filters to narrow results by field values, date ranges, or categories. **Results** — Each result includes the matched text, a similarity score indicating how closely it relates to your query, and any attribute fields you configured during setup. ## AI Search in Other Features AI Search integrates with automations, agents, and Tables. Rather than configuring AI Search differently in each context, you set it up once (as described above) and then reference the search table where needed. ### Automations Use the **AI Search** action in an automation to run a semantic query as part of a workflow. Select a configured AI Search table as the source and pass a dynamic query using value references from earlier in the automation (e.g., `{{trigger.description}}`). For full configuration details and output variables, see [AI Data Search](/workflows/automation-actions-reference#ai-data-search) in the Automation Actions Reference. For broader guidance on using AI within automations, see [AI in Automations](/ai-agents/ai-automations). ### Agents AI Search can be configured as a tool that agents call at runtime to look up relevant records during a conversation. When adding AI Search as an agent tool, you can define input value references with descriptions and use them in filters so the agent passes values dynamically for context-aware search. For details on configuring agent tools, see [Agent Skills](/ai-agents/agents-skills). For building and managing agents, see [Building Agents](/ai-agents/agents-experience). ### Tables Table admins can enable AI Search on any Table. The setup follows the same process described above. For details on enabling AI Search within the Tables interface, see the [AI Search section](/data/tables#ai-search) on the Tables page. ## Tips for Better Results * **Choose descriptive text fields.** The fields you index should contain meaningful, readable content — not codes or IDs. Fields with complete sentences or descriptions produce better semantic matches. * **Keep content at a reasonable length.** Embedding models work best with content in the 512–1,024 token range. Very short or very long text can reduce match quality. * **Use consistent language.** Consistent terminology and formatting across records improves how well the embedding model captures your domain's semantics. * **Set appropriate result limits.** For most use cases, 10–50 results strikes the right balance between coverage and relevance. In automation workflows, start with a smaller limit and increase if needed. * **Update your index regularly.** The Target Lag setting controls how often new or changed records are indexed. Daily updates (Target Lag = `1`) work well for most cases; adjust if your data changes more frequently. ## Troubleshooting **Symptoms:** AI Search fails to create or index properly, or you receive errors about change tracking. **Solutions:** 1. Enable change tracking on the source Snowflake table: ```sql theme={null} ALTER TABLE SET CHANGE_TRACKING = TRUE; ``` 2. Verify change tracking is active: ```sql theme={null} SHOW TABLES LIKE ''; ``` Check the `change_tracking` column in the output. 3. For "Record is updated" automation triggers, change tracking must be enabled before configuring the trigger. **Symptoms:** The setup dialog does not allow you to create a search configuration. **Solutions:** 1. Confirm the table is a **Standard Snowflake table**. Transient, temporary, hybrid, external, and dynamic tables are not supported. 2. Verify that a Snowflake Cortex **embedding service** is configured under [AI Services](/ai-agents/ai-services). 3. Check that change tracking is enabled on the underlying table. 4. Ensure you have the necessary permissions to configure search. **Symptoms:** Searches return results that don't match the intent of your query. **Solutions:** 1. Review the content in your indexed text fields — short, vague, or code-like values produce weaker embeddings. 2. Try rephrasing your query to be more specific. 3. Check that the correct embedding service is selected in the search configuration. 4. If the indexed content has changed significantly since the last index update, wait for the next index refresh or reduce the Target Lag setting. **Symptoms:** Search queries take longer than expected to return results. **Solutions:** 1. Reduce the number of attribute fields returned with results. 2. Lower the result limit if it is set high. 3. Ensure your Snowflake warehouse is appropriately sized for the data volume. 4. Check Snowflake Cortex service status for any provider-side latency. ## Next Steps Create and manage the embedding services that power AI Search Learn how AI actions — including AI Search — fit into automation workflows Create agents that use AI Search as a runtime tool Full configuration details for the AI Search automation action # AI Services Source: https://docs.elementum.io/ai-agents/ai-services Create and manage AI services for LLMs and embeddings using your configured providers ## What Are AI Services? AI Services are specific AI model instances that you configure for use in your workflows. While AI Providers establish connections to external AI platforms, AI Services define the actual models, settings, and configurations that power your AI features. **Prerequisites**: You must have at least one AI Provider configured before creating AI Services. See the [AI Overview](/ai-agents/ai-overview#ai-providers) for setup instructions. ## Types of AI Services Elementum supports two types of AI Services: * **LLM Services** -- Language models for text generation, conversation, and analysis. Used for [agents](/ai-agents/agents-experience), [automation actions](/ai-agents/ai-automations), and content generation. * **Embedding Services** -- Embedding models for semantic search and similarity analysis. Used in [AI Search](/ai-agents/ai-search) to convert data into vector representations for semantic querying. ## Prerequisites Before creating services, you need at least one configured AI provider. Provider setup is covered on its own page per provider; once your provider is saved in **Organization Settings → Providers**, return here to create services. Connect OpenAI as a provider Connect Anthropic for direct Claude access Connect Snowflake Cortex for LLM and embedding services Connect Vertex AI Gemini Connect Bedrock-hosted models Connect any OpenAI-compatible endpoint (configured below) **Only verified domain users can configure AI Providers.** Elementum employees cannot create or modify AI Providers or Models in any customer org. See the [AI FAQ](/support/faq/faq-ai) for compliance details. **CloudLink type matters.** AI services are not supported on [API CloudLinks](/administration/connect-rest-api-cloudlink). They require a data-warehouse CloudLink such as a [Snowflake CloudLink](/administration/connect-snowflake-to-elementum) (with key-pair authentication for Cortex features). ## Configure a Custom Provider Use the **Custom** provider type to connect any OpenAI-compatible endpoint, including LLM gateways, proxies, and self-hosted models. Once configured, a custom provider can be used across agents and automations just like any built-in provider. 1. In **AI Services**, click **+ Connect Provider** and choose **Custom** 2. Enter a **Name** to identify the provider in Elementum 3. Enter the **URL** of the OpenAI-compatible endpoint 4. Select the connection type from the dropdown: * **API Key** -- Provide a static API key issued by your endpoint * **OAuth Credentials** -- Provide the OAuth Client Credentials (client ID, client secret, and token URL) used to obtain a bearer token 5. Enter the required credentials for the connection type you selected 6. Click **Save** Once the custom provider is configured, click **+ Add Models** on the provider to add any model identifier exposed by the endpoint. Custom-provider models then appear in the model dropdown when creating an LLM Service. The endpoint must implement the OpenAI Chat Completions API contract. Capabilities available to a custom-provider model (such as structured output, multimodal input, or reasoning) depend on what the underlying endpoint supports. ## Manage Providers Once a provider is connected, click on it in the **Providers** tab to: * View connection details and status * Edit the provider configuration or credentials * Delete the provider * Click **+ Add Models** to make additional models from this provider available to your services ## Configure Provider Failover Configure one or more backup providers so traffic automatically reroutes if the primary provider is unreachable. No user action is required during an outage. **Prerequisites:** * At least two configured AI Providers of compatible model families. * Each provider must have active, tested credentials. **Configuration steps:** 1. On the **Providers** tab, open the dropdown for the desired provider and click the Provider Details icon **Provider Details** icon. 2. Click the Edit icon **Edit** icon next to **Backup Providers**. 3. Select a provider to use in case of failover. Choose multiple to ensure several options are available. 4. Click **Save**. **Behavior notes:** * Failover is automatic — no user action is required during an outage. * Only providers whose status is **Active** are eligible targets. * Failover applies to all features consuming the primary provider (agents, search, summarization, and so on). * When the primary provider recovers, new requests resume routing to it. ## Migrate a Model Across the Organization Replace any AI model with a different model in a single action. Every automation action and agent that references the source model switches over automatically, so you don't need to update each one individually. **Configuration steps:** 1. On the **Providers** tab, click the dropdown next to the service whose model you want to replace. 2. Click the Replace Model icon **Replace Model** icon. 3. Select the new model from the dropdown. The popup lists every automation that uses the current model so you can review the impact before confirming. 4. Click **Replace**. **Behavior notes:** * The migration runs in the background and can take time when many automations reference the source model. Track progress under **Background tasks**. * Agents and automation actions referencing the source model are updated in place — you don't need to reopen and republish each one. ## Create AI Services To create a service: 1. Navigate to the **AI Services** page and open the **Services** tab. 2. Click **+ Service** and choose the service type—**LLM** for language models or **Embedding** for AI Search. 3. Configure the fields described below for the service type you selected. 4. Click **Save**. New services appear in the **Services** tab and can be [tested](#test-services) before assignment. ### Create an LLM Service LLM Services power conversational AI, text generation, and intelligent automation. **Service Name**: Give your service a descriptive name (e.g., "Customer Support Bot") **Provider**: Select your configured AI Provider **Model**: Choose from available models for your provider. See [AI Models](/ai-agents/ai-models) for a detailed comparison of capabilities, use cases, and pricing considerations across all providers. **Cost Per Million Tokens**: Optional cost tracking (varies by provider) **Temperature**: Controls randomness and creativity of responses (0.0–1.0). Lower values produce more deterministic, consistent outputs; higher values produce more varied, creative responses. Set to 0.0–0.3 for automation tasks like classification where consistency matters. **Reasoning Effort**: Controls how much computational effort the model invests in internal reasoning before responding (minimal/low/medium/high) * Use **minimal** for simple lookups and straightforward answers * Use **low** for basic reasoning tasks and simple problem solving * Use **medium** for moderate analytical tasks requiring multi-step reasoning (default) * Use **high** for complex problem solving, mathematical proofs, multi-step logic, and detailed analysis **Max Tokens**: Maximum response length **Top P**: Controls diversity of responses (nucleus sampling) **Frequency Penalty**: Reduces repetition in responses **Presence Penalty**: Encourages topic diversity **Stop Sequences**: Custom stop sequences for response control For use-case-specific tuning recommendations (e.g., optimal temperature for classification vs. content generation), see the [Temperature Settings](/ai-agents/ai-models#temperature-settings) and [Performance Optimization](/ai-agents/ai-models#performance-optimization) sections on the AI Models page. ### Create an Embedding Service Embedding Services enable [AI Search](/ai-agents/ai-search) and semantic understanding. **Service Name**: Descriptive name (e.g., "Document Search Embeddings") **Provider**: Select your configured AI Provider **Model**: Choose from available embedding models: * **Snowflake Arctic L V2.0** -- Latest high-quality embeddings * **Snowflake Arctic M V1.5** -- Reliable embeddings for production use **Dimensions**: Embedding vector size (varies by model) **Batch Size**: Number of texts to process simultaneously **Chunk Size**: Maximum text length per embedding **Overlap**: Text overlap between chunks (for long documents) **Normalization**: Whether to normalize embedding vectors **Encoding**: Text encoding method (usually UTF-8) ## Assign to Features Assign AI models to Elementum features at the organization level so those features have a default model available across your workflows. 1. Navigate to the **AI Services** page and click the **Features** tab 2. Click **+ Assign Model** next to a feature and select a model from the dropdown 3. Click **Save** To update an existing assignment, click **Change** next to the currently assigned model, select a new model from the dropdown, and click **Save**. The dropdown for each feature only lists models that Elementum has enabled for that feature. This is why the model list can differ between features -- for example, between **Transform Data with AI** and **AI Classification** -- even when both features use models from the same providers. Enablement is managed by Elementum's engineering team based on how well each model fits the feature's task; it is not something admins configure per model or per service. For more detail on this behavior in automation actions, see [Model Availability Across AI Actions](/ai-agents/ai-automations#model-availability-across-ai-actions). *** ## Test Services Before using AI Services in production, test them from the Services list: 1. Click on a service name to open the testing interface 2. For **LLM Services**: enter sample prompts, review AI-generated responses, adjust parameters, and monitor response times 3. For **Embedding Services**: enter sample text, review generated embedding vectors, and test similarity calculations between texts ## Manage and Optimize Once your services are created and tested, keep the following in mind: * **Model selection** -- The right model depends on your use case. For recommendations by task type (agents, classification, content generation, semantic search) and guidance on balancing cost and performance, see the [Model Selection Guide](/ai-agents/ai-models#model-selection-guide). * **Cost optimization** -- Right-size your model choices, write concise prompts, and set appropriate token limits to control spending. See [Cost Optimization](/ai-agents/ai-models#cost-optimization) for detailed strategies. * **Multiple providers** -- You can configure services across different providers for redundancy or to use different model strengths for different tasks. See [AI Providers](/ai-agents/ai-overview#ai-providers) for setup details. * **Feature-specific guidance** -- For details on how AI Services integrate with specific capabilities, see [AI in Automations](/ai-agents/ai-automations) for automation actions, [Building Agents](/ai-agents/agents-experience) for conversational agents, and [AI Search](/ai-agents/ai-search) for embedding-powered search. ## Troubleshooting **Symptoms:** Cannot create new AI services **Common Causes:** * AI Provider not configured * Invalid model selection * Insufficient permissions **Solutions:** 1. Verify AI Provider is properly configured 2. Check model availability for your provider 3. Ensure proper permissions are granted 4. Try creating with different model options **Symptoms:** Slow response times or quality issues **Common Causes:** * Inappropriate model selection * Suboptimal configuration * Network or provider issues **Solutions:** 1. Review model selection for your use case 2. Optimize service configuration settings 3. Check provider status and network connectivity 4. Consider switching to different models **Symptoms:** Unexpected high token usage or costs **Common Causes:** * Inefficient prompts or queries * Inappropriate model selection * Excessive API calls **Solutions:** 1. Review and optimize prompts 2. Use more cost-effective models where appropriate 3. Implement caching and batching 4. Monitor and analyze usage patterns ## Next Steps Compare models across providers to choose the right one for your use case Use embedding services to power semantic search across your data Create conversational AI assistants using your LLM services Add AI-driven actions to your automation workflows # Anthropic Setup Source: https://docs.elementum.io/ai-agents/anthropic-setup Configure Anthropic as your AI provider for direct access to Claude models in agents and automations ## Overview Anthropic is an AI provider in Elementum that connects directly to the Anthropic API, giving you access to Claude models for agents, automation actions, and other AI-driven features. Using Anthropic as a direct provider expands model choice in your organization without routing requests through Snowflake Cortex or AWS Bedrock. Anthropic Claude is also the primary model used by [Studio Agents](/ai-agents/studio-agents), Elementum's coding-based agents that generate automations, agents, and flows through conversation. **Prerequisites**: You'll need an Anthropic account with API access. Workspace and organization accounts on the Anthropic Console are both supported. ## Step 1: Get Your Anthropic API Key ### Create an Anthropic Account 1. **Visit the Anthropic Console** * Go to [console.anthropic.com](https://console.anthropic.com) * Sign up for an account or log in to your existing account 2. **Set Up Billing** * Navigate to **Settings** → **Billing** * Add a payment method to enable API access * Consider setting usage limits and budget alerts to control costs ### Generate Your API Key In the Anthropic Console, navigate to **Settings** → **API Keys** Click **Create Key** Give your key a descriptive name like "Elementum Integration" **Critical**: Copy the API key immediately and store it securely You won't be able to view the full key again after closing the dialog If you're using Workspaces, scope the key to the workspace whose usage limits and billing should apply to Elementum traffic Ensure the key has access to the Claude models you plan to use Never share your API key or commit it to version control. Store it in a secure location like a password manager. ## Step 2: Configure Anthropic in Elementum ### Add the Provider 1. In Elementum, go to **Organization Settings** and select the **Providers** tab 2. Click **+ Provider** and select **Anthropic** from the provider options 3. Configure the provider settings: **Provider Name**: Enter a descriptive name (e.g., "Anthropic Production") **API Key**: Paste your Anthropic API key **CloudLink**: Select which CloudLinks can access models from this provider. Leave as "All CloudLinks" unless you need to restrict access. AI services do not support CloudLinks configured with **API** as the connection type. Only CloudLinks connected to a supported data warehouse (Snowflake, BigQuery, or Databricks) can be associated with this provider. **Request Timeout**: Default is usually sufficient (30 seconds) **Max Retries**: Number of retry attempts for failed requests (default: 3) **Rate Limiting**: Anthropic handles rate limiting automatically based on your account tier 4. Click **Save** to create the provider. Elementum will automatically validate your API key — look for a green checkmark indicating a successful connection. ## Step 3: Create your first AI service With your Anthropic provider configured, create an AI Service that uses a Claude model. See [AI Services](/ai-agents/ai-services) for the full walkthrough, including LLM service configuration, assignment, and failover. For Claude model capabilities and recommended use cases, see [AI Models](/ai-agents/ai-models#anthropic-direct). **Studio Agents**: Anthropic is the primary provider supported on Studio Agents. When using Studio Agents to build automations, agents, and flows, select a Claude model configured through this provider. **Note**: Embeddings for AI Search are handled exclusively through Snowflake Cortex. Anthropic models are used for LLM services only. ## Usage Guidelines ### Cost Management Anthropic charges based on input and output token usage, with rates that vary by model. To manage costs: * Monitor usage in the Anthropic Console * Set up budget alerts and spend limits * Review token consumption by model regularly * Use Haiku models for high-volume, lower-complexity tasks * Reserve Opus models for tasks that require the highest reasoning quality * Right-size prompts and set appropriate max-token limits * Cache or reuse system prompts where possible ### Best Practices * Use **Claude Haiku** models for fast, high-volume operations and simple automations * Use **Claude Sonnet** models for balanced reasoning, production agents, and detailed analysis * Use **Claude Opus** models for the most demanding reasoning and content tasks * Be specific and clear in your prompts * Use system messages to set consistent behavior and tone * Provide examples for tasks that need a particular format * Break complex requests into structured, step-by-step instructions * Choose Haiku models for speed-critical applications * Use Sonnet for the best balance of quality, speed, and cost * Reserve Opus for tasks where quality matters more than latency or cost * Implement retry logic with exponential backoff for transient errors ## Troubleshooting **Symptoms:** API key rejected or unauthorized errors **Common Causes:** * Invalid or revoked API key * Insufficient workspace permissions * Billing issues on the Anthropic account **Solutions:** 1. Verify the API key is correct and active in the Anthropic Console 2. Check the workspace the key is scoped to 3. Confirm billing is active and payment methods are valid 4. Regenerate the API key if needed and update the provider in Elementum **Symptoms:** Desired Claude model doesn't appear in service creation **Common Causes:** * Your Anthropic account or workspace doesn't have access to the model * Regional restrictions * Model deprecation or rollout in progress **Solutions:** 1. Confirm model availability for your account in the Anthropic Console 2. Review workspace-level access to the model 3. Contact Anthropic support for access questions 4. Consider an alternative Claude model with similar capabilities **Symptoms:** Requests being throttled or rejected **Common Causes:** * Exceeding account-tier rate limits * High concurrent usage across agents and automations * Burst traffic on a single workspace **Solutions:** 1. Implement exponential backoff and retries 2. Spread traffic across less time-sensitive workflows 3. Request a rate-limit increase from Anthropic 4. Use multiple workspaces or keys for traffic segmentation ## Security Considerations * Never expose API keys in client-side code or shared documents * Rotate keys regularly * Scope keys to the narrowest workspace that meets your needs * Monitor key usage for anomalies in the Anthropic Console * Review Anthropic's current data handling and privacy policies * Consider data sensitivity when crafting prompts * Implement data sanitization for fields that may contain PII or secrets ## Next Steps With Anthropic configured as your AI Provider: Set up specific LLM services that use your Claude models Compare Claude models and pick the right one for your use case Create conversational AI assistants using Claude models Add AI capabilities to your automation workflows # AWS Bedrock Agents Setup Source: https://docs.elementum.io/ai-agents/bedrock-agents-setup Connect a Bedrock Agent built in AWS to an Elementum App via App Intelligence, and invoke it from automations ## Overview AWS Bedrock Agents are agents you build in your own AWS account using Amazon foundation models, knowledge bases, action groups, and guardrails. Elementum lets you connect a Bedrock Agent to an App through **App Intelligence** so you can invoke it from automations and conversational workflows—while data access and execution stay inside your AWS environment. You will: * (If needed) Create a Bedrock Agent and an agent alias in AWS. * Add `bedrock:InvokeAgent` to the IAM user or IAM role used by your Bedrock AI Provider. * Connect the agent to an App through App Intelligence using the **Agent Alias ARN**. * Use the agent in automations via **Run Agent Task**. **Time required**: About 15–30 minutes if your Bedrock Agent already exists in AWS; longer if you are building the agent from scratch. ## Prerequisites ### Elementum requirements * **App access**: Access to the App where you want to use the Bedrock Agent. * **Bedrock AI Provider configured**: An Amazon Bedrock AI Provider must already exist in **Organization Settings → Providers** (using either credential-based or IAM role authentication). If you haven't set this up, complete [AWS Bedrock Setup](/ai-agents/bedrock-setup) first—this guide assumes that's done. ### AWS requirements Your AWS environment must have: * An **AWS Account** with Bedrock enabled in your target region. * **Foundation model access** granted to the model your agent will use. * The IAM user or IAM role used by your Bedrock AI Provider must include the `bedrock:InvokeAgent` permission (see [Step 2](#step-2-grant-invokeagent-permission)). **Model access**: Confirm model access in the Amazon Bedrock console for your account and region; approval timing depends on AWS. ## Step 1: Configure the Bedrock Agent in AWS If you have not yet built the agent in AWS, create it and an agent alias before connecting to Elementum. Skip to [Step 2](#step-2-grant-invokeagent-permission) if you already have a Bedrock Agent and alias. ### Create a Bedrock Agent in AWS 1. Sign in to the AWS Management Console. 2. Navigate to the **Amazon Bedrock** service. 3. Select **Agents** from the left navigation. Click **Create agent** and configure: * **Agent name**: Provide a descriptive name (e.g., "Customer Support Agent"). * **Description**: Describe the agent's purpose. * **Agent resource role**: Create a new role or select an existing one with Bedrock permissions. Provide clear instructions that define the agent's behavior: ``` You are a helpful customer support assistant. You help users with their questions about orders, returns, and product information. Always be polite and professional. ``` Clear, specific instructions lead to better agent performance. Include examples of expected behavior and any constraints. Choose the foundation model to power your agent. Model availability depends on your region and account access. Request model access in the Bedrock console if needed. Optionally enhance your agent with: **Knowledge Bases:** * Attach Amazon Bedrock knowledge bases using supported data sources (for example, Amazon S3). * The agent can retrieve and cite that content when answering. **Action Groups:** * Define custom actions via Lambda functions. * Enable the agent to perform specific tasks. **Guardrails:** * Implement content filtering. * Define topic restrictions. Click **Create** to save the agent configuration. The agent will be created in **Draft** status. ### Create an agent alias Elementum invokes agents with an **Agent Alias ARN**, not the base agent ARN. 1. In the Bedrock console, open the agent and open the **Aliases** tab. 2. Click **Create alias**. Set an alias name and description, and choose **Create a new version and associate it to this alias** so the alias points at a prepared version. 3. After creation, copy the **Agent Alias ARN**. Format: `arn:aws:bedrock:{region}:{account-id}:agent-alias/{agent-id}/{alias-id}` Example: ``` arn:aws:bedrock:us-east-2:123456789012:agent-alias/ABCD1234EF/GHIJ5678KL ``` ### Test the agent in the AWS console Before connecting to Elementum, verify your agent works correctly: 1. In the Bedrock console, open your agent. 2. Use the **Test** panel on the right side. 3. Send test messages to verify behavior. 4. Confirm responses match your expectations. ## Step 2: Grant InvokeAgent permission The IAM identity (user or role) backing your Bedrock AI Provider must be able to invoke agents. * If your provider uses **credential-based authentication**, edit the IAM user's policy. * If your provider uses **IAM role authentication**, edit the IAM role's policy. 1. In the AWS Console, go to **IAM** and open the user or role used by your Bedrock AI Provider. 2. Edit the attached policy and add `bedrock:InvokeAgent` to the existing statement (alongside `bedrock:InvokeModel`): ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "bedrock:InvokeModel", "bedrock:InvokeAgent" ], "Resource": "*" } ] } ``` **Least privilege**: For production, restrict the `Resource` to specific model and agent ARNs: ```json theme={null} "Resource": [ "arn:aws:bedrock:us-east-2::foundation-model/*", "arn:aws:bedrock:us-east-2:123456789012:agent-alias/*" ] ``` 3. Save the policy. If your agent uses knowledge bases or action groups, the agent's own IAM role (not the invoker role) needs additional permissions for those resources. ## Step 3: Connect the agent in App Intelligence ### Open App Intelligence 1. Open the App where you want to use the Bedrock Agent. 2. In the App menu, click **Intelligence**. ### Connect the Bedrock agent On the Intelligence page, click **+ Connect** (or the control your workspace uses to connect a managed agent). Choose **Bedrock** as the agent source. Choose your Amazon Bedrock AI Provider. Only providers with working credentials appear. Paste the **Agent Alias ARN** from [Create an agent alias](#create-an-agent-alias). Do not use the base agent ARN. **Agent Name**: Optionally customize the display name in Elementum. **Description**: Add notes about how this agent will be used in your App. Click **Save** to connect the external agent. The agent will now appear in your App's Intelligence configuration. ## Step 4: Test the integration Verify the agent connection works correctly. ### Test in Elementum In App Intelligence, click on the connected Bedrock agent. Click **Chat** to open the interactive testing panel. Send messages to confirm: * The agent responds successfully. * Responses are appropriate and match expectations. * Latency is acceptable for your use case. Test various scenarios relevant to your use case: * Standard queries. * Edge cases. * Knowledge base retrieval (if configured). * Action group execution (if configured). ### Expected behavior | Test | Expected result | | ------------------------ | ------------------------------------------- | | Simple greeting | Agent responds appropriately | | Domain-specific question | Agent uses knowledge base (if configured) | | Action request | Agent executes action group (if configured) | | Out-of-scope question | Agent handles gracefully per instructions | ## Step 5: Use the agent in automations Use your Bedrock Agent in App automations for production workflows. ### Using agents in automation actions In the automation builder, the action type is **Run Agent Task**. For full field-level detail, see [Run Agent Task](/workflows/automation-actions-reference) in the automation actions reference. In your App, open the automation where you want to use the agent. Add a new action or edit an existing one, then choose **Run Agent Task**. Under **AI Agent** (or equivalent), choose the external Bedrock Agent you connected in Intelligence. It may appear as **External** or **Managed**, depending on your workspace. **Task definition**: Describe what the agent should do and how success is judged. Use value references for record fields, prior action outputs, or static text where supported. **Output type**: Choose **Text** or **Structured**. For structured output, define fields so later automation steps can map results to records or variables. Configure any error or follow-up behavior your automation requires after the task completes. **Timeout**: Set a maximum execution time that fits your agent and knowledge sources (the editor may suggest a default). **Retry Policy**: Configure retry behavior for transient failures. **Error Handling**: Define failure behavior: * Continue with default values. * Halt automation and alert. * Escalate to human review. ### Example automation (conceptual) The following illustrates how steps might flow; exact builder labels can vary by release. ```yaml theme={null} Workflow: Customer Inquiry Processing Trigger: New inquiry record created Automations: 1. Gather Context: - Collect customer information - Retrieve previous interactions 2. Run Agent Task – Analysis: Type: Run Agent Task Agent: Customer Support Agent (Bedrock / Managed) Inputs: - customer_inquiry: {record.description} - customer_history: {customer.interaction_history} Outputs: - response: record.suggested_response - category: record.inquiry_category - sentiment: record.customer_sentiment 3. Route Based on Category: - High priority → Immediate escalation - Standard → Queue for review - FAQ → Auto-respond with suggestion ``` ## How Bedrock Agent invocation works When Elementum invokes a Bedrock Agent: ```mermaid theme={null} sequenceDiagram participant Auto as Automation participant Intel as App Intelligence participant Prov as Bedrock AI Provider participant AWS as AWS Bedrock participant BA as Bedrock Agent participant KB as Knowledge Bases participant AG as Action Groups Auto->>Intel: Invoke External Agent Intel->>Prov: Route via Provider Prov->>AWS: InvokeAgent API AWS->>BA: Execute Agent BA->>KB: Query Knowledge (optional) KB->>BA: Return Context BA->>AG: Execute Actions (optional) AG->>BA: Return Results BA->>AWS: Generate Response AWS->>Prov: Return Response Prov->>Intel: Format Response Intel->>Auto: Continue Automation ``` ### AWS Bedrock API used **InvokeAgent** sends a prompt to the agent and returns the agent's response (including optional tool and knowledge-base steps on the AWS side). **Key parameters:** * `agentAliasId`: The alias ID of the agent. * `agentId`: The unique identifier of the agent. * `sessionId`: Session identifier for conversation continuity. * `inputText`: The message to send to the agent. **Documentation**: [Amazon Bedrock InvokeAgent API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent-runtime_InvokeAgent.html) ### Security model | Aspect | Implementation | | ------------------- | ---------------------------------------------------------------------------------- | | **Authentication** | IAM Access Key/Secret Key or IAM Role (assumed at runtime) via Bedrock AI Provider | | **Authorization** | IAM policies control which agents can be invoked | | **Data in transit** | TLS encryption for all API calls | | **Audit** | AWS CloudTrail logs all Bedrock API calls | | **Isolation** | App-level configuration with provider-based access | ## Monitoring and Maintenance ### Monitoring agent performance **In Elementum** * Use automation history and related logs to review invocations, response times, success and failure rates, and error messages. **In AWS** * Use CloudWatch and Cost Explorer (as applicable) for Bedrock API volume, latency, errors, and token or usage-related metrics. ### Maintenance tasks **Weekly:** * Review automation logs for agent errors. * Monitor response times and latency. * Check for timeout patterns. **Monthly:** * Review agent usage and costs. * Audit IAM permissions. * Test agent behavior after any updates. **Quarterly:** * Rotate IAM access keys. * Review and optimize agent instructions. * Evaluate new foundation models. When updating Bedrock Agents: 1. **Test in AWS**: Verify changes in the Bedrock console first. 2. **Create New Alias**: Create a new alias for the updated version. 3. **Update Elementum**: Update the Agent Alias ARN if using a new alias. 4. **Test Integration**: Validate automations with the updated agent. 5. **Monitor**: Watch for issues after deployment. Use separate aliases for testing and production to safely test changes. As usage grows: **AWS Side:** * Monitor Bedrock service quotas. * Request quota increases if needed. * Consider provisioned throughput for consistent performance. **Elementum Side:** * Monitor automation execution times. * Implement caching for repeated queries. * Use async patterns for long-running operations. ## Troubleshooting **Error**: "Access Denied" or "Not authorized to perform bedrock:InvokeAgent". **Possible causes:** * IAM user or role missing `bedrock:InvokeAgent` permission. * Policy not attached to the user or role. * Resource restrictions in policy don't match the agent ARN. * For IAM Role auth: trust policy does not allow Elementum to assume the role. **Solutions:** 1. Verify the IAM policy includes `bedrock:InvokeAgent` and is attached to the IAM identity (user or role) configured on the Bedrock AI Provider (see [Step 2](#step-2-grant-invokeagent-permission)). 2. Ensure the policy `Resource` matches your agent alias ARNs or uses a permitted pattern. 3. For credential-based auth, confirm the access keys in Elementum belong to the correct IAM user. 4. For IAM Role auth, verify the role's trust policy allows Elementum to assume it. **Error**: "Invalid ARN format" or "Resource not found". **Possible causes:** * Using the base agent ARN instead of the agent alias ARN. * Typo in the ARN. * Wrong region in the ARN. **Solutions:** 1. Ensure you're using the **Agent Alias ARN**, not the base Agent ARN. 2. Verify the format: `arn:aws:bedrock:{region}:{account}:agent-alias/{agent-id}/{alias-id}` 3. Copy the ARN directly from the AWS console. 4. Check that the region matches your provider configuration. **Correct format:** ``` arn:aws:bedrock:us-east-2:123456789012:agent-alias/ABCD1234EF/GHIJ5678KL ``` **Incorrect (base agent ARN):** ``` arn:aws:bedrock:us-east-2:123456789012:agent/ABCD1234EF ``` **Error**: "Could not connect to endpoint" or timeout errors. **Possible causes:** * Provider configured for a different region than the agent. * Agent not available in the specified region. **Solutions:** 1. Verify the region in your Bedrock AI Provider matches where the agent is deployed. 2. Check the region in the Agent Alias ARN. 3. Confirm Bedrock is available in your target region. 4. Update provider configuration if needed. **Error**: "Agent execution timed out". **Possible causes:** * Timeout set too low for agent complexity. * Agent accessing slow knowledge bases. * Large response generation. * Network latency. **Solutions:** 1. Increase timeout in automation configuration. 2. Optimize agent instructions for faster responses. 3. Review knowledge base configuration for performance. 4. Consider breaking complex tasks into multiple calls. **Error**: "Alias has no associated version" or unexpected behavior. **Possible causes:** * Alias created without linking to a version. * Agent in draft state without prepared version. **Solutions:** 1. In the Bedrock console, verify the alias has an associated version. 2. Create a new alias and select "Create a new version and associate it". 3. Ensure the agent is not in draft state. ### Debugging tips 1. **Test in AWS first**: Always verify the agent works in the Bedrock console before troubleshooting Elementum integration. 2. **Check CloudTrail**: Review AWS CloudTrail logs for detailed API call information. 3. **Verify credentials**: Test IAM credentials independently using the AWS CLI. 4. **Review provider status**: Check the Bedrock AI Provider status in Elementum. ## Best Practices * Use Bedrock Guardrails and clear instruction scope where appropriate. * Review agent behavior and access periodically. Clear, concise agent instructions usually produce faster, more predictable responses. Prefer explicit scope, examples, and constraints over long generic prompts. Track response times in automations and in AWS where you have metrics. Set automation timeouts high enough for knowledge-base retrieval and tool use, without masking real failures. Where the same or similar agent inputs occur often, consider caching or deduplicating at the automation level so you do not pay latency and usage for identical work. For automations that invoke agents at high volume, add throttling or batching so you stay within quotas and avoid unnecessary parallel cost spikes. Review knowledge base size, refresh cadence, and retrieval settings so you are not indexing or retrieving more content than the agent needs. ## Example Use Cases **Scenario:** Automatically triage and respond to IT support tickets. **Implementation:** 1. Create a Bedrock Agent with an IT knowledge base (documentation, FAQs). 2. Configure action groups for ticket operations. 3. Connect the agent in the IT Support App Intelligence. 4. Set up automation: New ticket → Agent analysis → Auto-categorize and suggest resolution. **Outcomes:** * Faster first response times. * Consistent ticket categorization. * Reduced L1 support workload. **Scenario:** Generate personalized customer communications. **Implementation:** 1. Create a Bedrock Agent with communication templates and brand guidelines. 2. Configure guardrails for appropriate content. 3. Connect the agent in the CRM App. 4. Automation: Communication request → Agent drafts message → Human review → Send. **Outcomes:** * Consistent brand voice. * Personalized content at scale. * Faster communication turnaround. ## Next Steps Configure the Bedrock provider for AI Services (prerequisite for this guide) Build automations that invoke your Bedrock Agent Compare native Elementum agents with managed external agents Reference AWS's official Bedrock Agents documentation # AWS Bedrock Setup Source: https://docs.elementum.io/ai-agents/bedrock-setup Configure AWS Bedrock as an AI provider for Claude and other Bedrock-hosted models in Elementum AI Services ## Overview This guide walks you through setting up Amazon Bedrock as an AI Provider in Elementum so you can use Bedrock-hosted Claude (and other foundation) models across your AI Services, automations, and agents. Running models through your own AWS account keeps AI workloads within your cloud infrastructure and compliance boundaries. **Connecting a Bedrock Agent built in AWS to an Elementum App is a separate setup.** Once this provider is configured, see [AWS Bedrock Agents Setup](/ai-agents/bedrock-agents-setup) to invoke a Bedrock Agent through App Intelligence. **Time required**: About 15–20 minutes, depending on your existing AWS setup. ## Prerequisites ### Elementum requirements * **Organization permissions**: Ability to add or edit AI Providers in **Organization Settings**. ### AWS requirements * **AWS Account**: Active AWS account with Bedrock access. * **Region**: Bedrock available in your target region (e.g., `us-east-1`, `us-east-2`, `us-west-2`). * **Bedrock Access**: Amazon Bedrock service enabled for your account. * **Foundation Model Access**: Access granted to at least one foundation model (Claude, Titan, etc.). * **IAM Permissions**: Ability to create IAM users and policies. **Model access**: You need access to the foundation models you plan to use. In the Amazon Bedrock console, confirm model access for your account and region; approval timing depends on AWS. ## Step 1: Prepare AWS Authentication Elementum supports two methods for authenticating the Bedrock AI Provider with AWS: * **Credential-based (Access Key + Secret Key)** — Create an IAM user with programmatic access and provide its access keys to Elementum. Best when your organization manages service accounts with long-lived credentials. * **IAM Role** — Provide an IAM role ARN that Elementum assumes at runtime. Aligns with enterprise AWS security practices by eliminating static credentials and using role-based access instead. Choose one method below and follow the corresponding steps. Create an IAM user whose access keys Elementum will use to call Bedrock models. In the AWS Console, go to **IAM** → **Users** → **Create user**. * **User name**: Choose a descriptive name (e.g., `elementum-bedrock-invoker`). * Do not enable console access (programmatic access only). Create and attach a policy with `bedrock:InvokeModel`. If you also plan to connect Bedrock Agents later, include `bedrock:InvokeAgent` now or add it then. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "bedrock:InvokeModel" ], "Resource": "*" } ] } ``` **Least privilege**: For production, restrict the `Resource` to specific model ARNs: ```json theme={null} "Resource": [ "arn:aws:bedrock:us-east-2::foundation-model/*" ] ``` 1. Open the user details. 2. Go to the **Security credentials** tab. 3. Click **Create access key**. 4. Choose a use case that matches programmatic access from outside AWS, then complete the prompts. 5. Copy and securely store the **Access Key ID** and **Secret Access Key**. **Store credentials securely**: The secret access key is only shown once. Store it in a secure password manager until you configure it in Elementum. Create an IAM role that Elementum assumes at runtime to call Bedrock models. In the AWS Console, go to **IAM** → **Roles** → **Create role**. Set up the trust relationship so Elementum can assume the role. Select **Custom trust policy** and configure it to allow Elementum's AWS account to assume the role. Attach a policy with `bedrock:InvokeModel`. If you also plan to connect Bedrock Agents later, include `bedrock:InvokeAgent` now or add it then. ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "bedrock:InvokeModel" ], "Resource": "*" } ] } ``` **Least privilege**: For production, restrict the `Resource` to specific model ARNs: ```json theme={null} "Resource": [ "arn:aws:bedrock:us-east-2::foundation-model/*" ] ``` After creation, copy the **Role ARN** from the role summary page. Format: `arn:aws:iam::{account-id}:role/{role-name}` ## Step 2: Create the Bedrock AI Provider in Elementum Configure Elementum to connect to AWS using the authentication method you prepared in Step 1. 1. Go to **Organization Settings** and open the **Providers** tab. 2. Click **+ Provider** and select **Amazon Bedrock**. 3. Enter a **Provider name** and the **Region** where your Bedrock resources are deployed (for example `us-east-2`). 4. Choose your authentication method: * **Credential-based**: Enter the **Access Key ID** and **Secret Access Key** from your IAM user. * **IAM Role**: Enter the **Role ARN** from the IAM role you created. 5. Use **Test Connection** to confirm the configuration, then **Save**. The provider is now available for creating AI Services. **Tips** * The provider **Region** must match the region where your Bedrock models are available. * Use separate providers for different AWS accounts or regions if needed. * IAM Role authentication avoids static credential rotation and aligns with AWS security best practices for enterprise environments. ## Step 3: Create your first AI service With the provider saved, create an AI Service that uses a Bedrock-hosted model. See [AI Services](/ai-agents/ai-services) for the full walkthrough, including LLM and embedding service configuration, assignment, and failover. Bedrock-hosted models run within your AWS account, keeping AI workloads inside your own cloud infrastructure and compliance boundaries. For a side-by-side comparison of available Bedrock models against other providers, see [AI Models](/ai-agents/ai-models). ## How Bedrock model invocation works When Elementum invokes a Bedrock-hosted model: ```mermaid theme={null} sequenceDiagram participant Auto as Automation / Agent participant Svc as AI Service participant Prov as Bedrock AI Provider participant AWS as AWS Bedrock participant FM as Foundation Model Auto->>Svc: Generate completion Svc->>Prov: Use Bedrock provider Prov->>AWS: InvokeModel API AWS->>FM: Run prompt on model FM->>AWS: Return tokens AWS->>Prov: Return response Prov->>Svc: Return response Svc->>Auto: Continue ``` ### AWS Bedrock API used **InvokeModel** sends a prompt to a Bedrock-hosted foundation model and returns the model response. Used by all AI Services created with the Bedrock provider. **Key parameters:** * `modelId`: The identifier of the foundation model. * `body`: The request payload (prompt, parameters). * `contentType` / `accept`: Media types for the request and response. **Documentation**: [Amazon Bedrock InvokeModel API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html) ### Security model | Aspect | Implementation | | ------------------- | ---------------------------------------------------------------------------------- | | **Authentication** | IAM Access Key/Secret Key or IAM Role (assumed at runtime) via Bedrock AI Provider | | **Authorization** | IAM policies control which models can be invoked | | **Data in transit** | TLS encryption for all API calls | | **Audit** | AWS CloudTrail logs all Bedrock API calls | ## Troubleshooting **Error**: "Access Denied" or "Not authorized to perform bedrock:InvokeModel". **Possible causes:** * IAM user or role missing `bedrock:InvokeModel` permission. * Policy not attached to the user or role. * Resource restrictions in policy don't match the model ARN. * For IAM Role auth: trust policy does not allow Elementum to assume the role. **Solutions:** 1. Verify the IAM policy includes `bedrock:InvokeModel` and is attached to the IAM user (for credential-based auth) or IAM role (for role-based auth) configured on the Bedrock AI Provider. 2. Ensure the policy `Resource` matches your foundation model ARNs or uses a permitted pattern. 3. For credential-based auth, confirm the access keys in Elementum belong to the correct IAM user. 4. For IAM Role auth, verify the role's trust policy allows Elementum to assume it. **Error**: "Could not connect to endpoint" or timeout errors. **Possible causes:** * Provider configured for a different region than where the model is available. * Model access not granted in the configured region. **Solutions:** 1. Verify the region in your Bedrock AI Provider matches where the model is enabled. 2. Confirm Bedrock and the model are available in your target region. 3. Update provider configuration if needed. **Error**: Connection test returns an error despite credentials looking correct. **Solutions:** 1. Confirm the IAM user or role has at least `bedrock:InvokeModel` permission. 2. Verify the **Region** field uses the AWS region code (for example `us-east-2`, not `US East 2`). 3. Check that no SCP or AWS Organizations policy is blocking Bedrock for the account. 4. For IAM Role auth, confirm the role's trust policy is configured correctly. ## Best Practices * Apply least privilege; scope `bedrock:InvokeModel` to specific model ARNs when practical. * Prefer IAM Role authentication for enterprise environments to avoid managing static credentials. * If using credential-based auth, rotate access keys on a schedule your organization defines (for example, every 90 days). * Use different IAM users, keys, or roles per environment (development vs production). Pick a foundation model that balances latency, cost, and quality for your task. Available models depend on your AWS region and account. See [AI Models](/ai-agents/ai-models) for a comparison across providers. Use AWS Cost Explorer (and related billing views) to monitor token-related usage and Bedrock charges tied to your provider. Prefer smaller or faster models for straightforward classification or short replies when quality requirements allow; reserve larger models for harder reasoning. ## Next Steps Create LLM services using Bedrock-hosted models Compare models across providers Connect a Bedrock Agent you've built in AWS to an Elementum App Reference AWS's official Bedrock documentation # Google Gemini Setup Source: https://docs.elementum.io/ai-agents/gemini-setup Configure Google Gemini as your AI provider for language model services ## Overview Google Gemini provides language models through Google Cloud's Vertex AI platform, including Gemini 2.5 Pro, Gemini 2.5 Flash, and Gemini 1.5 Pro. This guide walks you through setting up Google Gemini as an AI Provider in Elementum. **Prerequisites**: You'll need a Google Cloud account with billing enabled and access to Vertex AI APIs. ## Step 1: Set Up Google Cloud Project ### Create or Select a Project 1. **Access Google Cloud Console** * Go to [console.cloud.google.com](https://console.cloud.google.com) * Sign in with your Google account 2. **Create a New Project** (or select an existing one) * Click on the project selector at the top of the page * Click **New Project** * Enter a project name (e.g., "Elementum AI Integration") * Select your billing account * Click **Create** 3. **Enable Billing** * Ensure your project has billing enabled * Navigate to **Billing** in the left sidebar * Link a billing account if not already configured ### Enable Required APIs Enable the following APIs for Vertex AI access: 1. In the Google Cloud Console, go to **APIs & Services** → **Library** 2. Search for **Vertex AI API** and click **Enable** — this may take a few minutes to complete 3. Search for **Cloud Resource Manager API** and click **Enable** — this is required for project access ## Step 2: Create Service Account ### Generate Service Account In the Google Cloud Console, go to **IAM & Admin** → **Service Accounts** Click **Create Service Account** **Service Account Name**: Enter a descriptive name (e.g., "elementum-ai-service") **Service Account ID**: Will be auto-generated **Description**: Optional description for the service account Assign the following roles to your service account: **Required Role**: * **Vertex AI User** (`roles/aiplatform.user`) — Access to Vertex AI models including Gemini **Optional Roles** (for advanced features): * **BigQuery User** — If integrating with BigQuery * **Storage Object Viewer** — If accessing Cloud Storage Click **Continue** and then **Done** to create the service account ### Generate Service Account Key In the Service Accounts list, click on your newly created service account Go to the **Keys** tab Click **Add Key** → **Create new key** Choose **JSON** as the key type Click **Create** The JSON key file will be automatically downloaded **Critical**: Copy and store this file securely — it contains credentials for your service account and cannot be downloaded again Never share your service account key file or commit it to version control. Store it in a secure location like a password manager. ## Step 3: Configure Gemini in Elementum ### Add the Provider 1. In Elementum, go to **Organization Settings** and select the **Providers** tab 2. Click **+ Provider** and select **Gemini** from the provider options 3. Configure the provider settings: **Provider Name**: Enter a descriptive name (e.g., "Google Gemini Production") **Location**: Select your Google Cloud region (e.g., "us-central1") **Project ID**: Enter your Google Cloud project ID **CloudLink**: Select which CloudLinks can access models from this provider. Leave as "All CloudLinks" unless you need to restrict access. AI services do not support CloudLinks configured with **API** as the connection type. Only CloudLinks connected to a supported data warehouse (Snowflake, BigQuery, or Databricks) can be associated with this provider. **Service Account Credentials**: Upload or paste your JSON key file content The JSON should look like this: ```json theme={null} { "type": "service_account", "project_id": "your-project-id", "private_key_id": "...", "private_key": "...", "client_email": "elementum-ai-service@your-project.iam.gserviceaccount.com", "client_id": "...", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token" } ``` 4. Click **Save** to create the provider. Elementum will automatically validate your credentials — look for a green checkmark indicating a successful connection. ## Step 4: Create your first AI service With your Gemini provider configured, create an AI Service that uses a Gemini model. See [AI Services](/ai-agents/ai-services) for the full walkthrough, including LLM service configuration, assignment, and failover. For a side-by-side comparison of the Gemini models available in Elementum—including recommendations for daily tasks vs. complex reasoning—see [AI Models](/ai-agents/ai-models). **Note**: Embeddings for AI Search are handled exclusively through Snowflake Cortex. Gemini models are used for LLM services only. ## Usage Guidelines ### Cost Management Google Cloud charges for Vertex AI usage. To manage costs: * Monitor usage in the Google Cloud Console * Set up billing alerts for cost control * Review and adjust API quotas as needed * Regularly review usage patterns * Choose appropriate models for each task * Use Gemini 2.5 Flash for speed-critical applications * Cache responses when possible * Minimize unnecessary API calls ### Best Practices * Use **Gemini 2.5 Flash** for most general-purpose tasks and customer support * Use **Gemini 2.5 Pro** for complex reasoning, advanced analysis, and large responses * Use **Gemini 1.5 Pro** for established production workloads requiring reliable performance * Be specific and clear in your prompts * Use system messages for consistent behavior * Provide examples for better results * For Gemini 2.5 Pro, structure complex problems step-by-step * Select Google Cloud regions closest to your users * Choose Gemini 2.5 Pro for tasks requiring detailed analysis * Use Gemini 2.5 Flash for high-volume, simple tasks * Implement retry logic for transient errors ## Troubleshooting **Symptoms:** Service account authentication failures **Common Causes:** * Invalid service account key * Insufficient permissions * Disabled APIs **Solutions:** 1. Verify service account key is valid JSON 2. Check service account roles and permissions 3. Ensure required APIs are enabled 4. Regenerate service account key if needed **Symptoms:** Cannot access Vertex AI APIs **Common Causes:** * APIs not enabled * Billing not configured * Regional restrictions **Solutions:** 1. Enable Vertex AI API in Google Cloud Console 2. Verify billing is enabled and active 3. Check regional availability of services 4. Review project quotas and limits **Symptoms:** Requests being throttled or rejected **Common Causes:** * Exceeding Vertex AI quotas * High concurrent usage * Regional quota limitations **Solutions:** 1. Implement exponential backoff 2. Reduce request frequency 3. Review and adjust quotas in Google Cloud Console 4. Distribute load across multiple regions **Symptoms:** Expected models don't appear in service creation **Common Causes:** * Regional model availability * Account access restrictions * Model deprecation **Solutions:** 1. Check model availability in your region 2. Review account access and permissions 3. Contact Google Cloud support for access issues 4. Consider alternative models ## Security Considerations * Regularly rotate service account keys * Use IAM roles for fine-grained access control * Monitor service account usage for anomalies * Enable audit logging for security tracking * Review Google's current data handling and privacy policies * Consider data sensitivity when crafting prompts * Data is encrypted in transit and at rest * Monitor data access patterns ## Advanced Configuration ### Multi-Region Setup For global deployments, consider the following when selecting regions: * **Region Selection**: Choose regions closest to your users for lower latency * **Data Residency**: Ensure your region choices meet data residency requirements * **Failover**: Implement failover strategies across regions for high availability * **Compliance**: Verify regional compliance with applicable regulations ### Custom Model Access If you need access to specialized or private models in Vertex AI: * **Model Registration**: Register custom models in Vertex AI * **Access Control**: Configure proper IAM permissions for model access * **Monitoring**: Set up custom monitoring and alerting for model performance ## Next Steps With Google Gemini configured as your AI Provider: Set up specific LLM and embedding services for your workflows Set up Snowflake Cortex for AI Search and embeddings Create conversational AI assistants using Gemini models Add AI capabilities to your automation workflows # OpenAI Setup Source: https://docs.elementum.io/ai-agents/openai-setup Configure OpenAI as your AI provider for language model services ## Overview OpenAI provides language models including o3, o4-mini, and GPT-4 Omni. This guide walks you through setting up OpenAI as an AI Provider in Elementum. **Prerequisites**: You'll need an OpenAI account with API access. Individual accounts and organization accounts are both supported. ## Step 1: Get Your OpenAI API Key ### Create an OpenAI Account 1. **Visit OpenAI Platform** * Go to [platform.openai.com](https://platform.openai.com) * Sign up for an account or log in to your existing account 2. **Set Up Billing** * Navigate to **Settings** → **Billing** * Add a payment method to enable API access * Consider setting up usage limits to control costs ### Generate Your API Key In your OpenAI dashboard, navigate to **API Keys** in the left sidebar Click **Create new secret key** Give your key a descriptive name like "Elementum Integration" **Critical**: Copy the API key immediately and store it securely You won't be able to view it again after closing the dialog If using an organization account, you can set specific permissions for the key Ensure the key has access to the models you plan to use Never share your API key or commit it to version control. Store it in a secure location like a password manager. ## Step 2: Configure OpenAI in Elementum ### Add the Provider 1. In Elementum, go to **Organization Settings** and select the **Providers** tab 2. Click **+ Provider** and select **OpenAI** from the provider options 3. Configure the provider settings: **Provider Name**: Enter a descriptive name (e.g., "OpenAI Production") **API Key**: Paste your OpenAI API key **Endpoint URL** (Optional): Custom endpoint URL for Azure OpenAI or other OpenAI-compatible APIs. Leave blank to use the default OpenAI API endpoint. **CloudLink**: Select which CloudLinks can access models from this provider. Leave as "All CloudLinks" unless you need to restrict access. AI services do not support CloudLinks configured with **API** as the connection type. Only CloudLinks connected to a supported data warehouse (Snowflake, BigQuery, or Databricks) can be associated with this provider. **Request Timeout**: Default is usually sufficient (30 seconds) **Max Retries**: Number of retry attempts for failed requests (default: 3) **Rate Limiting**: OpenAI handles rate limiting automatically 4. Click **Save** to create the provider. Elementum will automatically validate your API key — look for a green checkmark indicating a successful connection. ## Step 3: Create your first AI service With your OpenAI provider configured, create an AI Service that uses an OpenAI model. See [AI Services](/ai-agents/ai-services) for the full walkthrough, including LLM service configuration, assignment, and failover. For a side-by-side comparison of the OpenAI models available in Elementum—including recommendations for daily tasks vs. complex reasoning—see [AI Models](/ai-agents/ai-models). **Note**: Embeddings for AI Search are handled exclusively through Snowflake Cortex. OpenAI models are used for LLM services only. ## Usage Guidelines ### Cost Management OpenAI charges based on token usage. To manage costs: * Monitor usage in the OpenAI dashboard * Set up billing alerts * Review token consumption regularly * Use appropriate models for each task * Implement context windowing * Cache responses when possible * Use o4-mini for speed-critical applications ### Best Practices * Use **o4-mini** for most customer support and daily automation tasks * Use **o3** for complex reasoning, research, and advanced problem-solving * Use **GPT-4 Omni** for content creation and detailed analysis * Be specific and clear in your prompts * Use system messages for consistent behavior * Provide examples for better results * For o3, structure complex problems step-by-step * Choose o4-mini for speed-critical applications * Use o3 sparingly for tasks requiring maximum intelligence * Implement caching for repeated queries * Consider request queuing for high-volume usage ## Troubleshooting **Symptoms:** API key rejected or unauthorized errors **Common Causes:** * Invalid or expired API key * Insufficient permissions * Billing issues **Solutions:** 1. Verify API key is correct and active 2. Check billing status and payment methods 3. Ensure key has proper permissions 4. Regenerate API key if needed **Symptoms:** Desired model doesn't appear in service creation **Common Causes:** * Account doesn't have access to specific models * Regional restrictions * Model deprecation **Solutions:** 1. Check OpenAI account tier and access levels 2. Review model availability in your region 3. Contact OpenAI support for access issues 4. Consider alternative models **Symptoms:** Requests being throttled or rejected **Common Causes:** * Exceeding rate limits * High concurrent usage * Account tier limitations **Solutions:** 1. Implement exponential backoff 2. Reduce request frequency 3. Upgrade account tier if needed 4. Distribute load across multiple keys ## Security Considerations * Never expose API keys in client-side code * Rotate keys regularly * Use environment variables for storage * Monitor key usage for anomalies * Review OpenAI's current data handling and privacy policies * Consider data sensitivity when crafting prompts * Implement data sanitization if needed ## Advanced Configuration ### Organization Accounts If you're using an OpenAI organization account, you can centralize API access, billing, and team permissions under a single organization: * **Organization ID**: Required for organization accounts * **Member Management**: Control team access through OpenAI dashboard * **Usage Tracking**: Monitor usage across team members * **Billing Management**: Centralized billing for the organization ### Custom Endpoints If you use Azure OpenAI or another OpenAI-compatible API, you can point your provider at a custom endpoint instead of the default OpenAI API: * **Endpoint URL**: Enter your custom endpoint (e.g., `https://your-resource.openai.azure.com/`) * **Authentication**: May require additional authentication headers depending on the endpoint * **Model Names**: Custom model names may be required for non-standard endpoints * **Rate Limits**: May differ from standard OpenAI limits ## Next Steps With OpenAI configured as your AI Provider: Set up specific LLM and embedding services for your workflows Set up Snowflake Cortex for AI Search and embeddings Create conversational AI assistants using OpenAI models Add AI capabilities to your automation workflows # Automating AI Document OCR with Elementum and Snowflake Source: https://docs.elementum.io/ai-agents/snowflake-ai-ocr Extract text from PDFs and images stored in Snowflake stages using AI_PARSE_DOCUMENT OCR capabilities and automated workflows ## Overview This workflow enables you to automatically extract text content from documents (PDFs, images, etc.) stored in Snowflake stages using Snowflake's AI\_PARSE\_DOCUMENT capability with OCR mode and Elementum's Automation System. The Snowflake AI OCR workflow consists of nine main steps: 1. **Create a Snowflake stage** for document files 2. **Create an AI OCR stored procedure** in Snowflake 3. **Create a Snowflake view** for stage files 4. **Import the stored procedure** into Elementum via CloudLink 5. **Import the view as an Elementum table** 6. **Build a Data Mine** to monitor for new or changed documents 7. **Create an automation** triggered by the Data Mine 8. **Process documents** using the Run Function action to call your OCR procedure 9. **Add additional actions** to work with the extracted text This workflow leverages Snowflake AI capabilities to extract text from documents without moving your files outside of your data environment. The OCR processing is orchestrated through Elementum within your Snowflake environment, keeping your data secure and centralized. ## Prerequisites Before starting this workflow, ensure you have: * **Snowflake access** with permissions to create stages, views, and stored procedures * **Elementum CloudLink** configured and connected to your Snowflake instance * **Documents uploaded** to a Snowflake stage (e.g., PDFs, images) * **Directory Table enabled on your Snowflake stage** for file listing and metadata access * **Snowflake AI features enabled** in your account for AI\_PARSE\_DOCUMENT functionality * **Understanding** of [Elementum Tables](/data/tables), [Data Mining](/data/data-mining), and [Automation System](/workflows/automation-system) ## Step 1: Create Snowflake Stage First, create a Snowflake stage for your documents with encryption enabled and directory table enabled. Execute this SQL in your Snowflake environment: ```sql theme={null} USE DATABASE YOUR_DATABASE; USE SCHEMA YOUR_SCHEMA; -- Create internal stage with directory table and encryption enabled CREATE OR REPLACE STAGE DOCUMENT_STAGE DIRECTORY = (ENABLE = TRUE) ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE'); ``` ## Step 2: Create AI OCR Stored Procedure Create a stored procedure that uses Snowflake's AI\_PARSE\_DOCUMENT function to extract text from documents. ```sql theme={null} CREATE OR REPLACE PROCEDURE AI_OCR_FROM_STAGE_SP(FILE_PATH STRING) RETURNS STRING LANGUAGE JAVASCRIPT EXECUTE AS OWNER AS $$ var sql = ` SELECT TO_VARCHAR( AI_PARSE_DOCUMENT( TO_FILE('@YOUR_DATABASE.YOUR_SCHEMA.DOCUMENT_STAGE', ?), OBJECT_CONSTRUCT('mode', 'OCR') ) ) AS response `; var stmt = snowflake.createStatement({ sqlText: sql, binds: [FILE_PATH] }); var rs = stmt.execute(); if (rs.next()) { return rs.getColumnValue(1); // response } else { return null; } $$; ``` * **`FILE_PATH`**: Takes the relative path of the file within the stage * **`TO_FILE()`**: References the file in the Snowflake stage * **`AI_PARSE_DOCUMENT()`**: Snowflake's AI function that processes the document * **`mode: 'OCR'`**: Specifies OCR mode for text extraction * **Returns**: JSON string with extracted content and metadata The response structure looks like this: ```json theme={null} { "content": "Extracted text content from the document...", "metadata": { "pageCount": 1 } } ``` Ensure your Elementum CloudLink role has permission to execute the stored procedure: ```sql theme={null} GRANT USAGE ON PROCEDURE YOUR_DATABASE.YOUR_SCHEMA.AI_OCR_FROM_STAGE_SP(STRING) TO ROLE YOUR_CLOUDLINK_ROLE; ``` ## Step 3: Create Snowflake View from Stage Create a Snowflake view that provides access to your stage files with metadata. Execute this SQL in your Snowflake environment: ```sql theme={null} CREATE OR REPLACE VIEW DOCUMENT_STAGE_VIEW AS SELECT RELATIVE_PATH, SIZE, LAST_MODIFIED, MD5 FROM DIRECTORY(@DOCUMENT_STAGE); ``` * **`RELATIVE_PATH`**: File path within the stage (used to identify files for OCR processing) * **`SIZE`**: File size in bytes * **`LAST_MODIFIED`**: Timestamp of last file modification * **`MD5`**: File hash for integrity checking ## Step 4: Import Stored Procedure into CloudLink Before building your automation, import the stored procedure into Elementum through CloudLink to make it available for use. 1. Navigate to your **CloudLink** connection settings 2. Click on **Functions** 3. Select the **database** and **schema** where your stored procedure is located 4. Find your `AI_OCR_FROM_STAGE_SP` stored procedure in the list 5. Optionally **rename** it for easier identification in automations 6. Click **Save** to make it available for use in automations Once saved, the stored procedure will appear in the **Run Function** action dropdown when building automations. ## Step 5: Import View as Elementum Table Once your Snowflake view is created, import it into Elementum as a table. 1. Navigate to **Tables** → **Explore Data** → **CloudLink** 2. Select your Snowflake connection and choose the view you created 3. Click **Create Table** and fill out the details ## Step 6: Build Data Mine for Document Monitoring Create a Data Mine to automatically detect when new documents arrive or existing documents change. 1. In your table, go to **Data Mining** → **Create Data Mine** → **Logic-Based Rules Mining** 2. **Identifying Columns**: Select `RELATIVE_PATH`, `LAST_MODIFIED`, and `MD5` These columns work together to track individual files across Data Mine runs, detect when files are modified or replaced, and ensure accurate state management (ON/OFF transitions). 3. **Matching Criteria**: Set filters for file types or conditions (optional - e.g., only `.pdf` files) 4. **Name and Schedule**: Give it a name and set check frequency ## Step 7: Create Automation with Data Mine Trigger Build an automation that processes documents when the Data Mine detects them. Your automation will follow this logical flow: **Data Mine Trigger** → **Run OCR Function** → **Process Extracted Text** (e.g., store content in a record, trigger AI analysis) 1. Navigate to **Automations** → **Create Automation** 2. Add **Data Mine Trigger** and select your Data Mine 3. Set trigger option to **Trigger when data meets requirement** ## Step 8: Process Documents Using Run Function Action Add a Run Function action to your automation to OCR documents using the stored procedure. **Run Function** action details: * **Function**: Select your `AI_OCR_FROM_STAGE_SP` stored procedure from CloudLink * **Parameters**: * `FILE_PATH`: `$RELATIVE_PATH` (from the Data Mine trigger) **Variable Reference**: The `$RELATIVE_PATH` variable comes from the Data Mine trigger, providing access to all fields from the matching stage file record. The Run Function action will return a JSON response containing: * **`content`**: The extracted text content from the document * **`metadata.pageCount`**: Number of pages processed ## Step 9: Work with the OCR Results After the Run Function action completes, subsequent actions in your automation will have access to the OCR results. Add an **Update Record** or **Create Record** action to store the extracted text in an Elementum record for future reference and searchability. Add an **AI Action** to analyze, summarize, or categorize the extracted text content using your configured AI provider. Add **Conditional Logic** to route documents based on extracted content (e.g., if certain keywords are detected, assign to specific team members). ## Summary This workflow provides a powerful way to automatically extract text from documents stored in Snowflake stages: 1. **Snowflake Stage** stores your document files with encryption and directory tracking 2. **AI OCR Stored Procedure** leverages Snowflake's AI\_PARSE\_DOCUMENT for text extraction 3. **Snowflake View** makes stage files accessible with metadata 4. **CloudLink Functions** imports the stored procedure for use in automations 5. **Elementum Table** brings stage file information into your workspace 6. **Data Mine** automatically detects new or changed documents 7. **Automation** orchestrates the OCR processing workflow 8. **Run Function Action** executes the OCR procedure on each document 9. **Additional Actions** enable text analysis, storage, and intelligent workflow automation By following this guide, you can create a robust, automated document processing system that transforms your Snowflake stage into an intelligent OCR pipeline, enabling your business to automatically extract and process text from documents as they arrive. *** ## Appendix: Complete Quick Setup Use the following SQL to create a complete OCR processing setup in Snowflake. Replace the `ALL_CAPS` placeholders with your actual values. ```sql theme={null} USE DATABASE DATABASE_NAME; USE SCHEMA SCHEMA_NAME; -- Create internal stage with directory table and encryption enabled CREATE OR REPLACE STAGE DOCUMENT_STAGE DIRECTORY = (ENABLE = TRUE) ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE'); -- Create AI OCR stored procedure CREATE OR REPLACE PROCEDURE AI_OCR_FROM_STAGE_SP(FILE_PATH STRING) RETURNS STRING LANGUAGE JAVASCRIPT EXECUTE AS OWNER AS $$ var sql = ` SELECT TO_VARCHAR( AI_PARSE_DOCUMENT( TO_FILE('@DATABASE_NAME.SCHEMA_NAME.DOCUMENT_STAGE', ?), OBJECT_CONSTRUCT('mode', 'OCR') ) ) AS response `; var stmt = snowflake.createStatement({ sqlText: sql, binds: [FILE_PATH] }); var rs = stmt.execute(); if (rs.next()) { return rs.getColumnValue(1); } else { return null; } $$; -- Create view for stage files CREATE OR REPLACE VIEW DOCUMENT_STAGE_VIEW AS SELECT RELATIVE_PATH, SIZE, LAST_MODIFIED, MD5 FROM DIRECTORY(@DOCUMENT_STAGE); ``` Ensure your Elementum CloudLink role has the necessary permissions to access the stage, view, and stored procedure. ```sql theme={null} GRANT USAGE ON DATABASE DATABASE_NAME TO ROLE CLOUDLINK_ROLE; GRANT USAGE ON SCHEMA DATABASE_NAME.SCHEMA_NAME TO ROLE CLOUDLINK_ROLE; GRANT USAGE ON STAGE DATABASE_NAME.SCHEMA_NAME.DOCUMENT_STAGE TO ROLE CLOUDLINK_ROLE; GRANT SELECT ON VIEW DATABASE_NAME.SCHEMA_NAME.DOCUMENT_STAGE_VIEW TO ROLE CLOUDLINK_ROLE; GRANT USAGE ON PROCEDURE DATABASE_NAME.SCHEMA_NAME.AI_OCR_FROM_STAGE_SP(STRING) TO ROLE CLOUDLINK_ROLE; ``` Upload a test document to verify the stage and OCR processing are working correctly: ```sql theme={null} -- Using SnowSQL CLI PUT file://path/to/test-document.pdf @DATABASE_NAME.SCHEMA_NAME.DOCUMENT_STAGE OVERWRITE=TRUE AUTO_COMPRESS=FALSE; ``` You can also upload files through the Snowflake web interface by navigating to your stage and using the "Upload Files" option. Test your stored procedure directly in Snowflake: ```sql theme={null} CALL AI_OCR_FROM_STAGE_SP('test-document.pdf'); ``` You should receive a JSON response with the extracted text content and metadata. ## Additional Resources * [Snowflake AI\_PARSE\_DOCUMENT Documentation](https://docs.snowflake.com/en/sql-reference/functions/ai_parse_document) * [Accessing Files from Snowflake Stages](/administration/snowflake-stages) - For workflows that need to download files * [Automation System](/workflows/automation-system) - Learn more about building automations * [Data Mining](/data/data-mining) - Deep dive into Data Mine capabilities # Snowflake Cortex Agents Setup Source: https://docs.elementum.io/ai-agents/snowflake-cortex-agents-setup Complete guide to integrating Snowflake Cortex Agents into Elementum Apps through Intelligence configuration ## Overview By connecting Cortex Agents to your Elementum Apps, you enable AI-powered automation that runs directly on your Snowflake data warehouse, maintaining data security while leveraging advanced AI capabilities. Cortex Agents are configured at the **App level** through the Intelligence settings, allowing each App to discover and use external agents available through its CloudLink connection. ## Prerequisites Before beginning this setup, ensure you have the following in place: ### Elementum Requirements * **App access**: Access to the App where you want to integrate Cortex Agents. * **Snowflake AI Provider**: A configured Snowflake AI Provider with a CloudLink that uses **key-pair authentication**. **Authentication Requirement**: Snowflake Cortex Agents require a Snowflake AI Provider configured with key-pair authentication. Password-based CloudLinks cannot access Cortex features. ### Snowflake Requirements Your Snowflake environment must have: * **Snowflake Edition**: Enterprise or higher * **Cortex AI Features**: Enabled on your account * **Cortex Agents**: At least one Cortex Agent configured in your Snowflake account * **Permissions**: Service account with USAGE privileges on: * Cortex functions * Agent resources * Target database and schema ### Verify Your Snowflake AI Provider Before proceeding, verify you have a Snowflake AI Provider configured: Go to **Organization Settings** → **Providers** Verify a Snowflake provider is configured Ensure it uses a CloudLink with **Key-Pair Authentication** Verify the provider is active and can connect to Snowflake **Need Help with Providers?** See the [Snowflake Cortex Setup Guide](/ai-agents/snowflake-cortex-setup) for detailed instructions on configuring Snowflake AI Providers with key-pair authentication. ## Step 1: Prepare Snowflake Cortex Agents Before connecting to Elementum, ensure your Cortex Agents are properly configured in Snowflake. ### Verify Cortex Agents in Snowflake 1. Log into your Snowflake account 2. Navigate to **AI & ML** → **Cortex Agents** 3. Verify your agents are listed and active 4. Note the database and schema where agents are located ```sql theme={null} -- List available Cortex Agents SHOW CORTEX AGENTS IN DATABASE your_database; -- View agent details DESCRIBE CORTEX AGENT your_database.your_schema.agent_name; ``` ### Required Permissions Ensure your service account has the necessary permissions: ```sql theme={null} -- Grant usage on database and schema GRANT USAGE ON DATABASE your_database TO ROLE elementum_role; GRANT USAGE ON SCHEMA your_database.your_schema TO ROLE elementum_role; -- Grant usage on Cortex features GRANT USAGE ON CORTEX TO ROLE elementum_role; -- Grant execute on specific agents GRANT USAGE ON CORTEX AGENT your_database.your_schema.agent_name TO ROLE elementum_role; ``` **Principle of Least Privilege**: Grant only the minimum permissions necessary for the agents and data your Elementum automations will access. ## Step 2: Configure Intelligence in Your App Now you're ready to discover and configure Snowflake Cortex Agents through your App's Intelligence settings. ### Access Intelligence Settings Go to the App where you want to integrate Cortex Agents Click **Intelligence** in the App menu ### Add External Agent Click the **Add Agent** button at the top of the Intelligence page In the agent type selection, choose **External** This indicates you're connecting to an agent hosted outside Elementum Choose your configured Snowflake AI Provider from the dropdown **Provider Selection:** * Only Snowflake providers with key-pair authentication appear * The provider must have access to Cortex features * Multiple providers can be available if you have different Snowflake environments The system uses the selected provider to discover available Cortex Agents **What happens:** * Elementum connects to Snowflake using the provider's CloudLink credentials * Queries the Snowflake Cortex REST API for available agents * Lists all agents accessible through the provider's service account From the discovered agents list, select the Cortex Agent you want to use You'll see: * Agent name * Agent description * Database and schema location * Available capabilities **Agent Name**: Optionally customize the display name in Elementum **Description**: Add notes about how this agent will be used in your App **Configuration**: Review agent input/output schemas Click **Save** to connect the external agent The agent will now appear in your App's Intelligence configuration ### What Happens During Discovery When you add an external agent, Elementum: 1. **Selects Provider**: Uses the selected Snowflake AI Provider's connection 2. **Authenticates**: Authenticates with Snowflake using the provider's CloudLink credentials 3. **Discovers Agents**: Queries the Cortex REST API for available agents 4. **Retrieves Metadata**: Gets agent capabilities, schemas, and configuration 5. **Registers Agent**: Makes the agent available for use in App automations 6. **Monitors Status**: Tracks agent availability through the provider connection ```mermaid theme={null} sequenceDiagram participant App as App Intelligence participant Prov as Snowflake AI Provider participant CL as CloudLink participant SF as Snowflake participant API as Cortex REST API App->>Prov: Request Agent Discovery Prov->>CL: Use Provider CloudLink CL->>SF: Authenticate (Key-Pair) SF->>CL: Connection Established Prov->>API: List Available Agents API->>Prov: Return Agent Metadata Prov->>App: Display Available Agents App->>App: Register Selected Agent ``` ## Step 3: Understanding Cortex REST APIs Elementum leverages three primary Snowflake Cortex APIs for agent integration: ### Agent Discovery API Discovers available agents accessible through your CloudLink. **Snowflake Documentation**: [Cortex Agents REST API](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-rest-api) **What Elementum Retrieves:** * Agent names and identifiers * Agent capabilities and descriptions * Input/output schemas * Required permissions * Configuration metadata ### Agent Run API Executes agent tasks and retrieves results. **Snowflake Documentation**: [Cortex Agents Run](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-run) **Used For:** * Invoking agents from automations * Passing input parameters * Receiving agent responses * Monitoring execution status * Handling errors and timeouts ### Threads API Manages conversational threads for stateful agent interactions. **Snowflake Documentation**: [Cortex Agents Threads REST API](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-threads-rest-api) **Capabilities:** * Create conversation threads * Maintain context across interactions * Retrieve conversation history * Resume interrupted conversations * Manage thread lifecycle **API Authentication**: All API calls use the credentials from the selected Snowflake AI Provider's CloudLink connection, ensuring secure and auditable access to Cortex resources. ## Step 4: Integrate Agents into Automations With your Cortex Agent configured in Intelligence, you can now use it in App automations. ### Using External Agents in Automation Actions In your App, go to the automation where you want to use the external agent Add a new automation action or edit an existing one Select **Agent Action** as the action type In the agent configuration: **Agent**: Choose the external Cortex Agent you configured in Intelligence The agent will be labeled as **External** or **Managed** **Input Mapping**: Map automation data to agent input parameters * Use field values from the current record * Reference previous automation action outputs * Include static values or formulas **Output Handling**: Configure how to handle agent responses * Map agent outputs to record fields * Store results for later automation actions * Set error handling behavior **Timeout**: Set maximum execution time (default: 60 seconds) **Retry Policy**: Configure retry behavior for failures **Error Handling**: Define what happens if the agent fails * Continue automation with default values * Halt automation and alert user * Escalate to human review Use the automation test mode to verify agent integration Monitor execution logs for agent calls and responses ### Example: Data Analysis Automation **Scenario**: Automatically analyze sales data when a monthly report is requested ```yaml theme={null} Workflow: Monthly Sales Analysis Trigger: Report requested Automations: 1. Gather Data: - Collect sales records for the month - Aggregate by region and product 2. External Agent - Analysis: Type: External Agent (Cortex) Agent: Sales Analysis Agent Inputs: - sales_data: {aggregated_data} - analysis_type: "trend_analysis" - time_period: "monthly" Outputs: - trends: record.analysis_results - insights: record.key_insights - forecast: record.forecast_data 3. Generate Report: - Create formatted report with insights - Include visualizations from forecast 4. Distribute: - Email report to stakeholders - Post summary to Teams channel ``` ### Using Agents in Multiple Automations External agents configured in Intelligence can be used across multiple automations within the same App: **Trigger**: New transaction record created **Conditions**: Transaction amount > \$10,000 **Actions**: 1. **Call External Agent** * Agent: Fraud Detection Agent (Cortex) * Input: Transaction details and customer history * Output: Risk score and explanation 2. **Conditional Logic** * If risk\_score > 75: Flag for review and notify security team * If risk\_score 50-75: Request additional verification * If risk\_score \< 50: Auto-approve transaction 3. **Log Results** * Record analysis in audit log * Update transaction status based on outcome ## Step 5: Monitor and Maintain ### Monitoring Agent Performance View agent execution logs in automation history Monitor: * Invocation frequency * Response times * Success/failure rates * Error messages Track agent usage in Intelligence settings View: * Active agent connections * Last successful execution * Configuration changes * CloudLink status ### Provider Connection Health Since external agents depend on the Snowflake AI Provider: * **Monitor Provider Status**: Ensure the provider and its CloudLink remain active * **Check Connectivity**: Regularly test Snowflake connectivity through the provider * **Review Permissions**: Verify service account permissions haven't changed * **Update Credentials**: Rotate provider CloudLink keys according to your security policy **Snowflake Monitoring**: Use Snowflake's query history and warehouse monitoring to track Cortex Agent compute costs and performance. This complements Elementum's automation logs. ### Maintenance Tasks **Weekly**: * Review automation logs for agent errors * Monitor agent performance metrics * Check for timeout or failure patterns **Monthly**: * Review agent usage and optimization opportunities * Audit permissions and access patterns * Test agent functionality after Snowflake updates **Quarterly**: * Rotate provider CloudLink credentials * Review and optimize automation integrations * Evaluate new Cortex Agent capabilities When you update agents in Snowflake: 1. **Test Changes**: Verify agent behavior in Snowflake first 2. **Refresh Intelligence**: Re-discover agents in Intelligence settings if schemas changed 3. **Update Automations**: Modify automations if input/output schemas changed 4. **Test Integrations**: Validate all automations using the updated agent 5. **Monitor**: Watch for issues after deployment As usage grows: **Snowflake Side**: * Scale warehouse size for agent workloads * Consider dedicated warehouses for different agent types * Implement resource monitors to control costs **Elementum Side**: * Monitor automation execution times * Implement caching for frequently accessed agent results * Use async invocations for long-running agents * Configure multiple Snowflake AI Providers for different environments or redundancy ## Configuration Best Practices ### Security Best Practices **Minimal Permissions**: Grant only necessary privileges **Role Separation**: Use dedicated roles for agent access **Audit Logging**: Enable comprehensive audit trails **Regular Reviews**: Quarterly access audits **Rotation Schedule**: Rotate keys every 90 days **Secure Storage**: CloudLink manages credential encryption **No Sharing**: Unique credentials per environment **Revocation Process**: Document emergency revocation steps ### Performance Optimization 1. **Warehouse Sizing** * Use appropriately sized warehouses for agent complexity * Consider multi-cluster warehouses for concurrent agent calls * Enable auto-suspend to minimize costs 2. **Provider Management** * Provider connections are reused across multiple agent invocations * Monitor provider connection performance metrics * Configure appropriate timeout values 3. **Timeout Configuration** * Set realistic timeouts based on agent complexity * Implement progressive timeout strategies * Consider async patterns for very long-running operations 4. **Caching Strategies** * Cache agent responses for identical inputs * Implement time-based cache invalidation * Use Snowflake result caching when appropriate ### Error Handling Patterns **Transient Failures**: Implement exponential backoff for temporary issues ``` Attempt 1: Immediate Attempt 2: Wait 2 seconds Attempt 3: Wait 4 seconds Attempt 4: Wait 8 seconds Max Attempts: 4 ``` **Permanent Failures**: Don't retry for authentication or permission errors **Circuit Breaker**: Stop attempting after consecutive failures reach threshold **Default Values**: Use sensible defaults when agent unavailable **Alternative Agents**: Configure backup agents for critical operations **Human Escalation**: Route to human review when automated analysis fails **Graceful Degradation**: Continue automation with reduced functionality ## Troubleshooting ### Discovery Issues **Error**: "No agents found" when adding external agent **Possible Causes**: * Snowflake AI Provider not configured or inactive * Provider's CloudLink has wrong permissions * No Cortex Agents configured in Snowflake * Service account lacks USAGE privileges **Solutions**: 1. Verify Snowflake AI Provider is configured in Organization Settings → Providers 2. Check that provider uses a CloudLink with key-pair authentication 3. Run `SHOW CORTEX AGENTS` in Snowflake to verify agents exist 4. Verify service account has USAGE privileges on Cortex 5. Check database and schema permissions 6. Test provider connection in Provider settings **Error**: "Unable to authenticate with Snowflake" **Possible Causes**: * Provider CloudLink not configured with key-pair authentication * Expired or invalid credentials * Network connectivity issues * Snowflake account unavailable **Solutions**: 1. Verify provider uses CloudLink with key-pair authentication (not password) 2. Test provider connection in Organization Settings → Providers 3. Check for expired credentials and refresh provider if needed 4. Verify network connectivity to Snowflake 5. Confirm Snowflake account is active and accessible 6. Review provider configuration and CloudLink settings **Error**: "Access denied to Cortex resources" **Possible Causes**: * Missing USAGE grant on Cortex * Insufficient privileges on agent * Role not properly assigned * Database or schema access missing **Solutions**: ```sql theme={null} -- Verify current role and grants SHOW GRANTS TO ROLE elementum_role; -- Grant necessary permissions GRANT USAGE ON DATABASE your_database TO ROLE elementum_role; GRANT USAGE ON SCHEMA your_database.your_schema TO ROLE elementum_role; GRANT USAGE ON CORTEX TO ROLE elementum_role; GRANT USAGE ON CORTEX AGENT your_database.your_schema.agent_name TO ROLE elementum_role; ``` ### Runtime Issues **Error**: "Agent execution exceeded timeout" **Possible Causes**: * Agent task too complex for timeout setting * Insufficient Snowflake warehouse resources * Network latency issues * Agent accessing large datasets **Solutions**: 1. Increase timeout value in automation configuration 2. Scale up Snowflake warehouse for agent workload 3. Optimize agent queries and data access 4. Consider splitting complex tasks into multiple automation actions 5. Use async invocation for long-running operations **Error**: Agent output doesn't match expected format **Possible Causes**: * Input parameters incorrect or malformed * Agent configuration changed in Snowflake * Schema version mismatch * Data quality issues in source data **Solutions**: 1. Validate input parameters match agent expectations 2. Test agent directly in Snowflake with same inputs 3. Check for recent agent updates or schema changes 4. Review agent logs in Snowflake for execution details 5. Verify data quality and completeness **Error**: Agent responses taking too long **Possible Causes**: * Undersized Snowflake warehouse * Network latency between Elementum and Snowflake * Agent querying large datasets inefficiently * Cold warehouse startup time **Solutions**: 1. Use larger warehouse for agent operations 2. Keep warehouse running during peak usage (disable auto-suspend temporarily) 3. Optimize agent queries and data access patterns 4. Consider warehouse dedicated to agent workloads 5. Implement result caching for repeated queries ## Multi-App Configurations ### Using Agents Across Multiple Apps Each App configures its own external agents through Intelligence: * **Configure per App**: Each App that needs Cortex Agents must configure them individually, even if multiple Apps connect to the same Snowflake agents. * **Provider selection**: Apps can use the same Snowflake AI Provider (shared access) or different providers (isolated access or different Snowflake environments). * **Independent configuration**: Each App can select different providers, use different agents from the same provider, configure the same agent differently, and define unique timeout and error handling settings. * **Monitor separately**: Track agent usage and performance per App in each App's Intelligence dashboard. ### Multi-Environment Setup For organizations with multiple environments (dev, staging, production): Configure separate Snowflake AI Providers for each environment Each provider uses a CloudLink with environment-specific service accounts In each environment's App, configure external agents through Intelligence Select the appropriate provider (dev/staging/prod) to discover agents Test in dev environment before deploying to production Validate in staging with production-like data When deploying configurations: * Test agent connectivity in target environment * Verify provider configuration is correct for the environment * Validate automation configurations * Monitor closely after deployment ## Example Use Cases **Scenario**: Automatically validate data quality when new datasets are loaded **Implementation**: 1. Create Cortex Agent in Snowflake for data profiling and quality analysis 2. In your Data Management App, configure the agent through Intelligence 3. Set up automation trigger on data load completion 4. Agent analyzes dataset and returns quality metrics 5. Automation creates alerts or blocks further processing based on results **Benefits**: * Immediate data quality feedback * Prevents downstream issues from bad data * Reduces manual validation effort * Maintains audit trail of quality checks **Scenario**: L1 support agent with direct access to customer data warehouse **Implementation**: 1. Create Cortex Agent trained on support knowledge base and customer data 2. Configure agent in Support App through Intelligence 3. Integrate agent into support automation 4. Customer inquiry triggers agent to analyze history and suggest resolution 5. Agent creates ticket with context and recommended actions **Benefits**: * Faster response times for customers * Consistent support quality * Reduces escalations to L2 support * Data stays secure in Snowflake environment **Scenario**: Generate executive reports with natural language insights **Implementation**: 1. Create Cortex Agent for financial analysis and narrative generation 2. Configure agent in Finance App through Intelligence 3. Schedule monthly report generation automation 4. Agent analyzes trends, generates insights, and creates narrative 5. Report distributed automatically with executive summary **Benefits**: * Consistent reporting schedule * Natural language insights for non-technical stakeholders * Reduces analyst workload * Real-time access to latest data ## Next Steps Understand the technical architecture and A2A protocol Learn how to build sophisticated automations with agents Reference Snowflake's official Cortex Agents documentation *** *By integrating Snowflake Cortex Agents through your App's Intelligence configuration, you create a powerful automation ecosystem that combines the flexibility of AI with the security of keeping your data in your own warehouse. This architecture ensures compliance, performance, and scalability for enterprise deployments.* # Snowflake Cortex Setup Source: https://docs.elementum.io/ai-agents/snowflake-cortex-setup Configure Snowflake Cortex as your AI provider for language model and embedding services ## Overview Snowflake Cortex brings AI capabilities directly to your data warehouse, allowing you to run LLMs and embedding models on your data without moving it outside your secure environment. This guide walks you through setting up Snowflake Cortex as an AI Provider in Elementum. Snowflake Cortex AI features are only available when your Snowflake CloudLink uses **key-pair authentication**. Password authentication cannot access these capabilities. If you haven't connected Snowflake yet, complete [Connect Snowflake to Elementum](/administration/connect-snowflake-to-elementum) first—this guide assumes that's done. For background on CloudLink itself, see the [CloudLink Overview](/administration/cloudlink-overview). ## Step 1: Verify CloudLink prerequisites Before setting up Snowflake Cortex, confirm your Snowflake CloudLink is in place: 1. Go to **Organization Settings** → **CloudLinks** and verify your Snowflake connection is active. 2. Confirm the CloudLink uses **key-pair authentication**. If it doesn't, follow [Key rotation](/administration/connect-snowflake-to-elementum#key-rotation) on the Snowflake setup page to migrate. 3. Confirm the [Cortex AI grants](/administration/connect-snowflake-to-elementum#step-4-grant-permissions-and-set-the-network-policy) have been applied to the `ELEMENTUM` role. ### Snowflake Account Requirements Your Snowflake account must meet the following requirements for Cortex AI access: * **Snowflake Edition**: Enterprise or higher * **Cortex Features**: Enabled and available in your region (most AWS, Azure, and GCP regions are supported) * **Permissions**: USAGE privileges on Cortex functions for your service account * **Billing**: Cortex usage is billed through your Snowflake account ## Step 2: Configure Snowflake Cortex in Elementum When you have a CloudLink connection with key-pair authentication, Elementum automatically discovers available Snowflake Cortex capabilities. ### Add the Provider 1. In Elementum, go to **Organization Settings** and select the **Providers** tab 2. Click **+ Provider** and select **Snowflake** — you'll see your existing CloudLink connections listed 3. Configure the provider settings: **Provider Name**: Enter a descriptive name (e.g., "Snowflake Cortex AI") **CloudLink**: Select your key-pair authenticated CloudLink **Service Account Credentials**: Auto-populated from your CloudLink If automatic discovery doesn't populate your settings, you may need to configure manually: **Provider Name**: Descriptive name for your Snowflake provider **Location**: Your Snowflake region and account details **Project ID**: Your Snowflake account identifier **CloudLink**: Select the appropriate CloudLink connection 4. Click **Save** to create the provider. Elementum will automatically validate your connection and discover available models — look for a green checkmark indicating a successful connection. ## Step 3: Create your first AI service With your Snowflake Cortex provider configured, create an AI Service that uses a Cortex model. See [AI Services](/ai-agents/ai-services) for the full walkthrough, including LLM and embedding service configuration, assignment, and failover. For a side-by-side comparison of Cortex LLMs and embedding models—including recommendations for daily tasks vs. complex reasoning and embedding quality tiers—see [AI Models](/ai-agents/ai-models). **Embeddings for AI Search**: Snowflake Cortex is the only provider that supports embedding services in Elementum. If you plan to use [AI Search](/ai-agents/ai-search), create an embedding service from this provider. **Model availability**: Available models depend on your Snowflake account tier, region, and current Cortex offerings. Model selection may vary over time. ## Usage Guidelines ### Cost Management Snowflake Cortex usage is billed through your Snowflake account. To manage costs: * Monitor Cortex function usage in the Snowflake console * Track warehouse usage for AI workloads * Set up Snowflake resource monitors and billing alerts * Review token consumption regularly * Use appropriate models for each task (Claude 3.7 Sonnet for routine work, Opus 4 only when necessary) * Process multiple requests in batches when possible * Cache frequent AI results to avoid redundant calls * Scale warehouses appropriately — larger models may need bigger warehouses ### Best Practices * Use **Claude 3.7 Sonnet** for most daily automation and customer support tasks * Use **Claude Sonnet 4** for advanced reasoning and premium applications * Reserve **Claude Opus 4** for the most complex tasks requiring maximum intelligence * Use **Mistral Large 2** for European regulatory compliance and multilingual tasks * Be specific and clear in your prompts * Use system messages for consistent behavior * Provide examples for better results * Structure complex problems step-by-step for reasoning models * Scale warehouses based on model complexity and concurrent usage * Enable auto-scaling for variable workloads * Choose models appropriate for the task complexity — avoid over-provisioning * Implement result caching for repeated queries ## Troubleshooting **Symptoms:** Cannot access Snowflake Cortex AI functions **Common Causes:** * Using password authentication instead of key-pair * Insufficient permissions on Cortex functions * Account doesn't have Cortex access **Solutions:** 1. Verify key-pair authentication is configured on your CloudLink 2. Check USAGE privileges on Cortex functions 3. Contact Snowflake support for account access 4. Verify account edition (Enterprise or higher) and region support **Symptoms:** Expected models don't appear in service creation **Common Causes:** * Regional model availability * Account tier limitations * CloudLink connection issues **Solutions:** 1. Verify CloudLink connection is active 2. Check regional model availability in Snowflake documentation 3. Review account tier and permissions 4. Refresh provider configuration **Symptoms:** Slow AI response times or timeouts **Common Causes:** * Undersized warehouse for AI workloads * Inefficient query patterns * Large data volumes **Solutions:** 1. Scale up warehouse size 2. Optimize data queries 3. Implement result caching 4. Consider dedicated warehouses for AI workloads ## Security Considerations Snowflake Cortex runs AI directly on your data warehouse, which provides key security advantages: * Data never leaves your Snowflake environment * Maintains existing data governance and compliance policies * Leverages Snowflake's built-in security model and encryption * All access is auditable through Snowflake's audit logging * CloudLink manages credential encryption and secure storage * Rotate key-pair credentials according to your security policy * Use dedicated service accounts with minimal permissions * Monitor service account usage in Snowflake for anomalies ## Next Steps With Snowflake Cortex configured as your AI Provider: Set up specific LLM and embedding services using Cortex models Use Snowflake embeddings for intelligent search on your data Create agents that can directly access your Snowflake data Integrate Snowflake Cortex Agents into your Apps # Studio Agents Source: https://docs.elementum.io/ai-agents/studio-agents Build automations, agents, and flows in Elementum through natural language conversation with a coding-based agent ## Overview Studio Agents are a coding-based agent type in Elementum that build automations, agents, and flows through conversation. Describe what you need in natural language, and the Studio Agent writes the TypeScript that assembles the flow inside your app—lowering the barrier to creating complex workflows without hand-building every stage, decision point, and automation. Studio Agents live on the **Flows** page of your app and stay available whenever you're building or iterating on a workflow. The agent handles the underlying code while you review the generated flow in a live **Preview** pane, refine it in the chat, and publish when it looks right. Studio Agents run on Anthropic Claude models. Configure an [Anthropic AI provider](/ai-agents/anthropic-setup) and select a supported Claude model (for example, **Claude 4.5 Sonnet**) before starting a Studio Agent session. See [AI Models](/ai-agents/ai-models#anthropic-direct) for model capabilities. ## Prerequisites Before you can use a Studio Agent, make sure your organization has: * An [Anthropic AI provider](/ai-agents/anthropic-setup) configured in **Organization Settings**. * At least one Claude LLM service available to the app where you plan to build the flow. See [AI Services](/ai-agents/ai-services) for setup steps. * App Administrator access on the app whose flow you want to build. ## Start a Studio Agent session 1. Open your app and click **Flows** in the left navigation menu. 2. In the natural language chat at the top of the **Flows** page, describe the workflow you want to build. Explain the stages, decision points, and automations you'd like included. 3. Click the **Send** icon to hand the request off to the Studio Agent. 4. Follow along in the chat pop-up as the agent writes the TypeScript that builds the flow. Click any action in the chat to see more details about what the agent did. 5. Use the **Preview** pane to verify the workflow is being built as expected. 6. If something doesn't look right, keep chatting with the agent to refine the flow. The agent maintains context across the session, so you can iterate stage by stage or make broad changes in a single message. 7. Click **Publish** when the flow is ready. After publishing, the flow behaves like any other flow in your app—you can open it, add or remove stages, edit each step manually, and connect it to the rest of your app's automations, elements, and views. ## Prompt templates Below the chat on the **Flows** page, Elementum surfaces pre-built prompt templates you can use as a starting point instead of writing a prompt from scratch. Examples include: * **Expense approval** — Multi-stage approval workflow with reviewer routing and status updates. * **Customer onboarding** — Sequenced steps for kicking off a new customer, gathering intake data, and triggering follow-up tasks. * **Incident triage** — Intake, classification, and escalation of incoming issues. Select a template to prefill the chat with a starter prompt, then edit it to match the specifics of your app before sending it to the Studio Agent. ## Resume a session In-progress builds are saved automatically as you chat with the agent. To pick a session back up later: 1. Open the **Flows** page in your app. 2. Scroll to **Studio Agent Sessions** to see drafts that haven't been published yet. 3. Select the session you want to continue. The chat, preview, and all prior context are restored so you can keep iterating with the agent. Because the Studio Agent generates the underlying TypeScript, you don't need to worry about losing your work between sessions—the full conversation, generated code, and current preview state are all preserved. ## After you publish Published flows are fully editable by hand. Use the flow editor to: * Rename or reorder stages the agent created. * Add or remove automations, approval steps, or assignment rules. * Wire the flow into other parts of your app—for example, [managed views](/workflows/managed-views), [Elements](/workflows/object-data-access), or [record layouts](/workflows/layouts). If you want to keep iterating with a Studio Agent after publishing, start a new session on the same **Flows** page and describe the changes you'd like the agent to make. ## Related documentation Configure the Anthropic AI provider that powers Studio Agents Compare Claude models and choose the right one for Studio Agents Create and configure conversational agents in your app Learn how the automations Studio Agents build fit into your app # Upcoming Model Deprecations Source: https://docs.elementum.io/ai-agents/upcoming-model-deprecations Schedule of AI model deprecations, recommended replacements, and how to get notified when a model leaves the supported list This page lists AI models scheduled for deprecation and recommended replacements. For capabilities and when to use each model, see [AI Models](/ai-agents/ai-models). The RSS feed for this page publishes when a model is added to the schedule and includes the date it will be deprecated. ## Upcoming ### Open AI **Engine version:** `gpt-3.5-turbo-1106` **Recommended replacement:** `GPT_5_4_MINI` **Engine version:** `gpt-3.5-turbo` **Recommended replacement:** `GPT_4_1_MINI` or `GPT_5_4_MINI` **Engine version:** `gpt-4` **Recommended replacement:** `GPT_4_1` **Engine version:** `gpt-4.1-nano` **Recommended replacement:** `GPT_5_NANO` or `GPT_5_4_NANO` **Engine version:** `o3-mini` **Recommended replacement:** `GPT_5_4_MINI` (supports reasoning) ### Gemini **Engine version:** `gemini-2.5-pro` **Recommended replacement:** `GEMINI_3_PRO` **Engine version:** `gemini-2.5-flash` **Recommended replacement:** `GEMINI_2_0_FLASH` or `GEMINI_3_PRO` ## Requires Attention
    | Enum | Engine Version | Platform | Notes | Recommended Replacement | | ----------------- | -------------- | ---------- | --------------------------- | ---------------------------------- | | `OPEN_AI_O1_MINI` | `o1-mini` | OpenAI API | Deprecated October 27, 2025 | `OPEN_AI_O3_MINI` → `GPT_5_4_MINI` |
    ## Previously deprecated
    | Enum | Engine Version | Platform | Deprecation Date | Recommended Replacement | | ------------------------ | --------------------- | ---------------- | ---------------- | ---------------------------------------- | | `GPT_4_TURBO_PREVIEW` | `gpt-4-turbo-preview` | OpenAI API | March 26, 2026 | `GPT_4_1` or `GPT_5_4` | | `CLAUDE_3_5_SONNET` | `claude-3-5-sonnet` | Snowflake Cortex | March 31, 2026 | `CLAUDE_4_6_SONNET` | | `CORTEX_OPEN_AI_O4_MINI` | `openai-o4-mini` | Snowflake Cortex | April 16, 2026 | `CORTEX_GPT_5_MINI` | | `CLAUDE_3_7_SONNET` | `claude-3-7-sonnet` | Snowflake Cortex | April 28, 2026 | `CLAUDE_4_6_SONNET` | | `SNOWFLAKE_ARCTIC` | `snowflake-arctic` | Snowflake Cortex | April 28, 2026 | `LLAMA3_3_70B` or `MISTRAL_LARGE_2` | | `CLAUDE_4_OPUS` | `claude-4-opus` | Snowflake Cortex | May 1, 2026 | `CLAUDE_4_6_SONNET` or `CLAUDE_4_6_OPUS` |
    ## References * [Snowflake Cortex April 2026 Deprecations](https://docs.snowflake.com/en/release-notes/bcr-bundles/un-bundled/bcr-april-model-deprecations) * [Snowflake Cortex May 2026 Deprecations](https://docs.snowflake.com/en/release-notes/bcr-bundles/un-bundled/bcr-may-model-deprecations) * [OpenAI Deprecations](https://developers.openai.com/api/docs/deprecations) * [Google Vertex AI Gemini 2.5 Retirement Notice](https://cloud.google.com/vertex-ai/generative-ai/docs/deprecations) ## Stay notified Use the RSS button on this page to hear when a model is added to the deprecation schedule. The feed includes the date the model will be deprecated. Subscribe below to get an email when a model is removed from Elementum's supported list. # Elementum API Source: https://docs.elementum.io/api-reference/api-introduction Get started with the Elementum API to integrate with your systems and streamline workflow automation. ## Overview Our API is designed to provide you with programmatic access to core features of Elementum, enabling you to build integrations, automate workflows, and extend the capabilities of your Elementum workspace. This guide will walk you through the essential steps to get started, from authentication to making your first API call. View the full OpenAPI specification file for a complete list of endpoints and schemas. Check the current status of our API services and get notified of any issues. ## Authentication API access is at the user level. You create a Client ID and Secret for a user; those credentials are used to obtain a Bearer token. Tokens expire after 24 hours and are required for all API requests. ### Step 1: Create API credentials 1. Sign in to Elementum in your web browser 2. Open the **User Settings** menu and go to the **OAuth** section 3. Select **Create New Token**, choose **API Access**, and click **Generate Token** 4. Save the generated **Client ID** and **Client Secret** immediately — they are shown only once and cannot be retrieved later Store your Client ID and Client Secret securely. They provide access to your Elementum data. Do not expose them in frontend applications or public repositories. ### Step 2: Obtain a Bearer token Request an access token from the OAuth 2.0 endpoint. Use this step each time you need a new Bearer token (for example, after expiry). * **Endpoint:** `POST https://api.elementum.io/oauth/token` (EU: `https://api.eu.elementum.io/oauth/token`) * **Content-Type:** `application/x-www-form-urlencoded` * **Authorization:** Basic Auth with your Client ID as the username and Client Secret as the password (base64-encoded `client_id:client_secret`) * **Body:** `grant_type=client_credentials` Example with cURL: ```bash theme={null} curl -X POST 'https://api.elementum.io/oauth/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --user 'YOUR_CLIENT_ID:YOUR_CLIENT_SECRET' \ --data 'grant_type=client_credentials' ``` A successful response returns an `access_token`. Use it in the `Authorization` header as `Bearer {access_token}` for all API requests. Records created or updated via the API are attributed to the API user. ### Step 3: Make authenticated API calls Include the access token in the `Authorization` header: ```bash theme={null} curl -X GET 'https://api.elementum.io/v1/apps/your-app-namespace' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --header 'Content-Type: application/json' ``` Replace `YOUR_ACCESS_TOKEN`, the record type, and namespace with your values. See [Record Types and Namespaces](#record-types-and-namespaces) and the endpoint reference below. ## Base URL All API requests are made to the following base URL. All endpoints in this documentation are listed relative to this base URL. `https://api.elementum.io/v1` For users in the EU region, use the EU endpoint: `https://api.eu.elementum.io/v1` ## Core Concepts ### Record Types and Namespaces The API supports record types such as **Apps**, **Tasks**, and **Elements**. You must specify the record type and its **alias** (namespace) in the path. Aliases are unique identifiers for the app, element, or task. **Where to find the alias:** * In the **Create Record** modal for that record type * In **Admin** — aliases can be set in the Create Definition (or equivalent) modals for the app, element, or task Example endpoint structure: `/{recordType}/{alias}` (e.g. `/{recordType}/{alias}/{id}` for a specific record). ### File Attachments The Elementum API supports adding attachments to records via the attachment endpoints. When working with file uploads: * **Maximum File Size**: **250MB** per file * **Supported Operations**: Upload attachments, add URL links, delete attachments * **File Storage**: Files are stored as attachments on records and can be accessed via the attachment URL * **Common Use Cases**: Document uploads, image attachments, report files, contracts **Example Endpoint**: ``` POST https://api.elementum.io/v1/elements/testelement/TTE-11/attachments ``` See the [Attachments API endpoints](/api-reference/endpoints/attachments/add-an-attachment) for specific implementation details. ## Filtering Results Search endpoints accept **RSQL** filter strings in the `filter` query parameter. Use the operators below in your filter expressions. ### Operators | Operator | Description | Example | | ----------------- | ------------------- | ------------------------------------------------------------------ | | `==` | Equal To | `Status==Open` | | `!=` | Not Equal To | `Status!=Closed` | | `=gt=` | Greater Than | `Created on=gt=2022-01-01T00:00:00.000Z` | | `=ge=` | Greater Or Equal To | `Created on=ge=2022-01-01T00:00:00.000Z` | | `=lt=` | Less Than | `Created on=lt=2022-04-01T00:00:00.000Z` | | `=le=` | Less Or Equal To | `Created on=le=2022-04-01T00:00:00.000Z` | | `=bt=` | Between | `Created on=bt=2022-01-01T00:00:00.000Z:2022-04-01T00:00:00.000Z` | | `!bt=` or `=nbt=` | Not Between | `Created on=!bt=2022-01-01T00:00:00.000Z:2022-04-01T00:00:00.000Z` | | `=in=` | In | `Status=in=Open:Closed` | | `=out=` | Not In | `Priority=out=Low:Medium:High` | | `=lk=` | Like | `Title=lk=Order 1234` | ### Combining Filters * **AND**: Use semicolon (`;`) — e.g. `Status==Open;Priority==High`. In URLs, encode as `%3b`. * **OR**: Use comma (`,`) — e.g. `Status==Open,Status==Closed`. In URLs, encode as `%2c`. AND operators take precedence over OR operators in filter expressions. URL-encode special characters when passing filters in query parameters. ## Error Handling The Elementum API uses standard HTTP status codes to indicate the success or failure of an API request. | Status Code | Meaning | | --------------------------- | ------------------------------------------------------------------------ | | `200 OK` | The request was successful. | | `201 Created` | The resource was successfully created. | | `202 Accepted` | The request was accepted for processing, but has not yet been completed. | | `400 Bad Request` | The request was improperly formatted or contained invalid parameters. | | `401 Unauthorized` | Your access token is wrong, expired, or you did not provide one. | | `403 Forbidden` | You don't have permission to access the requested resource. | | `404 Not Found` | The requested resource could not be found. | | `429 Too Many Requests` | You're sending too many requests. | | `500 Internal Server Error` | We had a problem with our server. Try again later. | ## Rate Limiting To ensure the stability of our services for all users, the Elementum API enforces rate limiting. If you exceed the rate limit, you will receive an HTTP `429 Too Many Requests` response. ## Endpoint reference The base URL is `https://api.elementum.io/v1` (EU: `https://api.eu.elementum.io/v1`). Supported endpoints by area: | Function | Method | Path | | ------------------------- | ------ | ------------------------------------------------------- | | Search for record(s) | GET | `/{recordType}/{alias}` | | Find record by ID | GET | `/{recordType}/{alias}/{id}` | | Create a record | POST | `/{recordType}/{alias}` | | Update a record | PUT | `/{recordType}/{alias}/{id}` | | Get related items | GET | `/{recordType}/{alias}/{id}/related-items` | | Add related item | POST | `/{recordType}/{alias}/{id}/related-items` | | Remove related item | DELETE | `/{recordType}/{alias}/{id}/related-items/{relationId}` | | Find attachment by ID | GET | `/{recordType}/{alias}/{id}/attachments/{attachmentId}` | | Get list of attachments | GET | `/{recordType}/{alias}/{id}/attachments` | | Add attachment | POST | `/{recordType}/{alias}/{id}/attachments` | | Add link | POST | `/{recordType}/{alias}/{id}/attachments/url-links` | | Remove attachment | DELETE | `/{recordType}/{alias}/{id}/attachments/{attachmentId}` | | Get watchers | GET | `/{recordType}/{alias}/{id}/watchers` | | Add watcher(s) | POST | `/{recordType}/{alias}/{id}/watchers` | | Remove watcher(s) | DELETE | `/{recordType}/{alias}/{id}/watchers` | | Get comments | GET | `/{recordType}/{alias}/{id}/comment` | | Add comment | POST | `/{recordType}/{alias}/{id}/comment` | | List users | GET | `/users` | | Create a user | POST | `/users` | | Get a user by ID | GET | `/users/{userId}` | | Deactivate a user | POST | `/users/{userId}/deactivate` | | List groups | GET | `/groups` | | Get a group by ID | GET | `/groups/{groupId}` | | List users in a group | GET | `/groups/{groupId}/users` | | Add users to a group | POST | `/groups/{groupId}/users` | | Remove users from a group | DELETE | `/groups/{groupId}/users` | When `recordType` is `elements`, see the [tip on reliably listing element records](/api-reference/endpoints/records/get-the-list-of-records) before calling the search endpoint through an interactive API explorer. See the [API Reference](/api-reference/endpoints/records/get-the-list-of-records) sections for parameters, request bodies, and response schemas. ## Best Practices and important notes * **Field names and picklist values** match what is configured in the record type definition in Admin. Use the exact names and values from your app. * **Date and date-time fields** must be in ISO 8601 format with UTC (`Z`) offset: `YYYY-MM-DDTHH:MM:SS.SSSZ` — for example, `2026-06-05T14:30:00.000Z`. Mixing local-timezone offsets can cause display inconsistencies; always send UTC. * **Record creation** must include all required fields defined for that record type. * **Relating items** (e.g. adding Elements to an App record) is done one item at a time. * URL-encode special characters in filter strings when using query parameters. * Access tokens expire after 24 hours; obtain a new token when needed. ## Versioning Our API is versioned to ensure that changes are predictable and non-breaking. The current version is `v1`, which is specified in the URL of your API requests. `https://api.elementum.io/v1/{endpoint}` # Request an access token Source: https://docs.elementum.io/api-reference/endpoints/access-token/request-an-access-token post /oauth/token Obtain a Bearer token using OAuth 2.0 client credentials. Send either (1) JSON body with client_id, client_secret, and grant_type, or (2) application/x-www-form-urlencoded body with grant_type=client_credentials and Basic Auth header (Client ID as username, Client Secret as password). Tokens expire after 24 hours. # Add a link Source: https://docs.elementum.io/api-reference/endpoints/attachments/add-a-link post /{recordType}/{alias}/{id}/attachments/url-links # Add an Attachment Source: https://docs.elementum.io/api-reference/endpoints/attachments/add-an-attachment post /{recordType}/{alias}/{id}/attachments Upload a file attachment to a specific record ## Overview Upload file attachments to records in Elementum. Files are stored as attachments on the record and accessible through the record's attachments block. **File Size Limit**: Maximum file size is **250MB** per attachment. ## Endpoint ``` POST https://api.elementum.io/v1/elements/{elementname}/{record-handle}/attachments ``` ## Request The request body should be `multipart/form-data` containing the file to upload. **Path Parameters:** * `elementname` - The namespace of your element (e.g., `testelement`) * `record-handle` - The unique identifier for the record (e.g., `TTE-11`) **Headers:** * `Authorization: Bearer {access_token}` * `Content-Type: multipart/form-data` **Body:** * `file` (required) - The file to upload * `description` (optional) - Description for the attachment ## Example Request ```bash theme={null} curl -X POST 'https://api.elementum.io/v1/elements/testelement/TTE-11/attachments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -F 'file=@/path/to/document.pdf' \ -F 'description=Contract document' ``` ## Response **Success (202 Accepted):** ```json theme={null} { "id": "att_abc123xyz", "name": "document.pdf", "description": "Contract document", "mediaType": "application/pdf", "size": 2458624, "state": "processing", "createdAt": "2025-01-08T14:30:00Z" } ``` The `202 Accepted` status indicates the file upload has been accepted and is being processed asynchronously. **Common Errors:** * `400` - Invalid file or exceeds size limit * `401` - Invalid or expired access token * `404` - Record not found * `413` - File exceeds 250MB size limit ## Related Documentation Comprehensive guide to working with files and attachments Add a URL link as an attachment Remove an attachment from a record Authentication and getting started # Delete a record attachment Source: https://docs.elementum.io/api-reference/endpoints/attachments/delete-a-record-attachment delete /{recordType}/{alias}/{id}/attachments/{attachmentId} # Download attachment content Source: https://docs.elementum.io/api-reference/endpoints/attachments/download-attachment-content get /{recordType}/{alias}/{id}/attachments/{attachmentId}/content # Find an attachment by ID Source: https://docs.elementum.io/api-reference/endpoints/attachments/find-an-attachment-by-id get /{recordType}/{alias}/{id}/attachments/{attachmentId} # Get the list of attachments Source: https://docs.elementum.io/api-reference/endpoints/attachments/get-the-list-of-attachments get /{recordType}/{alias}/{id}/attachments # Add a comment Source: https://docs.elementum.io/api-reference/endpoints/comments/add-a-comment post /{recordType}/{alias}/{id}/comment # Get the list of comments Source: https://docs.elementum.io/api-reference/endpoints/comments/get-the-list-of-comments get /{recordType}/{alias}/{id}/comment # Add users to a group Source: https://docs.elementum.io/api-reference/endpoints/groups/add-users-to-a-group post /groups/{groupId}/users # Get a group by ID Source: https://docs.elementum.io/api-reference/endpoints/groups/get-a-group-by-id get /groups/{groupId} # List groups in your organization Source: https://docs.elementum.io/api-reference/endpoints/groups/list-groups get /groups # List users in a group Source: https://docs.elementum.io/api-reference/endpoints/groups/list-users-in-a-group get /groups/{groupId}/users # Remove users from a group Source: https://docs.elementum.io/api-reference/endpoints/groups/remove-users-from-a-group delete /groups/{groupId}/users # Create a record Source: https://docs.elementum.io/api-reference/endpoints/records/create-a-record post /{recordType}/{alias} # Find a record by ID Source: https://docs.elementum.io/api-reference/endpoints/records/find-a-record-by-id get /{recordType}/{alias}/{id} # Get the list of records Source: https://docs.elementum.io/api-reference/endpoints/records/get-the-list-of-records get /{recordType}/{alias} When listing **Element-type records**, calling this endpoint through an interactive API explorer can resolve to the Elements management API (`GET /elements/{alias}`, "Get an element by alias") instead of the record list, because both share the `/elements/{alias}` path shape. To reliably reach the records list, call the endpoint directly — for example with cURL or Postman — using the full path `https://api.elementum.io/v1/{recordType}/{alias}`. To retrieve one known record by ID instead of a list, `GET https://api.elementum.io/v1/elements/{namespace}/{recordId}` returns that single record directly. # Update a record Source: https://docs.elementum.io/api-reference/endpoints/records/update-a-record put /{recordType}/{alias}/{id} # Add a related item Source: https://docs.elementum.io/api-reference/endpoints/related-items/add-a-related-item post /{recordType}/{alias}/{id}/related-items # Get the list of related items Source: https://docs.elementum.io/api-reference/endpoints/related-items/get-the-list-of-related-items get /{recordType}/{alias}/{id}/related-items # Remove a related item Source: https://docs.elementum.io/api-reference/endpoints/related-items/remove-a-related-item delete /{recordType}/{alias}/{id}/related-items/{itemId} # Create a user in your organization Source: https://docs.elementum.io/api-reference/endpoints/users/create-a-user post /users # Deactivate a user Source: https://docs.elementum.io/api-reference/endpoints/users/deactivate-a-user post /users/{userId}/deactivate # Get a user by ID Source: https://docs.elementum.io/api-reference/endpoints/users/get-a-user-by-id get /users/{userId} # List users in your organization Source: https://docs.elementum.io/api-reference/endpoints/users/list-users get /users # Add a watcher Source: https://docs.elementum.io/api-reference/endpoints/watchers/add-a-watcher post /{recordType}/{alias}/{id}/watchers # Delete a watcher Source: https://docs.elementum.io/api-reference/endpoints/watchers/delete-a-watcher delete /{recordType}/{alias}/{id}/watchers # Get the list of watchers Source: https://docs.elementum.io/api-reference/endpoints/watchers/get-the-list-of-watchers get /{recordType}/{alias}/{id}/watchers # Analytics Source: https://docs.elementum.io/data/analytics Build charts and dashboards from Apps, Elements, Tasks, Tables, and CloudLinks data with aggregations, time ranges, and filters Analytics turns Tables Tables, Elements Elements, Tasks Tasks, Apps Apps, and CloudLink-backed data into charts and dashboards. You can aggregate fields, group by time, filter to subsets, and place results on dashboards with widgets that refresh as source data changes. **Analytics vs Reports:** Analytics are interactive charts and dashboards you explore in the product. For scheduled or on-demand **Excel** and **PDF** outputs from report templates (including via [automations](/workflows/automation-system)), use [Reports](/data/reports) instead. **Capabilities:** * **Charts** — Seven types (bar, line, pie, donut, single bar, single line, single value) for comparisons, trends, and KPIs * **Aggregations** — Count, sum, average, min/max, percentages, and grouping; use [Calculations](/data/calculations) for formulas before charting when logic is complex * **Time analysis** — Intervals (daily through yearly), custom and relative ranges, and period comparisons where configured * **Dashboards** — Chart widgets, metric-style layouts, sizing, refresh intervals, and summary-style groupings ## Chart types | Type | Use for | Examples | | ---------------------------- | --------------------------------- | -------------------------------------------------------- | | **Bar** | Categories and distributions | Sales by region, tickets by priority, volume by channel | | **Line** | Trends over time | Recurring revenue by month, satisfaction over quarters | | **Pie / donut** | Parts of a whole | Pipeline by stage, budget split, share by product | | **Single bar / single line** | One metric or a simple comparison | Period vs. target, single KPI trend | | **Single value** | One number with context | Active customers, monthly revenue, response-time average | ## Create and Configure Charts 1. **Open the target view** — Table or dashboard where the chart should appear. 2. **Choose a chart type** — Match the type to the comparison or trend you need. 3. **Select the data source** — Fields and metrics from connected data (including CloudLinks where available). 4. **Set aggregation** — Count, sum, average, min/max, or grouped rollups as supported for that source. 5. **Apply filters** — Narrow rows with saved or ad hoc filters, including combined conditions where supported. 6. **Adjust display** — Titles, colors, legends, and axis formatting. ### Aggregations * **Count** — Total rows, distinct values, or conditional counts * **Mathematical** — Sum, average, minimum, maximum for numeric fields * **Advanced** — Include other values as a single aggregated group; percentage calculations for proportional analysis; custom calculations using field combinations For logic beyond basic aggregations, define values with [Calculations](/data/calculations) first, then chart the result. ### Time ranges and date grouping * **Intervals** — Daily, weekly, monthly, quarterly, or yearly (as offered for the field). * **Ranges** — Fixed date spans, relative windows (for example last 30 days or this quarter), and rolling periods where supported. * **Date Grouping** — By calendar unit or field; compare periods (for example month over month or year over year) when that option exists. ## Dashboards and widgets * **Chart widgets** — Place charts on dashboard layouts with size and position controls. * **Metric-style widgets** — Single values with optional trend indicators and threshold coloring where configured. * **Summary layouts** — Multiple related metrics in one area for role-specific views (for example executive or department summaries). ### Real-time data updates Analytics refresh as underlying data changes. Charts update when source data changes through live data sync. You can configure scheduled refresh intervals for automatic updates, run manual refresh when you need an immediate read, and use change indicators for visual cues that data has been updated. Set refresh frequency in line with how volatile your data is so dashboards stay current without overloading slow queries. ## Filters, interaction, and layout ### Filters **Dynamic filtering:** Apply filters to narrow charts to specific data subsets; reuse saved filters for consistent analysis; combine conditions with AND/OR logic where supported. **Segmentation:** Segment by categories, status, or custom field values; compare metrics across segments; use cohort-style breakdowns for customer behavior where available. **Conditional display:** Show or hide chart elements based on data values; apply conditional formatting for threshold alerts; build legends that respond to which data is present where configured. ### Interaction **Chart interaction:** Click chart elements to drill into underlying detail where enabled; hover for extra context and exact values; zoom time-series views where available. **Export and sharing:** Export charts as images for presentations and reports; download the underlying tabular data for analysis outside Elementum; share chart configurations with collaborators when your permissions allow. ### Layout **Visual styling:** Set chart titles and descriptions; choose color schemes for brand consistency; adjust legend placement and formatting; customize axis labels and number formats. **Placement and display:** Control chart size and position within dashboards; use layouts that adapt for mobile viewing where supported; arrange charts in grid layouts for organized dashboard views. ## Example configurations Use these as templates; rename sources and fields to match your App. * Line chart — Sum of deal value by month, filter status = Closed Won (revenue trend). * Donut chart — Count of opportunities by stage (pipeline mix). * Line chart — Average survey rating by week. * Bar chart — Count of tickets by priority. * Single value — Average completion time on Task records, filter by team. * Pie chart — Sum of hours by project type. * Bar chart — Sum of amount by budget vs. actual category. * Single bar — Sum of expenses by department. ## Performance * Prefer shorter time windows, heavier aggregation, and filters so each chart returns fewer points. * Align refresh frequency with how often the data changes; use manual refresh for rarely viewed boards. * Group and filter on fields that are practical for your data source (indexed or selective where possible). * Move heavy logic into [Calculations](/data/calculations) instead of pushing complex expressions into the chart query alone. Very large result sets or deep aggregations can slow dashboards. Favor focused charts and summary widgets for broad exploration. ## Design and metric hygiene * **Clarity** — Titles that state the measure and period; chart type that matches the question; limit color categories to a small set; show units on axes and labels. * **Layout** — Important metrics first; group related charts; keep styling consistent across a dashboard. * **Definitions** — Document what each metric means, reuse the same calculation for the same KPI, and review definitions when fields change. * **Access** — Apply permissions appropriate to sensitive metrics; align dashboard access with data access policies. ## Work with other Elementum features * **Tables** — Charts can follow table filters and table calculations where wired together; table updates flow to chart data. * **Automations** — Automations react to [record and system events](/workflows/automation-system), not to chart widgets directly. Use data changes (for example field thresholds on underlying records) or schedules to drive notifications, [reports](/workflows/automation-actions-reference), and workflows that relate to the same metrics you chart. * **Flows and approvals** — Track duration, volume, and outcomes with charts to spot bottlenecks in [approval](/workflows/approval-processes) and other processes. * **Data mining** — Chart quality or volume metrics to monitor [data mining](/data/data-mining) outcomes and source health where you store those values in Elements or Tables. # Calculations Source: https://docs.elementum.io/data/calculations Build formulas to transform values, aggregate related records, and evaluate conditions—in automations, layouts, and anywhere calculations are supported. Calculations let you combine fields, operators, and functions to derive values from your data. Use them in automations, layouts, and data processing when you need totals, text formatting, date math, or conditional logic. When a formula isn't behaving as expected, ask the [AI Docs Assistant](/support/resources#ai-docs-assistant) to help troubleshoot your calculation or Execute Script action. Describe your input, the result you want, and where the value is used (for example, an Update Record field or a Repeat for Each loop), and it will compose or debug the expression from documented functions. ## Where to use calculations Calculations can be configured in several places in Elementum: * **Automations** — Use the **Run Calculation** action to evaluate expressions from triggers or previous actions (see [Automation actions reference](/workflows/automation-actions-reference)). * **Element layouts** — Add formulas to derive values on records. * **Calculated columns in tables** — For example, `Total = Quantity × Price` (see [Tables](/data/tables)). * **Reports** — Add formulas to Excel reports (see [Reports](/data/reports)). Get started with basic calculations Complete list of all available functions Real-world calculation scenarios Common issues and solutions ## Quick Start New to calculations? Start with these patterns for totals, text, dates, and conditional logic. ### Most Used Functions ```javascript theme={null} // Sum all invoice amounts SUM(INVOICES."Amount") // Average customer rating AVERAGE(REVIEWS."Rating") // Count completed tasks COUNT(TASKS."ID") ``` ```javascript theme={null} // Create full name CONCAT(CUSTOMERS."FirstName", ' ', CUSTOMERS."LastName") // Standardize email format LOWER(CUSTOMERS."Email") // Format product codes UPPER(PRODUCTS."SKU") ``` ```javascript theme={null} // Current date and time (there is no TODAY() function — use NOW()) NOW() // Add 5 days to today DATEADD(DAY, 5, NOW()) // Subtract 1 month from a due date DATEADD(MONTH, -1, TASKS."DueDate") // Days since order placed DATEDIF(ORDERS."OrderDate", NOW(), 'D') // Convert text to date (input must be YYYY-MM-DD) DATEVALUE(CUSTOMERS."SignupDate") ``` ```javascript theme={null} // Customer status based on spending IF(CUSTOMERS."TotalSpent" > 1000, 'VIP', 'Standard') // Eligible for discount AND(CUSTOMERS."TotalSpent" > 500, CUSTOMERS."MembershipLevel" = 'Gold') // Nested conditions for customer tiers IF(CUSTOMERS."TotalSpent" > 5000, 'Enterprise', IF(CUSTOMERS."TotalSpent" > 1000, 'Premium', 'Standard')) ``` ### Common date recipes The most-asked date questions, with the exact syntax to use. #### Get today's date Elementum does not have a `TODAY()` function. Use `NOW()` for the current date and time, and wrap it in `DATE()` if you need just the date portion: ```javascript theme={null} // Current date and time NOW() // Just today's date (no time component) DATE(YEAR(NOW()), MONTH(NOW()), DAY(NOW())) ``` #### Get the current date and time `NOW()` returns the current timestamp. It takes no arguments: ```javascript theme={null} NOW() ``` Use it inside other functions to derive values against the current moment: ```javascript theme={null} // Days since a stored date DATEDIF(ORDERS."OrderDate", NOW(), 'D') // Current year for reporting YEAR(NOW()) ``` #### Add days to a date Use [`DATEADD(unit, value, date)`](#dateadd---add-or-subtract-time-from-a-date) with an unquoted unit token like `DAY` or `MONTH`: ```javascript theme={null} // Add 5 days to today DATEADD(DAY, 5, NOW()) // Expected ship-by, 30 days after order DATEADD(DAY, 30, ORDERS."OrderDate") ``` #### Subtract days from a date Pass a negative value to `DATEADD`: ```javascript theme={null} // 7 days ago DATEADD(DAY, -7, NOW()) // One month before a due date DATEADD(MONTH, -1, TASKS."DueDate") ``` `DATEADD` handles month and year rollovers automatically — adding days across the end of a month advances into the next month as expected. ## Business Examples ### Calculate Monthly Sales Performance ```javascript theme={null} // Total monthly revenue SUM(ORDERS."Amount") // Average order value AVERAGE(ORDERS."Amount") // Top performing month MAX_AGGREGATE(MONTHLY_SALES."Revenue") // Sales growth percentage ROUND((THIS_MONTH."Revenue" - LAST_MONTH."Revenue") / LAST_MONTH."Revenue" * 100, 2) // High-value customer identification IF(CUSTOMERS."TotalSpent" > 5000, 'Enterprise', IF(CUSTOMERS."TotalSpent" > 1000, 'Premium', 'Standard')) ``` ### Customer Insights & Segmentation ```javascript theme={null} // Customer full name CONCAT(CUSTOMERS."FirstName", ' ', CUSTOMERS."LastName") // Days since last purchase DATEDIF(CUSTOMERS."LastPurchaseDate", NOW(), 'D') // Customer lifetime value SUM(ORDERS."Amount") // Customer age DATEDIF(CUSTOMERS."BirthDate", NOW(), 'Y') // At-risk customer flag IF(DATEDIF(CUSTOMERS."LastPurchaseDate", NOW(), 'D') > 90, 'At Risk', 'Active') ``` ### Inventory Management ```javascript theme={null} // Stock level status IF(PRODUCTS."StockLevel" < PRODUCTS."ReorderPoint", 'Low Stock', 'OK') // Days of inventory remaining ROUND(PRODUCTS."StockLevel" / AVERAGE(DAILY_SALES."Quantity"), 0) // Total inventory value SUM(PRODUCTS."StockLevel" * PRODUCTS."Cost") // Product performance score ROUND((PRODUCTS."Revenue" / PRODUCTS."Cost") * 100, 2) // Reorder recommendation IF(PRODUCTS."StockLevel" < PRODUCTS."ReorderPoint", CONCAT('Reorder ', PRODUCTS."ReorderQuantity", ' units'), 'Stock OK') ``` ## Function Reference Functions are organized by category. Use the search function (Ctrl/Cmd + K) to quickly find specific functions. ### Logical Functions Tests multiple conditions and returns TRUE only if all are TRUE. **Syntax:** `AND(condition1, condition2, ...)` **Business Example:** ```javascript theme={null} // Check if customer is eligible for discount AND(CUSTOMERS."TotalSpent" > 500, CUSTOMERS."MembershipLevel" = 'Gold') // Validate complete order AND(ORDERS."PaymentStatus" = 'Paid', ORDERS."ShippingAddress" != '') // Employee bonus eligibility AND(EMPLOYEES."SalesTarget" <= EMPLOYEES."ActualSales", EMPLOYEES."Tenure" > 1) ``` **Arguments:** * `condition1, condition2, ...`: Logical expressions that evaluate to TRUE/FALSE If any condition is blank, the result will be blank. Tests multiple conditions and returns TRUE if any are TRUE. **Syntax:** `OR(condition1, condition2, ...)` **Business Example:** ```javascript theme={null} // Flag tickets that are urgent or overdue OR(TICKETS."Priority" = 'Urgent', TICKETS."DaysOpen" > 7) // Identify customers worth re-engaging OR(CUSTOMERS."DaysSinceLastPurchase" > 90, CUSTOMERS."OpenTickets" > 0) // Apply discount when any qualifying condition is met OR(ORDERS."DiscountCode" != '', ORDERS."LoyaltyTier" = 'Gold') ``` **Arguments:** * `condition1, condition2, ...`: Logical expressions that evaluate to TRUE/FALSE If any condition is blank, the result will be blank. Returns different values based on a condition. **Syntax:** `IF(condition, value_if_true, value_if_false)` **Business Example:** ```javascript theme={null} // Customer status based on spending IF(CUSTOMERS."TotalSpent" > 1000, 'VIP', 'Standard') // Shipping cost calculation IF(ORDERS."Amount" > 100, 0, 9.99) // Performance rating IF(EMPLOYEES."SalesTarget" <= EMPLOYEES."ActualSales", 'Exceeded', 'Below Target') // Nested conditions for customer tiers IF(CUSTOMERS."TotalSpent" > 5000, 'Enterprise', IF(CUSTOMERS."TotalSpent" > 1000, 'Premium', 'Standard')) ``` **Arguments:** * `condition`: Logical expression * `value_if_true`: Value returned when condition is TRUE * `value_if_false`: Value returned when condition is FALSE For more than two outcomes, use `IFS` instead of nesting multiple `IF` statements—it's flatter and easier to read. Evaluates multiple conditions in order and returns the value corresponding to the first condition that is TRUE. **Syntax:** `IFS(condition1, value1, condition2, value2, ...)` **Business Example:** ```javascript theme={null} // Customer tier based on spending IFS( CUSTOMERS."TotalSpent" > 5000, 'Enterprise', CUSTOMERS."TotalSpent" > 1000, 'Premium', TRUE(), 'Standard' ) // Order priority based on age IFS( ORDERS."DaysOpen" > 14, 'Critical', ORDERS."DaysOpen" > 7, 'High', ORDERS."DaysOpen" > 3, 'Medium', TRUE(), 'Low' ) // Shipping band based on order amount IFS( ORDERS."Amount" >= 250, 'Free', ORDERS."Amount" >= 100, 'Discounted', TRUE(), 'Standard' ) // Evaluation walkthrough — returned value depends on field values IFS( BAT."Number" = 0, '0', BAT."Number" > 4, '>4', BAT."Status" = 'New', 'New' ) // Number=0, Status='New' → '0' (first condition matches) // Number=1, Status='New' → 'New' (skips 0 and >4, matches Status) // Number=5, Status='New' → '>4' (matches >4 before Status is checked) // Number=null, Status='New' → 'New' (null comparisons don't match) // Number=null, Status='Old' → blank (no condition matches) ``` **Arguments:** * `condition1, condition2, ...`: Logical expressions evaluated in order * `value1, value2, ...`: Value returned for the corresponding condition when it is the first to evaluate to TRUE When no condition is TRUE, `IFS` returns blank. Include a final `TRUE()` condition as a catch-all to guarantee a value is always returned. ### Numeric Functions Calculates the total sum of values in a related field. **Syntax:** `SUM(related_field)` **Business Example:** ```javascript theme={null} // Total revenue from all orders SUM(ORDERS."Amount") // Total hours worked by employee SUM(TIMESHEETS."Hours") // Total inventory value SUM(PRODUCTS."StockLevel" * PRODUCTS."UnitCost") // Customer lifetime value SUM(CUSTOMER_ORDERS."Amount") ``` **Arguments:** * `related_field`: Field from related records to sum This function only works with related fields, not individual values. For adding individual values, use the '+' operator. Returns the numerical average of values in a related field. **Syntax:** `AVERAGE(related_field)` **Business Example:** ```javascript theme={null} // Average customer rating AVERAGE(REVIEWS."Rating") // Average order value AVERAGE(ORDERS."Amount") // Average employee salary by department AVERAGE(EMPLOYEES."Salary") // Average project completion time AVERAGE(PROJECTS."CompletionDays") ``` **Arguments:** * `related_field`: Field from related records to average Blank values are automatically excluded from the calculation. Counts the number of non-null values in a related field. **Syntax:** `COUNT(related_field)` **Business Example:** ```javascript theme={null} // Number of orders placed COUNT(ORDERS."ID") // Number of completed tasks COUNT(TASKS."CompletedDate") // Number of active customers COUNT(CUSTOMERS."LastLoginDate") // Number of products in stock COUNT(PRODUCTS."StockLevel") ``` **Arguments:** * `related_field`: Field from related records to count Use the ID field to count total records, or use a specific field to count only non-null values. Counts non-null values in a related field that meet a specified condition. **Syntax:** `COUNTIF(related_field, criterion)` **Business Example:** ```javascript theme={null} // Count high-value orders COUNTIF(ORDERS."Amount", '>1000') // Count 5-star reviews COUNTIF(REVIEWS."Rating", '=5') // Count overdue tasks COUNTIF(TASKS."DueDate", '<' + TEXT(NOW())) // Count products with low stock COUNTIF(PRODUCTS."StockLevel", '<10') ``` **Arguments:** * `related_field`: Field from related records to count * `criterion`: Condition to meet (supports comparison operators) Alternative syntax: `SUM(IF(RELATED."Field" = 'Paid', 1, 0))` Counts the number of unique values in a related field. **Syntax:** `COUNTUNIQUE(related_field)` **Business Example:** ```javascript theme={null} // Number of unique customers COUNTUNIQUE(ORDERS."CustomerID") // Number of different product categories COUNTUNIQUE(PRODUCTS."Category") // Number of unique sales reps COUNTUNIQUE(DEALS."SalesRep") // Number of unique support ticket types COUNTUNIQUE(TICKETS."Type") ``` **Arguments:** * `related_field`: Field from related records to count unique values Null values are excluded from the count. Returns the maximum value from a given set of values. **Syntax:** `MAX(value1, value2, ...)` **Business Example:** ```javascript theme={null} // Highest of three scores MAX(PERFORMANCE."Q1Score", PERFORMANCE."Q2Score", PERFORMANCE."Q3Score") // Maximum shipping cost between options MAX(SHIPPING."Standard", SHIPPING."Express", SHIPPING."Overnight") // Latest date from multiple fields MAX(CUSTOMER."LastPurchase", CUSTOMER."LastContact", CUSTOMER."LastLogin") ``` **Arguments:** * `value1, value2, ...`: Values to compare Blank values are ignored. For aggregate calculations, use MAX\_AGGREGATE. Finds the maximum value from a related field or calculation. **Syntax:** `MAX_AGGREGATE(related_field)` **Business Example:** ```javascript theme={null} // Highest order amount MAX_AGGREGATE(ORDERS."Amount") // Best employee performance score MAX_AGGREGATE(EMPLOYEES."PerformanceScore") // Peak sales month MAX_AGGREGATE(MONTHLY_SALES."Revenue") // Highest customer satisfaction rating MAX_AGGREGATE(SURVEYS."SatisfactionScore") ``` **Arguments:** * `related_field`: Field from related records to find maximum This is the aggregate version of MAX for related data. Returns the minimum value from a given set of values. **Syntax:** `MIN(value1, value2, ...)` **Business Example:** ```javascript theme={null} // Lowest of three prices MIN(PRICING."Standard", PRICING."Discount", PRICING."Wholesale") // Earliest date from multiple fields MIN(PROJECT."StartDate", PROJECT."PlannedStart", PROJECT."ActualStart") // Minimum required inventory MIN(PRODUCT."SafetyStock", PRODUCT."ReorderPoint", 10) ``` **Arguments:** * `value1, value2, ...`: Values to compare Blank values are ignored. For aggregate calculations, use MIN\_AGGREGATE. Finds the minimum value from a related field or calculation. **Syntax:** `MIN_AGGREGATE(related_field)` **Business Example:** ```javascript theme={null} // Lowest order amount MIN_AGGREGATE(ORDERS."Amount") // Shortest project duration MIN_AGGREGATE(PROJECTS."Duration") // Lowest inventory level MIN_AGGREGATE(PRODUCTS."StockLevel") // Minimum customer age MIN_AGGREGATE(CUSTOMERS."Age") ``` **Arguments:** * `related_field`: Field from related records to find minimum This is the aggregate version of MIN for related data. Rounds a number to a specified number of decimal places. **Syntax:** `ROUND(number, [decimal_places])` **Business Example:** ```javascript theme={null} // Round currency to 2 decimal places ROUND(ORDERS."Amount", 2) // Round percentage to whole number ROUND(SALES."GrowthRate" * 100, 0) // Round to nearest thousand ROUND(REVENUE."Annual", -3) // Round average rating ROUND(AVERAGE(REVIEWS."Rating"), 1) ``` **Arguments:** * `number`: Number to round * `decimal_places`: \[OPTIONAL] Number of decimal places (default: 0) Negative decimal\_places rounds to left of decimal point (e.g., -1 rounds to tens). Calculates the standard deviation of a related field. **Syntax:** `STDEV(related_field)` **Business Example:** ```javascript theme={null} // Variability in order amounts STDEV(ORDERS."Amount") // Consistency of employee performance STDEV(EMPLOYEES."PerformanceScore") // Product rating consistency STDEV(REVIEWS."Rating") // Sales performance variability STDEV(SALES_REPS."MonthlySales") ``` **Arguments:** * `related_field`: Field from related records to calculate standard deviation Standard deviation measures how spread out values are from the average. Returns the sum of values in a field that meet a specified condition. **Syntax:** `SUMIF(related_field, criterion)` **Business Example:** ```javascript theme={null} // Revenue from high-value orders SUMIF(ORDERS."Amount", '>1000') // Total hours for completed tasks SUMIF(TASKS."Hours", TASKS."Status" = 'Completed') // Revenue from premium customers SUMIF(ORDERS."Amount", CUSTOMERS."Tier" = 'Premium') // Sales from specific region SUMIF(SALES."Amount", SALES."Region" = 'North') ``` **Arguments:** * `related_field`: Field from related records to sum * `criterion`: Condition values must meet Use operators like greater than, less than, greater than or equal to, less than or equal to, and equal to in your criteria. ### Date and Time Functions Returns the current date and time. **Syntax:** `NOW()` **Business Example:** ```javascript theme={null} // Timestamp for new records NOW() // Days since order placed DATEDIF(ORDERS."OrderDate", NOW(), 'D') // Current year for reporting YEAR(NOW()) // Age calculation DATEDIF(CUSTOMERS."BirthDate", NOW(), 'Y') ``` This function takes no arguments and always returns the current moment. There is no separate `TODAY()` function — use `NOW()` and, if you need date-only, wrap it in `DATE(YEAR(NOW()), MONTH(NOW()), DAY(NOW()))`. Adds a value in a given unit to a date or datetime. Pass a negative value to subtract. **Syntax:** `DATEADD(unit, value, date)` **Business Example:** ```javascript theme={null} // Add 7 days to today DATEADD(DAY, 7, NOW()) // Subtract 1 month from a due date DATEADD(MONTH, -1, TASKS."DueDate") // Expected ship-by, 30 days after an order DATEADD(DAY, 30, ORDERS."OrderDate") // Ninety-day follow-up after a customer's last purchase DATEADD(DAY, 90, CUSTOMERS."LastPurchaseDate") ``` **Arguments:** * `unit`: Date/time unit token — for example, `DAY` or `MONTH`. Passed unquoted. * `value`: Number of units to add. Use a negative number to subtract. * `date`: Starting date or datetime `DATEADD` handles month and year boundaries automatically — adding days across the end of a month or year rolls forward as expected. This is the recommended way to shift a date by a fixed amount. Returns a date value based on provided year, month, and day. **Syntax:** `DATE(year, month, day)` **Business Example:** ```javascript theme={null} // Create fiscal year start date DATE(YEAR(NOW()), 4, 1) // Build date from separate fields DATE(ORDERS."Year", ORDERS."Month", ORDERS."Day") // Create quarter end date DATE(2024, 3, 31) // Generate report date DATE(REPORTS."ReportYear", REPORTS."ReportMonth", 1) // Extract the date portion from a datetime field // (use this to populate a Date field from a DateTime field // in an Update Record Fields automation action) DATE( YEAR(ORDERS."OrderDateTime"), MONTH(ORDERS."OrderDateTime"), DAY(ORDERS."OrderDateTime") ) ``` **Arguments:** * `year`: Four-digit year * `month`: Month (1-12) * `day`: Day of month (1-31) Values exceeding normal ranges automatically adjust (e.g., month 13 becomes January of next year). To shift a date by a fixed amount (add or subtract days, months, and so on), use [`DATEADD`](#dateadd---add-or-subtract-time-from-a-date) rather than building a new `DATE` with adjusted components. There is no direct "datetime to date" conversion option in calculations or in the **Update Record Fields** automation action. To populate a Date field from a DateTime field, wrap the datetime value in `DATE(YEAR(...), MONTH(...), DAY(...))` as shown above. Returns a datetime value in the company's timezone. **Syntax:** `DATETIME(year, month, day, hour, minute, second)` **Business Example:** ```javascript theme={null} // Create meeting start time DATETIME(2024, 3, 15, 9, 30, 0) // Build timestamp from fields DATETIME(EVENTS."Year", EVENTS."Month", EVENTS."Day", EVENTS."Hour", 0, 0) // Create deadline DATETIME(TASKS."DueYear", TASKS."DueMonth", TASKS."DueDay", 23, 59, 59) // Sentinel "max" datetime — 12/31/9999 11:59 PM DATETIME(9999, 12, 31, 23, 59, 0) // Sentinel "min" datetime — 1/1/1901 12:00 AM (midnight) DATETIME(1901, 1, 1, 0, 0, 0) // Add 1 hour to now DATETIME(YEAR(NOW()), MONTH(NOW()), DAY(NOW()), HOUR(NOW()) + 1, MINUTE(NOW()), 0) ``` **Arguments:** * `year`: Four-digit year * `month`: Month (1-12) * `day`: Day of month (1-31) * `hour`: Hour (0-23) * `minute`: Minute (0-59) * `second`: Second (0-59) Time is set in your company's timezone. Calculates the difference between two dates in specified units. **Syntax:** `DATEDIF(start_date, end_date, unit)` **Business Example:** ```javascript theme={null} // Customer age DATEDIF(CUSTOMERS."BirthDate", NOW(), 'Y') // Days since last purchase DATEDIF(CUSTOMERS."LastPurchaseDate", NOW(), 'D') // Project duration in months DATEDIF(PROJECTS."StartDate", PROJECTS."EndDate", 'M') // Employee tenure DATEDIF(EMPLOYEES."HireDate", NOW(), 'Y') ``` **Arguments:** * `start_date`: Beginning date * `end_date`: End date * `unit`: 'Y' for years, 'M' for months, 'D' for days Returns negative values if start\_date is after end\_date. Truncates a datetime to a specified unit. **Syntax:** `DATETIME_TRUNC(datetime, unit)` **Business Example:** ```javascript theme={null} // Start of month for reporting DATETIME_TRUNC(ORDERS."OrderDate", 'MONTH') // Start of day for daily summaries DATETIME_TRUNC(EVENTS."EventTime", 'DAY') // Start of quarter DATETIME_TRUNC(SALES."SaleDate", 'QUARTER') // Start of year DATETIME_TRUNC(EMPLOYEES."HireDate", 'YEAR') ``` **Arguments:** * `datetime`: Datetime to truncate * `unit`: YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND Useful for grouping data by time periods. Converts text date value into a DATE object. **Syntax:** `DATEVALUE(text_date)` **Business Example:** ```javascript theme={null} // Convert imported date text DATEVALUE(IMPORTS."DateString") // Parse date from external system DATEVALUE(EXTERNAL."FormattedDate") // Convert user-entered date DATEVALUE(FORMS."SubmissionDate") ``` **Arguments:** * `text_date`: Text representation of a date Returns null if the text cannot be parsed as a date. **Accepted format:** input must be in `YYYY-MM-DD` form — date only, no time component. Other formats (`MM/DD/YYYY`, written-out months, ISO 8601 strings with a time component) are not parsed and return blank. See [Calculations troubleshooting](/data/calculations-troubleshooting#datevalue-only-accepts-year-month-day-input) for patterns. Returns the day of the month (1-31) from a date. **Syntax:** `DAY(date)` **Business Example:** ```javascript theme={null} // Extract day for daily reports DAY(ORDERS."OrderDate") // Get payment day DAY(INVOICES."DueDate") // Extract birth day DAY(CUSTOMERS."BirthDate") ``` **Arguments:** * `date`: Date to extract day from Returns a number between 1 and 31. Returns the month (1-12) from a date. **Syntax:** `MONTH(date)` **Business Example:** ```javascript theme={null} // Extract month for monthly reports MONTH(ORDERS."OrderDate") // Get birth month MONTH(CUSTOMERS."BirthDate") // Extract fiscal month MONTH(TRANSACTIONS."TransactionDate") ``` **Arguments:** * `date`: Date to extract month from Returns a number between 1 (January) and 12 (December). Returns the year from a date. **Syntax:** `YEAR(date)` **Business Example:** ```javascript theme={null} // Extract year for annual reports YEAR(ORDERS."OrderDate") // Get hire year YEAR(EMPLOYEES."HireDate") // Extract birth year YEAR(CUSTOMERS."BirthDate") ``` **Arguments:** * `date`: Date to extract year from Returns a four-digit year number. Returns the hour (0-23) from a datetime. **Syntax:** `HOUR(datetime)` **Business Example:** ```javascript theme={null} // Extract hour for time-based analysis HOUR(ORDERS."OrderTime") // Get meeting hour HOUR(MEETINGS."StartTime") // Extract login hour HOUR(USERS."LastLogin") ``` **Arguments:** * `datetime`: Datetime to extract hour from Returns a number between 0 (midnight) and 23 (11 PM). Returns the minute (0-59) from a datetime. **Syntax:** `MINUTE(datetime)` **Business Example:** ```javascript theme={null} // Extract minute for precise timing MINUTE(MEETINGS."StartTime") // Get appointment minute MINUTE(APPOINTMENTS."ScheduledTime") // Extract timestamp minute MINUTE(EVENTS."EventTime") ``` **Arguments:** * `datetime`: Datetime to extract minute from Returns a number between 0 and 59. Returns the second (0-59) from a datetime. **Syntax:** `SECOND(datetime)` **Business Example:** ```javascript theme={null} // Extract second for precise timing SECOND(TRANSACTIONS."Timestamp") // Get event second SECOND(EVENTS."EventTime") // Extract log second SECOND(LOGS."LogTime") ``` **Arguments:** * `datetime`: Datetime to extract second from Returns a number between 0 and 59. Returns the day of the week (1-7) for a date. **Syntax:** `WEEKDAY(date, [type])` **Business Example:** ```javascript theme={null} // Get weekday for scheduling WEEKDAY(MEETINGS."MeetingDate", 2) // Analyze sales by day of week WEEKDAY(SALES."SaleDate") // Check if order was placed on a specific day WEEKDAY(ORDERS."OrderDate") = 1 ``` **Arguments:** * `date`: Date to get weekday from * `type`: \[OPTIONAL] 1=Sun-Sat (1-7), 2=Mon-Sun (1-7), 3=Mon-Sun (0-6) Type 1 (default): Sunday=1, Monday=2, ..., Saturday=7 ### Text Functions Joins multiple text values into a single string. **Syntax:** `CONCAT(text1, text2, ...)` **Business Example:** ```javascript theme={null} // Customer full name CONCAT(CUSTOMERS."FirstName", ' ', CUSTOMERS."LastName") // Product description CONCAT(PRODUCTS."Brand", ' - ', PRODUCTS."Model", ' (', PRODUCTS."Color", ')') // Order summary CONCAT('Order #', ORDERS."OrderNumber", ' - ', ORDERS."Status") // Address formatting CONCAT(CUSTOMERS."Street", ', ', CUSTOMERS."City", ', ', CUSTOMERS."State") ``` **Arguments:** * `text1, text2, ...`: Text values to join together Various field types are automatically converted to text for concatenation. `CONCAT` is the only way to join text values. **The `+` operator is for numeric addition only** — it does not concatenate strings, even though it does in some other languages. See [Calculations troubleshooting](/data/calculations-troubleshooting#concatenating-strings). Calculations cannot insert a raw newline inside `CONCAT` — there is no `CHAR` or `CHR` function, and `'\n'` is treated as two literal characters. For multi-line output, build the string in an [Execute Script](/workflows/automation-actions-reference#data-actions) action. See [Adding a newline between concatenated values](/data/calculations-troubleshooting#adding-a-newline-between-concatenated-values). Converts text to uppercase letters. **Syntax:** `UPPER(text)` **Business Example:** ```javascript theme={null} // Standardize product codes UPPER(PRODUCTS."SKU") // Format state abbreviations UPPER(CUSTOMERS."State") // Consistent department names UPPER(EMPLOYEES."Department") // Normalize country codes UPPER(ADDRESSES."CountryCode") ``` **Arguments:** * `text`: Text to convert to uppercase Useful for standardizing data entry and comparisons. Converts text to lowercase letters. **Syntax:** `LOWER(text)` **Business Example:** ```javascript theme={null} // Standardize email addresses LOWER(CUSTOMERS."Email") // Consistent username format LOWER(USERS."Username") // Normalize search terms LOWER(SEARCH."Query") // Standardize domain names LOWER(WEBSITES."Domain") ``` **Arguments:** * `text`: Text to convert to lowercase Use when you need case-insensitive comparisons or normalized text (for example, email addresses). Extracts characters from the beginning of a string. **Syntax:** `LEFT(text, number_of_characters)` **Business Example:** ```javascript theme={null} // Extract first 3 characters of product code LEFT(PRODUCTS."SKU", 3) // Get first initial LEFT(CUSTOMERS."FirstName", 1) // Extract area code from phone LEFT(CUSTOMERS."Phone", 3) // Get first part of order number LEFT(ORDERS."OrderNumber", 4) ``` **Arguments:** * `text`: String to extract from * `number_of_characters`: Number of characters to extract Returns the entire string if requested length exceeds string length. Extracts characters from the end of a string. **Syntax:** `RIGHT(text, number_of_characters)` **Business Example:** ```javascript theme={null} // Extract last 4 digits of credit card RIGHT(PAYMENTS."CardNumber", 4) // Get file extension RIGHT(ATTACHMENTS."FileName", 4) // Extract year from date string RIGHT(RECORDS."DateString", 4) // Get last part of account number RIGHT(ACCOUNTS."AccountNumber", 6) ``` **Arguments:** * `text`: String to extract from * `number_of_characters`: Number of characters to extract Returns the entire string if requested length exceeds string length. Extracts substring from specified position. **Syntax:** `MID(text, start_position, number_of_characters)` **Business Example:** ```javascript theme={null} // Extract middle digits from account number MID(ACCOUNTS."AccountNumber", 5, 4) // Get month from date string (MM/DD/YYYY) MID(RECORDS."DateString", 4, 2) // Extract product category from code MID(PRODUCTS."SKU", 3, 2) ``` **Arguments:** * `text`: String to extract from * `start_position`: Starting position (1-based) * `number_of_characters`: Number of characters to extract Position counting starts at 1, not 0. Returns position of first case-sensitive substring match. **Syntax:** `FIND(search_text, text_to_search, [start_position])` **Business Example:** ```javascript theme={null} // Find @ symbol in email FIND('@', CUSTOMERS."Email") // Find dash in product code FIND('-', PRODUCTS."SKU") // Find space in full name FIND(' ', CUSTOMERS."FullName") ``` **Arguments:** * `search_text`: Text to find * `text_to_search`: Text to search within * `start_position`: \[OPTIONAL] Starting position for search Returns 0 if text not found. Case-sensitive search. Returns position of first case-insensitive substring match. **Syntax:** `SEARCH(search_text, text_to_search, [start_position])` **Business Example:** ```javascript theme={null} // Find 'premium' in product name (any case) SEARCH('premium', PRODUCTS."Name") // Find 'manager' in job title SEARCH('manager', EMPLOYEES."JobTitle") // Find 'urgent' in support ticket SEARCH('urgent', TICKETS."Subject") ``` **Arguments:** * `search_text`: Text to find * `text_to_search`: Text to search within * `start_position`: \[OPTIONAL] Starting position for search Returns 0 if text not found. Case-insensitive search. Replaces text occurrences in a string. **Syntax:** `SUBSTITUTE(text, old_text, new_text)` **Business Example:** ```javascript theme={null} // Replace dashes with spaces in product codes SUBSTITUTE(PRODUCTS."SKU", '-', ' ') // Replace old company name in addresses SUBSTITUTE(CUSTOMERS."Address", 'Old Corp', 'New Corp') // Clean phone number formatting SUBSTITUTE(CUSTOMERS."Phone", '(', '') ``` **Arguments:** * `text`: Original text * `old_text`: Text to replace * `new_text`: Replacement text Replaces ALL occurrences of old\_text with new\_text. Removes whitespace from the beginning and end of a string. **Syntax:** `TRIM(text)` **Business Example:** ```javascript theme={null} // Clean up imported customer names TRIM(IMPORTS."CustomerName") // Normalize email entries before comparison TRIM(LOWER(CUSTOMERS."Email")) // Remove padding from form input TRIM(FORMS."CommentField") ``` **Arguments:** * `text`: Text to trim Useful for cleaning imported data or user input that may contain accidental whitespace. Spaces between words are preserved. Returns the number of characters in a string. **Syntax:** `LEN(text)` **Business Example:** ```javascript theme={null} // Check if password meets minimum length LEN(USERS."Password") >= 8 // Validate phone number length LEN(CUSTOMERS."Phone") = 10 // Check product code format LEN(PRODUCTS."SKU") = 8 // Validate input length LEN(FORMS."Description") <= 500 ``` **Arguments:** * `text`: Text to measure Useful for data validation and formatting checks. Concatenates multiple related strings with a delimiter. **Syntax:** `STRING_AGG(related_field, delimiter)` **Business Example:** ```javascript theme={null} // List all order items STRING_AGG(ORDER_ITEMS."ProductName", ', ') // Create skill list for employee STRING_AGG(EMPLOYEE_SKILLS."SkillName", ', ') // List customer tags STRING_AGG(CUSTOMER_TAGS."TagName", ', ') ``` **Arguments:** * `related_field`: Field from related records to concatenate * `delimiter`: Text to put between each value Builds a single text value from related records, separated by the delimiter you choose. **Accepted input types:** single-value text only, supplied via a related-field aggregation. Passing a `MULTI_PICKLIST` field or an array-shaped value raises `Invalid Type Error`. There is no supported way to aggregate a multi-picklist field directly in a calculation — do the work in [Execute Script](/data/multi-value-fields#aggregating-into-a-comma-separated-string) instead. See also [Calculations troubleshooting](/data/calculations-troubleshooting#aggregating-a-multi-picklist-into-a-delimited-string). Concatenates unique values from a related field. **Syntax:** `STRING_AGG_UNIQUE(related_field, delimiter)` **Business Example:** ```javascript theme={null} // List unique product categories STRING_AGG_UNIQUE(ORDER_ITEMS."Category", ', ') // List unique customer locations STRING_AGG_UNIQUE(CUSTOMERS."City", ', ') // List unique skills STRING_AGG_UNIQUE(EMPLOYEE_SKILLS."SkillName", ', ') ``` **Arguments:** * `related_field`: Field from related records to concatenate * `delimiter`: Text to put between each value Automatically removes duplicates before concatenating. **Accepted input types:** single-value text only, supplied via a related-field aggregation. Passing a `MULTI_PICKLIST` field or an array-shaped value raises `Invalid Type Error`. There is no supported way to aggregate a multi-picklist field directly in a calculation — do the work in [Execute Script](/data/multi-value-fields#aggregating-into-a-comma-separated-string) instead. See also [Calculations troubleshooting](/data/calculations-troubleshooting#aggregating-a-multi-picklist-into-a-delimited-string). Splits a string into an array of substrings using a delimiter. **Syntax:** `SPLIT(text, delimiter)` **Business Example:** ```javascript theme={null} // Split a multi-value tag field // If PRODUCTS."Colors" is 'Red|Green|Blue', returns ['Red', 'Green', 'Blue'] SPLIT(PRODUCTS."Colors", '|') // Parse comma-separated labels SPLIT(CUSTOMERS."Tags", ',') // Break apart a structured order reference SPLIT(ORDERS."Reference", '-') ``` **Arguments:** * `text`: String to split * `delimiter`: Character or string to split on Returns an array of substrings. An empty delimiter (`''`) splits the text into individual characters. Returns blank if the input is blank. `SPLIT` returns an array, but **selecting a single element from the result is not currently supported** in calculations. To extract "the part before the dash" or similar, use `LEFT`/`RIGHT`/`MID` combined with `FIND`/`SEARCH` instead — see [Calculations troubleshooting](/data/calculations-troubleshooting#split-returns-an-array-you-cant-index-into) for patterns. Converts numbers or dates to text format. **Syntax:** `TEXT(value)` **Business Example:** ```javascript theme={null} // Convert order amount to text TEXT(ORDERS."Amount") // Convert date to text TEXT(ORDERS."OrderDate") // Convert ID to text for concatenation TEXT(CUSTOMERS."ID") ``` **Arguments:** * `value`: Number or date to convert Useful when you need to treat numbers as text for concatenation. **`TEXT` does not accept a format string.** It returns the value's default text representation — there is no second argument to control output (no `'YYYY-MM-DD'`, `'MM/DD/YYYY'`, or similar). To produce a specific date or datetime string, extract the parts with `YEAR`, `MONTH`, `DAY`, `HOUR`, `MINUTE`, `SECOND` and assemble them with `CONCAT`: ```javascript theme={null} // 'YYYY-MM-DD' from a date or datetime field CONCAT( TEXT(YEAR(ORDERS."OrderDate")), '-', TEXT(MONTH(ORDERS."OrderDate")), '-', TEXT(DAY(ORDERS."OrderDate")) ) ``` Pad single-digit months and days yourself if you need zero-padding (for example with `IF(MONTH(...) < 10, CONCAT('0', TEXT(MONTH(...))), TEXT(MONTH(...)))`). Converts text to a number. **Syntax:** `VALUE(text)` **Business Example:** ```javascript theme={null} // Convert text amount to number VALUE(IMPORTS."AmountText") // Convert text quantity to number VALUE(FORMS."QuantityInput") // Convert text ID to number VALUE(EXTERNAL."IDString") ``` **Arguments:** * `text`: Text to convert to number Returns blank if text cannot be converted to a number. Repeats a string a specified number of times. **Syntax:** `REPT(text, number_of_times)` **Business Example:** ```javascript theme={null} // Repeat a character to match a rating or count REPT('*', PRODUCTS."Rating") // Create padding REPT(' ', 10) // Create separators REPT('-', 20) ``` **Arguments:** * `text`: String to repeat * `number_of_times`: Number of repetitions Use for padding, separators, or repeating a character a fixed number of times. Extracts text using a regular expression pattern. **Syntax:** `REGEXEXTRACT(text, pattern)` **Escape backslashes in regex patterns.** Calculation strings parse `\` as an escape character, so any regex metacharacter that uses a backslash must be written with a doubled backslash. Use `'\\d'` (not `'\d'`), `'\\s+'`, `'\\.'`, `'\\(\\d{3}\\)'`, etc. A single backslash will be stripped before the regex engine sees the pattern, causing the match to silently fail and return an empty value. For literal characters that don't strictly need escaping in regex (such as a pipe), prefer a character class — `'[|]'` — to sidestep escaping entirely. This applies to `REGEXEXTRACT`, `REGEXMATCH`, and `REGEXREPLACE`. **Business Example:** ```javascript theme={null} // Extract phone area code REGEXEXTRACT(CUSTOMERS."Phone", '\\((\\d{3})\\)') // Extract email domain REGEXEXTRACT(CUSTOMERS."Email", '@(.+)') // Extract order number REGEXEXTRACT(ORDERS."Reference", 'ORD-(\\d+)') ``` **Arguments:** * `text`: Text to extract from * `pattern`: Regular expression pattern Requires knowledge of regular expressions. Use with caution. **Returns the first match only**, not a list of matches. There is no built-in way to extract every match in one call. Patterns follow **Java-style regex syntax**. Most expressions port unchanged from JavaScript, Python, or PCRE, but watch for escape handling and a few advanced constructs. See [Calculations troubleshooting](/data/calculations-troubleshooting#regex-syntax-java-style) for the differences that matter. Tests if text matches a regular expression pattern. **Syntax:** `REGEXMATCH(text, pattern)` **Business Example:** ```javascript theme={null} // Validate email format REGEXMATCH(CUSTOMERS."Email", '^[\\w\\.-]+@[\\w\\.-]+\\.[a-zA-Z]{2,}$') // Check phone format REGEXMATCH(CUSTOMERS."Phone", '^\\(\\d{3}\\) \\d{3}-\\d{4}$') // Validate product code REGEXMATCH(PRODUCTS."SKU", '^[A-Z]{3}-\\d{4}$') ``` **Arguments:** * `text`: Text to test * `pattern`: Regular expression pattern Returns TRUE if pattern matches, FALSE otherwise. **`REGEXMATCH` does not enforce input format.** It only returns a boolean — it does **not** block saving a record, display a validation error to the user, or revert a bad value on its own. To act on a non-match, use the result in an automation (for example, block a stage transition, send a notification, or set a status flag when `REGEXMATCH` returns `FALSE`). To require a format on the form itself, use the **Required** flag and **Helper Text** in the [Form Builder](/workflows/form-builder) — there is no built-in regex mask on text fields. Patterns follow **Java-style regex syntax**. See [Calculations troubleshooting](/data/calculations-troubleshooting#regex-syntax-java-style) for syntax differences if you're porting patterns from another flavor. Replaces text using regular expression patterns. **Syntax:** `REGEXREPLACE(text, pattern, replacement, [case_insensitive])` **Business Example:** ```javascript theme={null} // Format phone numbers REGEXREPLACE(CUSTOMERS."Phone", '(\\d{3})(\\d{3})(\\d{4})', '($1) $2-$3') // Clean product codes REGEXREPLACE(PRODUCTS."SKU", '[^A-Z0-9-]', '') // Standardize names REGEXREPLACE(CUSTOMERS."Name", '\\s+', ' ') ``` **Arguments:** * `text`: Text to modify * `pattern`: Regular expression pattern * `replacement`: Replacement text * `case_insensitive`: \[OPTIONAL] TRUE for case-insensitive matching Advanced feature requiring regex knowledge. Replaces **all** matches of the pattern in the string, not just the first. Patterns follow **Java-style regex syntax**. Backreferences in the replacement string use `$1`, `$2`, etc. See [Calculations troubleshooting](/data/calculations-troubleshooting#regex-syntax-java-style) for syntax differences if you're porting patterns from another flavor. Escapes special characters in a string for use in JSON. **Syntax:** `JSON_ESCAPE(text)` **Business Example:** ```javascript theme={null} // Escape a string with quotes and newlines JSON_ESCAPE('Hello "world" with\nnewlines') // Result: "Hello \\"world\\" with\\\\nnewlines" ``` **Arguments:** * `text`: Text to escape This function is useful for safely embedding text into JSON payloads. Learn how to send JSON data to external systems. Learn how to parse and import data from JSON files. Unescapes special characters in a JSON string. **Syntax:** `JSON_UNESCAPE(text)` **Business Example:** ```javascript theme={null} // Unescape a JSON-escaped string JSON_UNESCAPE('Hello \\"world\\" with\\\\nnewlines') // Result: "Hello \"world\" with\nnewlines" ``` **Arguments:** * `text`: Text to unescape This is the inverse of JSON\_ESCAPE, useful for parsing data from JSON payloads. Learn how to send JSON data to external systems. Learn how to parse and import data from JSON files. ### Mathematical Functions Raises a number to a specified power. **Syntax:** `POWER(base, exponent)` **Business Example:** ```javascript theme={null} // Calculate compound interest POWER(1.05, YEARS."Investment") // Calculate area of square POWER(DIMENSIONS."Side", 2) // Calculate exponential growth POWER(GROWTH."Rate", PERIODS."Number") ``` **Arguments:** * `base`: Base number * `exponent`: Power to raise to Any number raised to the power of 0 equals 1. Calculates the square root of a number. **Syntax:** `SQRT(number)` **Business Example:** ```javascript theme={null} // Calculate standard deviation component SQRT(VARIANCE."Value") // Calculate distance formula component SQRT(COORDINATES."X" * COORDINATES."X" + COORDINATES."Y" * COORDINATES."Y") // Calculate geometric mean component SQRT(METRICS."Value1" * METRICS."Value2") ``` **Arguments:** * `number`: Number to find square root of Returns null if the number is negative. ### Special Functions Returns the Boolean value TRUE. **Syntax:** `TRUE()` **Business Example:** ```javascript theme={null} // Set default active status TRUE() // Use in conditional logic IF(CUSTOMERS."Status" = 'Active', TRUE(), FALSE()) // Initialize flags TRUE() ``` Useful for setting boolean field values and conditional logic. Returns the Boolean value FALSE. **Syntax:** `FALSE()` **Business Example:** ```javascript theme={null} // Set default inactive status FALSE() // Use in conditional logic IF(ORDERS."Amount" > 0, TRUE(), FALSE()) // Initialize flags FALSE() ``` Useful for setting boolean field values and conditional logic. Returns a blank/null value. **Syntax:** `BLANK()` **Business Example:** ```javascript theme={null} // Clear a field conditionally IF(ORDERS."Status" = 'Cancelled', BLANK(), ORDERS."ShipDate") // Set default empty value BLANK() // Use in conditional assignments IF(CUSTOMERS."Type" = 'Guest', BLANK(), CUSTOMERS."LoyaltyPoints") ``` Represents the absence of data, different from empty string. Tests if a value is blank/null. **Syntax:** `ISBLANK(value)` **Business Example:** ```javascript theme={null} // Check if customer has phone number ISBLANK(CUSTOMERS."Phone") // Validate required fields ISBLANK(ORDERS."ShippingAddress") // Check for missing data ISBLANK(PRODUCTS."Description") // Conditional logic based on blank values IF(ISBLANK(CUSTOMERS."Email"), 'No Email', 'Has Email') ``` **Arguments:** * `value`: Value to test for blankness Returns TRUE if the value represents an absence of data — an empty text value (`''`) or a true null both count as blank. Returns FALSE if the value contains any actual data, including a text field whose content is the four-character string `null` (an actual text value that's different from a true absence of value) — see [Calculations troubleshooting](/data/calculations-troubleshooting#detecting-missing-values-including-the-literal-text-null) for the pattern to detect that case. Generates a random UUID (Universally Unique Identifier). **Syntax:** `UUID()` **Business Example:** ```javascript theme={null} // Generate unique transaction ID UUID() // Create unique reference number UUID() // Generate API key UUID() ``` Returns a string in format: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6' ## Troubleshooting **Problem:** Your calculation returns blank instead of expected values. **Causes & Solutions:** * **Blank input data**: Check that referenced fields contain data * **Invalid field references**: Ensure field names are correct and properly quoted * **Type mismatches**: Verify you're using the right function for your data type **Example Fix:** ```javascript theme={null} // Instead of this (might return blank): AVERAGE(ORDERS."Amount") // Try this (handles blanks better): IF(COUNT(ORDERS."Amount") > 0, AVERAGE(ORDERS."Amount"), 0) ``` **Prevention:** * Always test with sample data * Use ISBLANK() to check for missing data * Validate field names match exactly **Problem:** Functions like SUM, COUNT, AVERAGE don't work with fields from the current record. **Solution:** These functions only work with related fields. For current record calculations, use operators: ```javascript theme={null} // Wrong - won't work: SUM(CURRENT."Field1", CURRENT."Field2") // Right - use operators: CURRENT."Field1" + CURRENT."Field2" // Right - for related data: SUM(RELATED_RECORDS."Field") ``` **Key Point:** Aggregate functions (SUM, COUNT, AVERAGE, etc.) are designed for related data, not individual field operations. **Problem:** Date calculations returning unexpected results. **Common Fixes:** * **Text dates**: Use `DATEVALUE()` to convert text to proper dates * **Timezone issues**: Ensure consistent timezone handling * **Format problems**: Check date format consistency **Example Fix:** ```javascript theme={null} // If date is stored as text: DATEDIF(DATEVALUE(CUSTOMERS."SignupDate"), NOW(), 'D') // For consistent date creation: DATE(YEAR(NOW()), MONTH(NOW()), 1) // Handle blank dates: IF(ISBLANK(ORDERS."ShipDate"), 'Not Shipped', DATEDIF(ORDERS."OrderDate", ORDERS."ShipDate", 'D')) ``` **Problem:** FIND vs SEARCH, UPPER vs LOWER, concatenation issues. **Solutions:** * **FIND**: Case-sensitive search * **SEARCH**: Case-insensitive search * **CONCAT**: Joins multiple values * **Always use single quotes** for text literals **Example Fixes:** ```javascript theme={null} // Case-sensitive search: FIND('Manager', EMPLOYEES."Title") // Case-insensitive search: SEARCH('manager', EMPLOYEES."Title") // Proper concatenation: CONCAT(CUSTOMERS."FirstName", ' ', CUSTOMERS."LastName") // Wrong - don't use double quotes: CONCAT(CUSTOMERS."FirstName", " ", CUSTOMERS."LastName") ``` **Problem:** Field references not working, getting 'field not found' errors. **Solutions:** * **Check field names**: Must match exactly (case-sensitive) * **Use proper syntax**: HANDLE."FieldName" format * **Verify relationships**: Ensure fields are properly related **Example Fixes:** ```javascript theme={null} // Correct field reference: CUSTOMERS."FirstName" // Wrong - missing quotes: CUSTOMERS.FirstName // Wrong - incorrect case: CUSTOMERS."firstname" // For related fields: RELATED_CUSTOMERS."FirstName" ``` **Problem:** Calculations running slowly or timing out. **Solutions:** * **Simplify complex calculations**: Break into smaller parts * **Avoid nested functions**: Use intermediate calculations * **Check data volumes**: Large datasets may need optimization **Example Optimization:** ```javascript theme={null} // Instead of nested complexity: IF(AND(CUSTOMERS."Status" = 'Active', DATEDIF(CUSTOMERS."LastPurchase", NOW(), 'D') < 30), 'Recent', 'Old') // Break it down: // Step 1: Days since purchase DATEDIF(CUSTOMERS."LastPurchase", NOW(), 'D') // Step 2: Use result in simpler IF IF(PREVIOUS_CALC < 30, 'Recent', 'Old') ``` ## Best Practices These guidelines help keep calculations reliable and easy to maintain. * Use descriptive field names that clearly indicate purpose * Keep calculations simple and readable * Break complex logic into multiple steps * Document complex calculations with comments * Always check for blank values using ISBLANK() * Validate data types before performing operations * Use IF statements to handle edge cases * Test calculations with various data scenarios * Avoid deeply nested functions * Use intermediate calculations for complex logic * Consider data volume when designing calculations * Test performance with realistic data sets * Use proper field reference syntax: HANDLE."FieldName" * Always use single quotes for text literals, never double quotes * Verify field relationships before using aggregate functions * Test calculations thoroughly before deployment ## Related documentation * **[Core concepts](/getting-started/fundamentals/core-concepts)** — Apps, Elements, fields, and how records connect * **[Tables](/data/tables)** — Calculated columns and spreadsheet-style views of your data * **[Showing relationships](/data/showing-relationships)** — Related records and how aggregates apply to related fields * **[Data best practices](/data/data-best-practices)** — Structuring data so formulas and reports stay maintainable * **[Automation system](/workflows/automation-system)** — Triggers and actions where calculations often appear ## Need More Help? Support options, self-help topics, and how to reach the team Get direct help from our support team Learn advanced calculation techniques Watch step-by-step calculation examples # Calculations troubleshooting Source: https://docs.elementum.io/data/calculations-troubleshooting Common calculation gotchas—multi-value fields, array shapes, regex syntax, date parsing—with the recommended pattern for each. Calculations work well for single-value math, text, dates, and conditional logic against a single record or a related set of records. A handful of shapes and operations behave differently than people expect — especially folks coming from spreadsheets or SQL. This page collects the most common gotchas, the errors you're likely to see, and the recommended path forward for each. If you're here because of a specific error, jump to the [Error reference](#error-reference). This page reflects current behavior. Where a section notes that something isn't supported, it may change in a future release — the section will say so when that's the case. ## Multi-value and array-shaped values The most common source of confusion. Two related shapes: * **Multi-picklist fields** — fields whose type is `MULTI_PICKLIST`. A single cell holds several selected options. * **Multi-value text columns surfaced through Data Mine** — when a [Data Mine](/data/data-mining) trigger fires, multi-value text columns in the payload serialize as a JSON array of objects, not as plain text. The shape looks like this: ```json theme={null} [ { "value": "WD", "type": "TEXT" }, { "value": "ZIP", "type": "TEXT" } ] ``` Both shapes are *lists* of values, and almost every calculation function expects a *single* value at a time. The two limitations below cover what that means in practice. If you're working with a multi-picklist field and want the working patterns for iteration, aggregation, and passing selections into an API body, see [Multi-value fields](/data/multi-value-fields). This section covers what specifically breaks inside a calculation. ### Aggregating a multi-picklist into a delimited string **Not currently supported.** Aggregations over list-typed fields aren't supported in calculations. **What people try:** ```javascript theme={null} STRING_AGG_UNIQUE(CLAI."Claim Edit(s)", ',') ``` **What they get:** ``` Invalid Type Error at line 1, position 18: MULTI_PICKLIST ``` `STRING_AGG` and `STRING_AGG_UNIQUE` only accept single-value text supplied via a related-field aggregation — they cannot operate on a `MULTI_PICKLIST` field directly. There is no calculation function that aggregates the selections of a multi-picklist into a delimited string. **What works instead.** Do the aggregation in an [Execute Script](/workflows/automation-actions-reference#execute-script) action and, if the result needs to live on a record, write it back with **Update Record Fields**. The full pattern (input mapping, iteration, aggregation, and passing the result into a Send API Request body) is on [Multi-value fields](/data/multi-value-fields). ### Flattening a Data Mine array payload into plain text **Not currently supported.** Calculations cannot convert structures — the `[{"value":..., "type":...}, ...]` shape that Data Mine produces for multi-value text columns cannot be flattened into plain delimited text inside a calculated column or the field mapping on a Create Record action. **What happens if you try:** the destination text field stores the literal JSON, for example: ``` [{"value":"WD","type":"TEXT"},{"value":"ZIP","type":"TEXT"}] ``` …rather than the friendly `WD, ZIP` users expect. ## SPLIT returns an array you can't index into `SPLIT(text, delimiter)` returns an array of substrings. That's expected — but **selecting a single element from that array isn't supported in calculations.** There's no array indexing syntax (`[0]`, `[1]`, etc.) and no `INDEX`/`NTH` function to pick a piece. **Example of the trap:** ```javascript theme={null} // Returns the array ['TPFN', '123'] — but you can't extract 'TPFN' from it. SPLIT('TPFN-123', '-') ``` **Recommended patterns:** * If the position is **genuinely fixed** (for example, every ID is always exactly 4 characters), use `LEFT`, `RIGHT`, or `MID`. These return text you can use directly. * If the split point is variable (for example, "everything before the dash"), combine `FIND` or `SEARCH` to locate the delimiter with `LEFT`/`MID` to extract the piece you want: ```javascript theme={null} // 'Everything before the first dash' in CONTRACTS."Reference" LEFT(CONTRACTS."Reference", FIND('-', CONTRACTS."Reference") - 1) ``` The `LEFT`/`RIGHT`/`MID` pattern only stays correct while the position is truly fixed. If the value's length can change — for example, IDs growing from `99` to `100` add a character — the calculation will silently start returning the wrong substring without raising an error. For anything length-variable, use the `FIND`/`SEARCH` + `LEFT`/`MID` pattern instead. ## DATEVALUE only accepts year-month-day input `DATEVALUE(text_date)` doesn't auto-detect or parse arbitrary date formats. The input must be in `YYYY-MM-DD` form — **date only, no time component.** Other formats won't parse and the function returns blank, including: * US-style `MM/DD/YYYY` or European `DD/MM/YYYY` * Written-out months like `Jun 1, 2026` * ISO 8601 strings with a time component like `2026-06-01 12:34:56` or `2026-06-01T12:34:56Z` **Recommended patterns:** * Normalize date text to `YYYY-MM-DD` in the source system or an ingest step before it reaches the calculation. * If the components are available as separate values, skip `DATEVALUE` entirely and build the date with [`DATE(year, month, day)`](/data/calculations#date-and-time-functions). * For text dates with predictable structure, use `LEFT`/`MID`/`RIGHT` to rearrange the pieces into year-month-day before passing to `DATEVALUE`. ## Regex syntax: Java-style `REGEXEXTRACT`, `REGEXMATCH`, and `REGEXREPLACE` are fully supported. Standard regex operations — character classes, quantifiers, groups, anchors, alternation, backreferences — work as expected. **`REGEXEXTRACT` returns the first match only** — not a list of matches. There is no built-in way to extract every match in one call. **`REGEXREPLACE` replaces all matches** of the pattern in the string, not just the first. Patterns follow **Java-style regex syntax** because of the backend implementation. If you're porting patterns from JavaScript, Python, or PCRE-flavored tools, most expressions work unchanged, but watch for the differences that bite: * **Escaping inside string literals** — calculation text is enclosed in single quotes, so backslashes in patterns need to be escaped: write `'\\d+'` (not `'\d+'`) to match one or more digits. * **A few advanced constructs** — possessive quantifiers (`*+`, `++`) and certain Unicode property classes behave per the Java spec, not PCRE. The [Java `Pattern` javadoc](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html) is the authoritative syntax reference. When in doubt, test the pattern with a small string against `REGEXMATCH` before building a larger calculation around it. ## Adding or subtracting days from a date Use [`DATEADD(unit, value, date)`](/data/calculations#dateadd---add-or-subtract-time-from-a-date). Unit tokens are unquoted, and a negative value subtracts: ```javascript theme={null} // Today + 14 days DATEADD(DAY, 14, NOW()) // A due date minus 3 days DATEADD(DAY, -3, TASKS."DueDate") // One month before a due date DATEADD(MONTH, -1, TASKS."DueDate") ``` For "is this date yesterday/today/tomorrow" comparisons, use [`DATEDIF`](/data/calculations#date-and-time-functions) against `NOW()` with the `'D'` unit: ```javascript theme={null} // TRUE when the field's date is exactly yesterday (FALSE for today) DATEDIF(YOUR_ELEMENT."DateField", NOW(), 'D') = 1 ``` ## IF branches must return the same type Both branches of `IF(condition, value_if_true, value_if_false)` must return the same data type. Mixing types raises a validation error and the calculation won't save. A common trip-up is using `''` (empty string) as a placeholder in the false branch of an otherwise date-typed expression: ```javascript theme={null} // Incorrect — the true branch returns a date, the false branch returns text IF(ISBLANK(ACQ."Close Date"), '', ACQ."Close Date" + 30) ``` Use [`BLANK()`](/data/calculations#blank---return-blank-value) instead. It represents the absence of a value without changing the branch's type, so both sides stay date-typed: ```javascript theme={null} // Correct — both branches are date-typed IF(ISBLANK(ACQ."Close Date"), BLANK(), ACQ."Close Date" + 30) ``` The same rule applies for numeric and text branches — use `BLANK()` (not `0` or `''`) when one branch has no meaningful value. ## Detecting missing values, including the literal text 'null' `ISBLANK(field)` detects when a field has no value at all. Elementum normalizes empty text and true nulls the same way at the field level — `ISBLANK` returns TRUE for both. In practice you don't need a separate check for "null vs. blank" on a field. What `ISBLANK` does **not** catch is a text field whose *content* is the four characters `n`, `u`, `l`, `l`. This shows up when the field was populated by an upstream system that writes the string `null` as a marker for missing data — API responses, webhook payloads, and some CSV exports do this. From the calculation's perspective the field holds a non-empty text value, so `ISBLANK` returns FALSE. To detect that literal string, compare against the quoted text: ```javascript theme={null} // TRUE when the field's text content is the four characters n-u-l-l SOURCE."StatusAsOfDate" = 'null' ``` To cover both shapes in one condition, combine the checks with `OR`: ```javascript theme={null} // TRUE when the field is empty OR contains the text 'null' OR(ISBLANK(SOURCE."StatusAsOfDate"), SOURCE."StatusAsOfDate" = 'null') ``` `null` is not a keyword in the calculation language. Writing `null` bare (unquoted) raises a syntax error like `Invalid Syntax Error at line 1, position N: missing ')' at ','`. Use [`BLANK()`](/data/calculations#blank---return-blank-value) to *return* an empty value from a branch of an `IF`, and `'null'` (quoted) to compare against the literal text. ### Worked example: text-to-date, empty when the source is 'null' Convert a text field to a date, and return blank — not today's date — when the source is empty or contains the string `null`: ```javascript theme={null} IF( OR(ISBLANK(SOURCE."StatusAsOfDate"), SOURCE."StatusAsOfDate" = 'null'), BLANK(), DATEVALUE(SOURCE."StatusAsOfDate") ) ``` A few details worth calling out: * **Both branches must be date-typed.** `BLANK()` on the true branch takes the surrounding branch's type — `''` (empty string) is text-typed and would raise a validation error. See [IF branches must return the same type](#if-branches-must-return-the-same-type). * **`DATEVALUE` only parses `YYYY-MM-DD`.** If the source date is in another format, `DATEVALUE` returns blank silently rather than the value you expect — see [DATEVALUE only accepts year-month-day input](#datevalue-only-accepts-year-month-day-input). * **`IF` takes exactly three arguments** — condition, value if true, value if false. Nested checks belong inside the condition (as with `OR` above), not as extra positional arguments in the outer `IF(...)`. ## Inserting text into the middle of a string There is no dedicated "insert" function. Split the string at the target position with `LEFT` and `RIGHT`, then reassemble it with [`CONCAT`](/data/calculations#concat---join-text-together): ```javascript theme={null} // Insert " Sorry" after the first 11 characters of "Hello world this is ME" CONCAT( LEFT(SOURCE."Text", 11), ' Sorry', RIGHT(SOURCE."Text", LEN(SOURCE."Text") - 11) ) // Result: "Hello world Sorry this is ME" ``` When the insertion point isn't at a fixed offset, use [`FIND`](/data/calculations#find---find-text-position-case-sensitive) to locate the anchor dynamically: ```javascript theme={null} // Insert " Sorry" immediately after the word "world" CONCAT( LEFT(SOURCE."Text", FIND('world', SOURCE."Text") + 4), ' Sorry', RIGHT(SOURCE."Text", LEN(SOURCE."Text") - (FIND('world', SOURCE."Text") + 4)) ) ``` `SUBSTITUTE(text, old_text, new_text)` is a different tool — it *replaces* every match of `old_text`. It only produces an "insert" when you replace an anchor with itself plus the new text (for example, `SUBSTITUTE(text, 'world', 'world Sorry')`), which requires a unique anchor and rewrites every occurrence. `FIND` is case-sensitive and returns the position of the first match. If the anchor could appear more than once in the source text, this pattern inserts before the first occurrence only. ### Worked example: building an HTML email body from records A common driver for this pattern is assembling an HTML email body from a list of records — the outer template is fixed, and you need to drop `
    ` rows into the `` before sending. The template looks like this: ```html theme={null}
    ...
    ``` Given a `template` value holding that markup and a `new_rows` value holding the row markup to insert — for example: ```html theme={null} Jane DoePaid ``` split the template around `` and stitch the rows in front of it: ```javascript theme={null} CONCAT( LEFT(template, FIND('', template) - 1), new_rows, RIGHT(template, LEN(template) - FIND('', template) + 1) ) ``` What each piece does: * `FIND('', template)` locates the character position where the closing tag starts. * `LEFT(template, FIND(...) - 1)` returns everything in the template *before* the closing tag. * `RIGHT(template, LEN(template) - FIND(...) + 1)` returns the closing tag and everything after it, so the tag itself is preserved. * `CONCAT(...)` glues the three pieces back together in order — before, rows, after. **Build multi-row markup as its own calculation first.** When rows come from several related records (one row per line item, for example), aggregate the row markup in its own calculation and pass the result into the insert formula as `new_rows`. Nesting the aggregation and the insertion in a single expression is hard to read and hard to debug. ### The same pattern in an Execute Script action If your automation already uses an [Execute Script](/workflows/automation-actions-reference#data-actions) action for other logic, JavaScript's `String.prototype.replace` is shorter and avoids off-by-one arithmetic with character positions. Replace the marker with the new content followed by the marker itself: ```javascript theme={null} const { template, newRows } = input.parameters; const result = template.replace('', `${newRows}`); return { emailBody: result }; ``` When rows come from a list of records, build the row markup with `.map(...).join('')` and insert once: ```javascript theme={null} const { template, records } = input.parameters; const rowsHtml = records .map(r => `${r.name}${r.status}`) .join(''); const result = template.replace('', `${rowsHtml}`); return { emailBody: result }; ``` Two failure modes worth checking if the script raises `Cannot read property 'replace' of undefined`: * `records` must be the array of record data, not a single record or an unresolved reference. Access it via `input.parameters` — parameter names are not injected as standalone variables in the script scope (see [Execute Script](/workflows/automation-actions-reference#data-actions)). * `template` must be a string at the point you call `.replace()` on it. A field reference that hasn't loaded yet resolves to `undefined`. For more than one insertion point in the same template (for example, rows inside `` **and** a summary line before ``), chain `.replace()` calls — one per marker. Pick one tool per insertion and stay there. If the rest of your workflow already lives in calculations, use the `LEFT`/`FIND`/`CONCAT`/`RIGHT` pattern. If it already lives in an Execute Script action, use `.replace()`. Bouncing between a calculation, a Run Calculation action, and an Execute Script for the same string-assembly job adds surface area for bugs. ## Concatenating strings `CONCAT(a, b, c, ...)` is the function to join text values. **The `+` operator is for numeric addition only** — applying it to text fields does not concatenate them. This is a common surprise for people coming from JavaScript, PHP, or some spreadsheet languages where `+` doubles as a string-concatenation operator. ```javascript theme={null} // Correct — produces 'Jane Doe' CONCAT(CUSTOMERS."FirstName", ' ', CUSTOMERS."LastName") // Incorrect — '+' is numeric addition only; this does not concatenate text CUSTOMERS."FirstName" + ' ' + CUSTOMERS."LastName" ``` `CONCAT` accepts any number of arguments and converts non-text values (numbers, dates) to text automatically before joining. ### Adding a newline between concatenated values Calculations do not expose a `CHAR`, `CHR`, or newline function, and escape sequences like `'\n'` inside a string literal are treated as the two characters `\` and `n`, not as a line break. There is no supported way to insert a raw newline character inside a `CONCAT` expression. If you need multi-line output — for example, an address block or a message body where each value sits on its own line — use an [Execute Script](/workflows/automation-actions-reference#data-actions) action instead. JavaScript's `\n` escape does produce a newline: ```javascript theme={null} const { line1, line2, line3 } = input.parameters; return { result: `${line1}\n${line2}\n${line3}`, }; ``` Pass the values as inputs to the action, then reference the `result` output in downstream steps (for example, an Update Record action writing to a multi-line text field, or a Send Email action). Whether the newline is preserved when the value is displayed depends on the destination. Multi-line text fields, email bodies, and most external systems render `\n` as a line break. Single-line text fields and some UI surfaces collapse whitespace. ## Referencing a dynamic dropdown field A [dynamic dropdown](/workflows/api-powered-dropdowns) — a dropdown whose options come from an API Element rather than a static picklist — is referenced the same way as any other field: `HANDLE."FieldName"`. The value the calculation sees is the option the user selected, as a single text value. ```javascript theme={null} // Single-select dynamic dropdown — the selected option, as text CONCAT('Selected: ', VENDORS."Region") // Use it in a conditional IF(ORDERS."Category" = 'Hardware', 'Route A', 'Route B') ``` Replace `VENDORS` / `ORDERS` with your Element's handle and the field name with the exact, case-sensitive name of the dynamic dropdown field (in double quotes). **Multi-select dynamic dropdowns behave like other list-valued fields.** Calculations cannot aggregate a multi-select dropdown's selections into a delimited string — the same limitation described in [Aggregating a multi-picklist into a delimited string](#aggregating-a-multi-picklist-into-a-delimited-string) applies. Do that work in an [Execute Script](/workflows/automation-actions-reference#execute-script) action instead. ## Changing a column's field type **Not supported.** A column's field type cannot be changed in place after the column is created. This applies to all type conversions — single-value text ↔ multi-value text, text ↔ multi-picklist, and so on. **Recommended pattern** — create a new column of the desired type, then delete the old one. If the old column has data you need to preserve, backfill the new column via an automation or import before deleting the old, and update any dependencies (calculations, automations, filters, layouts) to point at the new column. ## Error reference | Error you see | What it means | Where to go | | -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `Invalid Type Error at line N, position M: MULTI_PICKLIST` | A calculation function received a `MULTI_PICKLIST` field where it expected a single value. | [Aggregating a multi-picklist into a delimited string](#aggregating-a-multi-picklist-into-a-delimited-string) | | Destination field stores literal JSON like `[{"value":"...","type":"TEXT"}, ...]` | A Data Mine multi-value text payload was passed to a plain-text destination without being flattened. | [Flattening a Data Mine array payload into plain text](#flattening-a-data-mine-array-payload-into-plain-text) | | `DATEVALUE` returns blank for a date that "looks valid" | The input isn't in year-month-day form. | [DATEVALUE only accepts year-month-day input](#datevalue-only-accepts-year-month-day-input) | | Expected to pull "the first piece" out of a `SPLIT` result and got nothing usable | `SPLIT` returns an array, but array indexing isn't supported. | [SPLIT returns an array you can't index into](#split-returns-an-array-you-cant-index-into) | | Validation error on an `IF` where one branch is `''` and the other is a date or number | Both branches of `IF` must return the same type; `''` is a text literal and won't type-match a date or numeric branch. | [IF branches must return the same type](#if-branches-must-return-the-same-type) | | `Invalid Syntax Error at line N, position M: missing ')' at ','` on an `IF` that references `null` | `null` isn't a keyword in the calculation language. Use `BLANK()` to return an empty value, or `'null'` (quoted) to compare against the literal text. | [Detecting missing values, including the literal text 'null'](#detecting-missing-values-including-the-literal-text-null) | | `ISBLANK(field)` returns FALSE for a field that looks empty | The field contains the four-character text `null` (typically from an upstream system that writes `null` as a marker), not a true empty value. | [Detecting missing values, including the literal text 'null'](#detecting-missing-values-including-the-literal-text-null) | ## Related documentation * **[Calculations](/data/calculations)** — Full function reference * **[Tables](/data/tables)** — Calculated columns on tables * **[Data mining](/data/data-mining)** — Triggers and payload shapes # Data Management Source: https://docs.elementum.io/data/data-best-practices Guidelines for organizing, sharing, and managing data in Elementum Maximize your data's value with proven strategies for organization, sharing, and management. These guidelines cover table and view choices, identifiers, integrity, change monitoring, and loading patterns. For related options by use case, see [Data structure options](#data-structure-options). **New to data integration?** Start with the [CloudLink setup guide](/administration/connect-snowflake-to-elementum) to establish your data connection first. ## Data Sharing Fundamentals ### Tables vs Views: The Foundation Decision Choose between tables and views based on whether you need writes, how you filter columns, and performance. For a concise matrix of structure types by scenario, see [Data structure options](#data-structure-options) below. #### Write Operations Required Use a table when data is updated through automations or user input: * User form submissions * Automation-driven status updates * Real-time data modifications * Transactional processing #### Performance is Critical Use a table when queries run often and latency matters: * Dashboard data sources * Real-time reporting * Frequently accessed reference data * Performance-sensitive workflows #### Data Subset Needed Use a view when you need to share only certain columns or filtered rows: * Security-sensitive data with column restrictions * Department-specific data views * Filtered datasets based on business rules * Simplified data presentations #### Read-Only Access Sufficient Use a view when no writes are required: * Reporting and analytics * Reference data lookups * Audit and compliance views * Data exploration and discovery #### Data exchange tables When you need both read and write behavior and the presentation benefits of a view, use a view for display and a separate exchange table for updates. **Example:** A customer view for display plus a `customer_updates` table for changes. To create automations based on record changes (updates, new records, etc.) or track business entities, create an [Element](/getting-started/fundamentals/core-concepts#data--elements) with your data instead. ## Unique Identifiers Each row in your data must have a unique identifier. If one does not exist, create it using: * UUID functions * Concatenated fields * Incremental number assignment Always verify uniqueness by running a validation query before linking. ## Table Integrity Guidelines These changes cause "No Rows" errors: * Renaming tables * Renaming shared columns Consult with Elementum before: * Deleting columns * Repurposing columns * Using Create/Replace table commands * Adding new columns (requires Elementum admin to update layouts) ## Data Structure Options | Use Case | Recommended Option | Example | | -------------------- | ------------------------------ | ----------------------------- | | Read-only access | Regular table/view | Data Mining | | Write access needed | Hybrid table | Reclaim License Data Exchange | | Performance critical | Materialized view/hybrid table | - | | Multi-table queries | Dynamic table | - | For conceptual guidance on tables versus views, see [Tables vs Views](#tables-vs-views-the-foundation-decision) above. ## Change Monitoring Choose your monitoring approach based on frequency: * Use data mining for hourly, daily, weekly, or monthly updates * Row limits per data mine apply; see [Field updates](#field-updates) * Use record created/updated triggers * Enable `CHANGE_TRACKING` for automated updates (configuration details in [Change tracking configuration](#change-tracking-configuration)) * Use time-based triggers for known update schedules * Elementum detects changes based on resource scheduler or data mine schedule ## Field Updates ### Automation Options * Use create triggers for non-null initial values * Use data mines for batch updates (**100,000 row limit** per data mine) * Enable change tracking for real-time element updates (see [Change tracking configuration](#change-tracking-configuration)) ### Calculated Fields Use for related item data: ```sql theme={null} STRING_AGG_UNIQUE(HANDLE."Field", ', ') -- For text MAX(HANDLE."Field") -- For numbers ``` ## Change Tracking Configuration ### Capabilities * Tables: Select, Update, Insert, Delete (with permissions) * Views: Select only ### Implementation Notes * Enables automation triggers from tables and Elements * Supports table modifications for joins and data mines * Works best when update frequency is known so scheduling stays efficient ## Data Loading Strategies ### Incremental Loading * Works directly with `CHANGE_TRACKING` * Efficient for regular updates ### Flush and Fill * Requires duplicate checking * Use search actions before create/update operations ## Update Behavior Matrix (Snowflake) The following describes trigger behavior when using Snowflake with change tracking: | CHANGE\_TRACKING | Elementum Triggers | Snowflake Triggers | | --------------------- | ------------------ | ------------------ | | Enabled before config | Immediate | Based on scheduler | | Enabled after config | Immediate | Won't fire | | Disabled | Immediate | Won't fire | ## Next Steps Use these guides to connect your warehouse, align table design with how Elementum uses data, and operationalize monitoring and loads. Run the setup script and connect your Snowflake account to Elementum Schedule batch pulls, respect row limits, and align mines with your change strategy Concepts, authentication, platform schema rules, and the security model Work with table objects, layouts, and how data surfaces in the workspace Choose Standard vs Hybrid tables that match your read, write, and performance needs Size and configure your Snowflake warehouse for Elementum workloads # Data Mining Source: https://docs.elementum.io/data/data-mining Monitor CloudLink-backed table data on a schedule, track per-record match state, and start automations when conditions are met or cleared. ## What is a Data Mine? **Data Mining** is a way to start [automations](/workflows/automation-system) from data that lives in your data warehouse and is exposed in Elementum through [CloudLinks](/administration/setup-cloudlink). You define a **Data Mine** on a [Table](/data/tables) that reads that data: Elementum runs your criteria on a schedule, tracks whether each row **matches** or **does not match**, and fires automations when a row **transitions** between those states (for example, from unmatched to matched, or the reverse). A Data Mine does not run arbitrary one-off queries for reporting—it **watches** the same logical rows over time and pairs that behavior with **state management** so you are not notified on every scan when nothing has changed for a given row. When your criteria match a row, that row is **ON** (matched); when they do not, it is **OFF** (unmatched). [Automations](/workflows/automation-system) run on **transitions** between those states, not on every evaluation where the state is unchanged. **Key components:** * **Data source** — Rows from a Table backed by a [CloudLink](/administration/setup-cloudlink) to your data warehouse (for example Snowflake or BigQuery, depending on your connection). * **Matching criteria** — Filters that define which rows count as matched. * **State management** — Per-row tracking of matched vs. unmatched across runs. * **Automations** — Workflows you attach via the **Data Mine** trigger. **Important:** A Data Mine alone does not complete work in your process. Connect it to automations that take the next steps (notifications, updates, handoff to an agent, and so on). Decide those steps before you finalize the Data Mine. ## When to Implement Data Mines Use Data Mining when you need **scheduled, condition-based** reactions to warehouse data: thresholds, SLAs, inventory levels, open claims, and similar rules. It fits **batch-style** monitoring (for example hourly or daily), which is also how many CloudLink-backed tables are refreshed. For very fast reactions when a record changes inside an Elementum app, [record triggers and other automation triggers](/workflows/automation-triggers-reference) may be a better fit—see [Automations](/getting-started/fundamentals/core-concepts#automations) and [Change monitoring](/data/data-best-practices#change-monitoring). **Outcomes you can expect:** * Automations start when a condition becomes true (or false) for a row, not on every run. * Teams spend less time scanning reports to find exceptions. * You can chain work: notify, assign, update records, or call [Agents](/ai-agents/ai-overview) when your automation design includes them. Data Mining connects warehouse-backed table data to automations. CloudLinks provide access to that data; Data Mines define **what** to watch and **when** to run; [automations](/workflows/automation-system) define **what** happens next. ## How Data Mines Operate 1. **Table** — Use a Table whose source is CloudLink data you want to monitor (see [Tables](/data/tables)). 2. **Data Mine** — In that Table, create a Data Mine (see [Create a Data Mine](#create-a-data-mine-in-the-ui)), set identifying columns, matching criteria, and a schedule. 3. **Automation** — Create an automation with a **Data Mine** trigger and choose whether it runs when data **meets** or **no longer meets** your criteria (see [Data Mine trigger](/workflows/automation-triggers-reference#data-mine)). ## Understand state management: ON and OFF Instead of firing an automation on every scheduled run for every matching row, Elementum tracks state for each row (using your **identifying columns**). Automations tied to the Data Mine run when **state changes** in a way you configured. **How state transitions map to events:** ``` Record state: OFF → ON = Automation can run for "Data Mine Triggered" (condition newly met) Record state: ON → ON = No transition; no new trigger for that row Record state: ON → OFF = Automation can run for "Data Mine Cleared" (condition no longer met) Record state: OFF → OFF = No transition; no new trigger for that row ``` This supports workflows such as: alert when a case first crosses a threshold, stay quiet while it stays above the threshold, then run a different path when it drops back below. **Scenario:** Claims over \$10,000 while status is open need immediate attention. **Data Mine setup:** * **Source:** Claims table (CloudLink) * **Criteria:** `claim_amount > 10000 AND status = 'open'` * **Schedule:** Every 15 minutes **State behavior:** 1. **New high-value open claim (OFF → ON):** Automation runs (for example assign adjuster, notify a queue). 2. **Claim still matches (ON → ON):** No additional automation from this transition. 3. **Claim closed or amount no longer in range (ON → OFF):** Automation runs for clearance steps (for example update a dashboard record, notify that the exception cleared). **Scenario:** Reorder when stock falls below a threshold for active SKUs. **Data Mine setup:** * **Source:** Inventory table (CloudLink) * **Criteria:** `stock_level < reorder_threshold AND status = 'active'` * **Schedule:** Hourly **State behavior:** 1. **OFF → ON:** Start reorder or approval automation. 2. **ON → ON:** No duplicate reorder signal for the same row until state changes. 3. **ON → OFF:** Run follow-up when stock is back above the threshold (for example notify sales). **Scenario:** Tickets open past the response window without a first response. **Data Mine setup:** * **Source:** Support tickets table (CloudLink) * **Criteria:** Example pattern: open tickets where the clock has passed your SLA and `first_response_date` is still null—adjust fields to match your schema. * **Schedule:** Every 30 minutes **State behavior:** 1. **OFF → ON:** Escalation or reassignment automation. 2. **ON → ON:** No repeated escalation for the same breach state. 3. **ON → OFF:** Automation when the ticket is responded to or no longer breaches. ## Working with Agents Data Mine triggers can start automations whose actions include [Agents](/ai-agents/ai-overview): for example summarizing the matched row, classifying it, or drafting a reply. Agent behavior depends on how you configure prompts, tools, and steps in that automation—not on automatic “learning” stored inside the Data Mine itself. For details, see [Agent tools, deployment, and integrations](/ai-agents/agents-tools-and-deployment) and the [AI overview](/ai-agents/ai-overview). ## Types of Data Mining When you create a Data Mine, you choose a **type** that matches how you want to detect rows of interest. The product may show one or more of the following. **Best for:** Clear business rules and known patterns. **Example:** Alert when any order exceeds \$5,000. ``` Criteria: order_total > 5000 Actions: Route to approval workflow, notify finance team ``` You define explicit filters (comparisons, ranges, null checks, time windows) that rows must satisfy. Most guided documentation (including the UI steps below) uses this type. **Best for:** Discovering unexpected patterns or behaviors. **Example:** Detect unusual spending patterns in expense reports. ``` AI Model: Learns normal spending patterns Detection: Flags expenses that deviate significantly from learned norms Actions: Flag for review, request additional documentation ``` **Best for:** Finding numerical outliers using statistical methods. **Example:** Identify processing times that are unusually long. ``` Statistical Method: Z-score analysis Threshold: 2 standard deviations above mean Actions: Alert operations team, investigate bottlenecks ``` Available Data Mine types depend on your workspace and product configuration. If an option is not shown in the UI, use the types your environment supports and follow the on-screen steps for that type. ## Create a Data Mine in the UI These steps align with guided flows elsewhere in the docs (for example file and document monitoring). Exact labels may vary slightly by workspace. 1. Open the **[Table](/data/tables)** that uses your CloudLink data. 2. Go to **Data Mining** → **Create Data Mine** → **Logic-Based Rules Mining**. 3. **Identifying columns** — Choose stable columns so the same business row is recognized across runs (IDs, composite keys). See [Define identifying columns](#define-identifying-columns). 4. **Matching criteria** — Set filters for rows that should count as matched. See [Build matching criteria](#build-matching-criteria). 5. **Name and schedule** — Name the Data Mine and set how often it runs. Then build an automation: 1. Go to **Automations** → **Create Automation**. 2. Add a **Data Mine** trigger and select this Data Mine. 3. Set the trigger to **Trigger when data meets requirement** and/or **Trigger when data no longer meets requirement**, depending on whether you need ON or OFF transition handling. Details and option names are in [Automation triggers reference — Data Mine](/workflows/automation-triggers-reference). ## Best Practices for Data Mine Creation Before creating a Data Mine, decide: * What should happen the first time a row **matches** (OFF → ON)? * What should happen when it **stops** matching (ON → OFF), if anything? * Who or what receives the work (users, records, [Agents](/ai-agents/ai-overview))? * Which fields from the row the automation needs? Choose a CloudLink-backed Table where: * Data is sufficiently current for your process. * You have permission to read the objects you reference. * Refresh timing matches how often you need to evaluate conditions (see [Change monitoring](/data/data-best-practices#change-monitoring)). **Purpose:** Identifying columns let the system recognize the **same** logical row across Data Mine runs so state (OFF/ON) is stable. **Practices:** * Prefer stable unique identifiers (IDs, UUIDs). * Add business keys when they help disambiguate (order number, case ID). * Avoid using columns that change every run unless they are part of your identity rule. **Example (support tickets):** ``` Identifying columns: - ticket_id (primary identifier) - customer_id (context) - created_date (if required for your keying strategy) ``` **Simple conditions:** ``` WHERE priority = 'High' WHERE amount > 1000 WHERE status IN ('pending', 'review') ``` **Grouped logic:** ``` WHERE ( (priority = 'High' AND amount > 500) OR (priority = 'Critical' AND amount > 100) ) AND status = 'active' ``` **Time-based conditions (adjust functions to your warehouse SQL dialect):** ``` WHERE created_date > NOW() - INTERVAL '7 days' WHERE last_updated < NOW() - INTERVAL '24 hours' ``` **Scheduling:** Match frequency to the process—tighter schedules (for example 15–30 minutes) when latency matters; hourly or daily when batch refresh and cost matter more. **Volume:** Each Data Mine can process up to **100,000 rows** per run (see [Field updates](/data/data-best-practices#field-updates)). For performance and predictable run times, keep the **matching** set as small as practical with selective criteria; very large match sets may need longer runs or a different split of rules. * Start with one clear business rule per Data Mine when possible. * Name Data Mines and automations so owners know what is monitored. * Document assumptions (SLA definition, thresholds, timezone). * Revisit criteria when business rules change; archive Data Mines you no longer use. 1. Use **VIEW MATCHING DATA** (or the equivalent in your Table) to confirm which rows match. 2. Start with a narrow criterion or time window if possible. 3. Confirm automations fire on **OFF → ON** and **ON → OFF** as intended. 4. If the automation uses an Agent, run end-to-end tests with realistic rows. ## Schedule an automation with a Data Mine A Data Mine evaluates its Table on a schedule, so it can also be used purely as a way to run an automation on a recurring cadence — every 15 minutes, hourly, daily at 8:00 UTC, and so on. This is the only way to schedule an automation in Elementum; the [Time-Based trigger](/workflows/automation-triggers-reference#time-based) fires relative to a date field on a specific record and is not a recurring scheduler. This is a sidecar use of Data Mining — the primary purpose is monitoring warehouse data for state transitions. Reach for this pattern only when you genuinely need a scheduled automation; otherwise prefer event-based [automation triggers](/workflows/automation-triggers-reference). To schedule with a Data Mine, use the **trigger record pattern**: 1. **Create a small dedicated Table** for scheduled jobs and add a single record per job, named clearly (for example `Next Run` or `Daily 8:00 Job`). 2. **Define a Data Mine on that Table** with the cadence you want as the schedule, and matching criteria that the trigger record satisfies. 3. **Include a column whose value changes each run** (for example `Updated On`) in the Data Mine's identifying columns alongside the record's stable ID. Each scheduled run then treats the row as a new logical row and re-evaluates its state from OFF. 4. **Update the trigger record from the automation** — typically the field captured by the volatile identifying column. This guarantees the next scheduled run produces an OFF → ON transition and fires the automation again. Each scheduled run still consumes a Data Mine evaluation and the automation runs once per transition, so pick the longest cadence that meets the requirement and design the automation to be idempotent in case a run overlaps a previous one or is retried. ## Advanced patterns **Cascade:** One automation updates data that a second Data Mine or process depends on—design order and idempotency carefully. **Threshold ladders:** Separate Data Mines or criteria bands for different severities (for example response time tiers). **Trends over time:** Compare snapshots or use conditions that encode “worse than prior period” if your table holds the needed history. ## Troubleshooting * Confirm CloudLink and Table access. * Validate criteria against sample rows. * Check schedule and that a **state transition** occurred (not ON → ON). * Review the [Data Mine](/workflows/automation-triggers-reference) trigger configuration on the automation. * Tighten criteria. * Run less often if business rules allow. * Confirm you are not relying on repeated ON → ON when you need only the first match. * Reduce the matched row count with stricter filters. * Align schedule with warehouse refresh and off-peak windows where applicable. * See [Data best practices](/data/data-best-practices) for limits and change strategies. * Review agent configuration and prompts in the automation. * Confirm the trigger passes the fields the agent needs. ## Measuring results Track what matters for your process: time to act on exceptions, number of manual touches avoided, and error rates. A simple cost view is: ``` ROI ≈ (time saved × loaded cost rate × frequency) − setup and maintenance effort ``` Use it only with numbers your organization accepts; the value is in consistent measurement, not the formula itself. For automation design, see [Automation System](/workflows/automation-system). For trigger options and variables, see [Automation triggers reference](/workflows/automation-triggers-reference). # Digital Labor Dashboard Source: https://docs.elementum.io/data/digital-labor-dashboard Measure the work Elementum AI agents and automations perform, expressed as full-time-employee (FTE) equivalents, with trends, breakdowns, configurable time rules, and export The Digital Labor dashboard quantifies the work your Elementum AI agents and automations perform and expresses it as a full-time-employee (FTE) equivalent. It gives Organization Administrators a single place to measure and communicate the productivity value the organization gets from Elementum. Find it in **Organization Settings** under the **Analytics** section, on the **Digital Labor** page. Digital Labor figures are approximations meant to communicate productivity value. They are based on an estimated time each action would take a person to complete manually — a default estimate out of the box, which you can refine with your own time rules. ## How the FTE calculation works Elementum builds the FTE figure from the actions your digital workforce completes: * **Successful actions only.** Failed and skipped agent runs and automation executions are not counted. * **A time estimate per action.** Each action is assigned an estimated manual handling time — 5 minutes by default — representing how long the task would take a person to do by hand. * **Total hours.** The number of successful actions is multiplied by the time per action to produce the total productive hours. * **FTE equivalent.** The total hours are divided by a full-time workload for the period — 8 hours per working day. For a 90-day period, that denominator is `90 days × 8 hrs = 720 hrs`. The headline at the top of the dashboard states the result in plain language — for example, "Your digital workforce delivered the output of 2.30 full-time employees" — and splits the figure into **Agents** and **Automations** contributions. Each headline metric has an inline hover tip that explains how the figure is calculated. ## Choose a time period Use the period selector in the top-right corner to set the window the dashboard reports on. Preset options are **Last 7 Days**, **Last 30 Days**, and **Last 90 Days**. The dashboard opens to the last 30 days by default. The selected period drives every metric, the trend chart, the breakdowns, and the export. The dashboard is environment-aware: it reflects the environment you currently have selected. Switching environments changes the data shown. ## Digital Labor breakdown Below the headline, the breakdown section shows the numbers behind the FTE figure for the selected period: | Metric | What it shows | | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | **Agent Actions** | The count of successful agent executions. | | **Automation Actions** | The count of successful automation executions. | | **Total Hour Equivalent** | The total productive hours delivered by your digital workforce, split into the share contributed by agent actions and by automation actions. | | **FTE Calculation** | The total hours, the period hours used as the denominator (for example `90 days × 8 hrs = 720 hrs`), and the resulting Digital Workforce FTE. | ## FTE trend A stacked bar chart plots FTE over time for the selected period, with one bar per day. Each bar is split into the share contributed by agents and the share contributed by automations, so you can see how digital labor accumulates day to day and where it comes from. The trend also surfaces the highest and lowest days and the number of active apps contributing over the period. ## Break down by app, agent, or category Tabs at the top of the table let you view your Digital Labor by: * **By App** — Contribution grouped by the app each action ran in. * **By Agent** — Contribution grouped by the agent or automation that performed the action. * **By Category** — Contribution grouped by the categories you define (see [Categories](#categories)). Apps and agents are defined by the platform. Categories are labels you create yourself. Actions that have not been assigned a category are grouped under **Uncategorized** so nothing is left out. ## Improve accuracy with time rules Out of the box, every action uses the default 5-minute estimate. The most effective way to make the dashboard reflect your organization is to set your own time estimates. A coverage indicator on the dashboard shows the percentage of actions covered by a custom rule versus the default, and links to the settings where you refine them. Open the settings from the **Settings** button in the top-right corner of the dashboard (or the **Customize** prompt in the coverage banner), then use the **Rules** tab. ### Add a time rule A rule sets the human-equivalent time for the actions it targets, and can narrow the scope to just the actions or agents you care about. 1. On the **Rules** tab of Digital Labor settings, click **Add Rule**. 2. Under **Where does this rule apply?**, choose the scope: * **App** — A specific app, or **Any app**. * **Action type** — A specific action type, or **Any**. * **Specific agent or task** — A specific agent or task, or **Any**. 3. Under **Human-equivalent time per action**, enter a **Value** and choose a **Unit** (for example, 5 Minutes) for how long the task would take a person to complete manually. 4. Optionally, assign one or more **Categories** to the actions the rule covers. 5. Review the summary showing which actions the rule will apply to, then click **Add Rule**. **Behavior notes:** * Rules apply **retroactively** — updating a rule recalculates the metrics across all past runs the rule covers, not just future activity. * Use a broad "umbrella" rule to set a single time for a shared action type across many agents, then add narrower rules for the specific agents, tasks, or apps that need a different estimate. * Any action not covered by a rule continues to use the 5-minute default. ## Categories Categories are free-form labels, scoped to your organization, that let you group actions into the buckets that matter to you — for example, Finance or a specific department. They are not configured automatically; you create and assign them yourself. Manage them on the **Categories** tab of Digital Labor settings, and assign categories to actions when you add or edit a time rule. A single category can be applied to actions across multiple agents, tasks, and apps, and an action can carry more than one category. Once categories are assigned, use the **By Category** tab on the dashboard to see your Digital Labor broken out by them. Actions with no category appear under **Uncategorized**. ## Export the data Click **Export** in the top-right corner to export the dashboard data for the selected time period. The export is generated as an Excel (`.xlsx`) file and includes the overall metrics, the daily breakdown, and the by-app, by-agent, and by-category breakdowns. Uncategorized actions are included in their own section so nothing is missed. The file is prepared in the background. Download it from **Background Tasks** in your profile once it is ready. ## Access and permissions Organization Administrators have access to the Digital Labor dashboard automatically. You can grant access to other users as well. The aggregate figures at the top of the dashboard — the headline FTE, the Agent and Automation Actions, and the Total Hour Equivalent — always reflect the full organization, whether or not the user has access to every object behind them. Access scoping applies only to the breakdown table: in the **By App**, **By Agent**, and **By Category** views, a non-admin user sees only the apps, agents, and categories they have access to. # Multi-value fields Source: https://docs.elementum.io/data/multi-value-fields How multi-select values behave across calculations, Execute Script, Repeat for Each, and Send API Request — with the working pattern for each need. Multi-select fields (fields whose type is Multi-Select on a layout, stored internally as `MULTI_PICKLIST`) hold several selected options in a single value. That shape works cleanly on the record itself, but it behaves differently in each place you might reference it downstream — calculations, an Execute Script action, a Repeat for Each loop, or a Send API Request body. This page names the shape, says which action to pick for each need, and gives the working pattern. If you're here because of the specific error `Invalid Type Error at line 1, position N: MULTI_PICKLIST`, jump to [In calculations](#in-calculations). ## The two shapes you'll encounter **Multi-picklist fields.** A field configured as Multi-Select on an Element or Table layout. A single cell holds several selected options. Elementum stores the underlying type as `MULTI_PICKLIST`. **Multi-value text from Data Mine.** When a [Data Mine](/data/data-mining) trigger fires, a multi-value text column in the payload serializes as an array of objects like `[{"value":"WD","type":"TEXT"}, ...]` rather than plain text. This is a different problem from a multi-picklist field — it's a text or JSON payload whose *value* happens to be array-shaped. See [Flattening a Data Mine array payload into plain text](/data/calculations-troubleshooting#flattening-a-data-mine-array-payload-into-plain-text) for the specifics; the rest of this page is about multi-picklist fields on a record. ## Which action to use Pick the action that matches what you're trying to do with the selections. Every row below has a working pattern later on this page. | I want to… | Use | Notes | | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | Loop over each selection and do something with it (send a message per, create a record per) | [Repeat for Each](#in-repeat-for-each) pointed at the field | Simplest option. No script needed. | | Aggregate the selections into a single string, count, or other summary value | [Execute Script](#aggregating-into-a-comma-separated-string) | Calculations can't aggregate a multi-picklist directly. | | Include the selections in a JSON body for an outbound API call | [Execute Script](#passing-multi-select-values-into-a-json-api-body) → **JSON Input** | Build the payload in a script, then pass the stringified result into the Send API Request action. | | Produce a delimited string inside a calculated column on a Table or a formula on an Element layout | Not currently possible | See [In calculations](#in-calculations). Do the work in Execute Script and write the result back to a field. | ## In Execute Script Multi-select inputs come through as an **array of objects with named properties**, not an array of primitive strings. What the object exposes depends on how the multi-select field is configured — a static option list and a data-source-backed multi-select map into the Inputs panel differently. ### The runtime shape Given a multi-select field mapped as an input parameter, the value at `input.parameters.` is an array where each item is an object. The object's properties are the ones you expose in the Inputs panel: ```javascript theme={null} input.parameters.tags = [ { label: "High priority" }, { label: "Needs review" } ]; input.parameters.addresses = [ { id: "addr_123", title: "HQ", street: "1 Main St" }, { id: "addr_456", title: "Warehouse", street: "500 Depot Rd" } ]; ``` The value is an array in every expected case: * **Zero selections** — an empty array `[]`. * **Exactly one selection** — an array of length 1, not a bare object. Call `.map()` unconditionally rather than normalizing with `Array.isArray(x) ? x : [x]`. * **Several selections** — one item per selection. Because the value can still arrive as `null` in edge cases, treat every list input as though it might be null or missing. The `?? []` pattern is safe whether the input is `null`, missing, or already an array: ```javascript theme={null} const items = input.parameters.tags ?? []; ``` ### Configuring the input mapping Every multi-select input in the **Script Configuration → Inputs** panel starts with a **Parameter** name — that's the JavaScript variable you'll reference through `input.parameters.`. The rows nested underneath control which properties of each selected item are exposed inside the script. Two behaviors, depending on how the source field is configured: * **Static option list.** The Inputs panel shows one locked row with `label` in both **Select Field** and **Parameter**. No **+ Add Field** control. Each item in the resulting array has exactly one property — `label`. This applies to static single-select fields too (with the same locked `label` behavior), but the value comes through as an array only for multi-select. * **Data-source-backed multi-select** (options come from records of an Object, an API-powered dropdown, or a similar dynamic source). The Inputs panel shows a **+ Add Field** control. Each field you add has three inputs: | Input | Purpose | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Select Field** | Choose which property on the underlying source object to expose. | | **Parameter** | The JavaScript property name used inside `input.parameters.[i].`. Rename freely — you're not stuck with the source field's name. | | **Test value** | Sandbox value used when clicking **Execute** in the script editor. Doesn't affect production runs. | Only the properties you expose here are available to the script. If a script needs an additional field from the source object later, come back to the Inputs panel and add it — the Output Schema regenerates when you next click **Execute**. ### Iterating each selection Loop over the array and reach into whichever property you exposed. For a static multi-select, that property is always `label`: ```javascript theme={null} const labels = (input.parameters.tags ?? []).map(tag => tag.label); return { labels }; ``` For a data-source-backed multi-select, use the **Parameter** name you configured for each field: ```javascript theme={null} const { addresses } = input.parameters; const streetLines = (addresses ?? []) .map(a => `${a.title}: ${a.street}`) .join('\n'); return { streetLines }; ``` If you only need to act on each selection in a downstream action (create a record per, send an email per, and so on), skip the script entirely and use [Repeat for Each](#in-repeat-for-each) directly on the field. Execute Script is the right choice when you need to *transform* the collection — aggregate, filter, reshape — before handing it off. ### Aggregating into a comma-separated string There is no calculation function that aggregates a multi-picklist into a delimited string (see [In calculations](#in-calculations)). The working pattern is Execute Script: ```javascript theme={null} const csv = (input.parameters.tags ?? []) .map(tag => tag.label) .join(', '); return { csv }; ``` Return `csv` from the script and reference it in downstream actions — for example, mapping it into a text field with **Update Record Fields**, or into a message body in **Post Comment** or **Send Email Notification**. For a data-source-backed multi-select, swap the `.map(tag => tag.label)` for whichever property you want to aggregate: ```javascript theme={null} const titles = (input.parameters.addresses ?? []) .map(a => a.title) .join(', '); return { titles }; ``` ### Passing multi-select values into a JSON API body The **JSON Input** field on the Send API Request action expects a plain JSON string, not a structured object. Build the payload in Execute Script, `JSON.stringify()` it, and map the resulting string into **JSON Input**. This pattern decouples payload construction from the API action — you can swap the script's inputs without touching the API step, and reuse the same body across several Send API Request actions. ```javascript theme={null} const tags = (input.parameters.tags ?? []).map(tag => tag.label); return { payload: JSON.stringify({ ticketId: input.parameters.ticketId, tags }) }; ``` Then map `payload` into the Send API Request action's **JSON Input** field. On the wire the request body becomes: ```json theme={null} { "ticketId": "T-1042", "tags": ["High priority", "Needs review"] } ``` What the receiving API sees depends entirely on how you structure the object before stringifying. Common variants: * **JSON array of strings** — `{ tags: (input.parameters.tags ?? []).map(t => t.label) }` * **JSON array of full objects** — `{ tags: input.parameters.tags ?? [] }` (each item keeps every property you exposed in the Inputs panel) * **Comma-separated string** — `{ tags: (input.parameters.tags ?? []).map(t => t.label).join(', ') }` For the general `JSON.stringify` requirement on this action and the `failed to convert input data to params` error you'll see if you skip it, see the [Send API Request](/workflows/automation-actions-reference#send-api-request) reference. ## In Repeat for Each If the collection is an array returned by Execute Script, see [Execute Script → Returning an array for Repeat for Each](/workflows/automation-actions-reference#returning-an-array-for-repeat-for-each). The Repeat for Each action accepts a multi-picklist field directly as its **Collection**. You do not need to bridge through Execute Script or a Search Records action first. Inside the loop, each property you exposed on the selected item becomes a separate value reference in the picker (type `$` in any inner action's fields). For a static multi-select, that's a single `Label` entry. For a data-source-backed multi-select, it's one entry per exposed field, prefixed with the parameter name — `Addresses - Title`, `Addresses - ID`, and so on. Two loop-level helpers are always available: * **Is First Item** — checkbox, `true` on the first iteration. * **Is Last Item** — checkbox, `true` on the last iteration. **When to prefer Repeat for Each over Execute Script:** * You want to run one action (or a small block of actions) per selection without transforming the collection. * The per-selection logic is visible in the automation builder rather than tucked inside JavaScript — easier for reviewers and future maintainers to read. * No aggregation is needed. If you need a totalled number or a joined string across selections, use Execute Script instead. ## In calculations There is **no supported calculation pattern that aggregates a multi-picklist field into a delimited string, or otherwise operates on all of its selections at once**. `STRING_AGG` and `STRING_AGG_UNIQUE` accept single-value text supplied through a related-field aggregation only, and passing a `MULTI_PICKLIST` field to either raises: ``` Invalid Type Error at line 1, position N: MULTI_PICKLIST ``` This applies everywhere calculations run — calculated columns on a [Table](/data/tables), formulas on an [Element](/workflows/layouts) layout, and the [Run Calculation](/workflows/automation-actions-reference#run-calculation) action. **What to do instead.** If your ultimate need is a text value derived from the selections (a comma-separated summary, a count, a joined description), do the work in [Execute Script](#aggregating-into-a-comma-separated-string) and, if the value needs to live on a record, write it back with **Update Record Fields**. If your need is per-selection processing, use [Repeat for Each](#in-repeat-for-each) directly. For the full error catalog and the analogous Data Mine limitation, see [Calculations troubleshooting → Multi-value and array-shaped values](/data/calculations-troubleshooting#multi-value-and-array-shaped-values). ## Related documentation * **[Execute Script action](/workflows/automation-actions-reference#execute-script)** — full reference for input mapping, Output Schema, and the runtime environment. * **[Repeat for Each action](/workflows/automation-actions-reference#repeat-for-each)** — collection loops in the automation builder. * **[Send API Request action](/workflows/automation-actions-reference#send-api-request)** — request body shapes, authorization, and the `JSON.stringify` requirement. * **[Calculations troubleshooting](/data/calculations-troubleshooting)** — the multi-value and Data Mine array sections cover the calculation-side limitations in more depth. * **[Data Mine](/data/data-mining)** — where the array-of-objects text payload shape comes from. # Reports Source: https://docs.elementum.io/data/reports Generate dynamic Excel and PDF reports from your data with customizable layouts and automated workflows ## Overview Reports are templates configured on an Apps icon **App** or Elements icon **Element** that produce **Excel** or **PDF** files from record data. You generate them from Record Details icon record details or from [automations](/workflows/automation-system) using the [Generate Report](/workflows/automation-actions-reference) action. For interactive charts and dashboards in the product, see [Analytics](/data/analytics) instead. Reports are available on both Apps icon **Apps** and Elements icon **Elements**. The setup and behavior are the same for either object—choose the object where the source records live. *** ## Prerequisites Admin permissions on the Apps icon **App** or Elements icon **Element** are required to create and configure reports. End users can generate reports once they're set up. Before creating reports, ensure you have: * **Admin access** — Required on the Apps icon **App** or Elements icon **Element** where you'll configure the report template * **A data source** — Records and fields (including related data) to include * **Defined outputs** — What each report should contain, how it should look, and Excel versus PDF *** ## Creating Reports Navigate to the admin settings of the object where you want the report to live to create it: **How to Access:** 1. Go to your Apps icon **App** or Elements icon **Element** → **Admin Settings** → **Reports** 2. Click **Create** to start building a new report Reports are created at the object level and can be generated from records within that Apps icon **App** or Elements icon **Element**. Set up the fundamental report properties: * **Report name** — A clear name so builders and users can recognize the template * **Data source** — Which records and fields to include (the object's own records and any related data) * **Report type** — Excel (`.xlsx`) or PDF * **Layout** — Structure and formatting in the report editor Create your report structure using the built-in spreadsheet editor: **Spreadsheet Interface:** * Use familiar Excel-like interface for report design * Configure rows and columns with dynamic data * Add formulas and calculations * Set up data formatting and styling **Key Features:** * **Dynamic Data Binding**: Connect cells to record fields * **Conditional Formatting**: Apply styling based on data values * **Formulas**: Include calculations and data transformations * **Multiple Sheets**: Create complex reports with multiple tabs **Document Layout:** * Design printable PDF reports with precise formatting * Include headers, footers, and page numbering * Add logos, images, and branding elements * Control page breaks and layout flow **Key Features:** * **Rich Formatting**: Professional document styling * **Image Integration**: Include charts, logos, and attachments * **Print Optimization**: Designed for professional printing * **Custom Layouts**: Flexible positioning and design options **Report Editor Features:** * **Field Mapping**: Connect report cells to specific record fields * **Dynamic Content**: Automatically populate data from records * **Field Types**: Support for text, numbers, dates, images, and more * **Relationships**: Include data from related records * **Cell Styling**: Background colors, borders, fonts, and alignment * **Zebra Striping**: Alternating row colors for better readability * **Grid Lines**: Control visibility of table borders * **Export Options**: PDF orientation (Portrait/Landscape) * **Attachment Gallery**: Include image galleries from record attachments * **Reference Values**: Pull data from related records * **Calculated Fields**: Create formulas and computed values * **Conditional Logic**: Show/hide content based on data conditions Set up how your reports will be generated and exported: **Excel Export Options:** * **File Format**: .xlsx format with full Excel compatibility * **Sheet Names**: Custom names for multiple worksheets * **Data Formatting**: Preserve number formats, dates, and currencies * **Formula Preservation**: Maintain Excel formulas in exported files **PDF Export Options:** * **Page Orientation**: Portrait or Landscape layout * **Page Size**: Standard paper sizes (Letter, A4, etc.) * **Margins**: Control spacing around content * **Print Settings**: Optimize for screen viewing or printing Test your export settings with sample data to ensure the output meets your requirements. Complete the report setup and verify it works correctly: 1. **Save Configuration**: Save your report template 2. **Test Generation**: Generate a sample report with existing data 3. **Review Output**: Check formatting, data accuracy, and layout 4. **Make Adjustments**: Refine the template as needed 5. **Publish Report**: Make it available for use Reports can be edited after creation, but changes will affect all future report generations. *** ## Generating Reports ### Manual Report Generation Users can generate reports directly from Record Details icon record details: **From Record Details:** 1. **Navigate to Record**: Open any record in your object 2. **Find Reports Section**: Look for available reports in the record interface 3. **Select Report**: Choose which report template to generate 4. **Generate**: Click to create the report 5. **Download**: The report will be generated and automatically attached to the record Reports can only be generated manually from individual Record Details icon record views or automatically through [automations](/workflows/automation-system). There is no separate reports dashboard for manual generation. **Report Output:** * When generated manually, reports are automatically attached to the source record * Files are available for immediate download from the record's attachments * Generated reports include timestamp and metadata ### Automated Report Generation Use the [Generate Report](/workflows/automation-actions-reference) automation action to build reports inside workflows. Typical triggers include record created or updated, schedules, and milestones in approval or status flows. The **Generate Report** action produces a file value for later steps; it does **not** attach the file to a record by itself. To store the file on a record, add **Save Attachment** immediately after **Generate Report**. Parameters and output variables are documented in the action reference. **Automation Setup:** 1. Go to **Automations** in your Apps icon **App** or Elements icon **Element** 2. Choose your trigger event (e.g., Record Updated) 3. Add **Generate Report** action 4. Add **Save Attachment** action (to attach the report to a record) 5. Configure the report generation and attachment settings **Generate Report Action Settings:** * **Report Template**: Select which report to generate * **Target Record**: Specify which source record to generate the report from * **File Name**: Set dynamic file names using variables * **Export Format**: Choose Excel or PDF output **Save Attachment Action Settings:** * **File**: Select the generated report from the previous action's output * **Target Record**: Specify which record to attach the report to * **File Name**: Optionally customize the attachment name 1. **Test Trigger**: Activate the automation trigger 2. **Verify Generation**: Check that reports are created correctly 3. **Review Attachments**: Ensure reports are properly attached to records 4. **Validate Data**: Confirm all data is accurately included **Automation Examples:** ``` Trigger: New customer record created Actions: 1. Generate Report (welcome packet PDF) 2. Save Attachment (attach report to customer record) 3. Send Email Notification (send welcome packet to customer) Result: Professional welcome document attached to customer record and emailed ``` ``` Trigger: Time-based (monthly) Actions: 1. Generate Report (summary report for all active projects) 2. Save Attachment (attach to company record) 3. Send Message to Teams (notify team with report link) Result: Excel report with project status attached to company record ``` ``` Trigger: Approval process completed Actions: 1. Generate Report (approval summary PDF) 2. Save Attachment (attach to approval record) 3. Post Comment (document approval completion) Result: PDF document with approval details attached to record ``` *** ## Report Management ### Viewing Generated Reports **Access Reports:** * **Record Attachments**: Reports appear in the record’s attachment section after they are saved * Manual generation: Reports are automatically attached to the source record * Automated generation: Reports are attached only if the **Save Attachment** action was included in the automation * **File Downloads**: Direct download links for immediate access from Record Details icon record details If an automation run completed but no file appears on the record, confirm the flow includes Save Attachment after Generate Report (see Automated Report Generation). **Report Metadata:** * **Generation Date**: When the report was created * **Template Used**: Which report template generated the file * **File Size**: Size of the generated report file * **Export Format**: Excel or PDF format indicator ### Editing Report Templates Changes to report templates affect all future report generations. Existing reports remain unchanged. **Modification Process:** 1. **Access Template**: Go to Reports → Select template → Edit 2. **Make Changes**: Update layout, formatting, or data sources 3. **Test Changes**: Generate sample reports to verify updates 4. **Save Updates**: Apply changes to the template 5. **Document Changes**: Note what was modified for team reference ### Report Performance **Optimization Tips:** **Best Practices for Report Performance:** * Limit data scope to necessary records and fields * Use efficient data queries and filters * Optimize image sizes in attachment galleries * Test with realistic data volumes * Monitor generation times for large reports **Performance Considerations:** * **Data Volume**: Large datasets may increase generation time * **Image Content**: Multiple images can impact file size and speed * **Complex Layouts**: Intricate formatting may slow generation * **Concurrent Generation**: Multiple simultaneous reports may queue *** ## Advanced Features You can add image galleries sourced from record attachments: * **Layout** — Grids with a maximum images-per-row setting (for example four per row) * **Image sizing** — Automatic scaling to fit the report layout * **Filtering** — Include only certain attachment types (for example images only) * **Fallback** — Define behavior when a record has no matching attachments **Reference Values:** * **Related Records**: Pull data from connected records * **Calculated Fields**: Include computed values and formulas * **Conditional Content**: Show/hide sections based on data * **Data Formatting**: Apply number, date, and text formatting **Broader data use:** * **Time ranges** — Limit or summarize data for specific periods where the template supports it * **Aggregations** — Summary statistics and calculations in the layout * **CloudLink and connected data** — Use fields and relationships available to the object's data model, including [CloudLink](/administration/setup-cloudlink)-backed sources where your Apps icon **App** or Elements icon **Element** exposes them **Excel Formatting:** * **Cell Styles**: Colors, fonts, borders, and alignment * **Number Formats**: Currency, percentages, dates * **Conditional Formatting**: Data-driven styling * **Charts and Graphs**: Visual data representations **PDF Formatting:** * **Professional Layouts**: Headers, footers, page numbers * **Brand Integration**: Logos, colors, and styling * **Print Optimization**: Margins, page breaks, scaling * **Interactive Elements**: Links and navigation *** ## Troubleshooting ### Common Issues **Common Causes:** * Missing or invalid data in source records * Template references non-existent fields * Large data volume causing timeouts * Insufficient permissions for data access **Solutions:** * Verify all referenced fields exist and contain data * Test with smaller data sets * Check user permissions for data access * Review template configuration for errors **Common Causes:** * Complex layouts not rendering correctly * Images not displaying properly * Text overflow or truncation * Inconsistent styling across sections **Solutions:** * Simplify complex layouts * Optimize image sizes and formats * Adjust cell sizes and text wrapping * Test formatting with various data lengths **Common Causes:** * Large number of records being processed * Multiple high-resolution images * Complex calculations and formulas * Concurrent report generation **Solutions:** * Limit data scope and record count * Optimize image sizes * Simplify calculations where possible * Schedule automated reports during off-peak hours ### Team enablement * Document each template’s purpose and intended audience * Show generators where reports appear (record attachments) and how automations differ from manual runs from Record Details icon record details *** ## Integration with Workflows * **Automations** — Combine **Generate Report** with **Save Attachment**, then chain email, Teams, comments, or other actions that accept files. See [Automated Report Generation](#automated-report-generation) and the [Generate Report](/workflows/automation-actions-reference) action reference. * **Approvals and milestones** — Attach summary PDFs to Apps icon **App** or Elements icon **Element** records when a process completes or status changes * **Distribution** — Send generated files by email or Teams using the automation outputs after the report is created Interactive analytics stay in [Analytics](/data/analytics); Reports delivers files for download or attachment. # Configure Related Records Source: https://docs.elementum.io/data/showing-relationships Show, filter, and link related records on record detail layouts using the Related Items widget and record action buttons On record detail layouts, you can list related records, open configuration similar to views, and add buttons that create or link records. Targets can be [Apps, Elements, or Tasks](/getting-started/fundamentals/core-concepts). ## Dynamic Relationships Dynamic relationships automatically link records between objects based on matching field values. You configure them at the app level, then reference them when setting up Related Items widgets on record detail layouts. ### Create a Dynamic Relationship 1. Click **Relationships** in the left nav of the app. 2. Click **+ Relationship**. 3. Under **Related Object**, select the object you want to join to. 4. Under **Source Field**, select the field from the current object to match on. 5. Under **Related Object Field**, select the corresponding field on the related object. 6. To join on additional fields, click **+ Field** and repeat the field mapping. 7. Under **Apply relationship when...**, add conditions to control when the relationship applies: * Click **+ Condition** to add a single filter rule using a field, operator, and value. * Click **+ Condition Group** to add a grouped set of conditions. 8. Click **Save** to complete the relationship. ## Related Items widget Use the **Related Items** widget to show related records in a table on the detail page. ### Add a Related Items Widget 1. Navigate to your record detail layout settings 2. Add a Related Items widget (full width) 3. Configure the widget settings: * Widget Name: Give it a descriptive name * Select Object: Choose which relationship to display (this can be changed at any time after saving) * Sort Order: Define how records are ordered * Additional Filters: Add conditions to filter related records * Rows per Page: Set how many records display at once * Display Columns: Choose which columns appear in the table ## Button widgets Button widgets let users create or relate records from the detail page. ### Types of buttons 1. **Relate Record button** * Links existing records together * Configurable target (Apps, Elements, or Tasks) * Optional default filters for the linking process 2. **Create Record button** * Creates new related records * Configurable target (Apps, Elements, or Tasks) ### Button configuration * Custom name * Optional icon * Button style: Primary, Secondary, or Inline * Width: full width or standard * Target: choose an App, Element, or Task; for Relate Record, set default filters when needed ## Best practices * Use clear, descriptive names for widgets * Configure relevant display columns for quick information access * Set appropriate rows per page based on expected data volume * Use filters to show the most relevant related records * Choose button styles that match other actions on the record detail page ## Manage related items Each Related Items widget has its own configuration screen, similar to view setup, where you can: * Change the selected Object to display a different relationship * Customize the display columns * Set default sorting * Configure filters * Adjust pagination settings # Tables Source: https://docs.elementum.io/data/tables Reusable grid views of your data that stay current with underlying sources—shape what you show, combine related information, and share a consistent view with your team. ## Working with Tables and Views Tables icon **Tables** are saved, spreadsheet-style views of data from across your workspace. You decide what appears, how it is sorted and filtered, and how multiple sources fit together so everyone works from the same picture of the information. Later sections cover configuration in detail—including sources, joins, calculated columns, and optional connections to external tools such as BI platforms when your [CloudLink](/administration/setup-cloudlink) and warehouse setup support them. **Data sources you can build a table from:** * **[CloudLinks](/administration/setup-cloudlink)** — Connect to external data warehouses (Snowflake, BigQuery, etc.) * Apps icon **[Apps](/getting-started/build-an-app)** — Data from your custom applications * Elements icon **[Elements](/getting-started/fundamentals/core-concepts#data--elements)** — Shared data across teams and departments * Tasks icon **[Tasks](/workflows/tasks)** — Workflow steps and progress tracking ## Create a table 1. In the left navigation, click Tables icon **Table**. 2. Next to the **Tables** heading, click the More icon **More** icon. 3. Click **Create New Table**. 4. Fill in the required fields: * **Table name** * **Table handle** * **Category** * **Source** 5. Click **Create**. **Explore the underlying data:** Next to the **Tables** heading, click the More icon **More** icon and select **Explore Data**. There you can see additional detail about what Elementum is reading from your databases for the table you are viewing. ## Data View Each table has a single **Data** view — the spreadsheet-style grid that displays the table's data. Table admins manage what appears in this view through [Configure](#configure) in Table Settings, where they control columns, joins, filters, data cleansing, and calculated columns. Changes made in Configure are reflected in the Data view for all users. Users can personalize how they see the Data view by applying their own filters and sort orders. These adjustments are per-user and do not change the underlying table configuration. If different teams need different perspectives on the same table data — for example, finance focused on cost columns while logistics focuses on shipping fields — use [Workspaces](#workspaces) to create separate dashboard views rather than duplicating tables. ## Workspaces Workspaces within a table work the same way as [Workspaces on the home page](/getting-started/home-page#workspaces) — they are dashboards that consolidate widgets and visualizations into a single place. When a Workspace is created inside a table, it is scoped to that table and shared with users who have access to it. Workspaces are the way to create different "views" of a table's data for different audiences. Each Workspace can contain its own set of widgets with distinct filters, sort orders, and chart configurations. ### Create a table Workspace 1. In the table sidebar under **Workspaces**, click the More icon **More** icon. 2. Select **Create New Workspace**. 3. Name the Workspace and click **Create**. 4. Add widgets by navigating to views or charts and selecting **+ Add To Workspace**. Shared Workspaces in a table are visible to other users who have access to that table, making them useful for team dashboards built around a specific dataset. ## Why use Tables? **One current picture of the data.** Tables read from connected sources, so when data changes in Elementum or your warehouse, what people see in the grid can reflect that without re-exporting files or merging attachments. That cuts down on copy-paste errors and on everyone working from slightly different versions of the same numbers. **Different questions, same foundation.** You can define more than one table on the same sources: each table can use its own columns, filters, and joins to match how a team works. Sales might emphasize pipeline and revenue, support might emphasize open cases and response times, and finance might emphasize payment status—while still drawing from the same underlying data instead of maintaining parallel spreadsheets or extracts. ## Configuring Data Sources ### Snowflake View Configuration When connecting to Snowflake or other data warehouses, you'll configure: **Database Selection** * Choose your target database from available options * Example: `ACME_ANALYTICS_PROD` **Schema Selection** * Select the appropriate schema within your database * Example: `DATA` **View Name** * Define a meaningful name for your view * Example: `DET` (Deal Execution Table) Proper naming conventions help team members quickly identify and locate the right data views. ### FAQ: Internal Snowflake Tables If a table is deleted in Elementum and you still see related objects in the CloudLink schema, that is expected behavior for platform-managed storage. The `ELEMENTUM_PLATFORM` schema is part of Elementum's internal storage layer. It stores application state, intermediate processing data, and metadata required for platform operations. These tables are system-generated and support how Elementum manages platform objects, datasets, and execution state. Hashed names are intentionally used to: * Guarantee uniqueness across apps, workflows, and object types * Prevent naming collisions in shared environments * Support internal state management at scale Yes. As teams create objects, update configurations, and run processes, Elementum creates additional internal tables to support those operations. Increases in internal table volume generally reflect normal platform usage, not a configuration issue. No supported configuration is available to limit or consolidate these internal tables. This storage model is required for platform isolation, scalability, and reliability. Restricting it can impact core functionality. Internal tables should not be manually removed. Even when a table is not actively queried, it may still be needed for: * Auditability and traceability * Version rollback and recovery * Dependency resolution across platform services If you delete a field or change its type on a table that is mapped to an Element field, the mapping can become invalid. When this happens, users may see errors in the list view or when loading the record detail page. To resolve this issue: 1. Identify the mapped field causing the error. 2. Remove any dependencies on that field (for example, [automations](/workflows/automation-system), formulas, filters, or views that reference it). 3. Delete the problematic mapped field. 4. Re-add the field from the unmapped table fields list so Elementum can create a fresh mapping. After remapping, reapply any needed dependencies. ## Table Features ### Join types Elementum provides four join types with visual representations so you can see how rows are combined. Each join type fits different reporting and analysis needs. For how relationships between records and objects are modeled more broadly, see [Showing relationships](/data/showing-relationships). **Join configuration** * **Source Field**: Select the field from your primary table * **Joined Object Field**: Select the matching field from the secondary table * The system guides you through field selection with dropdown menus **What it does:** Shows only records that exist in both tables with matching values. **Visual representation:** Two overlapping circles, showing only the intersection. **Business use cases:** * **Active customers with orders**: Show only customers who have made purchases * **Employees with assigned projects**: Display staff members who are actively working on projects * **Products with sales data**: View only products that have been sold * **Vendors with active contracts**: List suppliers who currently have agreements **Example scenario:** ``` Customer Table: 1000 customers Orders Table: 500 orders from 300 customers Inner Join Result: 300 customers (only those who placed orders) ``` **When to use:** When you need to focus on records that have relationships and want to exclude unmatched data. **What it does:** Keeps all records from the left (primary) table, plus matching records from the right table. **Visual representation:** Left circle completely filled, with matching portion from right circle. **Business use cases:** * **All customers and their orders**: Show every customer, including those who have not ordered * **Complete employee roster**: Display all staff, whether they are on projects or not * **Full product catalog**: Show all products, including those never sold * **Marketing campaign analysis**: View all contacts, showing who responded to campaigns **Example scenario:** ``` Customer Table: 1000 customers Orders Table: 500 orders from 300 customers Left Join Result: 1000 customers (700 show no orders, 300 show order data) ``` **When to use:** When your primary concern is the complete dataset from your main table, but you want to enrich it with available data from another source. **What it does:** Keeps all records from the right (secondary) table, plus matching records from the left table. **Visual representation:** Right circle completely filled, with matching portion from left circle. **Business use cases:** * **All orders with customer details**: Show every order, even if customer data is missing * **Complete transaction log**: Display all payments, including those without customer profiles * **Full support ticket history**: Show all tickets, even if user accounts were deleted * **Inventory movements**: Track all stock changes, including anonymous transactions **Example scenario:** ``` Customer Table: 1000 customers Orders Table: 500 orders (50 from deleted/unknown customers) Right Join Result: 500 orders (450 with customer data, 50 without) ``` **When to use:** When you need complete data from your secondary table and want to see what primary table data is available to enrich it. **What it does:** Keeps all records from both tables, whether they match or not. **Visual representation:** Both circles completely filled, showing all data from both sources. **Business use cases:** * **Complete data audit**: See all customers AND all orders, identifying gaps * **System migration**: Compare old and new systems to ensure no data loss * **Reconciliation reports**: Match financial records from different systems * **Master data management**: Combine multiple data sources into one comprehensive view **Example scenario:** ``` Customer Table: 1000 customers Orders Table: 500 orders from 300 customers (50 from unknown customers) Full Outer Join Result: 1200 records (700 customers with no orders, 300 customers with orders, 50 orders without customer data) ``` **When to use:** When you need to see the complete picture from both data sources and identify what data exists, what's missing, and what's orphaned. **Choosing the right join:** Start by asking yourself: "Do I need ALL records from my primary table, or only the ones that have matching data?" This will help you decide between inner joins (matches only) and outer joins (keep everything). ## Table Settings The **Table Settings** section of the sidebar provides access to configuration, data quality, metadata, and access control for each table. The settings are organized into four areas: **Configure**, **Data Cleansing**, **Table Details**, and **Roles & Permissions**. ### Configure Configure is the management screen for the [Data View](#data-view). Open it from **Table Settings** → **Configure** in the table sidebar. This is where table admins control what data appears in the grid and how it is shaped. The Configure screen has three areas: **Toolbar** — Actions that apply to the table as a whole: * **Join** — Combine data from other tables. See [Join types](#join-types) for details. * **Filter** — Apply filters that affect the Data view for all users. See [Filtering, search, and data operations](#filtering-search-and-data-operations). * **Data Clean** — Open [Data Cleansing](#data-cleansing) tools to standardize, deduplicate, and fix data quality issues. **Columns** — Manage which columns appear in the Data view: * **Visible Columns** — Columns currently shown in the grid. Drag to reorder, or click **Hide All** to move them all to Hidden. * **Hidden Columns** — Columns available in the table but not shown in the grid. Click **Show All** to make them all visible. * **Search Columns** — Find a specific column by name across both lists. * **+ Calculated Column** — Add a formula-based column. See [Calculated columns](#calculated-columns). * Each column card shows the field name and its source. Use the drag handle to reorder or the copy icon to duplicate. **Table Preview** — A live preview of the Data view with your current configuration. Shows the row count and the data as it will appear to users. Click **Full Screen** to expand the preview. When you are done making changes, click **Save** to apply the configuration to the Data view. ### Data Cleansing Data Cleansing helps you review and fix value mismatches that result from [joins](#join-types). When two tables are joined, some values in the join field may not match exactly — Data Cleansing surfaces those discrepancies so you can resolve them. Access it from **Table Settings** → **Data Cleansing** in the table sidebar, or from the **Data Clean** button in the [Configure](#configure) toolbar. Data Cleansing requires at least one join on the table. If there are no joins configured, the screen displays "No current Joins on Table. Add one to use Data Cleansing." **How it works:** 1. **Select Join** — Choose which join to review from the dropdown on the right. 2. **Review match results** — The **Table Join Match Percentage** shows what percentage of values are **Matched** versus **Unmatched** across the joined tables. 3. **Switch between tabs:** * **Unmapped** — Values from the original table that did not find a match in the joined table. Each row shows the original value, a confidence score, the number of occurrences (count), and a suggested replacement value. * **Mapped** — Values that have already been matched, either automatically or manually. 4. **Resolve mismatches** — For unmapped values, review the suggested replacement and accept or override it. Select one or more rows and click **Apply Selected Matches**. **Intelligent Matching** — Elementum can suggest matches automatically based on similarity. Click **Apply Intelligent Matches** to accept the suggestions, or click the gear icon to adjust the confidence percentage threshold for what qualifies as a match. Run Data Cleansing after configuring joins and before setting up [Data Mining](/data/data-mining) triggers or [AI Search](/ai-agents/ai-search) on a table. Clean join mappings produce more accurate downstream results. ### Table Details Table Details shows the properties that were set when the table was first created. Access it from **Table Settings** → **Table Details** in the table sidebar. **General:** * **Table Name** — The display name for the table. Editable. * **Category** — The category the table belongs to (for example, Customer Support). Editable via dropdown. * **Source** — The data source the table reads from. This is set at creation and cannot be changed. The link opens the source object directly. **Cloud Details:** * **Cloud** — The cloud connection used by the table (for example, Default Elementum Connection). Read-only. ### Roles & Permissions Each table has its own **Roles & Permissions** settings that control who can view, edit, and administer the table. Access it from **Table Settings** → **Roles & Permissions** in the table sidebar. Table roles work the same way as [app-level roles](/administration/roles-permissions#managed-roles). **Managed roles** — Predefined roles with fixed permissions. You manage membership only (users and groups) through **Manage membership** on each role card. * **Content Editor** — View and edit content in the table. * **Content Viewer** — View content in the table (read-only). * **Table Admin** — Full admin access to the table, including configuration, data cleansing, and role management. **Custom roles** — For more granular control, click **Create custom role** to define a role with specific permissions tailored to your needs. Custom roles give you full control over both permissions and membership. For a full reference of permission types and how roles work across the platform, see [Roles & Permissions](/administration/roles-permissions). ## Snowflake BI View Permissions When using the Snowflake View feature, you need to configure permissions for two distinct purposes: allowing Elementum to create and manage the views, and allowing your users or BI tools to query the views. For Snowflake account and connection setup before BI views, see [Connect Snowflake to Elementum](/administration/connect-snowflake-to-elementum). ### Elementum Platform Permissions The Snowflake user account configured in your CloudLink connection needs permissions to create and manage BI views in your desired database and schema. **Required for BI View Creation**: These permissions must be granted to the Elementum role before you can create BI views. Without these permissions, the platform cannot create views in your specified Snowflake database and schema. **Grant these permissions to enable Elementum to manage BI views:** ```sql theme={null} -- Replace placeholders with your actual values: -- - Database where BI views will be created -- - Schema within the database for BI views -- - Role assigned to the Elementum user (typically "ELEMENTUM") USE ROLE ACCOUNTADMIN; -- Grant USAGE on the database GRANT USAGE ON DATABASE TO ROLE ; -- Grant USAGE on the schema GRANT USAGE ON SCHEMA . TO ROLE ; -- Grant the ability to manage views in the schema GRANT CREATE VIEW ON SCHEMA . TO ROLE ; ``` **Critical: Do Not Change View Ownership:** Once Elementum creates a BI view, the ownership must remain with the ELEMENTUM role. Changing ownership to another role will break Elementum's ability to manage, update, or delete the view. If view ownership is accidentally changed, you must transfer it back to the ELEMENTUM role using `GRANT OWNERSHIP ON VIEW .. TO ROLE ;` **Example:** ```sql theme={null} -- Example using common values USE ROLE ACCOUNTADMIN; GRANT USAGE ON DATABASE ANALYTICS_DB TO ROLE ELEMENTUM; GRANT USAGE ON SCHEMA ANALYTICS_DB.BI_VIEWS TO ROLE ELEMENTUM; GRANT CREATE VIEW ON SCHEMA ANALYTICS_DB.BI_VIEWS TO ROLE ELEMENTUM; ``` **Best Practice**: Create a dedicated schema for your BI views (e.g., `BI_VIEWS` or `ELEMENTUM_BI`) to keep them organized and separate from other data structures. ### End User Query Permissions After Elementum creates a BI view, you need to grant permissions to the Snowflake roles used by your BI tools, analysts, or other users who need to query the views. **Grant these permissions to enable users to query BI views:** ```sql theme={null} -- Replace placeholders with your actual values: -- - Database used in the creation of the BI view -- - Schema used in the creation of the BI view -- - Name used in the creation of the BI view -- - Role assigned to users that need access to query the BI view USE ROLE ACCOUNTADMIN; -- Grant USAGE on the database GRANT USAGE ON DATABASE TO ROLE ; -- Grant USAGE on the schema GRANT USAGE ON SCHEMA . TO ROLE ; -- Grant SELECT on the specific view GRANT SELECT ON VIEW .. TO ROLE ; ``` **Example for a specific view:** ```sql theme={null} -- Example granting PowerBI role access to a sales dashboard view USE ROLE ACCOUNTADMIN; GRANT USAGE ON DATABASE ANALYTICS_DB TO ROLE POWERBI_USERS; GRANT USAGE ON SCHEMA ANALYTICS_DB.BI_VIEWS TO ROLE POWERBI_USERS; GRANT SELECT ON VIEW ANALYTICS_DB.BI_VIEWS.SALES_DASHBOARD TO ROLE POWERBI_USERS; ``` ### Granting Access to All Future Views If you prefer to grant permissions on all future views in a schema (so you don't need to grant permissions for each new view individually), use this approach: ```sql theme={null} -- Replace placeholders with your actual values: -- - Database used for BI views -- - Schema used for BI views -- - Role assigned to users that need access USE ROLE ACCOUNTADMIN; -- Grant USAGE on database and schema GRANT USAGE ON DATABASE TO ROLE ; GRANT USAGE ON SCHEMA . TO ROLE ; -- Grant SELECT on all future views in the schema GRANT SELECT ON FUTURE VIEWS IN SCHEMA . TO ROLE ; ``` **Example:** ```sql theme={null} -- Automatically grant access to all future BI views for the analytics team USE ROLE ACCOUNTADMIN; GRANT USAGE ON DATABASE ANALYTICS_DB TO ROLE ANALYTICS_TEAM; GRANT USAGE ON SCHEMA ANALYTICS_DB.BI_VIEWS TO ROLE ANALYTICS_TEAM; GRANT SELECT ON FUTURE VIEWS IN SCHEMA ANALYTICS_DB.BI_VIEWS TO ROLE ANALYTICS_TEAM; ``` **Recommended Approach**: Using `FUTURE VIEWS` grants streamlines access management. When Elementum creates new BI views, users with this grant automatically have access without requiring additional permission changes. ### Permission Setup Workflow When setting up BI views: 1. Grant the Elementum role permissions to create and manage views in your target database and schema. 2. Configure your Elementum table and enable the Snowflake View feature through the Business Intelligence section. 3. Grant SELECT permissions to the roles used by your BI tools, analysts, or other users who need to query the view. 4. Configure your BI tools (PowerBI, Tableau, Looker) to connect to the Snowflake view using the appropriate role. **Common Issue**: If users report "Object does not exist or not authorized" errors when querying BI views, verify that: 1. The view was successfully created by Elementum (check in Snowflake) 2. The user's role has USAGE grants on both the database and schema 3. The user's role has SELECT grant on the specific view or FUTURE VIEWS Remember that grants must be applied at all three levels: database, schema, and view. ### Calculated columns Calculated columns let you add new columns derived from existing table data using Excel-like formulas. * **Mathematical operations**: `Revenue = Quantity × Price` * **Date calculations**: `Days_Open = TODAY() - Created_Date` * **Conditional logic**: `Risk_Level = IF(Amount > 10000, "High", "Low")` * **Text manipulation**: `Full_Name = CONCAT(First_Name, " ", Last_Name)` * **Aggregations**: `Total_Orders = COUNT(Orders.ID)` * **Column name**: Give your calculated column a descriptive name * **Function**: Enter your formula using Excel-like syntax * **Format options**: * Format as percentage * Format as percentage and multiply by 100 * Format as currency * No formatting (default) Elementum supports calculation functions similar to Excel, including: * **Mathematical**: SUM, AVERAGE, MIN, MAX, ROUND, POWER, SQRT * **Logical**: IF, AND, OR, NOT * **Date/Time**: DATE, NOW, DATEDIF, WEEKDAY, YEAR, MONTH, DAY * **Text**: CONCAT, LEFT, RIGHT, MID, UPPER, LOWER, TRIM * **Lookup**: VLOOKUP, COUNTIF, SUMIF, SEARCH, FIND For a complete list of functions and their syntax, see the [Calculations Reference](/data/calculations). **Sales analytics** ``` Commission = IF(Deal_Value > 50000, Deal_Value * 0.05, Deal_Value * 0.03) Days_in_Pipeline = DATEDIF(Created_Date, NOW(), "D") Deal_Size_Category = IF(Deal_Value > 100000, "Enterprise", IF(Deal_Value > 10000, "Mid-Market", "SMB")) ``` **Customer analysis** ``` Customer_Lifetime_Value = SUM(Orders.Total_Amount) Last_Order_Days = DATEDIF(MAX(Orders.Order_Date), NOW(), "D") Customer_Status = IF(Last_Order_Days > 365, "Inactive", "Active") ``` **Financial reporting** ``` Profit_Margin = (Revenue - Cost) / Revenue * 100 Quarterly_Growth = (Current_Quarter - Previous_Quarter) / Previous_Quarter * 100 Budget_Variance = Actual_Amount - Budget_Amount ``` **Multi-value and array-shaped fields:** Calculated columns operate on single values. `MULTI_PICKLIST` fields and multi-value text columns surfaced through [Data Mine](/data/data-mining) (which serialize as JSON arrays like `[{"value":"...","type":"TEXT"}, ...]`) are not supported as inputs to most calculation functions and cannot be flattened to plain text in a calculated column. If you need a text value derived from a multi-picklist, do the aggregation in an Execute Script action — see [Multi-value fields](/data/multi-value-fields) — and write the result to a plain text field. See also [Calculations troubleshooting](/data/calculations-troubleshooting#multi-value-and-array-shaped-values). **Performance Consideration**: While calculated columns are flexible, creating too many complex calculations can impact table performance. Each calculated column requires processing time when the table loads. For optimal performance: * Limit complex calculated columns to essential business logic * Use simple calculations when possible * Consider pre-calculating values in your data source for frequently used complex formulas * Monitor table load times and optimize as needed * **Increase warehouse size** for better performance with complex calculations and large datasets **Excel-like syntax**: If you use Excel formulas, Elementum calculation syntax follows similar patterns, so you can reuse familiar function names and structures. ### AI Search Table admins can enable **AI Search** on a Table. Setup follows the same process as for [AI Search](/ai-agents/ai-search) on Elements icon Elements. For field to search, embedding service, attribute fields, and filters, see [AI Search](/ai-agents/ai-search). ### Filtering, search, and data operations **Filter options** * **Field selection**: Choose any column for filtering * **Operators**: Contains, equals, greater than, less than, etc. * **Values**: Direct input or dropdown selection for known values * **Condition groups**: Combine multiple filters with AND/OR logic **Filter management** * **Add condition**: Build complex filter logic * **Condition groups**: Organize related filters * **Clear all**: Reset filters quickly * **Save filters**: Store frequently used filter combinations for quick access **Joins and data quality** Table admins manage joins and data cleansing through the [Configure](#configure) screen. See [Join types](#join-types) and [Data Cleansing](#data-cleansing) for details. ## Real Business Examples Combine Opportunities, Accounts, and Contacts tables. Join Opportunity.AccountID to Account.ID, then add a calculated column for Potential Revenue (Amount × Probability). Filter to Stage = "Proposal" and Region = "West" to surface active opportunities with contact details and revenue potential. Combine Customers, Support Tickets, and Orders tables. Join on Customer.ID to both Tickets.CustomerID and Orders.CustomerID, then add a calculated column for Lifetime Value using SUM(Order.Total). Filter to contacts within the last 90 days for a complete customer history with support and purchase context. Combine Inventory, Orders, and Shipping tables. Join Orders.ProductID to Inventory.ProductID, then add a calculated column for Stock Level (Inventory.Quantity − Orders.Pending). Filter to rows where Stock Level falls below the reorder point for real-time inventory status with reorder alerts. ## Best Practices **Join strategy** * Start with your primary data source * Join only necessary tables * Use indexed fields for joins when possible * Limit joins to 3-4 tables for optimal performance * **Increase warehouse size** for better performance with complex multi-table joins Each join multiplies data processing requirements. More than 4 joins can significantly slow down your views. Consider creating pre-joined summary tables for complex views you use frequently. **Query optimization** * Apply filters before joins when possible * Only display columns you need * Use calculated columns sparingly * Archive old data regularly * **Increase warehouse size** for better performance with large datasets and complex operations **Naming conventions** * Use clear, descriptive table names * Include data source and purpose * Example: `Sales_Pipeline_Q4_2024` **Access control** * Configure appropriate permissions ([Roles and permissions](/administration/roles-permissions)) * Document table purposes and owners * Regular access reviews **Data quality** * Validate join results * Monitor for data inconsistencies * Set up alerts for missing data **View design** * Keep views focused and simple * Group related columns together * Use meaningful column headers * Provide context through descriptions **Performance monitoring** * Track query execution times * Monitor user engagement * Optimize frequently used views ## Related documentation * **[Core concepts](/getting-started/fundamentals/core-concepts)** — How Apps, Elements, Tables, and Tasks work together * **[Data best practices](/data/data-best-practices)** — Choosing structures and organizing shared data * **[Setup CloudLink](/administration/setup-cloudlink)** — Connecting warehouses and CloudLink-backed sources * **[Connect Snowflake to Elementum](/administration/connect-snowflake-to-elementum)** — Snowflake roles, networking, and BI view prerequisites * **[Showing relationships](/data/showing-relationships)** — Relationships between records and join-style modeling * **[Calculations](/data/calculations)** — Formula syntax and functions for calculated columns * **[Data mining](/data/data-mining)** — Triggers and patterns that use table data * **[Analytics](/data/analytics)** — Charts and dashboards in the product * **[Reports](/data/reports)** — Excel and PDF report templates * **[AI Search](/ai-agents/ai-search)** — Enabling search on Tables and Elements Tables and views surface business data in one place: current figures, consistent definitions, and controls that help you keep reports accurate as sources change. # Authentication Source: https://docs.elementum.io/edk/authentication Sign in to Elementum, understand profiles, and select the correct organization workspace. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. The EDK separates authoring from authentication. The TypeScript SDK is credential-free and never calls the platform. The managed `elementum` toolchain owns sign-in and all authenticated platform operations. ## What a profile selects A profile is a locally saved authentication configuration for one Elementum target. It identifies: * The Elementum instance * The organization * An optional organization environment * Credentials and any custom endpoints Use clear names such as `acme-dev` or `acme-prod` when you work with more than one target. Leave the environment blank to target the organization's primary production environment. For a URL such as `development-acme.eu.elementum.io`, select the `EU` instance, enter `acme` as the organization, and enter `development` as the environment. The environment is saved as part of the named profile and reused whenever that profile is selected. It does not affect other profiles. When multiple profiles target the same instance and organization, provide `--profile ` explicitly so the CLI uses the intended environment. ## Sign in Create a named profile: ```bash theme={null} elementum auth login --profile ``` Follow the interactive prompts to select the instance and organization and provide the requested credentials. Do not commit client secrets, tokens, or other authentication material to the workspace. ### Create OAuth credentials `auth login` asks for a Client ID and Client Secret from an OAuth token: 1. Open your user profile from the bottom-right corner of the Elementum platform. 2. Select **OAuth** in the left navigation. 3. Click **Create New Token**. 4. Enter a name and expiration period, then enable **CLI Access**. 5. Click **Generate Token**. 6. Copy the Client ID and Client Secret into the matching terminal prompts. **CLI Access** is the only token access required for EDK commands. Leave **API Access**, **Read Only Access**, **Agents Execute Access**, and **SCIM Access** disabled unless another workflow explicitly requires them. This follows least privilege and avoids granting the token access to unrelated API, agent-execution, or user-provisioning capabilities. The Client Secret appears only when you create the token. Store it securely; if you lose it, generate a new token. Confirm the saved target: ```bash theme={null} elementum --profile auth status ``` Review the reported instance, organization, and environment before bootstrapping a workspace. ## Manage saved profiles Use the authentication commands to inspect or change locally saved profiles: ```bash theme={null} elementum auth list elementum auth switch elementum auth rename elementum auth logout --profile ``` `auth switch` changes the active profile used by platform commands that do not receive an explicit profile. It does not override the workspace safety checks described below. For a trusted non-interactive shell, `elementum auth env` prints `ELEMENTUM_*` export statements for the active profile. Because that output includes credentials, do not write it to logs, commit it, or store it as a build artifact. Prefer your CI system's secret store and workload identity where available. ## Bootstrap with an explicit profile The first organization pull must know where to create the workspace. Run it from the package workspace with an explicit profile: ```bash theme={null} elementum --profile pull org --data-only ``` This creates a marked organization workspace at `//`. Enter it and converge the local setup: ```bash theme={null} cd / elementum init ``` Use an explicit profile whenever no organization workspace exists yet. You should also provide one when multiple saved profiles could match the same instance and organization, or when reproducibility requires a named target. ## Automatic profile selection Inside a marked organization workspace, `plan` and `apply` read the `/` identity from the workspace path. If exactly one saved profile matches, the CLI selects it automatically: ```bash theme={null} elementum plan elementum apply ``` Instance and organization matching is case-insensitive, so a workspace such as `Dev/Sanofi` can match a profile for `dev/sanofi`. If the actual names do not match, the error identifies the conflict and may suggest renaming the local workspace folder. The target can be the organization root or a nested path under `apps/`, `elements/`, or an authored file. A nested target only helps the CLI find the organization root; it does not limit the deployment to that file. If no saved profile matches, or more than one profile has the same workspace identity, the command stops and asks for an explicit profile. An explicit profile also fails if its instance or organization conflicts with the workspace path. Automatic selection is based on the marked organization workspace, not shell variables. Always resolve an ambiguous target explicitly before planning or applying. ## Work safely across targets Keep each organization under its own `/` folder. Before a sensitive operation: 1. Confirm the terminal is inside the intended organization workspace. 2. Run `elementum auth status` when automatic selection is unambiguous, or check the intended named profile explicitly. 3. Review the complete EDK plan before applying. Authentication selects the organization and environment that EDK reads or changes. It does not replace Elementum's separate cross-environment promotion workflow. See [Plan and Apply](/edk/plan-and-apply) for that boundary. # Authoring Source: https://docs.elementum.io/edk/authoring Pull existing Elementum solutions, edit typed source safely, and validate changes before planning. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. EDK authoring starts from the current deployed definition. Pull it into an organization workspace, edit the reconstructed TypeScript, and validate the complete workspace before reviewing a deployment plan. Read the [EDK overview](/edk/getting-started) first. An organization workspace must contain the files created by `elementum pull org --data-only` before you pull other entities. The examples below assume you are working inside an organization workspace with one matching saved profile. See [Authentication](/edk/authentication) if the target is ambiguous. ## Start from the Deployed Definition Use a stable namespace, name, or handle supported by the pull command rather than copying platform IDs into authored source. First confirm that your profile points to the intended organization: ```bash theme={null} elementum auth status elementum list apps elementum list elements elementum list tables ``` Refresh organization-level references, then pull the object you intend to edit: ```bash theme={null} elementum pull org --data-only elementum pull app # Pull referenced Apps and Elements too: elementum pull app --with-dependencies # Other organization roots: elementum pull element elementum pull table elementum pull task ``` `pull app` reconstructs the App, its fields, and supported app-owned entities. `pull element`, `pull table`, and `pull task` reconstruct their supported children and references. Each command regenerates the applicable catalogs and automatically adopts existing resources into deployment state. Use plain `elementum pull org` when you also want editable organization resources such as categories and groups in `organization.ts`. The `--data-only` form refreshes lookup bags in `org.ts` without managing those resources. `elementum pull automation ` is a targeted recovery command for one app-owned Automation. Normal App pulls remain the primary way to reconstruct a complete App. ### Automatic adoption Normal pulls automatically connect the exported resources to the workspace's deployment state. This process verifies all of the following before it succeeds: * The expected resources are imported. * The adoption would create, update, or destroy nothing. * A follow-up plan is clean. These checks prevent an existing deployed object from being mistaken for a new one. Use `--no-adopt` only when you intentionally need source without binding it to this workspace. Pull commands write one JSON summary to standard output. Review its diagnostics and skipped items. If the summary reports a part of the solution that the EDK cannot reconstruct, do not assume that part is managed by the generated source. ## Understand the Workspace An organization workspace has this core structure: ```text theme={null} // ├── org.ts ├── organization.ts ├── generated/ │ └── catalog.ts ├── apps/ │ └── / │ ├── .ts │ ├── agents/ │ ├── automations/ │ ├── skills/ │ ├── visual-flows/ │ └── ... ├── elements/ │ └── / │ ├── .ts │ ├── search-tables/ │ └── ... ├── tables/ │ └── / │ ├── .ts │ └── search-tables/ ├── tasks/ │ └── / │ └── .ts ├── backend.tf # optional user-owned backend declaration ├── terraform.tfstate # local compatibility state when no backend is declared └── .tf/ ├── in/ └── out/ ``` Each path has a specific owner: * `organization.ts` contains editable organization resources pulled by plain `pull org`. * `apps/`, `elements/`, `tables/`, and `tasks/` contain editable source. * `org.ts` contains organization reference tokens, such as CloudLinks and connectors. Refresh it with `pull org --data-only`; do not edit it. * `generated/catalog.ts` is a generated barrel over authored entities. Its `@catalog` alias provides typed cross-entity references. Do not edit it. * `.tf/in/` contains temporary pull input. Pull commands own it. * `.tf/out/` contains generated deployment configuration. `elementum build` owns it. * Deployment state binds authored labels to deployed objects. Do not hand-edit it. Do not commit `.tf/` or `.terraform/`. A workspace without `backend.tf` uses the root `terraform.tfstate` compatibility mode. Shared workspaces and CI should use a committed, non-secret `backend.tf` with verified state locking; backend credentials belong in the backend's environment or workload identity, not in source. ## Author Typed Source Import builders from public EDK package subpaths and cross-entity references from `@catalog`: ```ts theme={null} import { app } from "@elementumai/edk/app"; import { element } from "@elementumai/edk/elements"; import { actions, automation, onDemand } from "@elementumai/edk/automations"; import { agent } from "@elementumai/edk/agents"; import { skill } from "@elementumai/edk/agents/skills"; import { organization } from "@elementumai/edk/organization"; import { table } from "@elementumai/edk/tables"; import { task } from "@elementumai/edk/tasks"; import { visualFlow } from "@elementumai/edk/visualFlows"; import catalog from "@catalog"; ``` Ownership is explicit: * Organization resources live in `organization.ts`; Tables and standalone Tasks live at the organization root. * Apps own Agents, platform agentic Skills, Approval Processes, Visual Flows, and app-owned Automations. * Elements and Tables can own Search Tables; Apps cannot. * Apps and Elements can own File Readers. Typical references include: ```ts theme={null} catalog.support catalog.support.fields.status catalog.support.automations.notifyOwner catalog.aiProviders.anthropic.models.claudeHaiku_4_5 ``` Use names and typed tokens in authored source. Do not paste UUIDs into TypeScript. If a reference is missing, refresh organization references or pull the owning App instead of guessing an identifier. Identity follows the source structure: * The App or Element directory and root filename supply its source ref. * An app-owned file's stem supplies that entity's ref. * A field's key in `fields` is its stable authored identity; `name` is its display label. Changing a display name is different from changing a file stem, namespace, handle, or field key. Treat the latter as an identity change and review any replacement or removal in the plan. Preserve unrelated pulled fields, layouts, list views, and child entities. Build diagnostics may identify options that cannot be represented safely. Resolve or report those diagnostics; do not silence them with casts, guessed tokens, or generated-file edits. ## Scaffold New Source Create new authoring files without contacting the platform: ```bash theme={null} elementum new app \ --name "Support Tickets" \ --namespace support \ --category "Operations" elementum new element \ --name "Locations" \ --namespace locations \ --category "Operations" elementum new automation --app supportTickets --name "Assign New Ticket" ``` `new app` and `new element` register their catalog references immediately. Use `elementum new agent` or `elementum new skill` for other app-owned authoring files. Run `elementum generate` after hand edits that change the catalog surface, such as adding an Automation output or copying an authoring file: ```bash theme={null} elementum generate elementum generate apps/support ``` Do not hand-edit `generated/catalog.ts`. The `new automation` and `pull automation` commands support app-owned Automations only; element-owned Automation authoring is not yet supported. Some Automation trigger and action kinds are reported but skipped during pull, and dynamic picklist filtering and sorting are not supported on the build/pull path. Treat the pulled TypeScript as the authoritative authoring surface for each EDK-managed object. Coordinate platform UI edits with the team and pull again before continuing in code; simultaneous edits can produce unexpected plan changes. ## Validate in Order Run each layer separately from the organization workspace: ```bash theme={null} npx tsc --noEmit elementum plan ``` 1. `tsc` checks the authored TypeScript and typed references. 2. `plan` builds the current source, then compares the complete workspace with the state and target environment. `plan` does not replace the standalone TypeScript check. It also does not deploy an individual file when you pass a nested path; the path locates the organization root, and the complete workspace is planned. Run `elementum build` separately only when you want to generate and inspect `.tf/out/` without contacting the platform. Review every create, update, replacement, and removal before running `elementum apply`. Stop if the plan contains an unexplained replacement, removal, or recreation of an object that already exists. ## Work with the Authoring Agent When you delegate EDK work to a coding agent, provide: * The business outcome and affected personas. * The profile, organization workspace, and App or Element namespace. * The source that must remain unchanged. * Required dependencies, available models, and expected automation publication behavior. * A requirement to pull before editing and preserve existing identities. * A requirement to run `tsc` and `plan` before applying. * A clear approval boundary for `apply`. Ask the agent to explain diagnostics and every planned lifecycle action in business terms. A clean plan is still subject to your review before apply. # CLI Reference Source: https://docs.elementum.io/edk/cli-reference Reference for the main `elementum` commands used to set up, author, review, and apply EDK changes. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. The `elementum` CLI combines EDK workspace commands with platform commands supplied by the managed toolchain. This page lists the current top-level command surface. Add `--help` to any command or subcommand for its arguments and options. ## Get help ```bash theme={null} elementum --help elementum --help elementum --help elementum --version ``` Platform commands are loaded dynamically and may vary by toolchain version. The output of `elementum --help` is the source of truth for your installed version. ## Global options | Option | Purpose | | --------------------- | ---------------------------------------------------------------------------------------------------------- | | `--profile ` | Use a specific authentication profile. Optional when the organization workspace matches one saved profile. | | `-V`, `--version` | Print the installed CLI version. | | `-h`, `--help` | Print help for the current command. | ## EDK commands These commands manage the installed toolchain and local EDK workspaces. | Command | Purpose | | ----------- | ------------------------------------------------------------------------------------------------- | | `init` | Check and converge the managed installation and current workspace. | | `update` | Update the installed Elementum compatibility train. | | `migrate` | Run explicit workspace migrations for backends or provider sources. | | `list` | List Apps, Elements, users, groups, categories, CloudLinks, AI providers, Automations, or tables. | | `pull` | Pull deployed objects into editable EDK source. | | `clone` | Clone a deployed App as a new local entity. | | `build` | Generate deployment configuration offline. `plan` and `apply` run this automatically. | | `generate` | Regenerate catalog files from the current authoring source. | | `plan` | Build the workspace and preview EDK changes. | | `apply` | Build the workspace and apply reviewed EDK changes. | | `new` | Scaffold a new App, Element, Automation, Agent, or agentic Skill authoring file. | | `canvas` | Open an offline workspace explorer or entity preview. | | `playbooks` | Install, update, list, and inspect coding-agent playbooks. | | `help` | Print help for a command. | ## Common EDK subcommands ### Pull existing source | Command | Purpose | | ------------------------------------------ | ------------------------------------------------------------------------------------ | | `pull org --data-only` | Refresh organization lookup bags in `org.ts`. | | `pull org` | Pull editable organization resources into `organization.ts` and refresh lookup bags. | | `pull app ` | Pull an App and its supported children with automatic adoption. | | `pull app --with-dependencies` | Also pull referenced Apps and Elements not yet in the workspace. | | `pull element ` | Pull an Element and its supported children with automatic adoption. | | `pull table ` | Pull an organization-owned Table with automatic adoption. | | `pull task ` | Pull a standalone Task with automatic adoption. | | `pull automation ` | Pull one app-owned Automation by UUID for targeted recovery. | Add `--no-adopt` only when you intentionally want source without connecting the existing resources to deployment state. Use `--max-depth ` with `pull app` to limit dependency traversal. ### Scaffold new source | Command | Purpose | | ------------------------------------------------------------------------- | -------------------------------------- | | `new app --name --namespace --category ` | Scaffold an organization-root App. | | `new element --name --namespace --category ` | Scaffold an organization-root Element. | | `new automation --app --name ` | Scaffold an app-owned Automation. | | `new agent --app --name ` | Scaffold an app-owned Agent. | | `new skill --app --name ` | Scaffold an app-owned agentic Skill. | `new app` and `new element` register their `@catalog` references immediately. Run `elementum generate [path]` after hand edits that change catalog-visible source. See [Quickstart](/edk/quickstart) for the core workflow, [Playbooks](/edk/playbooks) for playbook commands, and [Plan and Apply](/edk/plan-and-apply) for reviewing changes. ## Platform commands Platform commands operate against Elementum through the managed toolchain. They are still invoked through the same `elementum` executable. ### Agents and AI | Command | Purpose | | --------------- | --------------------------------------- | | `a2a` | Invoke Agents over the A2A protocol. | | `a2a-skills` | Manage A2A skills. | | `agent-tools` | Manage Agent tools. | | `agents` | Manage Agents. | | `ai-providers` | Manage AI providers. | | `ai-services` | Manage AI services. | | `chat` | Start a conversation with an Agent. | | `conversation` | Analyze Agent conversation performance. | | `interventions` | Manage Automation interventions. | | `skill-tools` | Manage agentic Skill tools. | | `skills` | Manage agentic Skills. | ### Apps and workflows | Command | Purpose | | ----------------- | -------------------------------- | | `app-flows` | Manage App Flows. | | `approvals` | Manage record approvals. | | `apps` | Manage Apps. | | `automations` | Monitor and operate Automations. | | `dynamic-layouts` | Manage typed dashboard layouts. | | `elements` | Manage Elements. | | `fields` | Manage fields. | | `file-readers` | Manage File Readers. | | `layouts` | Manage layouts and stages. | | `objects` | Manage objects. | | `records` | Manage records. | | `search-tables` | Manage AI Search Tables. | | `tasks` | Manage Tasks. | | `views` | Manage object views. | ### Data and integrations | Command | Purpose | | ----------------- | ---------------------------------- | | `cloudlinks` | Manage CloudLinks. | | `datamines` | Manage Datamines. | | `functions` | Manage stored Snowflake functions. | | `phone-providers` | Manage phone providers. | | `phone-services` | Manage phone services. | | `table` | Run table management commands. | | `tables` | Manage tables. | | `vault` | Manage vault entries. | ### Organization and access | Command | Purpose | | ----------------- | ------------------------------------------- | | `access-policies` | Manage object access policies. | | `auth` | Sign in and manage authentication profiles. | | `categories` | Manage categories. | | `deployments` | Manage platform Deployments. | | `environments` | Manage environments. | | `feature-flags` | Manage feature flags. | | `groups` | Manage groups. | | `org` | Run organization-level operations. | | `roles` | Manage object roles and membership. | | `users` | Manage users. | ### Advanced operations | Command | Purpose | | ------------ | -------------------------------------------------------- | | `completion` | Generate shell completion scripts. | | `destroy` | Destroy managed resources using Elementum credentials. | | `graphql` | Execute a raw GraphQL query or mutation. | | `import` | Import resources into state using Elementum credentials. | | `refs` | Show available references from state or the remote API. | | `state` | Run state commands such as `mv`, `list`, and `show`. | # Design with EDK Source: https://docs.elementum.io/edk/design/overview Design Elementum processes and record experiences before implementing them. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. EDK design starts with the work people need to complete, not with fields or page sections. Use the design workflow to define personas, stages, decisions, handoffs, and information hierarchy before implementing the experience. You can complete the design work with Cursor, Claude Code, Cortex Code (CoCo), Claude Cowork, or another coding agent that supports Agent Skills. You do not need to write EDK code. The output is a design brief that a delivery team can review and implement later. Install the `elementum` CLI to access playbooks. Learn how coding-agent playbooks work. ## Map the Process Create a stage matrix for every materially different part of the process: | Question | What to define | | --------------- | --------------------------------------------- | | Persona | Who is responsible at this stage? | | Primary job | What single outcome must that person produce? | | Decision | What must they understand or decide? | | Required inputs | What must they review or edit now? | | Evidence | What supports the decision? | | Primary action | What advances or closes the work? | | Failure path | What blocks, rejects, or returns the work? | Two stages can usually share an experience pattern when they have the same persona, decision, required information, and action. Define a different experience when the person's job changes materially. Keep distinct outcomes such as completed, rejected, cancelled, and retired. Combining them into a generic closed state removes information that reporting and Automations may need. ## Shape the Experience For each distinct stage, decide what the responsible person needs to recognize, review or change, decide, and do next. Keep supporting evidence and history available without letting them distract from the current job. The first view should answer three questions: What is this record? What matters now? What should I do next? See [Record Experiences](/edk/guides/design) for the complete workshop. ## Use a Coding Agent The design playbook uses the open Agent Skills format rather than a Cowork-specific format. You can use it before an EDK workspace exists. Install it in the standard project directory: ### Start with this prompt Paste this into a coding agent with terminal and local-file access. It prepares the design playbook without creating source code, authenticating, or deploying anything. ```text theme={null} Help me prepare a local workspace for designing an Elementum solution. Use the EDK quickstart as the primary setup reference: https://docs.elementum.io/edk/quickstart Please do the following: 1. Create a folder named elementum-solution-design and work inside it. 2. Check whether the elementum CLI is already installed. 3. If it is missing, install it with the official installer: curl -fsSL https://install.elementum.tools | sh 4. Reload the appropriate shell profile if necessary, then verify the CLI with: elementum --version 5. Install the Elementum design playbook in the current project: elementum playbooks install --skill elementum-design --yes 6. Verify that the playbook is installed and current: elementum playbooks status elementum-design 7. Confirm where the playbook was installed and that its SKILL.md is available. 8. Read the elementum-design skill so you are ready to use it next. Do not install Node.js or the TypeScript SDK. Do not authenticate with Elementum, initialize an implementation workspace, create source code, run a plan, or deploy anything. This is only preparation for a design exercise. If an installation command fails, explain the exact failure and ask before using an unrelated installation method or elevated permissions. When setup is complete, summarize the folder, CLI version, playbook status and location, whether you loaded its instructions, and any remaining issue. Then stop and ask what business process I would like to design. ``` If the CLI is already installed, you can install the playbook directly: ```bash theme={null} elementum playbooks install --skill elementum-design --yes elementum playbooks status elementum-design ``` Invoke `/elementum-design` and provide: * The business outcome and process description. * The people involved and their responsibilities. * Current stages, decisions, handoffs, and failure paths. * Existing screenshots, requirements, or user feedback. * Current platform configuration when it is available. Ask the agent to produce the stage matrix, record-experience recommendations, open questions, and a design brief. Make it explicit that the work should remain at the design level and that unsupported assumptions should be flagged. ### Cortex Code (CoCo) CoCo supports Agent Skills in a project-level `.cortex/skills` directory. Copy the design playbook there: ```bash theme={null} elementum playbooks install \ --skill elementum-design \ --copy-to ./.cortex/skills ``` In CoCo, run `/skill list` to confirm the playbook is available. Then ask CoCo to use `elementum-design` for the design task. ## Use Claude Cowork Claude Cowork can run the design workshop before an EDK workspace exists. It is well suited to reviewing process documents, interview notes, screenshots, and requirements and turning them into a structured design brief. Cowork loads skills enabled through your Claude account. It does not automatically load playbooks installed in a local `.agents/skills` directory. Copy only the design playbook into a temporary folder: ```bash theme={null} elementum playbooks install \ --skill elementum-design \ --copy-to ./cowork-skills ``` Create a ZIP with the `elementum-design` folder at its root: ```bash theme={null} cd cowork-skills zip -r elementum-design.zip elementum-design ``` In Claude Desktop for Mac, open **Customize** → **Skills**, select **+** → **Create skill** → **Upload a skill**, upload `elementum-design.zip`, and enable the skill for your account. Start a Cowork session, attach the relevant process material, and ask Claude to use `elementum-design`. Have it identify missing decisions and produce the stage matrix, information hierarchy, record-experience recommendations, open questions, and final design brief. Cowork can produce and refine the complete design brief without an EDK workspace. A delivery team can use that brief to configure Elementum visually or implement it with the EDK. ## Continue the Design Define what each person sees and does. Review scenarios and confirm the design. # Design Validation Source: https://docs.elementum.io/edk/design/validation Review an Elementum process and record-experience design before implementation. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. Design validation confirms that the proposed Elementum solution reflects the real process before a delivery team begins implementation. Walk through the design with process owners, subject-matter experts, and representative users. This review validates the design brief, not a deployed solution. It should expose missing decisions, unclear ownership, unsupported assumptions, and exception paths while they are still inexpensive to change. ## Prepare the Review Bring these materials into the session: * The business outcome and process boundaries. * The persona and stage matrix. * Record-experience and list-view recommendations. * Known policies, access rules, service levels, and reporting needs. * Representative examples, documents, screenshots, or current pain points. * Assumptions, open questions, and capabilities that still need confirmation. Include people who perform the work, not only the people who sponsor or manage it. ## Walk Through Real Scenarios Use realistic examples to tell the story from intake through each outcome: 1. **Typical path:** Ordinary work moves through the expected stages. 2. **Incomplete path:** Required information or evidence is missing. 3. **High-risk path:** Urgent or exceptional facts change the decision. 4. **Return path:** Work is rejected, corrected, and resubmitted. 5. **Ownership path:** Work is reassigned, escalated, or handed to another team. 6. **Terminal paths:** Completed, rejected, cancelled, and other final outcomes remain distinct. At each stage, ask the responsible person to explain what they would notice, decide, update, and do next. If the design brief cannot answer those questions, record the gap. ## Review Each Persona Confirm that every persona can: * Recognize the record and understand why it needs attention. * Find the information needed for the current decision. * Distinguish required work from supporting evidence and history. * Identify the primary action and understand its consequence. * Find and prioritize work across multiple records. * Complete handoffs without relying on knowledge outside the process. Check that sensitive information, edit rights, approvals, and separation of duties match the intended governance model. ## Check Completeness and Feasibility Review the design for: * Clear process boundaries, ownership, entry conditions, and final outcomes. * Defined failure, return, escalation, cancellation, and reassignment paths. * Information with a known source, owner, purpose, and retention need. * Actions with explicit outcomes and required confirmation. * Reporting, service-level, notification, and Automation requirements. * Usability expectations for long, sparse, exceptional, and high-volume work. * Accessibility requirements and expectations across devices and screen sizes. * Platform assumptions marked as confirmed, needs confirmation, or out of scope. A coding agent can help compare the brief with known Elementum capabilities, but it should not invent platform behavior. Route uncertain capabilities to the delivery team for confirmation. ## Record Decisions Update the brief with: * Decisions made during the review. * Requirements that changed and why. * Open questions, owners, and due dates. * Platform capabilities that require a prototype or technical check. * Deferred ideas and explicit out-of-scope items. * Approval from the process owner and affected personas. The design is ready for handoff when the key scenarios are coherent, each persona's job is clear, exceptions have owners, and unresolved assumptions are visible. Return to [Record Experiences](/edk/guides/design) to revise the brief. After implementation, use [Acceptance Testing](/edk/guides/acceptance-testing) to verify the working solution against these scenarios. # Overview Source: https://docs.elementum.io/edk/getting-started Understand how the Elementum Development Kit represents and manages Elementum solutions. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. The Elementum Development Kit (EDK) is a code-first toolkit for representing Apps, Elements, Tables, standalone Tasks, fields, Automations, Agents, platform agentic Skills, Search Tables, File Readers, Visual Flows, Approval Processes, organization resources, and user experiences as reviewable TypeScript source. Use the EDK when you want typed references, source control, coding-agent assistance, and a clear plan before changing an organization. For visual configuration without code, start with [Build an App](/getting-started/build-an-app). ## How the EDK works The EDK has three cooperating layers: * The `@elementumai/edk` SDK provides typed builders and references. It is credential-free and never calls the platform. * The `elementum` CLI manages installation, authentication, pull, build, plan, and apply operations. * EDK state tracks live identities so `plan` can calculate each add, change, replacement, and removal. Authored TypeScript uses names and typed tokens rather than platform UUIDs. Existing objects are pulled by namespace, reconstructed as editable source, and connected to EDK state. Generated catalogs let one entity reference another without copying opaque identifiers. ## Understand the workspace A package workspace can contain one or more organization workspaces: ```text theme={null} / package.json / / org.ts organization.ts tsconfig.json backend.tf # optional; recommended for shared workspaces apps/ elements/ tables/ tasks/ generated/ catalog.ts .tf/ in/ out/ ``` The organization folder is the deployment boundary. Planning from a nested app or file still builds and reviews the full organization workspace. Edit `organization.ts` and authored files under `apps/`, `elements/`, `tables/`, and `tasks/`. Do not hand-edit: * `org.ts`, which is refreshed from organization reference identities * `generated/catalog.ts`, which is regenerated from the authored file tree * `.tf/in/`, which belongs to platform exports * `.tf/out/`, which belongs to `elementum build` ## Start here Set up your first EDK workspace. Install and update the EDK. Sign in and manage profiles. ## Build with the EDK Edit organization resources and solution entities as typed source. Guide coding agents through EDK work. Review and apply EDK changes. ## Design Design processes and record experiences. Define what each person sees and does. Review scenarios and confirm the design. ## Test and troubleshoot Verify complete business outcomes. Diagnose and resolve EDK issues. # Acceptance Testing Source: https://docs.elementum.io/edk/guides/acceptance-testing Test deployed records, files, automations, agents, and complete business journeys. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. User acceptance testing verifies that a deployed solution produces the required business outcome. A successful command or plausible agent response is not enough: persisted records, files, automation executions, tool calls, and user-visible results must agree. The examples use the active profile. See [Authentication](/edk/authentication) if you need to select a different or ambiguous target. Use the `/elementum-uat` coding-agent playbook when you want an assistant to execute and document this workflow. See [Playbooks](/edk/playbooks). ## Define the Test Contract Before creating test data: 1. Confirm the profile, organization, App namespaces, test users, and permitted side effects. 2. Turn each requirement into a test with setup, action, expected observable result, and cleanup. 3. Identify every applicable layer: records, files, automations, agents, tools, conversations, integrations, and the final outcome. 4. Give test records and files a unique run prefix, such as `UAT-20260818-01`. 5. Decide whether cleanup is approved. Never delete data the test did not create. Check the target before continuing: ```bash theme={null} elementum auth status elementum list apps elementum automations list ``` Stop if the profile or App differs from the agreed target. Do not run tests that mutate production data without explicit approval. ## Use a Practical Test Sequence Test from the lowest layer upward. This makes failures easier to locate and prevents an end-to-end test from hiding a basic data or deployment problem. ### 1. Verify records and validation Preview record creation, then create and read back a uniquely named fixture: ```bash theme={null} elementum records create \ -f "Title=UAT-" --dry-run elementum records create \ -f "Title=UAT-" --json elementum records get \ --json ``` Exercise required updates, filters, status changes, relationships, and validation failures. Assert the stored field values after each operation. A zero exit code confirms that the request completed, not that the resulting record is correct. ### 2. Verify files When the solution accepts files, use a representative fixture with the expected type and realistic content: ```bash theme={null} elementum records create \ -f "Title=UAT--file" \ -a "Attachments=./fixture.pdf" --json ``` Read the record back and confirm the attachment is present. Then verify any downstream extraction, classification, automation, or agent behavior that depends on the file. Include unsupported type, empty file, large file, or malformed-content cases when the requirements define how they should behave. ### 3. Verify automations Trigger each automation through its real entry point, such as record creation, record update, an approved on-demand action, or a supported webhook. Inspect the resulting execution: ```bash theme={null} elementum automations status \ "" --latest --timeline elementum automations status \ "" --latest --all-io --json ``` Verify: * The intended trigger selected the execution. * Tasks ran in the expected order. * Each task received the correct inputs and returned the expected outputs. * Record changes and external effects occurred exactly once. * Failure and retry behavior matches the acceptance criteria. * The final business result is correct. ### 4. Verify agents and tools Test an agent with direct requests, missing-information prompts, confirmation or refusal gates, tool selection, multi-turn context, and error recovery: ```bash theme={null} elementum chat "" \ -m "" elementum chat "" \ --continue -m "" elementum conversation "" \ --json ``` For file-aware behavior, attach the same type of fixture used by the real process: ```bash theme={null} elementum chat "" \ -m "" -a ./fixture.pdf ``` For every expected tool call, confirm the selected tool, inputs, result, and resulting record, automation, or external effect. If the agent can access packaged capabilities or delegate to another agent, verify routing and the delegated result independently. Do not infer tool correctness from the final message alone. ### 5. Run the end-to-end journey Run at least one realistic journey across all participating components: 1. Create the initial record or submit the entry action. 2. Attach or generate required files. 3. Complete each user decision or stage transition. 4. Observe automation execution and external effects. 5. Exercise the agent and verify its tool calls where applicable. 6. Read back the final records. 7. Confirm the user-visible business outcome. Use the unique prefix to find the final fixtures: ```bash theme={null} elementum records list \ --where "Title=UAT-" --json elementum interventions list \ --status OPEN --json ``` Pass the journey only when the visible result, stored data, files, executions, conversations, tool calls, and required external effects all match the acceptance criteria. ## Record Evidence For each test, record: * Test ID and requirement. * Fixture and setup. * Commands or user actions. * Expected and actual results. * Record handles, execution identifiers, conversation identifiers, and relevant screenshots. * `PASS`, `FAIL`, or `BLOCKED`. * Cleanup status. Use `FAIL` when the product behavior contradicts the acceptance criterion. Use `BLOCKED` when the environment, permissions, unavailable dependency, or invalid fixture prevented the test from reaching the behavior under review. ## Clean Up Safely Delete only fixtures created by the current run, and only when cleanup was approved: ```bash theme={null} elementum records delete \ --dry-run elementum records delete \ ``` Record any fixture that could not be removed so the environment owner can review it. # Record Experiences Source: https://docs.elementum.io/edk/guides/design Design what each person needs to see and do throughout an Elementum process. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. Record-experience design defines what people need from Elementum at each stage of a process. It connects the process map to the information, decisions, and actions that should shape the eventual solution. This is a design activity for process owners and subject-matter experts. You do not need to write TypeScript or configure Elementum. Use the `/elementum-design` playbook to lead the workshop and capture the result. Complete [Design with EDK](/edk/design/overview) first so the business outcome, personas, stages, and handoffs are clear. ## Define Each Stage For every materially different stage, describe: * **Persona:** Who owns the work now, and who else needs visibility? * **Primary job:** What single outcome must that person produce? * **Decision:** What must the person understand, approve, reject, or resolve? * **Required inputs:** What do they need to see, enter, or update? * **Evidence:** What documents, relationships, history, or prior decisions support the work? * **Primary action:** What should they do next, and what is the consequence? * **Failure path:** What blocks, returns, escalates, or cancels the work? Create a distinct experience only when the person's job changes. A new status alone does not require a different experience if the same person is making the same decision with the same information. ## Shape the Record Experience Describe the experience in layers: 1. **Orientation:** Identity, ownership, stage, urgency, and the few facts needed to understand the record. 2. **Work area:** Information the current person must review or change. 3. **Decision and action:** The primary outcome, action label, confirmation, and possible failure. 4. **Evidence:** Attachments, relationships, findings, approvals, and source material. 5. **History:** Activity and audit detail that should remain available without dominating the work. The first view should answer three questions: What is this record? What matters now? What should I do next? Do not design around every available field. Include information because it supports the current job, decision, evidence, or handoff. Do not repeat information or actions already supplied by the record header. Prefer one clearly labeled primary action for each stage, and never communicate state through color alone. ## Design How People Find Work Record pages support one item at a time. Also define how each person finds and prioritizes multiple records. For each useful list or queue, identify: * The person and repeatable task it supports. * The records that belong in the view. * The fields needed to recognize and prioritize work. * The default order and useful filters. * The empty state and next action. A focused view usually needs an identifier, stage or status, owner, urgency or risk, and one or two process-specific facts. It should support scanning rather than reproduce the entire record. ## Account for Different States Describe how the experience should behave when: * Information is missing, sparse, unusually long, or high risk. * A person can view but not edit particular information. * An action is unavailable, requires confirmation, succeeds, or fails. * Work is reassigned, returned, rejected, cancelled, escalated, or completed. * Related records or evidence are empty, loading, or extensive. These scenarios become design requirements and later acceptance tests. ## Work with a Coding Agent Give the agent the process material and a clear design-only request: ```text theme={null} Use elementum-design to design the record experiences for [process]. Do not write code or configure Elementum. For each persona and stage, define the outcome, decision, required information, evidence, primary action, exceptions, and list-view needs. Identify open questions and assumptions, then produce a design brief for the delivery team. ``` Review the agent's recommendations with the people who perform and own the process. The agent should expose missing decisions and conflicting requirements rather than fill them in without evidence. ## Create the Design Brief The final brief should include: * The business outcome and process boundaries. * Personas, responsibilities, and handoffs. * A stage matrix with primary jobs, decisions, actions, and exceptions. * The record experience and information hierarchy for each distinct stage. * List or queue requirements for each persona. * Required information, evidence, relationships, and history. * Access, governance, reporting, and Automation considerations. * Assumptions, open questions, and platform capabilities that need confirmation. * Representative scenarios for design validation. Describe the intended behavior without prescribing implementation details. The delivery team should decide how to realize the approved design and confirm what the platform supports. Continue with [Design Validation](/edk/design/validation) to review the brief before implementation. # Troubleshooting Source: https://docs.elementum.io/edk/guides/troubleshooting Diagnose workspace, build, deployment, automation, record, and agent failures in a reliable order. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. Troubleshoot from the workspace outward. Confirm the target first, then isolate authoring and deployment failures before investigating records, automations, or agents. This order reduces unnecessary live changes and keeps each conclusion tied to evidence. The examples assume the organization workspace selects one matching saved profile. See [Authentication](/edk/authentication) if the target is ambiguous. Use the `/elementum-debug` coding-agent playbook when you want an assistant to follow this evidence-first sequence. See [Playbooks](/edk/playbooks). Before running commands, capture: * The exact action that failed. * The expected and actual results. * The profile and App namespace. * When the behavior last worked. * Any record, automation execution, or conversation identifier. Do not edit source until the evidence identifies the failing layer. ## 1. Confirm the Profile and Workspace Run from the affected organization workspace: ```bash theme={null} elementum auth status elementum playbooks status ``` Confirm that the profile's instance and organization match the workspace path. If the workspace is new or its generated references may be stale, verify that it was bootstrapped with: ```bash theme={null} elementum pull org --data-only ``` Classify an early failure as one of: * Authentication or permissions. * Profile and workspace mismatch. * Missing workspace setup. * Stale organization references. * Missing or incomplete App or Element source. Pull the affected App or Element before editing an existing deployed object: ```bash theme={null} elementum pull app # or elementum pull element ``` Review pull diagnostics and skipped items. Do not continue as though an unsupported part of the solution is managed by the generated source. List and pull commands paginate through large organizations. Pull writes are transactional, so a failed pull should not leave a partially replaced source tree. Correct the reported cause and rerun the pull rather than repairing generated output manually. ## 2. Isolate Typecheck and Build Run the validation layers separately: ```bash theme={null} npx tsc --noEmit elementum build ``` If typecheck fails: 1. Fix the first causal error rather than every downstream error. 2. Confirm builder imports use public `@elementumai/edk` subpaths. 3. Confirm cross-entity references come from `@catalog`. 4. Refresh the organization or owning entity when an expected catalog token is missing. Run `elementum generate` when hand edits changed catalog-visible source. 5. Do not use a broad cast, guessed token, UUID, or generated-file edit to silence the error. If build fails, use the source path and diagnostic in the output. A build diagnostic can mean that valid TypeScript contains an option the current deployment path cannot represent safely. Remove or change it only when that matches the intended behavior; otherwise report the limitation. Duplicate Agent tool, Skill tool, or A2A Skill names can collide when the complete workspace is assembled. The build error identifies the colliding names and source files; rename one of the authored tools or Skills rather than waiting for plan. Do not edit `org.ts`, `generated/catalog.ts`, `.tf/in/`, or `.tf/out/` to repair a typecheck or build failure. Refresh or regenerate those paths with their owning commands. ## 3. Isolate Plan and Apply After typecheck and build pass: ```bash theme={null} elementum plan ``` Separate: * Authentication or workspace selection failures. * Backend or deployment state failures. * Invalid authored configuration. * An unexplained create, replacement, or removal. * A difference that was authored correctly but has not been applied. If the plan warns that an App or Element exists on disk but has not been adopted, or shows a known deployed object as new, stop. Re-run the appropriate pull without `--no-adopt` to restore the state binding. Do not apply a plan that would recreate known live objects. If a plan succeeds but live behavior is stale, confirm that the intended plan was applied and that any required automation revision or publication change was included. Never apply a speculative fix. Review the plan and obtain approval first. After an approved apply, run a fresh plan and confirm that no unintended changes remain. ## 4. Inspect Records and Automations When deployment is current, inspect live data: ```bash theme={null} elementum records list \ --limit 10 --json elementum interventions list \ --status OPEN --json ``` Compare the stored record with the expected trigger inputs and final business result. Confirm field values, status or stage, relationships, files, and validation behavior. For an automation failure, begin with the execution timeline: ```bash theme={null} elementum automations status \ "" --latest --timeline ``` Then inspect only the failed action: ```bash theme={null} elementum automations status \ "" --latest-failure --io "" --json ``` Compare the trigger data, action input, action output, persisted record state, and expected business outcome. Expand to the complete input and output report only when the failing boundary remains unclear: ```bash theme={null} elementum automations status \ "" --latest --all-io --json ``` This sequence distinguishes a trigger problem from an action problem, a persistence problem, or a downstream integration problem. ## 5. Inspect Agents and Tools Reproduce an agent failure with one minimal turn: ```bash theme={null} elementum chat "" \ -m "" elementum conversation "" \ --json ``` Determine which layer failed: * Routing to the intended agent or capability. * Agent instructions or confirmation boundaries. * Tool selection. * Tool inputs. * The automation or service behind the tool. * Returned data. * Interpretation of the result in the final response. * Multi-turn context. If a file is involved, reproduce with the same file type and a representative size by adding `-a `. Verify the tool call and its effect independently; a reasonable final response does not prove that the correct tool ran. When an agent delegates work, inspect the delegated result separately from the parent agent's use of that result. ## Verify the Fix State one evidence-backed root cause and the smallest layer that owns it. After changing source, rerun: ```bash theme={null} npx tsc --noEmit elementum plan ``` `plan` builds the current source automatically. After an approved apply, repeat the original record, automation, or conversation reproduction. Add one adjacent regression check that could have been affected by the fix. Report: * Root cause and owning layer. * Evidence used to reach the conclusion. * The change made. * Validation and live verification results. * Any remaining uncertainty or untested boundary. # Installation Source: https://docs.elementum.io/edk/installation Install and maintain the Elementum CLI, TypeScript SDK, and coding-agent playbooks. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. The EDK includes two separately installed parts: * The `elementum` CLI is a signed toolchain for authentication, pulling, building, planning, and applying. * `@elementumai/edk` is the credential-free TypeScript SDK used by your workspace. Use Node.js 24 or newer. The CLI supports macOS on Apple Silicon or Intel and Linux x64 with glibc. On Windows, run the Linux x64 toolchain inside WSL2. The TypeScript SDK runs anywhere Node.js 24 or newer runs. ## Install the CLI Run the installer: ```bash theme={null} curl -fsSL https://install.elementum.tools | sh ``` The installer places `elementum` in `~/.elementum/bin` and updates your shell profile. Open a new terminal after installation, or reload the applicable profile. Then initialize and verify the managed toolchain: ```bash theme={null} elementum init elementum --version ``` `elementum init` is idempotent. It checks the installed compatibility train, authentication, SDK version and namespace, workspace layout, and provider identity. It does not sign you in or migrate deployment state. ## Install on Windows with WSL2 Use an x64 Ubuntu 22.04 or 24.04 distribution. ARM64 WSL and Alpine or other musl-based distributions are not supported. Install Ubuntu once from an elevated PowerShell or Windows Terminal: ```powershell theme={null} wsl --install -d Ubuntu ``` After any required restart, open Ubuntu and install the prerequisites, Node.js, and the CLI: ```bash theme={null} sudo apt update sudo apt install -y curl tar gnupg ca-certificates curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash - sudo apt install -y nodejs curl -fsSL https://install.elementum.tools | sh source ~/.bashrc elementum init --check ``` Keep EDK workspaces on the Linux filesystem, such as `~/elementum-workspace`, rather than under `/mnt/c/`. In VS Code or Cursor, install the WSL extension and select **Reopen Folder in WSL** so the editor, Node.js, auth profiles, and `elementum` CLI all run inside Ubuntu. ## Install the SDK and TypeScript Create a package workspace that will contain your Elementum organization folders: ```bash theme={null} mkdir elementum-workspace cd elementum-workspace npm init -y npm install @elementumai/edk npm install --save-dev "typescript@^6" ``` The SDK does not contain credentials and does not call the Elementum platform. Authenticated operations run through the CLI toolchain. ## Install coding-agent playbooks Install the bundled playbooks into the current project: ```bash theme={null} elementum playbooks install --yes elementum playbooks status ``` The default destination is `./.agents/skills`. Add `--global` to install under `~/.agents/skills`, or use `--copy-to ` for a specific Agent Skills directory. See [Playbooks](/edk/playbooks) for selective installation and inspection commands. ## Verify the installation Run these checks from your package workspace: ```bash theme={null} elementum init --check elementum playbooks status npx tsc --version ``` After you [authenticate and create an organization workspace](/edk/authentication#bootstrap-with-an-explicit-profile), run `elementum init` again from that organization folder to converge its local scaffolding. ## Update the toolchain Check for an available compatibility train without changing the installation: ```bash theme={null} elementum update --check ``` Update to the current stable toolchain: ```bash theme={null} elementum update ``` Use `elementum update --dry-run` to download and verify an update without activating it. After an update, run: ```bash theme={null} elementum init --check elementum playbooks status ``` If a playbook is stale, reinstall it from the updated toolchain with `elementum playbooks install --yes`. ## Next steps Sign in and create an organization workspace in [Authentication](/edk/authentication), then review the complete workflow in the [EDK overview](/edk/getting-started). # Plan and Apply Source: https://docs.elementum.io/edk/plan-and-apply Review, apply, and recover EDK changes. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. The EDK compares authored TypeScript with state and the live Elementum target, then shows the changes required to make them match. ## Plan and apply workflow Run the workflow from the marked `/` workspace: ```bash theme={null} npx tsc --noEmit elementum plan elementum apply elementum plan ``` Each command has a distinct purpose: 1. `npx tsc --noEmit` checks TypeScript without generating JavaScript. 2. `elementum plan` builds the current source, then previews the EDK changes for the selected Elementum target. 3. `elementum apply` builds again, then applies the reviewed changes. 4. A final `elementum plan` should report no changes. You do not need to run `elementum build` before `plan` or `apply`. Use it when you want to generate and inspect `.tf/out/` without contacting the platform. Use `--skip-build` only when you deliberately want `plan` or `apply` to use the existing `.tf/out/` output. ## Review the complete workspace `plan` and `apply` always operate on the full organization workspace. You can pass the organization root or any nested path: ```bash theme={null} elementum plan elementum plan apps/intake/intake.ts ``` The nested path only helps locate the marked organization root. It does not limit the plan to one App, Element, or file. Before applying, account for every reported operation: * **Add** creates a resource that is configured but not bound in state. * **Change** updates a resource in place. The plan may instead report a replacement when the changed property cannot be updated. * **Destroy** removes a resource that remains in state but is absent from the built configuration. Unexpected replacements and destroys are blockers. Resolve them before applying. ## Apply and confirm the result Apply only the plan you reviewed: ```bash theme={null} elementum apply ``` Then plan again: ```bash theme={null} elementum plan ``` A converged workspace produces a zero-change plan. If the EDK still proposes changes, do not repeatedly apply. Compare the remaining diff with the authored source, generated diagnostics, selected profile, and backend binding. ## Backend and state Behind the EDK workflow, OpenTofu state provides the durable mapping between authored labels and live Elementum objects. Losing or using the wrong state can make existing objects appear new. For compatibility, an organization workspace without `backend.tf` uses a committed root `terraform.tfstate` through a generated local backend. This supports a single-author workspace but does not provide locking. Avoid concurrent plans or applies. Shared workspaces and CI should commit a non-secret `/backend.tf` that declares a remote backend with verified locking. During build, the EDK copies that declaration to `.tf/out/backend.tf`. The backend locks state during plans, applies, pulls, renames, and repairs. Never commit: * `.tf/` or `.terraform/` * Backend credentials * Saved plan files * Recovery snapshots Keep credentials in the backend's normal environment or workload-identity chain. EDK does not provision backend infrastructure and does not accept secrets in `backend.tf`. ## Migrate or recover state Use the guarded migration command when moving local state to a declared remote backend or changing remote backends: ```bash theme={null} elementum migrate backend --check elementum migrate backend --dry-run elementum migrate backend --auto-approve elementum plan ``` The migration creates an ignored recovery snapshot, verifies the result, and requires a final zero-change plan. Follow the exact rollback instructions printed if it fails. If state is lost, do not run `apply`. The EDK can interpret live resources as new and attempt to create duplicates. Restore the recovery snapshot when available. Otherwise, refresh organization references and re-pull each existing managed root: ```bash theme={null} elementum --profile pull org --data-only cd / elementum pull app elementum pull element elementum pull table elementum pull task ``` Pull verifies the expected state bindings and requires a clean follow-up plan without changing the live resources. ## Apply versus environment promotion `elementum plan` and `elementum apply` reconcile authored source with the organization and environment selected by authentication. They do not perform Elementum's cross-environment promotion workflow. After testing an EDK change in a lower environment, use the platform promotion workflow to move it to another environment. If the promotion reports missing environment configuration, the `/elementum-deployments` playbook can review and configure it from the admin URL or `asyncTaskId`. See [Authentication](/edk/authentication) for target selection and [Playbooks](/edk/playbooks) for the promotion and UAT playbooks. # Playbooks Source: https://docs.elementum.io/edk/playbooks Install and inspect the five coding-agent playbooks bundled with the Elementum toolchain. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. The EDK bundles five coding-agent playbooks. Each follows the Agent Skills convention: a directory with a `SKILL.md` file and, when needed, supporting references or templates. A compatible coding assistant loads the relevant playbook to follow current EDK workflows and safety rules. ## Understand the terminology These three concepts are different: * A **coding-agent playbook** guides a coding assistant. Manage it with `elementum playbooks`. * A **platform agentic skill** is an app-owned Elementum component authored with `skill`. Manage platform operations through the `elementum skills` command family. * An **A2A skill** is a capability descriptor on an agent's A2A card so other agents can discover that capability. Coding-agent playbooks do not run inside an Elementum agent. ## Available playbooks * `/elementum` handles workspace setup, authoring, pull, build, plan, and apply across Apps, Elements, Tables, Tasks, organization resources, and their supported child entities. * `/elementum-uat` tests a deployed solution from records and automations through agents, tools, and complete business outcomes. * `/elementum-debug` diagnoses workspace, build, deployment, automation, tool, and agent failures from evidence. * `/elementum-deployments` configures and verifies platform cross-environment promotion when a deployment URL or `asyncTaskId` is provided. * `/elementum-design` helps process owners map stages, personas, decisions, information, and record experiences. Delivery teams can continue with the same playbook for EDK layouts, list views, responsive behavior, accessibility, and browser verification. See [Design with EDK](/edk/design/overview) for coding-agent and Claude Cowork workflows. ## List bundled playbooks Show every bundled playbook, its description, and installation status: ```bash theme={null} elementum playbooks list ``` Use `elementum playbooks list --json` when another tool needs a machine-readable catalog. ## Install or update playbooks Install all bundled playbooks in the current project: ```bash theme={null} elementum playbooks install --yes ``` By default, files are installed under `./.agents/skills`. Common alternatives are: ```bash theme={null} # Install all playbooks for the current user elementum playbooks install --global --yes # Install selected playbooks elementum playbooks install --skill elementum elementum-debug --yes # Copy selected playbooks to an agent-specific directory elementum playbooks install --skill elementum --copy-to ``` Without `--yes`, the command reports the destination and prints the command to confirm. Re-running installation replaces the selected installed copies with the versions bundled in the current toolchain. ## Check status Compare installed versions with the bundled versions: ```bash theme={null} elementum playbooks status elementum playbooks status elementum-debug ``` The result identifies playbooks that are current, stale, missing, unstamped, or newer than the bundled copy. Update the toolchain before replacing a playbook that is newer than its bundled version. ## Inspect paths and files Print the source path for a playbook, or its embedded identifier when the source is bundled in the standalone CLI: ```bash theme={null} elementum playbooks path elementum playbooks path elementum-uat ``` List every file bundled with one playbook: ```bash theme={null} elementum playbooks files elementum-uat ``` Print the default `SKILL.md` or a named supporting file: ```bash theme={null} elementum playbooks print elementum elementum playbooks print elementum-uat assets/report.md ``` Use these inspection commands when your coding assistant cannot discover a playbook automatically or when you want to review its instructions before use. ## Keep playbooks current The CLI can warn during pull, plan, or apply when the core `/elementum` playbook is missing or stale. After updating the toolchain, refresh the installed copies: ```bash theme={null} elementum update --check elementum playbooks install --yes elementum playbooks status ``` Continue with [Authoring](/edk/authoring) for source conventions or [Plan and Apply](/edk/plan-and-apply) for reviewing and applying EDK changes. # Quickstart Source: https://docs.elementum.io/edk/quickstart Set up an EDK workspace, pull an existing solution, and deploy a small change. **Limited Release.** The EDK is currently in limited release and is not available to all customers. Commands, generated file layouts, and package APIs may change before general availability. Confirm you're on the latest EDK version before starting new projects. This quickstart takes you from an empty local folder to an EDK workspace connected to your Elementum organization. Start in a development or test environment and choose a small existing App or Element for your first change. ## 1. Install the EDK Install the `elementum` CLI: ```bash theme={null} curl -fsSL https://install.elementum.tools | sh ``` Create a Node.js workspace and install the SDK and TypeScript: ```bash theme={null} mkdir elementum-workspace cd elementum-workspace npm init -y npm install @elementumai/edk npm install --save-dev "typescript@^6" ``` See [Installation](/edk/installation) for platform support, updates, and verification. ## 2. Install playbooks Install the bundled playbooks so your coding agent understands the current EDK workflows and conventions: ```bash theme={null} elementum playbooks install --yes elementum playbooks status ``` See [Playbooks](/edk/playbooks) for the available playbooks and management commands. ## 3. Sign in Create a profile for the organization and environment you want to change: ```bash theme={null} elementum auth login --profile elementum --profile auth status ``` Confirm that the reported instance, organization, and environment are correct. See [Authentication](/edk/authentication) for OAuth setup and profile management. ## 4. Create the organization workspace From the Node.js workspace, pull organization references: ```bash theme={null} elementum --profile pull org --data-only ``` The command creates `//` with typed references for items such as CloudLinks, categories, groups, and AI provider connectors. Enter that folder and finish the local setup: ```bash theme={null} cd / elementum init ``` ## 5. Pull something to change List the Apps or Elements available in the organization: ```bash theme={null} elementum list apps elementum list elements ``` Copy a namespace from the output, then pull that App or Element: ```bash theme={null} elementum pull app # or elementum pull element ``` Pulling creates editable TypeScript and connects the existing resources to EDK state without changing the live organization. Add `--with-dependencies` to `pull app` when you also want to pull referenced Apps and Elements that are not yet in the workspace. You can also pull organization-owned Tables with `elementum pull table ` and standalone Tasks with `elementum pull task `. ## 6. Make the change Edit the pulled source under `apps/`, `elements/`, `tables/`, or `tasks/`. Use `@catalog` for typed references to other authored entities. Check the TypeScript before contacting the platform: ```bash theme={null} npx tsc --noEmit ``` TypeScript reports invalid source and references. See [EDK Authoring](/edk/authoring) for workspace ownership, identity rules, and builder imports. ## 7. Plan and apply Review the EDK changes: ```bash theme={null} elementum plan ``` `plan` builds the current source automatically. Review every add, change, replacement, and destroy operation. Apply only when the plan matches the change you intended: ```bash theme={null} elementum apply elementum plan ``` The final plan should report no changes. This confirms that the source, state, and live organization agree. See [Plan and Apply](/edk/plan-and-apply) for shared backends, recovery, and cross-environment promotion. # Best Practices Source: https://docs.elementum.io/getting-started/best-practices Essential patterns and strategies for building effective Elementum workflows Master the art of building effective workflows with these proven patterns and strategies. This guide covers the essential principles that separate good Elementum implementations from great ones. **New to Elementum?** Start with [Getting Started](../getting-started/quickstart) to understand the basics before diving into these advanced practices. ## Core Objects Overview Understanding Elementum's core objects is fundamental to building effective workflows. Each object serves a specific purpose and excels in particular scenarios. Elementum's core objects fall into two categories: * **Process-oriented objects** (Services, Apps, Tasks) - For structured workflows and processes * **Data-oriented objects** (Elements, Tables, Surveys) - For data management and collection ### Services Services icon **Best for:** Customer support, help desk, and request portals * Creating user-facing portals for request submission * Automatically generating App records from submissions * Standardizing intake processes across teams * Providing self-service capabilities to end users **Example Use Cases:** * IT helpdesk portal * Employee onboarding requests * Customer support ticket system * Equipment request portal ### [Apps](/getting-started/build-an-app) Apps icon **Best for:** Tracking individual business processes and work items * Managing unique work items that progress through stages * Tracking complex business processes with multiple stakeholders * Coordinating work that spans multiple departments * Maintaining audit trails for compliance **Example Use Cases:** * Contract approval workflows * Employee onboarding processes * Customer implementation projects * Compliance audits ### Tasks Tasks icon **Best for:** Breaking down work into manageable, assignable activities * Decomposing complex Apps into smaller activities * Assigning specific work to individual team members * Creating parallel workstreams within larger processes * Tracking progress on detailed work items **Key Principles:** * Tasks should be specific and actionable * Assign clear ownership and deadlines * Use Tasks to create accountability within larger workflows * Complex Apps often require multiple related Tasks ### [Elements](/getting-started/fundamentals/core-concepts#data--elements) Elements icon **Best for:** Managing structured data with unique identifiers * Storing configuration, master, or transactional data * Managing data that needs unique identification * Creating relationships between different data types * Building searchable, updateable data repositories **Requirements:** * Each record must have a unique identifier * Data structure should be relatively stable * Updates need to be tracked and auditable ### [Tables](/data/tables) Tables icon **Best for:** Data analysis, reporting, and automation triggers * Joining and manipulating Elementum objects for insights * Accessing Snowflake data without primary key requirements * Powering Data Mines for automation workflows * Creating complex analytical views **Advantages:** * Unique Identifiers not required (unlike Elements), allowing for duplicates if needed * Effective for aggregations and analytics * Essential for automation triggers ### [Surveys](/workflows/survey-system) **Best for:** Collecting structured feedback and responses * Gathering feedback from internal and external users * Collecting parallel responses from multiple stakeholders * Linking feedback directly to App records * Creating standardized data collection processes **Best Practices:** * Design questions to minimize ambiguity * Link Surveys to relevant Apps for context * Use conditional logic to improve user experience * Plan for data analysis during survey design ## Implementation Strategies ### Object Selection Framework Follow this decision tree to choose the right object for your needs: * Need to track work through stages? → **Apps + Tasks** * Need to gather information? → **Surveys + Elements** * Need to analyze or report? → **Tables + Data Mines** * Need user self-service? → **Services** * **Unique identifiers needed?** → Elements * **No unique ID required?** → Tables * **User input required?** → Surveys * **Process tracking needed?** → Apps * Link Surveys to Apps for process feedback * Connect Tasks to Apps for work breakdown * Relate Elements to Apps for contextual data * Use Tables to join multiple object types for analysis ### Building Effective Relationships Strategic relationships between objects unlock Elementum's full potential: **Service → App → Tasks** Creates complete workflow from request to completion **Survey → App → Elements** Connects feedback to processes and reference data #### Relationship Best Practices **Avoid Over-Engineering:** Don't create relationships just because you can. Each relationship should serve a clear business purpose. * **Hierarchical Relationships:** Use parent-child relationships for natural hierarchies * **Reference Relationships:** Link to Elements for master data lookups * **Process Relationships:** Connect workflow stages through Apps and Tasks * **Contextual Relationships:** Link Surveys to Apps for process-specific feedback ## Performance Optimization ### Query Performance * Use meaningful unique identifiers * Index frequently searched fields * Minimize complex calculated fields * Regular cleanup of outdated records * Leverage Snowflake table types * Use efficient [Data Mine](/data/data-mining) queries * Implement proper data partitioning * Monitor query performance regularly ### Data Architecture * Plan for data growth from day one * Use appropriate object types for your data volume * Consider [Snowflake warehouse configuration](/administration/snowflake-warehouses) early * Avoid deep relationship chains (>3 levels) * Use reference relationships instead of duplicating data * Regular relationship cleanup and validation * Regular performance reviews * Optimize slow-running [Data Mines](/data/data-mining) * Clean up unused objects and relationships ## Security and Governance ### Access Control **Security First:** Plan your access control strategy before building complex workflows. * **Role-Based Access:** Align Elementum roles with organizational structure * **Data Sensitivity:** Classify data and apply appropriate restrictions * **Workflow Permissions:** Control who can view, edit, and approve at each stage * **Audit Trails:** Maintain complete records of all changes and approvals ### Governance Framework **Establish consistent naming patterns:** * Apps: `[Department]_[Process]_[Year]` * Elements: `[Type]_[Category]_[Identifier]` * Tasks: `[Action]_[Object]_[Stage]` * Surveys: `[Purpose]_[Audience]_[Version]` **Maintain clear documentation:** * Purpose and scope for each workflow * Role definitions and responsibilities * Process diagrams and flowcharts * Regular updates and reviews **Control modifications carefully:** * Test changes in development environments * Document all modifications * Communicate changes to affected users * Maintain rollback procedures ## Common Pitfalls to Avoid **Critical Mistakes That Can Break Your Implementation** ### Object Misuse **Problem:** Choosing Tables when Elements are needed, or vice versa **Solution:** * Use Elements when you need unique identifiers and data integrity * Use Tables for analysis and reporting without unique constraints * Use Apps for process tracking, not just data storage **Red Flags:** * Multiple "Tables" that should be related Elements * Apps with no associated Tasks or workflow * Elements being used purely for analytics ### Over-Engineering **Problem:** Building elaborate relationship networks that slow performance **Solution:** * Keep relationship chains under 3 levels deep * Document the business justification for each relationship * Regular reviews to eliminate unused connections **Red Flags:** * Relationships that require multiple hops to access data * Circular references between objects * Relationships created "just in case" ### Poor Data Design **Problem:** Not considering how data volume will impact performance **Solution:** * Plan for 10x current data volume * Implement archiving strategies early * Use appropriate Snowflake table types (see [Snowflake Table Types](/administration/snowflake-table-types)) **Red Flags:** * No data retention policies * Single large tables without partitioning * No performance monitoring in place ## Success Metrics Track these key indicators to measure your Elementum implementation success: ### Process Efficiency * Average time from request to completion * Percentage of on-time deliveries * User satisfaction scores * Error rates and rework frequency ### System Performance * Query response times * Data Mine execution duration * User adoption rates * System uptime and reliability ## Next Steps Ready to implement these best practices? Here's your roadmap: * Review existing workflows against these best practices * Identify quick wins and improvement opportunities * Plan your optimization roadmap * Start with [data best practices](/data/data-best-practices) * Optimize your [CloudLink setup](/administration/connect-snowflake-to-elementum) * Configure proper [table types](/administration/snowflake-table-types) and [warehouses](/administration/snowflake-warehouses) * Implement advanced automation with Data Mines * Build comprehensive governance frameworks * Monitor and continuously improve performance Deep dive into data management and optimization Optimize your data connectivity and performance *** *This guide is regularly updated based on customer feedback and new Elementum features. Last updated: * # Build an App Source: https://docs.elementum.io/getting-started/build-an-app A step-by-step walkthrough for creating your first Elementum app, from initial setup through testing and launch. Apps are the foundation of everything you build in Elementum. Each app is a self-contained workspace that organizes your data, workflow logic, automations, and user permissions around a specific business process. This guide walks you through creating one from scratch using a **Vendor Onboarding** app as a running example. This guide expands on the steps introduced in [Getting Started](./quickstart). If you haven't reviewed it yet, start there for a high-level overview. ## Before You Begin Make sure you have the following in place: * An active Elementum account with permission to create apps * At least one [CloudLink](/administration/setup-cloudlink) data source configured in your organization * A clear understanding of the business process you want to model Sketch your process on paper first — identify the stages, the people involved, the data you need, and what should happen automatically. For vendor onboarding, this might mean mapping out the path from initial application through final activation, along with the teams involved at each step. This upfront planning saves significant rework later. ## Step 1: Create the App Navigate to Apps icon **Apps** in your dashboard, click the More icon **More** icon, and select **Create New App**. Fill in the following required fields: 1. **CloudLink** — Choose the CloudLink with the data you'll need for your workflow. For vendor onboarding, select the CloudLink connected to your vendor and procurement data. 2. **Name** — The display name for your app in Elementum (e.g., "Vendor Onboarding"). 3. **Namespace** — A unique identifier for your app. This cannot be changed later. 4. **Handle** — A short reference key that appears as a prefix in every record ID (e.g., `VND-001`). This cannot be changed later. 5. **Description** — Help others in your organization understand what the app does (e.g., "Manages the end-to-end vendor onboarding process from application through activation"). 6. **Category** — Organizes all apps in your organization. Categories are managed by admins in Settings. Click **Create** once all fields are completed. The Record Details Layout icon **Record Details Layout** will open, where you can begin configuring how records are displayed and edited in your app. Apps are visible to other users in your organization as soon as they are created. If you want to build and test privately before going live, create your app in a [development environment](/administration/understand-organization-environments) first. You can test your app at any stage by creating sample records using the [Create Record Button](/workflows/create-a-record#create-record-button). This lets you verify that your layout and workflow are working as expected before your users see the app. ## Step 2: Design Your Layout After creating your app, the Record Details Layout icon **Record Details Layout** opens. This is where you choose which fields and components are available on each record — defining what information users can see and edit. For vendor onboarding, you might add fields like Company Name, Tax ID, Contact Email, Annual Revenue, and a Products/Services description. The layout also includes **stage-specific sections** that control what users see at each phase of the process. You define the stages and their visual appearance here in the Layout Builder — in [Step 5](#step-5-map-your-flow), you'll use Flow to connect those stages together and define how records transition between them. Use the [Layout Builder](/workflows/layouts) to add, arrange, and configure the fields and components your records need. For a detailed walkthrough, see the full [Layout Builder guide](/workflows/layouts). Some fields are required by the system and cannot be removed from the layout. These fields are essential for record tracking and workflow functionality. ## Step 3: Configure Views Your app supports five view types for displaying records: * **List** — Column-based listings best for scanning and filtering large sets of records. For vendor onboarding, use this to review all vendors sorted by submission date or status. * **Kanban** — Card-based workflow boards grouped by a status or category field. This gives your team a visual overview of where each vendor stands in the onboarding process. * **Calendar** — Date-based record visualization. Useful when dates and deadlines drive your process, such as vendor activation target dates or review deadlines. * **Dashboard** — Metrics, charts, and summary widgets for at-a-glance reporting on the records in your app. * **Agent** — A full-page embedded chat experience with an [agent](/ai-agents/agents-experience). Use for processes where the primary interaction is conversational. Views are created by App Admins under **Managed Views** in the **User Interface** section of the left navigation menu, then shared with specific users or groups. Users with access see the view in their view list but cannot modify its definition. See the [Managed Views](/workflows/managed-views) reference for full configuration details. Each view can be filtered by any field or component. Use **Display Settings** to manage which fields are visible. In the List view, if you find yourself using a specific filtered view consistently, click **Add to Workspace**, enter a **Location** and **Name**, then click **Save Widget**. The saved widget will be available from the menu when you click **Home**. **Multi-column sort in List view:** Hold **Shift** and click column headers in the order you want (e.g., Status, then Due Date). The list sorts by the first column, then by the second within that order. This sort is temporary and does not persist when you leave the page. See [Filtering](/getting-started/fundamentals/filtering#sorting-in-list-views) for details. When choosing a **Location** for a saved widget, select **Home** to save it to your personal dashboard (visible only to you), or add it to a **Workspace** within the app. Workspaces can be shared with others in your organization, so your team can access the same curated views. ## Step 4: Create a Form If your app collects input from users, create a form to standardize how data enters your workflow. Forms let you control which fields are required and how submissions are structured to keep incoming data clean and consistent. For vendor onboarding, a form lets prospective vendors submit their company details, certifications, and banking information through a guided experience. For a full walkthrough, see the [Form Builder guide](/workflows/form-builder). ## Step 5: Map Your Flow [Flow](/getting-started/fundamentals/core-concepts#processes--apps) is where you define how records move through your process — connecting the stages you set up in the Layout Builder and specifying the transitions between them. While the Layout Builder controls what each stage looks like, Flow controls how stages are connected and in what order records progress. Open the **Flow** tab and lay out the stages of your workflow. Flow captures *what* your process looks like. To make the process actually run — routing records between stages, sending notifications, updating fields — you'll configure [Automations](/workflows/automation-system) in the next step. ### Define Stages Each stage represents a phase in your business process. For the vendor onboarding workflow: 1. **Application** — Vendor submits their information through the intake form. 2. **Review** — Procurement team evaluates the submission for completeness and compliance. 3. **Approval** — Decision-maker approves or rejects based on vendor qualifications and risk assessment. 4. **Activation** — Approved vendor is onboarded into the system and granted access to relevant portals. ### Configure Assignments Use [assignment rules](/workflows/assignment-rules) to define who is responsible for work at each stage. For vendor onboarding, you might assign the Review stage to your procurement team, route Approval to a manager based on the vendor's annual revenue, and assign Activation to your IT operations team. Assignments can be based on: * Role or department * Workload balancing * Specific field values (e.g., region or product line) ## Step 6: Add Automations [Automations](/workflows/automation-system) are what bring your Flow to life. While Flow documents the process, automations make it run — triggering actions when specific events occur. This includes routing records to different stages based on conditions, so your process handles branching and decision points automatically. Start with a few high-impact automations, then add more as you learn how your team uses the app. ### Decision Points and Routing Use automations to handle the branching logic in your process. For vendor onboarding: * Route vendors to different review tracks based on annual revenue (e.g., vendors over \$1M go to VP approval). * Create parallel paths when both Legal and Finance need to review simultaneously. * Define exit criteria that must be met before a vendor can advance (e.g., all required documents uploaded). ### Common First Automations * **Notifications** — Alert team members when a record is assigned to them, a deadline is approaching, or a status changes. For vendor onboarding, notify the procurement team when a new application arrives. * **Field Updates** — Automatically set field values based on conditions — for example, set the vendor risk level to "High" when annual revenue exceeds a threshold. * **Approvals** — Route records through [approval processes](/workflows/approval-processes) based on value, category, or other criteria. * **Integrations** — Send data to external systems via webhooks or the [API](/api-reference/api-introduction) when key events happen — like pushing approved vendor data to your ERP system. ### Automation Tips * **Start simple.** One trigger, one condition, one action. Add complexity only after you've confirmed the basic flow works. * **Test thoroughly.** Run through each automation with sample data before going live. * **Monitor execution.** Use the automation log to verify that automations fire as expected and investigate any failures. Automations must be built within an App. Make sure your app's data structure and flow are in place before creating automations that depend on them. ## Step 7: Create Records Records are the individual data entries that live inside your app — each one representing a single item moving through your process. In vendor onboarding, each record is a vendor progressing from application through activation. Records can enter your workflow in several ways: * **Manual creation** — Users create records directly from the app or through forms. * **CloudLink sync** — Records are pulled from external data sources like Snowflake, BigQuery, or Databricks via [CloudLinks](/administration/setup-cloudlink). * **Automations** — Records are generated automatically in response to system events or triggers. * **Agents** — AI Agents create and populate records during conversations and task execution. * **API** — External systems create records through the [Elementum API](/api-reference/api-introduction). For a full walkthrough of each method, see the [Create a Record guide](/workflows/create-a-record). ## Step 8: Test and Launch Before inviting your team, walk through the entire vendor onboarding process yourself. Use this checklist to verify everything works end to end: * **Create test records** — Add several vendor records that represent realistic scenarios, including edge cases like missing documents, boundary revenue values, and vendors that should take different paths through the flow. * **Walk the flow** — Move each test vendor through every stage. Verify that assignments, notifications, and field updates behave correctly at each transition. * **Validate automations** — Check the automation log to confirm every automation fired when expected. Look for automations that didn't trigger or produced unexpected results. * **Invite early users** — Bring in a small group of users for feedback. Ask them to complete tasks without guidance — their experience will reveal layout issues, unclear labels, and missing automations. * **Iterate and go live** — Incorporate feedback, fix any issues, and roll out to your full team. Plan to revisit the app after a week of real usage to make further refinements. Depending on your organization's configuration, you may need to [deploy your app to a different environment](/administration/deploy-apps-between-environments) once it has been tested and is ready for production. ## Take an App Offline for Maintenance When you need to make changes to a live app, turn on maintenance mode so users see a maintenance page instead of a half-configured experience. To take an app offline: 1. Click **App Details** in the left navigation. 2. Turn on the **Under Maintenance** toggle. While maintenance mode is on, anyone who opens the app sees a maintenance page directing them to their administrator. Turn the toggle off to return the app to normal immediately. App admins keep full access to the app's settings while maintenance mode is on, so there is no risk of locking yourself out. Maintenance mode only changes what users see when they open the app — scheduled automations and other background work continue running as normal. ## Create an App from a Template Apps can also be created from templates exported from other apps, letting you replicate an existing app's structure without rebuilding from scratch. **To download a template:** 1. Open the app you want to use as a template. 2. Click the More icon **More** icon next to **Admin Settings**. 3. In the popup, click **Download** to begin preparing the export. This may take some time. 4. Once ready, open your profile and go to **My Background Tasks**. Click **Download** next to the completed task to save the JSON file to your computer. **To import the template:** 1. Open **Organization Settings**. 2. Under the **Platform** section, click **Import App**. 3. Drag and drop the downloaded JSON file into the upload area. 4. **Connect Your Data** — complete the following configuration for the new app: * Select a **Cloud Credential** * Configure how **data tables** should be set up * Configure **Email Aliases** 5. Select an **AI Service** to include in the new app from the dropdown. 6. Click **Finalize** and fill in the following details: * **Category** * **Handle** * **Name** * **Namespace** 7. Click **Done** to complete the import. After importing, review the app's automations and configuration to confirm they are appropriate for the new app's context before inviting users. ## Next Steps Once your app is running, configure who can see and modify your data. Head to the [Object Data Access guide](/workflows/object-data-access) to set up record-level permissions and ensure the right people have access to the right information. Then explore these capabilities to extend your app further: Add AI-driven triage, extraction, or routing to automate complex decisions. Build dashboards and reports to track process performance and identify bottlenecks. Layer in scheduled processing, SLA tracking, and multi-step automation chains. Review proven patterns for scaling and optimizing your workflows. # Core Concepts Source: https://docs.elementum.io/getting-started/fundamentals/core-concepts Foundational building blocks for creating custom business workflows in Elementum Elementum is a platform designed to build, automate, and scale custom business workflows. This page explains the foundational building blocks of the platform—how data, workflows, automation, and AI come together. **New to Elementum?** If you prefer a hands-on approach, try [Getting Started](../quickstart) first, then return here for deeper understanding. ## Processes & Apps Apps icon Apps are the containers that hold your business logic and configuration. They organize your data, configuration, automations, and user permissions into unified spaces tailored to specific business processes—like onboarding, incident management, or vendor reviews. Apps work hand-in-hand with Flow, a visual process builder that lets you design your workflow with stages, decision points, automations, and user inputs. Think of Apps as the workspace and Flow as the roadmap: Apps provide the structure and resources, while Flow defines how work moves through your process. ### What Makes Up an App Every App brings together several key components: * **Data structure** — [CloudLinks](/administration/setup-cloudlink) connect to existing data sources, Elements icon [Elements](#data--elements) define your business entities, and relationships link everything together. * **Process design** — Flow maps your workflow stages, approval processes handle reviews, and assignment rules route work automatically. * **User experience** — [Layouts](/workflows/layouts) control how users interact with data, forms capture input, and views display information clearly. * **Automation engine** — Event-driven rules trigger actions, [Agents](#ai--intelligence) handle complex decisions, and integrations connect external systems. ### How Workflows Start Apps provide multiple ways to initiate workflows: * **User-initiated** — Service portals, manual creation, and forms let people start workflows when needed. * **System-triggered** — [API endpoints](/api-reference/api-introduction), scheduled processes, and data mining automatically start workflows based on conditions. * **Smart automation** — AI agents and email ingestion intelligently create and route workflows based on content and context. ### Design Principles for Apps * **Process-first**: Map your business workflow before configuring the App * **User-centered**: Design for the people who will use it daily * **Data-driven**: Connect to authoritative data sources rather than creating duplicates * **Iterative**: Start simple and add complexity as users adopt the workflow * **Integrated**: Plan how the App will connect to your existing systems *** ## Data & Elements Elements are structured data objects that represent the key business entities in your organization—such as vendors, products, incidents, or customers. Each Element consists of defined fields that capture the essential information for that entity. By standardizing how business data is organized and accessed, Elements provide a consistent foundation for your workflows and processes. [CloudLinks](/administration/setup-cloudlink) connect Elementum to your existing data repositories (like Snowflake, BigQuery, or Databricks) to use as a data source without copying or syncing. External data becomes instantly usable inside workflows, unlocking real-time solutions and faster value delivery. CloudLink data can be made available to your workflows as Element objects. ### What Makes Up an Element * **Fields and properties** — Data types (including JSON columns for unstructured data), validation rules, default values, and calculated fields define what information the Element can contain. * **[Relationships](/data/showing-relationships)** — Connections between Elements mirror real-world business relationships, like customers linked to orders or incidents linked to products. * **Permissions and access** — Role-based controls determine who can view, edit, or delete Element records within your workflows. * **Automation triggers** — Event-driven rules automatically respond to Element changes, updates, or state transitions. ### How Elements Connect to Data Sources Elements can be populated and updated from multiple sources: * **CloudLinks** — External databases like Snowflake that serve as authoritative data sources without copying data. * **Manual entry** — Forms and interfaces where users directly create and update Element records. * **AI-assisted processing** — AI agents that automatically generate Element records, extract structure from unstructured data, and populate JSON fields from loose data sources. ### Element Types and Patterns Common Element patterns include: * **Master data Elements** — Core business entities (Customers, Products, Vendors) that other Elements reference. Relatively stable and often sourced from external systems. * **Transactional Elements** — High-volume business events and data records (Transaction Logs, Usage Records, Performance Metrics) used for analysis and reporting. * **Configuration Elements** — Settings and rules (Approval Thresholds, SLA Definitions, Routing Rules) that govern process behavior and change infrequently. * **Historical Elements** — Append-only records (Change Logs, Version History, Activity Records) used for audit trails and compliance. * **Semi-structured Elements** — Flexible data with varying structures (Form Responses, API Payloads, Survey Data) that use JSON columns, with AI helping extract structure from unstructured inputs. ### Design Principles for Elements * **Business-first**: Model real business entities, not technical database tables * **Validation-rich**: Include rules that prevent invalid data from entering your workflows * **Relationship-aware**: Design connections that reflect actual business relationships * **Evolution-ready**: Structure Elements to grow with your business needs ### Create a New Element Elements are created from within an App by an App Admin. The setup mirrors [creating an App](/getting-started/build-an-app#step-1-create-the-app), except Elements don't have a Flow (stages or transitions) or assignment rules to configure. 1. In the left navigation menu, click **Elements**, then click **Create New Element**. 2. Fill in the required details (**Name**, **Namespace**, **Handle**, and **Description**). See [Step 1 of Build an App](/getting-started/build-an-app#step-1-create-the-app) for field-by-field guidance. 3. Click **Create**. Once created, define the Element's fields, relationships, layout, and any object-level automations from its left navigation menu. See [Element and Task Capabilities](#element-and-task-capabilities) for the full list of configuration surfaces. Creating CloudLink-backed Elements requires the **Create Elements** permission under CloudLinks. See [Roles & Permissions](/administration/roles-permissions). ### Element and Task Capabilities Elements and Tasks share the same set of configuration surfaces, accessible from the object's left navigation menu: * **Views** — [List, Kanban, Calendar, Dashboard, and Agent views](/workflows/managed-views) for browsing, organizing, and interacting with records * **Workspaces** — Personalized dashboards that consolidate views and data * **Health** — Overview and Interventions for monitoring automation performance (labeled **Element Health** on Elements) * **Workflows & Processes** — [Automations](/workflows/automation-system) and [Intelligence](/ai-agents/ai-automations) configured at the object level. Tasks also include [Assignment Rules](/workflows/assignment-rules) for automated work distribution. * **User Interface** — [Record Details Layout](/workflows/layouts), [Related Views](/data/showing-relationships), and [Form Builder](/workflows/form-builder) for controlling how users interact with data * **Configuration** — [Field Mapping](/data/data-mining), [Relationships](/data/showing-relationships), [Languages](/workflows/translations), and [Notifications](/administration/notifications) * **Security** — [Roles & Permissions](/administration/roles-permissions), [Object Data Access](/workflows/object-data-access), and [Activity Log](/administration/activity-log) ### Manage Data with Tables Tables icon [Tables](/data/tables) in Elementum are dynamic, real-time data views that automatically stay synchronized with your data sources. They transform raw data into actionable business insights through an intuitive interface. Use a Table when you want to use [Data Mine triggers](/data/data-mining) in another object or create cross-functional dashboards to analyze data. If you have Elements that no one edits and are only used for reports, a Table would probably be a better fit for your data. *** ## Automations Automation in Elementum is event-driven. Rules define what should happen when something changes—like a field update, a form submission, or a time-based condition. Triggers start workflows, assign tasks, loop in an AI Agent, or modify records automatically. Use [platform APIs](/api-reference/api-introduction) and prebuilt automation actions to send or receive data between Elementum and other systems—triggering workflows, updating records, or enriching data. Automations must be built within an App, Element, or Task. You need to create or have access to one of these objects before you can build automations. ### Core Building Blocks * **Triggers** — Start automations on record changes, status transitions, comments, file events, or schedules. * **Conditions** — Target the right scenarios with filters, comparisons, and branch (if/else) logic. * **Actions** — Update fields, create related records, send notifications, request approvals, call webhooks, or invoke AI. * **Schedules and SLAs** — Time-based triggers and deadline tracking to escalate or remind when work is overdue. * **Error handling** — Built-in retries and failure paths keep processes resilient; log outcomes for audits. * **Observability** — View automation runs, success rates, and bottlenecks to improve reliability. ### Automation Patterns **Event-driven rules** execute immediately when data changes occur. Use them for data validation, field calculations, notifications, and workflow state transitions. Common triggers include field updates, status changes, record creation, and comment additions. **Scheduled processing** runs at fixed intervals for batch operations, maintenance tasks, and time-based business logic. Schedule options include hourly, daily, weekly, and monthly intervals. Use for SLA monitoring, data reconciliation, periodic reports, and cleanup tasks. **Human-in-the-loop workflows** combine automated processing with human decision points using assignments, approvals, and conditional routing for complex decisions, compliance requirements, and exception handling. **System integrations** synchronize data and trigger actions across external systems using webhooks, APIs, and database connections. Always implement retry logic and error handling for external system calls. ### Design Principles for Automations * **Single responsibility**: Each automation should handle one specific business rule or process step * **Idempotency**: Design actions to be safely repeatable—multiple executions produce the same result * **Observability**: Log execution details, measure success rates, and monitor performance metrics * **Failure resilience**: Implement retry policies, error handling, and fallback paths for failed operations **Performance tip**: Batch similar operations and use conditional logic to minimize unnecessary executions. Monitor automation frequency to avoid overwhelming system resources. *** ## AI & Intelligence AI in Elementum provides programmatic reasoning, data extraction, and content generation within your workflows. There are two primary ways to add intelligence: * **[Agents](/ai-agents/agents-tools-and-deployment)** — Reusable AI components with tools, memory, and policy controls. Ideal for multi-step reasoning and actions within a workflow. * **[AI Actions](/ai-agents/agents-experience)** — Lightweight actions powered by LLMs for one-off tasks like categorization, extraction, and transformation. Configure [models and providers](/ai-agents/ai-models) (OpenAI, Anthropic, Gemini, Snowflake Cortex, Amazon Bedrock, or any custom OpenAI-compatible endpoint) based on your data sensitivity, cost, and latency requirements. ### Common Use Cases * **Triage and routing** — Classify incoming requests, detect intent, and assign to the right team with confidence scores. * **Information extraction** — Pull structured fields from unstructured content (emails, PDFs, log files) into Elements. * **Summarization and drafting** — Generate summaries, replies, or knowledge base entries with human approval steps. * **Search and reasoning** — Retrieve relevant context and reason over it to propose next steps or detect anomalies. * **Vendor outreach** — Agents that email vendors for missing documents, validate responses, update Element fields, and advance workflows automatically. * **Support triage** — Conversational agents that answer FAQs, gather context, triage requests, and escalate with structured handoffs when needed. ### Enterprise AI Orchestration The key to successful AI implementation is embedding non-deterministic AI capabilities within deterministic workflow structures. This approach enables reliable, auditable, and scalable AI deployment. **Governance and controls** include: * **Workflow boundaries** — Clear input/output contracts and validation rules that AI actions must respect. * **Security and permissions** — Respect roles and data access controls when reading or writing records. * **Transparency** — Log prompts, context, and outputs for auditability and improvement. * **Human oversight** — Require approvals for high-impact actions; build review queues into your flow. * **Compliance assurance** — Built-in audit trails, approval workflows, and policy enforcement for regulatory requirements. ### Confidence Scoring AI actions return confidence scores that determine workflow routing and human oversight requirements: * **High confidence (90–100%)** — Auto-approve and execute actions * **Medium confidence (70–89%)** — Route to human review queue * **Low confidence (0–69%)** — Escalate to exception handling or manual processing Set thresholds based on business impact—use higher thresholds for financial or compliance-critical actions. A confidence score is not a native platform field. It only exists when you explicitly request it as an output — for example, as a structured output field on a [Run Agent Task](/workflows/agent-task-automation) or by referencing the `confidence` output of an [AI action](/ai-agents/ai-automations). There is also no built-in component that renders a green/yellow/red indicator by score range. To show a colored indicator on a layout, mirror the numeric score into a **Dropdown** field with a fixed set of options whose icons and colors you control, and keep that field in sync with an automation: 1. Add a **Dropdown** field (for example, `Confidence Band`) with static options such as **High**, **Medium**, and **Low**, and give each option a colored icon so it renders as a colored badge. See [Layout Builder](/workflows/layouts) for adding fields and configuring dropdown options. 2. In the object's automation, add an **Update Record Fields** action that sets the band from the numeric confidence output — for example, `>= 90` → **High**, `70–89` → **Medium**, `< 70` → **Low**. See the [Automation Actions Reference](/workflows/automation-actions-reference) for this action. 3. Place the Dropdown field on the record details layout next to the numeric score so reviewers see both the value and the colored band. For a read-only derivation that recalculates automatically, replace the automation with a [Calculation](/data/calculations) field that uses an `IF` expression to output the band label from the numeric score. *** ## User Collaboration Collaboration in Elementum enables human oversight and decision-making within automated workflows. Configure role-based interfaces, approval chains, and notification systems to maintain accountability while preserving automation benefits. Human-in-the-loop doesn't mean manual. Use automation to prepare, validate, and route; reserve human judgment for decisions. ### Building Blocks * **[Layouts and views](/workflows/layouts)** — Configure tables, timelines, and cards to present the right information for each role. * **[Forms](/workflows/form-builder)** — Capture structured inputs with validations, conditionals, and dynamic defaults. * **[Approvals](/workflows/approval-processes)** — Define approval chains with thresholds, parallel steps, and escalation policies. * **[Notifications](/administration/notifications)** — Keep stakeholders informed via in-app, email, and chat channels; respect SLAs. * **[Roles and permissions](/administration/roles-permissions)** — Control who can see and change data with fine-grained access rules. * **[Activity and audit](/administration/activity-log)** — Track history, comments, and changes for compliance and collaboration. ### Collaboration Patterns **Assignment and handoffs** route work based on user skills, workload, or business priority. Create role-specific views that highlight pending tasks and next actions. Automatic escalation ensures nothing falls through the cracks. **Approval workflows** support conditional logic—parallel approvals for speed, sequential for hierarchy—with timeout handling and automatic escalation paths. **Self-service portals** offer intake forms with conditional fields, real-time validation, and status tracking so users can monitor request progress without requiring admin access. ### Design Principles for Collaboration * **Clarity**: Make next actions obvious with clear buttons, status indicators, and task assignments * **Progressive disclosure**: Show essential information first, detailed data on demand * **Least privilege**: Grant minimal access by default, use approval workflows to elevate permissions when needed * **Feedback loops**: Send notifications with specific actions required, not just status updates *** ## How Core Concepts Work Together Understanding how these concepts connect is key to building effective workflows. Each layer builds on the previous to create sophisticated, automated business processes. Start with **Apps** to organize your workspace. Then use **Flow** to design your visual process with stages, decision points, and automations. *Example:* Create a "Vendor Onboarding" app with a flow that moves vendors through Application, Review, Approval, and Activation stages. Connect to existing data sources using **CloudLinks** without copying or syncing. Link data **Elements** from your CloudLink as structured objects to represent your business entities. *Example:* Connect to your CRM database via CloudLink and create Elements for Customers, Contracts, and Support Tickets. Set up **Automations** with rules that trigger when conditions are met. Use **external system integrations** via APIs and prebuilt actions to connect with other platforms. *Example:* Automatically create a support ticket in your help desk system when a customer submits a complaint form. Deploy **Agents** for complex workflow steps that require reasoning. Use **AI Actions** for lightweight, single-use tasks like categorization and data transformation. *Example:* Use an Agent to analyze customer feedback, automatically categorize issues, then route them to the appropriate team. Design **human-in-the-loop workflows** where people maintain control through roles, approvals, and notifications. Create **flexible interfaces** with forms, comments, and configurable views for real-time collaboration. *Example:* Set up approval workflows where managers review and approve expense requests, with automated notifications and deadline tracking. ## Next Steps * **[Getting Started](../quickstart)** — Build your first App and see these concepts in action * **[Best Practices](../best-practices)** — Learn design patterns for building effective workflows * **[Workflow Design](/workflows/app-health)** — Explore layouts, automations, approvals, and more * **[API Reference](/api-reference/api-introduction)** — Technical documentation for connecting external systems and building integrations # Home Page Source: https://docs.elementum.io/getting-started/home-page An overview of the Elementum home page, including assignments, approvals, and Workspaces. Home icon The **Home** page is your personal hub in Elementum. It surfaces the work that is relevant to you across all apps in your organization — without requiring you to navigate into each app individually. The left navigation menu is also used throughout the platform to move between objects within an app and to access organization and user settings. ## Sections The home page is divided into three sections, accessible from the left navigation: **My Work** — Records currently assigned to you across all apps. This includes any active work items where you are the designated owner at the current stage. **Approvals** — Records waiting on your approval. These are items that have reached an approval step and require your action before they can progress in the workflow. **Workspaces** — Personalized dashboards that you configure yourself. Workspaces let you pin views, charts, and data from across your apps into a single, consolidated view. ## Filtering and Sorting Each section on the home page supports filtering and sorting, the same way [Object views](/getting-started/fundamentals/core-concepts) work inside individual apps. You can narrow down records by field values or reorder them to prioritize what matters most. To save your current filters and display settings as the default view on the My Work page, click the **More** icon in the top-right corner and select **Save as Default**. The next time you visit the page, your saved filters and sort order will be applied automatically. The Approvals page has two tabs at the top — **Waiting on Me** and **Submitted by Me** — so you can switch between approvals that need your action and requests you've sent to others. ## Workspaces Workspaces are dashboards that consolidate views from across your apps into a single place. Workspaces created from the home page are tied to your user account by default, but you can share them with other users or groups in your organization. Workspaces created inside an App, Element, Task, or Table are scoped to that object and accessible to users with access to it. ### Create a Workspace 1. From the home page, click the vertical **More** icon next to **Workspaces** in the left navigation. 2. Enter a name for the Workspace. 3. Click **Create**. ### Add Widgets to a Workspace Widgets are filtered and sorted views of Apps, Elements, or Tasks that you pin to a Workspace. 1. Navigate to the App, Element, or Task you want to add. 2. Customize the list with your desired filters and sort order. 3. Click **+ Add To Workspace**. 4. Select the destination Workspace. ### Share a Workspace You can share a home page Workspace with specific users or groups so they see the same set of widgets in their own home page. 1. Open the Workspace from the **Workspaces** section of the left navigation. 2. Click the **More** icon in the top-right corner of the Workspace. 3. Select **Share**. 4. In the **Share Workspace** dialog, select one or more users or groups. 5. Click **Save**. ## Switching Organizations If you are a user in multiple organizations, click the current organization icon at the top of the left navigation menu. Select the organization you would like to work in. ## Customize the Navigation Menu The left navigation menu includes a few preferences that control how it behaves and what it shows. These settings are saved to your profile and persist across sessions. The left navigation also adapts to your permissions: only the items you have access to appear in the menu, and categories are hidden entirely when you don't have access to view or create any items inside. This filtering is based on Object-level permissions — users with organization-level permissions continue to see every item in the side navigation. ### Pin and Organize Navigation Items Pin the objects you use most to a dedicated section of the left navigation, hide the items and sections you don't use, and drag to reorder your pins. Each user personalizes their own side nav, and your layout persists across sessions, page navigation, and logins. To pin an object: 1. Click the **+** icon in the left navigation menu. 2. Select the type of object you'd like to pin — for example, **Apps**, **Views**, **Agents**, **Chats**, **Elements**, **Tasks**, or **Tables**. 3. Choose the specific object from the list by searching or scrolling. To rearrange or remove pinned items: 1. Click the **+** icon, then click **Manage**. 2. In the **Pinned** section, drag and drop a pin to move it, or click the Trash icon **Trash** icon to remove it from your main navigation. To show or hide items in the **Main** and **System** sections: 1. From the **Manage nav** panel, open the **Main** or **System** section. 2. Use the checkboxes next to individual items to show or hide them, or use the section's checkbox to toggle the entire section at once. Hidden items remain accessible through search and direct links; they are only removed from the visible side nav. ### Pin the Sidebar Open By default, the sidebar that shows an Object's menu collapses when you navigate away. To keep it open: 1. Hover over the Elementum icon in the bottom-left corner of the left navigation. 2. Click the Open Nav icon **Open Nav** icon. When the sidebar is collapsed, hovering over any navigation item reveals that section's contents in a floating preview — so you can scan other areas without losing your place on the current page. ### Show Navigation Labels Navigation labels are turned off by default, leaving only icons in the left navigation. To display text labels alongside the icons: 1. Click your user icon in the bottom-left corner of the left navigation. 2. On your **Profile** page, locate the **Navigation Labels** setting. 3. Select **Icons and text**. # Getting Started Source: https://docs.elementum.io/getting-started/quickstart An overview of what it takes to build your first business workflow in Elementum. ## Prerequisites * An active Elementum account with access to an organization * A [CloudLink](/administration/setup-cloudlink) datasource configured in your organization * Basic understanding of your business process When onboarding to Elementum, your Elementum contact will help you with initial Cloudlink setup. ## How to Build Your First App Throughout these steps, we'll use an **Expense Approvals** app as a running example — employees submit expense reports, managers review and approve them, and finance processes the reimbursement. Go to Apps icon Apps in your dashboard and click Create App. During setup you will: * Connect a CloudLink data source that holds the data your workflow needs * Set a name, namespace, and handle — the namespace and handle cannot be changed later * Add a description and category so others in your organization understand what the app does For the expense approvals example, you'd name the app "Expense Approvals", connect the CloudLink with your finance data, and set a handle like `EXP` so every record is identifiable (e.g., `EXP-001`). For a detailed walkthrough, see the [Build an App](/getting-started/build-an-app) guide. Use the [Layout Builder](/workflows/layouts) to define what users see and interact with on each record. This includes: * Adding fields for the data your process requires (e.g., contact info, status, priority, due dates) * Defining stage-specific sections that control what is visible at each phase of the workflow * Configuring views — List for scanning and filtering, Board for Kanban-style tracking, and Calendar for date-driven processes * Creating a [form](/workflows/form-builder) to control how data enters your workflow and which fields are required at submission For the expense approvals example, your fields might include Employee Name, Department, Expense Amount, Category (travel, software, meals), Description, and Receipt attachment. You'd create a submission form requiring all fields, and use a List view so finance can filter by department or status. Open the [Flow](/getting-started/build-an-app#step-5-map-your-flow) tab to connect your stages and define how records move through your process. Then layer in [automations](/workflows/automation-system) to make the process run. Key tasks include: * Defining stages that represent each phase of your business process * Setting [assignment rules](/workflows/assignment-rules) to define who owns work at each stage, based on role, workload, or field values * Adding automations for notifications, field updates, [approval routing](/workflows/approval-processes), and decision-point branching * Configuring integrations to push data to external systems when key events occur For the expense approvals example, your stages would be Submit → Manager Review → Finance Processing → Reimbursed (with a Rejected exit path). You'd assign the Manager Review stage to the submitting employee's manager, and add automations to notify the manager on submission, auto-approve expenses under \$50, and flag anything over \$500 for VP review. Before going live, walk through the entire process yourself and verify everything works end to end: * Create test records that represent realistic scenarios, including edge cases and branching paths * Move records through every stage to confirm assignments, field updates, and stage transitions behave correctly * Check the automation log to verify every automation fired as expected * Invite a small group of users for feedback and iterate before rolling out to your full team For the expense approvals example, submit test expenses at different amounts — one under \$50 to confirm auto-approval, one over \$500 to verify VP routing, and one mid-range to walk through the standard manager review path. *** ## Common First Apps Track deals from lead to close with automated approvals and notifications. Manage customer issues with smart routing and SLA tracking. Streamline expense processing with automated workflows. Handle supplier relationships and contract tracking. *** Best Practices:
    • **Start simple:** Begin with essentials, add complexity as you learn.
    • **Test thoroughly:** Always test your workflows before going live.
    • **Get feedback:** Involve your team early to ensure the workflow meets their needs.
    • **Document everything:** Keep notes on your configuration for future reference.
    *** ## Explore More Learn the fundamental concepts behind Elementum's platform. Master the automation system to build advanced workflows. Follow proven patterns for building effective workflows. Integrate Elementum with your existing systems. *** ## Take Your Workflows on the Go Stay on top of your workflows from anywhere with the Elementum mobile app. Monitor progress, receive real-time notifications, and take action on approvals and tasks — all from your phone. Available on the Apple App Store Available on the Google Play Store *** ## Need Help?
    • **Documentation:** Utilize our comprehensive guides and tutorials to get started.
    • **Support:** Contact our support team to report issues or request features.
    # Your Guide to Mastering Elementum Source: https://docs.elementum.io/getting-started/welcome-to-elementum Get started with intelligent workflows used by the world's largest companies. Elementum Platform - Light Mode Elementum Platform - Dark Mode ## What is Elementum? Elementum is an intelligent process automation platform that orchestrates people, rules, LLMs, and AI agents - without moving your data from your data warehouse. Use Elementum to build custom apps that automate workflows, analyze data, and deliver scalable business outcomes. **Elementum is a no-code platform** - Elementum is designed for business users, not engineers. ## Key Features Create custom business workflows tailored to your specific needs Automate repetitive tasks and build intelligent workflows Connect your data warehouse and use that data in apps and workflows Build workflows with a rich set of tools and components Import and process data from various file formats automatically Leverage AI to handle decisions and tasks typically done by humans ## What You Can Build **Sales Pipeline Management** - Track deals from lead to close with automated approvals and real-time insights **Support Ticket System** - Manage customer issues efficiently with smart routing and SLA tracking **Vendor Management** - Handle supplier relationships, contracts, and performance tracking **Expense Processing** - Streamline expense approvals with automated workflows and document processing ## Get Started An overview of what it takes to build your first workflow in Elementum Learn the fundamental concepts behind Elementum's platform Integrate Elementum with your existing systems Follow proven patterns for building effective workflows ## Ready to Try Elementum? Talk to our team about your specific needs Start building your first workflow today # August 2026 Source: https://docs.elementum.io/release-notes/august-2026 Elementum platform releases for August 2026. The colored badges indicate the area of Elementum where you will see the update (for example, Apps, Tables, Intelligence, or Automations). ## August 20, 2026 ### Agents & AI **Start Conversation Hook** Intelligence - Agents can run an on-demand automation before the first message in a conversation, so the agent has the context it needs on turn one. * Map inputs from available metadata such as user name, email, and record ID. * Capture automation outputs as a message sent to the agent before the first turn. * Optionally show users a progress message while the automation runs. **Voice Agents: Bring Your Own Key** Intelligence - Voice agent configuration includes an OpenAI provider option that routes the underlying voice agent experience through your own API key instead of shared infrastructure. * Apply an existing OpenAI agreement to voice so your organization controls voice AI costs and usage directly. * Choose the OpenAI provider option when configuring a voice agent. **Voice Auth Fallback: Employee ID + OTP** Intelligence - Voice agents support a layered caller authentication flow: PIN when the caller's phone number is recognized, and Employee ID plus a one-time passcode when it isn't. * Keep legitimate callers moving when they call from an unknown number instead of hitting a dead end. * Use PIN authentication for recognized numbers and Employee ID + OTP as the fallback. ### Apps **Batched Record Field Updates** Record Details - Editing several fields in a row on a record saves the changes together as a single update, so closely-timed edits no longer overwrite each other and the last value entered for each field is what sticks. * If a save fails, only the fields in that save roll back. * Background record refreshes will not overwrite edits that are still being saved. **Current User's Groups List Filter** Workspace - A new "Current User's Groups" function on list-view group-field filters resolves each viewer's group memberships at load time, so a single view can serve every team without picking a specific group. * Team members see one queue of work assigned to any group they belong to. * Membership changes are picked up on the next load without reconfiguring the view. **Expanded File Preview: Office and TIFF Formats** Record Details - Word, PowerPoint, and OpenDocument attachments, along with single- and multi-page TIFF scans, preview directly on the record details page and render as PDFs so page navigation works the same across formats. * Supported formats include DOCX, PPTX, PPT, ODT, ODS, ODP, and TIFF. * Both the side-by-side preview panel and full-screen preview support these formats. * A `/preview` API endpoint returns any supported attachment as a PDF. ### Automations **Automation Slack DM** Automations - Send automation updates as direct messages to any user in Slack, in addition to posting in channels, so time-sensitive notifications and alerts reach people where they already work. * Send a direct message to any user in Slack from the **Send Slack Message** action. * Include a title and message contents, with `{{value_references}}` that resolve when the automation runs, plus an optional link button that opens a URL you specify. * These are one-way notifications — recipients cannot reply to the DM to reach an agent. ### Platform **Parent Trace ID for Trace Forwarding** Org Settings - Include a W3C `traceparent` header on requests to Elementum so exported spans nest under your calling span, and the request appears in your platform as a single connected trace. * Exported spans adopt the trace ID you supply and attach under your parent span ID. * Requires a Trace Forwarding endpoint that is enabled and assigned to the environment. ## August 10, 2026 ### Platform **Digital Labor Dashboard** Reporting - Put a number on the value your AI is delivering — quantify the work your agents and automations complete as full-time-employee equivalents you can take straight to leadership. * Tell the productivity story at a glance, from total Digital Workforce FTE down to hours saved and a daily trend. * Pinpoint where automation is paying off by breaking impact down by app, agent, or your own categories. * Make the numbers yours with custom time rules, then export to Excel to build the case for scaling further. ## August 6, 2026 ### Agents & AI **Custom Inputs & Outputs on Skill Automation Tools** Intelligence - Skill builders get the same control over automation tool interfaces that agent builders already have — closing a key parity gap in the Skills framework. * Define custom inputs and outputs on automation-type Skill tools, just like you already can on agent automation tools. * When configured, the agent uses your custom inputs as its interface for the tool, guiding it to the right values for more accurate, predictable results. * Adopt it at your own pace: automation tools without custom inputs keep their existing behavior. **Permission Options on Skill Tools** Intelligence - Share Skills across your organization without compromising on security — every tool runs under exactly the identity you intend. * Match each Skill tool to your governance model by running it as the Agent default, Publisher, Current user, or Service account. * Consolidate one-off agent tools into shared, reusable Skills with confidence, keeping the same fine-grained access control you had before. * Adopt it with zero rework: existing tools keep running unchanged and new tools default to Agent default. ### Apps **Multiple Closed Statuses** Apps - Model the way your team really closes work — mark every ending you need as closed, not just one, so reporting and automations stay accurate. * Tag any number of status options as closed, like Closed-Good, Closed-Bad, Canceled, and Complete, instead of being boxed into a single closed status. * Trust your numbers everywhere, since every closed value carries the same indicator across reports, filters, dashboards, and automations. **Side-by-Side Attachment Viewer** Record Details - Read a record's attachments without losing your place — files now open in a side-by-side preview panel right next to the record instead of a modal that covers it. * Keep the record and its attachment on screen together, so you can reference both while you work. * Expand the preview to the full viewport with one click when you need a closer look. * Works with the file types Elementum already supports for preview, so it fits right into your existing workflow. ### Automations **"Is In" Filters for Automations** Automations - Match a whole list of values in one filter — pull every record you care about in a single Search Records condition instead of stacking OR conditions or hardcoding values. * Return every record whose field value is in a list you supply, using the new **is in** operator on Text, HTML, Number, and Decimal fields. * Build the list at runtime by feeding an **Execute Script** output straight into the filter, so your search adapts to each run. * Replace long chains of OR conditions with one clean condition that's easier to read and maintain. **Post Update Note** Automations - Keep everyone in the loop automatically — let your workflows post updates to a record's timeline the moment something changes, so your team never has to chase down status. * Surface automated updates in the same Updates feed your team already watches, so important changes never slip through the cracks. * Turn generic notifications into context-rich messages with dynamic values that resolve when the automation runs. * Add a clear, human-readable trail to any process by triggering the action from any automation you already run. ### Experience **Customizable Side Nav** Navigation - Make Elementum feel like yours — put the apps, agents, and views you use every day one click away and clear out everything else. * Keep your most-used work within reach by pinning Apps, Agents, Conversations, Views, Elements, Tables, and Tasks to a dedicated section. * Cut the clutter by hiding the items and sections you don't need and reordering the rest to match how you actually work. * Set it once and move faster every day — your personalized layout follows you across sessions, pages, and logins. ### Platform **Environments Secret Vault** Org Settings - Stop hardcoding secrets and rewriting configuration every time you promote work — store your keys once and let each environment resolve to the right value automatically. * Keep API keys and other sensitive values out of your configuration with write-only secrets that can't be read back once set. * Reference saved vault entries as values in Automations. At runtime, the value resolves from whichever environment the automation runs in. * Control exactly who can view or manage every entry with per-entry access policies. **RSA Key Rotation** Org Settings - Stay on top of your security posture on your own terms — rotate the RSA signing key on a Snowflake cloudlink whenever you need to, without opening a support ticket. * Rotate keys on your own schedule, right from Organization Settings, to keep pace with your security policies. * Swap with confidence: test the new key against a live connection before you apply it, so you never break an active connection. * See exactly what's changing, with the current and new keys displayed side by side during the rotation. ## August 20, 2026 ### Agents & AI **[Agent .ics File Support](/ai-agents/agents-interacting#sharing-files-in-a-conversation)** Intelligence **[Browser Use Agent Improvements](/ai-agents/agents-experience#agent-types)** Intelligence **[Conversation Timeout & Record Creation for Elementum Chat](/workflows/automation-triggers-reference#agent-conversation-ended)** Intelligence **[Studio Agents: Flow Builder](/ai-agents/studio-agents)** Intelligence **[TIFF File Support for Agents](/ai-agents/agents-interacting#sharing-files-in-a-conversation)** Intelligence **[Updated Agent Overview Page](/ai-agents/agents-overview)** Intelligence ### Apps **[Conditional Record View](/workflows/layouts#dynamic-record-details-layout)** Apps **Expand Table View Option for XS/S/M Dashboard Lists** Workspace **[Multi-Select Picklist Badges](/support/faq/faq-apps#managing-records)** Record Details **[Org Default Columns](/workflows/managed-views#widget-column-layouts)** Apps ### Automations **[Saving Attachments Between Apps and from Agents](/workflows/file-uploads-attachments#receiving-files-from-agent-interactions)** Automations **[Sort and Limit on Search Records Action](/workflows/automation-actions-reference#search-records)** Automations ### Platform **Consistent AI Metric Tracking** Org Settings - Reduce double counting by creating a single source of LLM usage across the organization. **[Custom Platform Branding](/administration/platform-branding)** Org Settings **[Generate Embeddings via Bedrock Models](/ai-agents/ai-services#create-an-embedding-service)** Org Settings **[Organization Admin Object Visibility](/administration/roles-permissions#managed-roles)** Org Settings **[SIP Trunking Provider](/administration/set-up-phone-integrations-for-agents#add-a-phone-provider)** Org Settings **[Voice: Employee ID with OTP Authentication](/ai-agents/agents-phone-integration#employee-id-with-otp-authentication)** Org Settings **[Voice: Organization Management](/administration/set-up-phone-integrations-for-agents#organization-voice-management)** Org Settings ## August 13, 2026 ### Apps **Group Member Hover Cards** Apps - Hover, focus, or click a group anywhere it appears to see its members, with avatars, names, and a total member count, without navigating away. * Available on record fields, conditional layouts, process lists, kanban and board cards, My Work, mobile list views, and the Approvals "Waiting On" column when an approval is sitting with a group. * Large groups load 50 members at a time, sorted by name, with a Load more control and a scrollable list. * Keyboard users can tab to a group to open its member list, and hovering never pulls focus away from what you were doing. * Editing a group field is more reliable: the picker now opens with its options already loaded, and working inside the dropdown no longer drops you out of edit mode. ## August 12, 2026 ### Platform **Multi-Region SIP Domains** Org Settings - Provision multiple SIP domains and pick the ingress region closest to your SIP infrastructure so voice calls land with lower latency—built for global telephony deployments. * Create and manage more than one SIP domain for your organization from Organization Settings. * Select the ingress region nearest your SIP infrastructure to reduce call setup latency. * Follow region selection and setup guidance in the UI next to the SIP domain configuration. ## August 10, 2026 ### Apps **Record Title Wrap and Confirm to Save** Record Details - Long record titles use the full header width and wrap up to three lines, and title edits require an explicit confirm so accidental clicks no longer write silent updates into the record history. * Long titles use the full header width and wrap up to three lines instead of truncating to one line with an ellipsis. * Status sits next to the record ID, so it no longer takes width away from the title. * Click the title to enter edit mode, then confirm or cancel. Clicking away discards the draft instead of saving it. * Confirming without changing the text does not create a record update. Applies to the record details header only — list columns, board cards, and mobile layouts are unchanged. ## Stay in the loop # July 2026 Source: https://docs.elementum.io/release-notes/july-2026 Elementum platform releases for July 2026. The colored badges indicate the area of Elementum where you will see the update (for example, Apps, Tables, Intelligence, or Automations). ## July 23, 2026 ### Agents & AI **Browser Use Agent Improvements** Intelligence - Browser use agents can now handle attachments and run on your own model, so they can automate document-driven workflows on external websites end to end. * Feed input attachments — PDFs, spreadsheets, and images — to the agent so it can read and act on their contents. * Capture output attachments such as screenshots, downloaded PDFs, and confirmation numbers, and return them to the calling action. * Bring your own model to power the browser use agent, including Snowflake Cortex models. ### Apps **Conditional Record View** Apps - Record detail pages can render a dynamic layout whose fields, sections, and components appear based on conditional visibility rules, so people see only the information relevant to the record in front of them instead of a one-size-fits-all page. * Build a dynamic Record Details Layout that shows the fields, sections, and components defined for each record type, including rich content like attachments, tags, assignees, and rich text. * Add conditional visibility rules to any field, section, or component, driven by other field values, stage, or user and group permissions. * Rules are evaluated per user and per record, so the same record can show different information depending on who is viewing it and its current state. **Multi-Select Picklist Badges** Record Details - Multi-select picklist fields on a record now show every selected value as its own badge, so you can read the full set at a glance instead of only the first value with a "+N" counter. * Each badge displays the option's configured icon alongside its label, and badges stay in the order the values were saved. * Long value lists stay compact: the field collapses to about two lines with an inline "Show more" / "Show less" control that reports the exact number of hidden values. * Display only — this replaces the old hover tooltip and changes nothing about how you edit picklists or which values are stored. Record view is the only surface affected; List View, Board View, and mobile are unchanged for now. ### Automations **Sort and Limit on Search Records Action** Automations - The Search Records automation action can now sort results by one or more fields and cap how many records it returns, so downstream steps only receive the records that matter. * Sort results by one or more fields in ascending or descending order. * Order by multiple fields, with results sorted by the first field and then by each subsequent field in priority order. * Set a limit between 1 and 500 to cap how many records pass to downstream steps such as Repeat for Each. ### Platform **SIP Trunking Provider** Org Settings - Bring your own telephony provider to Elementum by connecting SIP trunk-enabled phone providers to power voice agents. * Enable the SIP Trunk option in Organization Settings (available to Org Admins). * Configure the provider with username and password credentials, then use the callback URL Elementum provides to complete setup on the provider side. * Assign the provider when setting up phone numbers for voice agents. **Voice: Employee ID with OTP Authentication** Org Settings - Voice agents support a new phone authentication type where callers verify with their employee ID and a one-time password sent by email, so any employee can reach an agent from any phone. * Admins configure "Employee ID w/ OTP" as a phone authentication type on a voice agent. * Callers reach the agent without a pre-registered phone number. * Callers provide their employee ID, receive a one-time password by email, and speak or type the OTP to authenticate. **Voice: Organization Management** Org Settings - A single management surface brings all voice telephony configuration — phone numbers, providers, SIP settings, and voice agent mappings — into one place in Organization Settings. * Phone Numbers tab: view, add, and edit every provisioned number across the org, with provider, type, gateway, and language at a glance; searchable and sortable. * Phone Providers tab: configure carrier-managed and SIP trunk providers, and manage your org's SIP domain and allowed IP addresses with validation. * Voice Agents tab: see every voice-enabled agent with its app, gateway, and assigned numbers, plus active/inactive gateway status and surfaced configuration gaps. ## July 9, 2026 ### Agents & AI **Studio Agents: Flow Builder** Intelligence - Build automations, agents, and flows in Elementum through natural language with a coding-based agent. * Configure a Studio Agent with a supported model (currently Anthropic). * Describe what you need and watch the agent generate each step of the flow. * Preview the workflow and continue chatting to refine each step. * After publishing, manually edit each step. **Updated Agent Overview Page** Intelligence - The agent detail page opens to a refreshed overview with read-only configuration settings at a glance, matching the design of the gateway page. Click into any section to edit that area of the agent's configuration. ### Apps **Org Default Columns** Apps - App admins can now adjust which columns appear in Table View Widgets for everyone with access. * Open **Display Settings** on a Table View Widget to adjust which columns are visible. * Individual users can still adjust their own column view on top of the default. * If a user has personalized the layout, they can click **Reset to Default** in Display Settings to restore the admin-defined view. ### Platform **Custom Platform Branding** Org Settings - Set a custom accent color and logo that carry across the platform so external collaborators immediately recognize which customer they're working in, reducing wrong-account mistakes. * Available in Organization Settings to Organization Admins. * Accent color applies to primary buttons, links, active states in main and sub navigation, icon hover states, and the login flow. * Add a custom logo to appear on the login page and the Elementum organization icon. ## July 23, 2026 ### Agents & AI **[Dynamic Dropdowns on Agent-Driven Forms](/ai-agents/agents-tools-and-deployment#dynamic-dropdowns)** Intelligence **[Custom AI Provider](/ai-agents/ai-services#configure-a-custom-provider)** Intelligence **[Advanced Skill Discovery](/ai-agents/agents-skills#tune-skill-discovery)** Intelligence **[Cross-App Skill Sharing](/ai-agents/agents-skills#share-skills-across-apps)** Intelligence **[Agent Context Management via Summarization](/ai-agents/agents-experience#conversation-history)** Intelligence **[Voice Agent Authentication Configurability](/ai-agents/agents-phone-integration#voice-properties)** Intelligence **[Agent Evaluation Suites](/ai-agents/agents-evaluations)** Intelligence ### Apps **[Presence in Automations](/workflows/automation-system#viewer-presence)** Apps **[Schedule Trigger in Automations](/workflows/automation-triggers-reference#schedule)** Apps **[Linked Record Approvals](/workflows/approval-processes#linked-record-approvals)** Apps **[Execution History Filters](/workflows/automation-system#execution-history-filters)** Apps ### Automations **[Accept Files Through Run Agent Task](/workflows/agent-task-automation#file-inputs)** Automations **[Agent Email Conversation Action](/workflows/automation-actions-reference#initiate-email-conversation)** Automations ### Experience **[Fulfiller In-App Experience](/getting-started/home-page#customize-the-navigation-menu)** Navigation ### Platform **[AI Provider Failover](/ai-agents/ai-services#configure-provider-failover)** Org Settings **[Bedrock IAM Role Authentication](/ai-agents/bedrock-setup#step-1-prepare-aws-authentication)** Org Settings **[External User Re-Authentication](/administration/external-user-reauth)** Org Settings **[Organization Model Migration](/ai-agents/ai-services#migrate-a-model-across-the-organization)** Org Settings **[Voice Agent Gateway](/ai-agents/agent-gateways#voice)** Org Settings ## July 22, 2026 ### Apps **App Maintenance Mode** Apps - App admins can temporarily take an App offline while making updates, replacing its content with a maintenance page for users. * Turn on **Under Maintenance** in the App's settings to show users a maintenance page with instructions to contact their administrator. * App admins retain access to settings while maintenance mode is enabled and can restore the App immediately by turning off the toggle. * Scheduled automations and other background work continue running while the App is under maintenance. ## July 17, 2026 ### Agents & AI **TIFF File Support for Agents** Intelligence - Agents can now process and understand TIFF file contents passed in via chat or automation, removing a file-format gap for enterprises that rely on TIFF for scanned documents, images, and legacy archives. * Works across all agent interaction surfaces where file attachments are supported. * No additional configuration required — agents on multimodal-capable models interpret TIFF content automatically. ## July 15, 2026 ### Agents & AI **Conversation Timeout & Record Creation for Elementum Chat** Intelligence - Admins can now configure an inactivity timeout and post-conversation record creation for agent chats in Elementum, matching the behavior already available on Voice, A2A, Teams, and Slack. * Set an inactivity timeout on agent chats in Elementum so idle conversations close automatically. * Configure whether a record is created when an Elementum chat ends. * The "Agent Conversation Ended" automation trigger now supports Elementum as a conversation channel type, enabling the same post-processing workflows available on other channels. ## July 10, 2026 ### Automations **Saving Attachments Between Apps and from Agents** Automations - Copy files between records of different types and save files from agent interactions directly in automations. * Copy a file from a record of one type to a record of a different type within an automation, enabling cross-app file workflows. * Save a file provided by a user during an agent interaction to a record in an automation. ## July 8, 2026 ### Platform **Organization Admin Object Visibility** Org Settings - Users assigned the **Admin** role in **Org Settings → Roles & Permissions** can now see every Object (Apps, Elements, Tasks, Tables) and every record in the organization, without being explicitly granted access through data access policies or record sharing. * Applies to **Organization** Admins only. Object-level admins (assigned inside an individual App, Element, or Task) remain scoped to that Object. * Read access extends across all Apps, Elements, Tasks, and Tables in the org, including Objects an Admin has not been added to. * Records are visible regardless of [object data access policies](/workflows/object-data-access) or per-record sharing — Org Admins can read any record for audits, compliance reviews, or emergency support. * Visibility is **view-only**. Edit, update, delete, and other write actions remain governed by the Admin's existing role assignments and any Object-level permissions. * Activity by Org Admins reading records they would not otherwise see is captured in the [activity log](/administration/activity-log) for audit purposes. ## July 6, 2026 ### Agents & AI **Generate Embeddings via Bedrock Models** Org Settings - Generate embeddings natively inside automations using your own Bedrock account, without leaving Elementum. This does not replace AI Search; it's for custom implementations where the raw embeddings are needed. * Add Amazon Bedrock embedding models in AI Services and use them in the AI Transform automation task. * Optionally configure embedding dimensions per model. * Resulting embeddings are available as a reference for use in downstream automation steps. ## Stay in the loop # Release Notes Source: https://docs.elementum.io/release-notes/overview Monthly release summaries, upcoming features, and earlier platform releases for Elementum. Browse release documentation by topic. Monthly notes summarize what shipped in general availability; the upcoming features list covers capabilities in development or beta before general release. ## All release pages See what is in beta and may reach general availability next. Elementum platform releases for September 2026. Elementum platform releases for August 2026. Elementum platform releases for July 2026. Elementum platform releases prior to July 2026, including June 2026 and earlier. ## Stay in the loop # Previous Releases Source: https://docs.elementum.io/release-notes/previous-releases Elementum platform releases prior to July 2026. ## June 2026 #### Workflow Automation **Schedule Trigger in Automations** - Run automations on a recurring time-based cadence without setting up a Data Mine. **Execution History Filters** - Search and filter automation execution history by record, status, and timeframe. **Presence in Automations** - See who else is viewing the same automation configuration page. **Accept Files Through Run Agent Task** - Pass files directly to an agent through the Run Agent Task automation action. **Agent Email Conversation Action** - Start agent-led email conversations from an automation with the **Initiate Email Conversation** action. **Multi-Domain Sending in Automations** - Choose which verified email domain an automation uses in the Send Email Notification action. #### AI Agent Orchestration **Agent Evaluation Suites** - Define repeatable test suites on agents to catch regressions from prompt, model, or tool changes. **Cross-App Skill Sharing** - Configure agents with skills from any app in your organization. **Advanced Skill Discovery** - Control skill access policies and tune discovery with aliases, keywords, and routing priority. **Voice Agent Gateway** - Assign a single phone number to an Agent Gateway with pre-agent authentication, language detection, and intent routing. **Voice Background Noise Configuration** - Turn background sound on or off per voice agent. **Agent .ics File Support** - Agents receive and parse `.ics` calendar files shared in conversation. #### Application Design **Expand Table View Option for XS/S/M Dashboard Lists** - Open small table widgets in a full-size modal from a dashboard. #### Platform Management **Triggered By Value References for On-Demand Triggers** - Access the triggering user's identity and organizational context on On-Demand Triggers. **Environment Role Membership & Deployment Permissions** - Manage environment-specific role membership and a separate **Deploy Apps** permission per environment. *** ## May 2026 #### AI Agent Orchestration **Dynamic Dropdowns on Agent-Driven Forms** - Populate Ask User Question dropdowns from live platform data, with single- or multi-select responses and in-dropdown search. **Custom AI Provider** - Connect any OpenAI-compatible endpoint in AI Services, authenticated by API key or OAuth, for use across organization agents and automations. **Agent Context Management via Summarization** - Automatically summarize earlier messages as a conversation approaches the model's token limit so agents stay responsive across longer interactions. **Voice Agent Authentication Configurability** - Tailor voice authentication limits and messages per agent, including in-call PIN requests and custom failure messages. **Teams Inbound Attachments** - Send file attachments to agents directly in Microsoft Teams so the agent can process the file as part of the conversation. **Excel and Doc File Support on Agents** - Process .xlsx and .docx files natively, converting them to preserve embedded images and signatures before they reach the model. **Gateway Session History** - Review a complete session history of conversations routed through a gateway, including the agents involved and sub-conversations per session. **AI Provider Failover** - Configure failover providers so traffic reroutes automatically when the primary AI provider is unreachable and the backup is active. **Organization Model Migration** - Migrate every usage of an AI model to a different model in a single action, with a preview of affected automations and progress tracking. **Anthropic AI Provider** - Add Anthropic as an AI provider and configure Claude models across agents and automations, with Claude supported as a primary model on Studio Agents. #### Workflow Automation **Linked Record Approvals** - Run an approval template multiple times on a single record, each tied to linked records, to sign off on individual line items. **Execute Script Action Built-In File Reader** - Configure a script action's structured outputs directly within the action, without a separate File Reader. #### Application Design **Fulfiller In-App Experience** - Streamline navigation to show only the items a user has permission to access, hiding categories with no accessible items. #### Platform Management **External User Re-Authentication** - Require external users to periodically re-verify their identity via magic link, with configurable session duration and link validity. **AI Agent Trace Forwarding (OTEL + GenAI)** - Forward AI agent telemetry traces to external observability platforms via configurable OTEL endpoints, with connection testing and per-environment assignment. **Last Login Display** - See the date and time of your last successful login, and let Org Admins view last login timestamps for every user from the users list. **Account Lockout & Auto-Recovery** - Automatically lock accounts after five failed login attempts, restorable through the Forgot Password flow, with a Locked icon on the users list for admins. *** ## April 2026 #### AI Agent Orchestration **Skill Tool Types** - Configure agent skills with new tool types (Search Record, AI Search, Create Record, Update Record, Automation) that execute natively without a supporting automation. **Ask User Question Tool** - Collect structured user input during agent chats through in-chat forms controlled by agent instructions. **AI Powered Documentation Assistant** - Chat with the AI Docs Assistant from the Help icon for how-to and informational guidance across Elementum, with quick-link topics for popular articles. **Conversation Ended Tracking for A2A** - Trigger follow-up workflows when A2A conversations wrap up, with configurable record creation and timeout behavior. **Voice Agent Caller Authentication** - Authenticate callers with MFA passcodes and scope voice agents to run as the current caller. **Agents on Admin Managed Views** - Attach agents to Admin Managed Views, including a full-page chat experience for the new Agent view type. **Updated Provider Management Page** - Configure AI providers and models from a unified list, with the Features tab scoped to feature-model configuration. **Multi-Agent Gateway** - Connect one Agent Gateway to a curated set of agents, and assign a gateway to the Elementum homepage for unified chat. #### AI Search **AI Search on Tables** - Bring AI Search directly to the Tables object with multi-field search across semantic and keyword search per field. **Link to Existing Cortex Search Service** - Reuse an existing AI Cortex search service on a Snowflake table from any App or Element without recreating it in Elementum. #### Workflow Automation **Automation Tracing** - Step-by-step execution traces with live input/output inspection and a 72-hour rapid recovery window for debugging. **Execute Script Action Record List** - Bulk-change multiple records in a single Execute Script action with new Record and List of Record value references. #### Application Design **Admin Managed Views** - Configure customized List, Kanban, Dashboard, Calendar, and Agent views at the admin level with default filters, sorting, column visibility, row density, and sharing controls. **Navigation Sidebar Redesign** - Flexible sidebar layout with new icons, floating previews on hover, pinning, and optional labels. #### Platform Management **Environment Category Indicators** - Assign Development, Test, Stage, or Production categories to environments with color-coded indicators, a fly-out selector, and switch notifications. **Managed Groups Visibility** - Toggle Mentionable, Watchable, Assignable, Approvers, and Data Access permissions on system-managed groups. **User Group Visibility** - See a user's profile and all group memberships on the new User Detail page for faster audits. **App Deployment History** - Full deployment log per App with source and target environment, initiator, timestamp, outcome, and error details. *** ## March 2026 #### AI Agent Orchestration **Agent Skills** - Agents discover and execute Skills at runtime, with admin control over which skills each agent can access. **Pre-Loaded Skills** - Pre-load up to 3 skills on an agent so recurring tasks execute instantly without runtime discovery. **Agent Instructions Version History** - Track changes to agent instructions, compare versions side-by-side, and revert to a previous version when needed. **Agent Conversation History Waterfall View** - Waterfall breakdown of all requests in a conversation, with timing and message previews to debug agent performance. **Multi-Modal on Gemini-Powered Agents** - Attach images or PDFs in messages to Gemini-backed agents in the Admin Builder, Personal Assistant, and Record Details. **Tactical A2A Responses** - Receive streamed A2A messages from Elementum agents. #### AI Search **AI Search Table Creation Enhancements** - AI Search tables are created immediately with status indicators, support one-click retry on errors, and accept input value references for filters. **AI Search from Automations** - Add an AI Search action to automations, run dynamic semantic queries, and pass the results into downstream actions. #### Workflow Automation **Search Group Action** - Programmatically locate user groups by name during execution and pass resolved groups into downstream actions such as comments and notifications. **Limit Automation Actions Per Execution** - Default cap of 1,000 actions per workflow execution to prevent runaway loops. **Automation Versions** - View previously published automation versions and start a draft from any earlier version. **Trigger User Action Automations on Record Details** - Trigger automations directly from user-initiated actions on a record. **Webhook Trigger Custom Response Bodies** - Define JSON, cXML, or TEXT response bodies for webhook triggers to integrate with external systems. **Base64 Utility, Script Docs, and Testing** - Base64 encode/decode helpers, in-editor documentation, and a script testing experience inside Execute Script actions. #### Workspace & Data **Global Filters for Elements, Tasks, and Charts** - Apply global filters to Elements, Tasks, and Charts widgets for consistent data across workspace views. #### Record Experience **Real-Time Collaboration on Records** - See who else is viewing a record and where they are focused inside workspaces and objects to avoid conflicting changes. #### Channels **Accept Files Through Slack Agents** - Send file attachments to Elementum agents from Slack workspaces. #### Reporting **Report Layout Configuration Flexibility** - Custom PDF report formatting with reference value display, merged cells, text styling, and template duplication. *** ## February 2026 #### AI Agent Orchestration **Starting Actions for Agents** - Pre-configured action chips appear in chat before a user's first message, with optional inline forms to collect inputs. **Copy Agent Tools** - Duplicate or move tools across agents within an app, with auto-generated names to prevent conflicts. **Voice Agent Model Configuration** - Select the model powering voice experiences over the phone, including OpenAI GPT-4o Mini and xAI Grok 4.1 Fast. **Show Tool Calls in Chat** - Real-time visibility into when agent tool calls are running and completed. #### Workflow Automation **Run an Automation Button** - Add custom buttons to record layouts to trigger workflows, with custom labels, icons, integrated pop-up forms, and live status updates. **Reorder Actions** - Drag-and-drop handle to reorganize automation actions and Logic blocks, with real-time validation and an Undo button. #### Application Design **QR Code Scanning Support** - Contextual QR scanning directly within record fields, with downstream automations to parse the data across the record. #### Platform Management **Multi-Factor Authentication** - TOTP-based MFA using apps like Okta, 1Password, or Google Authenticator to protect against compromised passwords. **Activity Log Refresh** - Consolidated timeline across Support, Tasks, and App Admin records with searchable entries and click-to-expand before/after views. *** ## January 2026 #### AI Agent Orchestration **Copy Agent Configuration** - Duplicate existing agents with complete configurations for rapid deployment and iteration. **Field Filtering for Record Search** - Select specific fields in record searches to improve agent performance and manage context windows. #### Workflow Automation **Service Account Management** - Securely manage non-human access with automatic permission validation and access warnings. *** ## December 2025 #### AI Agent Orchestration **MCP Tool Protocol** - Standardize how agents run actions between systems with a unified protocol. **A2A Self-Signed JWT Auth** - Flexible authentication for agent-to-agent communication with automated key rotation. **Bedrock Agent Management** - Orchestrate specialized AWS agents alongside your existing fleet. **Custom OpenAI Endpoints** - Use your approved OpenAI or Azure endpoints globally without changing workflows. **Reasoning Effort Control** - Adjust AI reasoning depth from minimal to high for complex, multi-step tasks. #### Workflow Automation **Email Attachments** - Send generated reports and files directly from automation workflows. **Interventions Dashboard** - Monitor automation failures with metrics, alerts, and admin notifications. **Out-of-Office Status** - Automatically skip unavailable users in assignment workflows. **Slack Message Triggers** - Start automations from Slack messages with full content and metadata access. **API-Powered Elements** - Dynamically fetch real-time data from external APIs in your fields. *** ## November 2025 #### AI Agent Orchestration **Embedded Flow Agents** - Build intelligent workflows by embedding agents directly into your Flows. **Secure Portal Operations** - Agent tools execute with current user permissions for secure, portal-ready workflows. **End-to-End Agent Workflows** - Server agents now handle complete workflow execution from start to finish. **Snowflake Agent Management** - Manage and scale your agent operations seamlessly through Snowflake connections. #### Workflow Automation **Simplified File Processing** - Connect File Readers directly to Data Mining without additional App Record setup. **Streamlined Trigger Configuration** - New intuitive UI makes automation trigger setup faster and easier. *** ## October 2025 #### Integrations **OAuth Support** - Seamless OAuth authentication for secure API integrations. **Flexible API Formats** - Support for XML and plain text in API requests. #### Collaboration **Slack Integration** - Instant answers and agent integrations directly in Slack. #### AI Agent Orchestration **Language Routing** - Automatically route voice calls based on caller language. **Agent Task Automation** - Trigger and assign agent tasks through workflows. **Automated Calling** - Start agent phone calls directly from automations. **Multi-Agent Orchestration** - Enable agents to delegate tasks to other agents. #### Workflow Automation **XML Processing** - Process XML files within automation workflows. **Webhook Support** - Handle webhook payloads in automation triggers. **Script Execution** - Execute JavaScript scripts within automations. *** ## September 2025 #### AI Agent Orchestration **Voice Agent Enhancements** - Idle messages to keep callers engaged and custom start messages for agent tools. #### Workflow Automation **Real-Time Notifications** - Automate real-time notifications for key users. *** ## August 2025 #### AI Agent Orchestration **Multilingual Voice Agents** - Voice agents support additional languages including Chinese, Korean, and Thai. #### Workflow Automation **Phone-Based Workflows** - Launch workflows via AI agent phone calls for real-time assistance. **Notification Controls** - Configure notification settings at the app level. **Related Items Discovery** - Find related items in automations with flexible filtering and sorting. ### Enhancements #### Platform Management **Granular Permissions** - Manage roles and permissions at the individual app level. *** ## July 2025 #### AI Agent Orchestration **Agent Automation Triggers** - Agents can trigger automations directly for streamlined execution. #### Application Design **Streamlined Setup** - App creation wizard with optional access policy configuration. **Agent-Driven Workflows** - On-demand automation triggers for agent-driven deterministic workflows. **Inline Editing** - Edit rich text fields directly in List View. **Email Automation** - Automate custom email notifications with dynamic content. **BI Integration** - Create views for seamless BI tool integration. ### Enhancements #### Collaboration **Enhanced Messaging** - Threading, reactions, and editing for better communication. **Activity Tracking** - Track creation details and changes for better visibility. **Shared Dashboards** - Admins can manage and share dashboards across users. *** ## June 2025 #### AI Agent Orchestration **AI Agents** - Incorporate AI agents into your workflows and business processes with natural language design and workflow integration. #### Application Design **Workflow Health Monitoring** - Quickly assess workflow health with visual indicators and detailed run history. **AI-Powered File Processing** - Extract and query data from files using AI for dynamic automation workflows. **Validation Tools** - Identify and handle broken value references in automations. #### Platform Management **Expanded AI Support** - Support for OpenAI GPT 4.1. ### Enhancements #### User Experience **Streamlined Preview** - Faster record data preview with fewer clicks. **Enhanced Triggers** - Improved trigger management capabilities. *** ## May 2025 #### Workflow Automation **Organizational Hierarchy** - Access user's manager information in automations for dynamic workflow routing. **Flexible Relationships** - Multi-select dropdowns to support many-to-many data relationships. **File Processing** - Unzip files in automations and process individual files from archives. #### Platform Management **Expanded AI Support** - Support for OpenAI GPT models. ### Enhancements #### Workflow Automation **Graceful Error Handling** - Handle API failures elegantly within workflows. **Automatic Metrics** - Automation savings metrics are now saved automatically. **Loop Controls** - Reference first and last iterations when processing loops. *** ## April 2025 #### Workflow Automation **Text Processing** - SPLIT function for processing text data in automation calculations. **Approval Exceptions** - Exception option in approval processes to trigger specific workflows. **User Interaction Controls** - Lock records during automation to improve user experience and prevent conflicts. #### Platform Management **Flexible Timeout Settings** - Configure inactivity timeouts separately for desktop and mobile users. **Alternative Identifiers** - Support for non-email identifiers in Single Sign-On. ### Enhancements #### Workflow Automation **Performance Controls** - Configure automation triggers for enhanced performance. **Simplified Configuration** - Click-to-add actions and triggers for faster workflow setup. *** ## March 2025 #### Platform Management **Configurable Session Timeouts** - Set custom inactivity timeouts with separate settings for desktop and mobile users. **Flexible User Identification** - Choose how users are identified in SAML—by email or external ID. #### Application Design **Approval Exceptions** - Exception handling for more flexible approval workflows. **Automation Control** - Prevent specific updates from triggering automation chains. ### Enhancements #### Workflow Automation **Simplified Configuration** - Click any action to add it directly to your workflow. **Real-Time Visibility** - See active automations mid-progress on record details and list views. **Enhanced Stage Layouts** - Improved stage layout management with better guidance and navigation. #### User Experience **Streamlined Details** - Cleaner Record Details page with improved focus. **Clear Hover States** - Better visual feedback for ID fields across all views. **Organized Settings** - Display settings relocated for easier access. *** ## February 2025 #### AI Capabilities **DeepSeek R1 Support** - Cost-effective reasoning model for complex analytical tasks. **OpenAI o3-mini** - Enhanced problem-solving with improved efficiency and speed. #### Analytics & Reporting **Modernized Dashboards** - Refreshed design with improved layouts and enhanced readability. #### Application Design **Flexible Layout Options** - More flexible positioning for related items in record layouts. **Redesigned Approvals** - Updated approval interface with clearer status indicators. **JSON Field Type** - Store and work with structured JSON data directly in records. #### Workflow Automation **Automated Reporting** - Generate custom reports automatically at key workflow stages. **File Upload Workflows** - Send files to external systems via automation actions. #### Data Management **Bulk Operations** - Manage multiple relationships simultaneously for efficient data maintenance. **JSON Processing** - Process JSON files and API responses in automations. #### Integrations **Flexible Authentication** - Configure custom headers for OAuth-enabled API requests. #### Platform Management **Custom Email Domains** - Send emails from your organization's domain for improved deliverability. #### Advanced Features **Custom Functions** - Define custom functions for sophisticated data processing. *** ## January 2025 #### Application Design **Related Record Workflows** - Find and retrieve related records in automations for dynamic workflows. **Improved Settings** - Enhanced visibility for display settings controls. **Enhanced Date Selection** - Quick navigation to distant dates with improved date picker. **Modernized Interface** - Refreshed configuration interface with clearer organization. **Filtered Selection** - Filter available records when creating relationships for faster connection. #### Workflow Automation **Unified Approval Workflows** - Consolidated approval trigger for simplified configuration. **Consistent Builder Experience** - Unified automation interface across the platform. **Approval Context** - Access approval details directly in workflow triggers. **Enhanced API Integration** - Better handling of API responses in automations. #### Data Management **Configuration Interface** - Dedicated interface for managing table settings. #### Integrations **OAuth Support** - Secure integration with modern APIs using OAuth 2.0. **Teams Integration** - Send automated messages directly to Microsoft Teams channels. #### User Experience **Quick Preview** - Preview Kanban cards without leaving board context. *** ## December 2024 #### Application Design **Self-Assignment** - Automatically assign new records to their creator. **Consistent Processing** - Unified behavior across all record creation methods. **Resizable Previews** - Adjust preview panel width to optimize screen space. **Enhanced Error Pages** - Clearer guidance and helpful navigation for errors. **Automatic Recovery** - System automatically maintains data infrastructure integrity. **Default Protection** - Configure fields to be locked by default for security. **Data Governance** - Visibility into data storage locations for governance and troubleshooting. #### Workflow Automation **Protected Field Updates** - Automations can update locked fields while maintaining user restrictions. #### Integrations **Dynamic API Integration** - Pass record data dynamically to external systems. #### Mobile Experience **Enhanced Navigation** - Improved mobile navigation with faster transitions and better touch interactions. #### User Experience **Task Management** - Improved interface for managing background operations. *** ## November 2024 #### Application Design **Stage-Based Layouts** - Customize record layouts for each workflow stage to focus users on relevant information. **Enhanced Image Editor** - Improved editor with persistent preferences across sessions. **Mobile Navigation** - Enhanced mobile experience with better touch targets and streamlined menus. #### Workflow Automation **Approval Metadata** - Access approval completion details in automation triggers. #### Data Management **Complete Excel Support** - Support for all Excel file types for automated data extraction. **Enhanced Processing** - Better handling of unstructured spreadsheet data. #### Surveys **Flexible Survey Editing** - Remove and restructure survey pages without rebuilding. *** ## October 2024 #### Analytics & Reporting **Unified Dashboards** - Combine data from multiple applications on a single dashboard. **Optimized Exports** - Report images automatically optimized for easy sharing. #### Application Design **Access Controls** - Appropriate user visibility based on access boundaries. **SLA Management** - Configure service level agreements with detailed tracking. **Smart Assignment** - Automatically assign work based on team availability and workload. **Enhanced Bulk Uploads** - Faster processing for high-volume data imports. #### Workflow Automation **Dynamic Assignment** - Automate work routing based on workload and availability. **Comment-Based Triggers** - Trigger workflows when comments are added to records. #### User Experience **Optimized Images** - Images automatically sized for optimal performance. **Persistent State** - Kanban column selection remembered across sessions. *** ## September 2024 #### AI Capabilities **Expanded AI Models** - Additional AI model options to optimize for accuracy, speed, or cost. **Mistral Large 2 Support** - Strong multilingual performance and reasoning capabilities. **OpenAI o1-mini** - Advanced reasoning model for complex problem-solving. **Llama 3.2 Support** - Latest generation of open-source AI with improved performance. #### Analytics & Reporting **Image Galleries** - Add organized image galleries to custom reports. **Professional Exports** - PDF exports maintain formatting for professional sharing. #### Application Design **Enhanced Performance** - Faster page loads across list views and dashboards. **Legacy Format Support** - Support for older document and spreadsheet formats. #### Workflow Automation **Performance Improvements** - Faster workflow execution with reduced latency. *** ## August 2024 #### AI Capabilities **Jamba Model Support** - Extended context window ideal for processing large documents. #### Analytics & Reporting **Time-Series Analysis** - Create charts with flexible date/time-based grouping. **Widget Editing** - Modify dashboard widgets without recreating them. #### Application Design **Data Protection** - Safeguards prevent accidental data loss when creating records. **Advanced Calculations** - Reference calculated fields within formulas for sophisticated logic. **Flexible Calculations** - Run calculations on dynamic dropdown relationships. **Smart Configuration** - AI service options automatically filter to supported models. **Enhanced AI Access** - Access to latest AI capabilities regardless of primary data region. **Faster Loading** - Optimized record loading for quicker page loads. #### Workflow Automation **Advanced Filtering** - More precise control over workflow triggers and actions. **Context-Aware AI** - Dynamic AI categorization that adapts based on record data. **Multi-Value Processing** - Process multi-select dropdown values individually in workflows. #### Data Management **Hybrid Data Access** - Real-time transactional data access capabilities. #### Platform Management **Consumption API** - Programmatic access to consumption data for custom reporting. *** ## July 2024 #### AI Capabilities **GPT-4o Mini Support** - Cost-effective AI model option ideal for high-volume operations. **Llama 3.1 Support** - Access to latest open-source AI capabilities with enhanced reasoning. #### Analytics & Reporting **Consistent Report Exports** - Preserved formatting across exported documents. #### Application Design **Enhanced Reliability** - Improved data sync reliability with automatic reconnection handling. **Customizable Kanban** - Choose which fields display on Kanban cards for at-a-glance context. **Improved Navigation** - Hyperlinks open in new tabs to maintain context. **Flexible Picklists** - Update dependent picklist values while maintaining validation. **Filter Management** - Modify existing saved filters as needs evolve. #### Approvals **Improved Delegation** - Enhanced interface for managing approval coverage. #### Workflow Automation **Automation Visibility** - Visual indicators show when automations are actively running. #### Data Management **High-Volume Processing** - Support for enterprise-scale data migrations and batch processing. **Expanded Capacity** - Comprehensive results for large datasets and high-volume scenarios. #### Integrations **Enhanced Security** - Private key authentication for improved security and compliance. #### User Experience **Faster Navigation** - Instant section access with improved navigation bar. *** ## June 2024 #### Analytics & Reporting **Enhanced Reports** - Add related items and images to custom reports with professional layouts. **Complete Report Exports** - Exported reports include all visual context for complete documentation. #### Application Design **SLA Tracking** - Set service level agreements for workflow stages to measure velocity. **Branded Communications** - Configure branding for external notifications. #### Workflow Automation **Enhanced History** - Better visibility into automation execution for troubleshooting and auditing. **Simplified Updates** - Update multiple fields in a single automation action. #### Data Management **AI Template Mapping** - Create file reader templates with intelligent AI-suggested field mappings. **Shareable Templates** - Include complete data ingestion workflows in marketplace templates. #### Integrations **Performance Improvements** - Faster data retrieval for external system integrations. #### User Experience **Consistent Filtering** - Full filtering capabilities across all view types. #### Collaboration **Participant Management** - Granular control over external chat conversations. *** ## May 2024 #### AI Capabilities **Dynamic AI Classification** - AI classification with live data and full auditability. **AI Q\&A** - Ask natural language questions about records and get AI-generated answers. **Expanded AI Models** - Additional AI model options to match performance and compliance needs. **GPT-4o Support** - Faster processing with cost efficiency across AI-powered features. **Enterprise AI Integration** - Run AI entirely within your cloud environment for enhanced security. **AI Cost Visibility** - Track AI usage costs alongside ROI calculations. #### Analytics & Reporting **Custom Report Designer** - Create highly customized report layouts from multiple data sources. #### Application Design **Dynamic Relationships** - Define flexible automatic connections between records using filters. **Enhanced Editor** - Advanced formatting capabilities for professional documentation. **Advanced Formatting** - Custom number display formats for cleaner, more readable data. **Expanded Filters** - More precise control over chart data and time ranges. **Persistent Preferences** - Automatically save and restore filter selections across sessions. #### Data Management **Widget Configuration** - Configure sort order for dashboard widgets. **Document Processing** - Automated data extraction from Word documents. **Inline Editing** - Make changes directly within aggregated data views. #### User Experience **Enhanced Task Management** - Sort and filter work across all applications to prioritize effectively. *** ## April 2024 #### AI Capabilities **AI Conversation Summaries** - Generate instant summaries of conversation threads. **AI Document Extraction** - Automatically extract structured data from document images. **AI Anomaly Detection** - Automatically detect anomalies and outliers in data patterns. **Explainable AI** - AI classification with transparency into reasoning and decision-making. **AI Contract Analysis** - Automatically extract key terms from contracts for compliance. #### Application Design **Multi-Level Dropdowns** - Create complex dependent dropdown chains for guided selection. **Smart Filtering** - Show users only relevant options based on their attributes. **Quick Record Creation** - Rapid creation of related records directly from current record. **Customizable Sorting** - Control display order of dropdown values. **Advanced Filtering** - Comprehensive filtering with complex logic and saved presets. #### Data Management **Enhanced Filtering** - More precise control over data views and analysis. #### Integrations **Enhanced Security** - Improved authentication for cloud data connections. #### Platform Management **Historical Tracking** - Track changes to consumption rates over time. #### User Experience **Kanban View** - Visual board view for workflow and project management. *** ## March 2024 #### Application Design **Usage Alerts** - Proactive alerts about platform consumption within the Flow Designer. **Task Queue Visibility** - View all background tasks with progress tracking. #### Approvals **Enhanced Approval Context** - Preserved formatting in approval fields for better readability. #### Workflow Automation **Email Attachment Processing** - Automatically process and associate email attachments with records. #### Data Management **Enhanced Error Handling** - Clear diagnostics and automatic cleanup for failed operations. **On-Demand Validation** - Validate configurations before activating scheduled execution. **Data Relationships** - Create connections between aggregated and detailed data. #### Integrations **Cross-Platform Analytics** - Work with data across multiple cloud connections simultaneously. #### Platform Management **Flexible Pricing** - Configure consumption rates to align with business value. *** ## February 2024 #### AI Capabilities **AI Summarization** - Automatically summarize multiple field values into concise summaries. **AI Classification** - Automatically classify and categorize records using AI. #### Application Design **Inline Testing** - Test and validate calculated fields directly in the configuration interface. **Precise Time Calculations** - Support for exact hour and minute calculations in date fields. **Dependent Dropdowns** - Create nested dropdown relationships that filter options based on selections. **Secure Data Storage** - Store all conversation history with complete data control. **Unified Workflow Editing** - Modify automation logic directly within the Flow Designer. #### Approvals **Contextual Notifications** - Include dynamic field values in approval emails for informed decision-making. #### Workflow Automation **Email Workflow Templates** - Rapid deployment of email-to-record workflows. #### Marketplace **Configuration Management** - Manage user assignments and permissions for marketplace templates. **Pre-Configured Filters** - Templates include ready-to-use filtered views and reports. **Advanced Templates** - Include sophisticated data transformations in marketplace templates. #### Surveys **Survey Sharing** - Export and import complete survey configurations. #### User Experience **Regional Preferences** - Set preferred date format for regional display preferences. *** ## January 2024 #### Analytics & Reporting **Application Dashboards** - Create dedicated analytics dashboards with pre-configured charts and metrics. **Template Analytics** - Get insights from newly installed applications immediately with included analytics. #### Application Design **Persistent Preferences** - Your task list preferences are preserved across sessions. **Email Management** - Add BCC recipients to automated emails for oversight and record-keeping. **Personalized Notifications** - Enhanced email notifications with sender identification. **Multilingual Support** - Translate field labels and dropdown values for global teams. **Custom Styling** - Add colors and icons to dropdown options for better visual identification. **Secure File Storage** - Store attachments with complete control and visibility. #### Approvals **Approval Templates** - Export and import approval configurations with marketplace templates. **Dynamic Approval Routing** - Context-aware approval routing based on record data. **Enhanced Approval Interface** - Improved clarity and management of approval workflows. #### Workflow Automation **Template Automation** - Import pre-configured automations with marketplace templates. #### Data Management **Redesigned Interface** - Improved navigation and organization for data operations. **Template Data Views** - Deploy applications with pre-built data aggregation views. **Complete Workflow Templates** - Import complete data analysis workflows instantly. #### Marketplace **Communication Templates** - Pre-built response libraries to accelerate communication workflows. **Visual Flow Diagrams** - Understand application structure before installation. **Enhanced Marketplace** - Improved browsing experience and categorization. #### Platform Management **Usage Alerts** - Automatic notifications for platform consumption thresholds. #### User Management **Dependency Protection** - Warnings about dependencies to prevent accidental disruptions. *** ## December 2023 #### Platform Performance **Background Processing** - Long-running operations run in the background without blocking your work. #### Data Management **Record Export** - Export individual records for sharing with external stakeholders. **Template Flexibility** - Configure imported templates to use your existing elements for consistency. #### Marketplace **Template Management** - Administrative interface for publishing and managing templates. **Template Catalog** - Browse pre-built templates with search and preview capabilities. **Guided Installation** - Intuitive installation process for marketplace templates. #### Surveys **Advanced Survey Design** - Create multi-page surveys with custom sections and instructions. *** ## November 2023 #### Analytics & Reporting **Usage Dashboard** - Track platform usage across workflows and data processing. #### Application Design **Usage Analytics** - Monitor usage patterns and engagement metrics to optimize adoption. **Custom Branding** - Customize emails and surveys with your organization's branding. **Real-Time Collaboration** - See updates from other users across all views without refreshing. #### Workflow Automation **Enhanced Automation Builder** - More intuitive interface for creating complex workflows. **Conditional Branching** - Add switch-based conditional logic for multiple workflow paths. **High-Volume File Processing** - Process large files through automation actions. **Dynamic User Management** - Query and retrieve user information for dynamic assignments. **Personalized Notifications** - Create context-aware automated messages. **Inline Calculations** - Perform calculations directly within automation actions. **External Data Integration** - Connect to external systems for data transformations. #### Marketplace **Pre-Built Templates** - Browse and install application templates for rapid deployment. #### Platform Management **Flexible Pricing** - Configure consumption rates to align with business value. #### Surveys **Automated Reminders** - Send reminder notifications to increase survey completion rates. **Enhanced Survey Management** - Improved administration interface for survey management. #### User Experience **Streamlined Admin Experience** - Comprehensive improvements focused on ease of configuration. #### User Management **Automated User Provisioning** - Automatically provision and manage users through your SSO provider. *** ## October 2023 #### AI Management **Centralized AI Control** - Configure which AI models are available for your organization. #### Platform Performance **Enhanced Performance** - Significant speed improvements for faster page loads across all applications. **Improved Error Handling** - Better troubleshooting information without blocking navigation. #### Workflow Automation **Advanced Record Operations** - Query and update records within single automation actions. #### Data Management **File Processing** - Import and process data from Excel files automatically. #### Surveys **Survey Builder** - Create reusable survey templates integrated into workflows. **Visual Survey Design** - Configure surveys within the Flow Designer. #### Collaboration **Real-Time Updates** - See record changes instantly without refreshing. *** ## September 2023 #### AI Capabilities **AI Translation** - Automatically translate text fields into multiple languages for global teams. **AI-Powered Design** - Get intelligent field recommendations when building forms. **Flexible AI Integration** - Choose between AI providers to meet security and compliance requirements. #### Application Design **No-Code Form Builder** - Create custom intake forms with drag-and-drop interface. **Comprehensive Audit Log** - Track all changes and activities within applications. **Flexible Workflows** - Easily reorder workflow stages as processes evolve. **Unified Task Management** - View all assigned work in a single consolidated list. **Safety Controls** - Confirmation prompts for bulk operations to prevent accidents. #### Workflow Automation **Flexible Data Relationships** - Control how automations structure data relationships. **Batch Processing** - Process large sets of data with looping automations. #### Collaboration **Group Mentions** - Notify entire groups with @mentions. **Environment-Based Security** - Configure security requirements separately for production and testing. *** ## August 2023 #### Analytics & Reporting **Flexible Visualizations** - Configure chart types and axes for clearer insights. #### Application Design **Multi-Select Fields** - Allow users to select multiple values in dropdown fields. #### Approvals **Parallel Approvals** - Configure workflows where multiple approvers must approve simultaneously. **Approval Data Protection** - Automatically lock fields when approvals are submitted. **Approval Delegation** - Delegate approval authority to keep workflows moving. **Enhanced Approval Experience** - Role-specific views for requestors, approvers, and administrators. #### Workflow Automation **Precise Approval Control** - Reference specific approval chains in automations. **Cross-Application Updates** - Update fields in related records across different applications. #### Data Management **Multi-Source Analytics** - Create charts from aggregated data across multiple sources. #### Integrations **Connection Management** - Visual interface for managing cloud data connections. #### Mobile Experience **iOS App** - Native iOS application with enhanced performance and offline capabilities. #### Platform Management **Timezone Management** - Set default timezone for consistent handling across the organization. #### User Experience **Visual Form Builder** - Drag-and-drop designer for complex intake forms. **File Upload Support** - Enable file attachments on forms for supporting documentation. *** ## July 2023 #### User Experience **Enhanced Error Handling** - Clear, actionable error messages with automatic support reporting. #### Workflow Automation **ROI Tracking** - View estimated time and cost savings for each automation. **Organization Dashboard** - Overview of all applications with ROI and savings metrics. **Dynamic Approval Routing** - Route approvals dynamically based on record data. #### Data Management **Advanced Preview** - Filter and sort data when previewing tables before analysis. *** ## June 2023 #### Analytics & Reporting **KPI Displays** - Display key metrics prominently on dashboards with single-value visualizations. #### Application Design **Smart Data Relationships** - Automatically create relationships between records for seamless analytics and navigation. **Data Quality Tools** - Clean and standardize data for accurate analysis. **Streamlined Admin Experience** - Redesigned interface for faster application configuration. **Enhanced Navigation** - Updated navigation system with improved structure and organization. **Real-Time Collaboration** - See live updates and who else is viewing records to prevent duplicates. **Smart Formula Builder** - Intelligent suggestions when building calculated fields. **Advanced Calculations** - Reference dropdown values in calculated fields for dynamic logic. **Organization Hierarchy** - Manage organizational structure for reporting and workflow routing. **Data Protection** - Lock specific fields to prevent unauthorized changes. **Simplified Intake** - Request submission interface for users who don't need full application access. #### Approvals **Email-Based Approvals** - Approve or reject requests directly from email without logging in. #### Data Management **Export Capabilities** - Export multi-source data views for external sharing and analysis. #### Marketplace **Pre-Built Solutions** - Access pre-built data applications for rapid deployment. #### Mobile Experience **Android App** - Native Android application with full mobile capabilities. #### User Experience **Enhanced Forms** - Improved field configuration with helper text and guidance. **Updated Views** - Refreshed design with improved performance. *** ## May 2023 #### AI & Automation **AI-Powered Email Processing** - Automatically extract and structure data from incoming emails into actionable records. #### Analytics & Visualization **Goal Tracking** - Add target lines to charts to track progress against KPIs and business objectives. **Image Collaboration** - Edit and annotate images directly within the platform for quality assurance and reviews. #### Workflow Automation **Execution Tracking** - View detailed logs of automation triggers and executions for auditing and troubleshooting. #### Mobile Experience **Native Mobile Apps** - Enhanced mobile capabilities with offline support for iOS and Android. *** ## April 2023 #### Application Design **Advanced Filtering** - Filter related records based on field values for easier data navigation. **Visual Workflow Designer** - Map and configure multi-stage processes with visual tools. **Enhanced Analytics** - Use calculated fields in charts for sophisticated data analysis. #### Workflow Automation **Pattern-Based Triggers** - Trigger automations based on discovered data patterns and trends. **Cross-Application Workflows** - Reference data from multiple sources within automations. **Automated Data Connections** - Connect insights to relevant records automatically. **Smart Templates** - Use templates to ensure consistency when creating records. **Dynamic Context** - Build flexible, context-aware automation actions. #### Data Intelligence **Automated Data Analysis** - Schedule automated queries to discover patterns and trends in your data. *** ## March 2023 #### Application Design **Role-Based Dashboards** - Create customized dashboards assigned to specific users or groups. **Smart Data Inheritance** - Automatically populate related records with relevant field values for consistency. **Improved Navigation** - Streamlined menu structure for faster access. #### Workflow Automation **Automated Approvals** - Trigger approval requests automatically based on conditions. **Context-Aware Workflows** - Pass data between automation steps and notify users dynamically. **Multi-Step Workflows** - Build sophisticated workflows that cascade through multiple stages. #### Integrations **External System Integration** - Send data to external systems and third-party tools. #### Platform Management **Enhanced Usage Controls** - Customizable monitoring to match operational needs. *** ## February 2023 #### Analytics & Reporting **Cross-Application Analytics** - Create visualizations that show how business processes connect across applications. #### Application Design **Dynamic Data Selection** - Populate dropdown fields automatically based on your existing data. **Personalized Dashboards** - Create and assign custom dashboards tailored to different teams and roles. **Enhanced User Experience** - Redesigned home layout with improved navigation. #### Workflow Automation **Advanced Conditions** - Set automation conditions that compare values between fields. **Improved Reliability** - Enhanced automation configuration experience. #### Data Management **Streamlined Interface** - Improved visibility into data structure and relationships. *** ## January 2023 #### Analytics & Reporting **Analytics Builder** - Create custom charts and visualizations to understand data trends and gain actionable insights. #### Application Design **Cloud Data Flexibility** - Seamlessly work with data across cloud providers. **Enhanced Navigation** - Collapsible navigation that maximizes workspace efficiency. **Advanced Calculations** - Build sophisticated conditional logic in calculated fields. #### Workflow Automation **Multi-Channel Notifications** - Route automated notifications to specific channels while maintaining access controls. #### Platform Management **Usage Monitoring** - Track platform usage to understand resource utilization. *** ## December 2022 #### Analytics & Visualization **Top Charts** - Visualize your most impactful data with charts that help identify trends and priorities at a glance. **Advanced Filtering** - Filter records based on related items to analyze impacts across your data. #### Workflow Automation **Automated Communication** - Automatically add comments to records based on workflow triggers. **Approval Workflows** - Trigger automations based on approval actions for streamlined approval processes. # September 2026 Source: https://docs.elementum.io/release-notes/september-2026 Elementum platform releases for September 2026. The colored badges indicate the area of Elementum where you will see the update (for example, Apps, Tables, Intelligence, or Automations). ## September 3, 2026 ### Agents & AI **Agent Managed View Customization** Intelligence - Choose a **Standard** or **Custom** layout when you configure an Agent managed view, then brand the chat with an image, header, and subheader and build a portal-like content area beneath it. * **Standard** keeps the existing full-page Agent managed view experience. * **Custom** adds an image, header, subheader, and a JSON-defined content section with cards, lists, and static text. * Starting actions on the agent render differently in the **Custom** layout to match the branded experience. **Voice Call Handoff** Intelligence - Voice agents on SIP-based phone numbers can escalate a live call to a human or another SIP destination without dropping the caller. * Add a **Handoff** tool with the standard tool name, description, and start message fields. * Set a SIP URI **Destination** and optionally pass warm-transfer context through a customizable **Context Key Header Name**. * Combine **dynamic** headers from the agent with **static** headers on the tool when the call is transferred. **Agent Overview V3** Intelligence - The agent detail page opens to Agent Overview V3 with read-only configuration settings at a glance, matching the design of the gateway page. * Review the agent's configuration from a single overview without digging through separate tabs first. * Click into any section to edit that area of the agent's configuration. * Aligns the agent detail experience with the gateway overview layout. ### Apps **Record Work Breakdown** Record Details - Every automation action on a record is categorized as AI, Computer, or Human Action, showing at a glance how much of a record's work ran autonomously versus manually. * A work breakdown bar with a legend sits atop the **Automations and AI** panel on record details. * Hover the bar for exact percentages and action counts. * See how AI, automated, and manual steps contributed to work on the record without opening each execution. **Add Option from List View** Workspace - Add a missing option to a dynamic picklist directly from your List view, without leaving the list or navigating to the underlying element. * Type a new picklist option in a dynamic picklist cell and press **Enter** to open the **Create** modal. * Complete the required fields to create the record in the element the picklist references. * The new option becomes selectable in every dynamic picklist that references the same element. ### Platform **Deployments Overview** Org Settings - Preview a deployment with a dry run that walks the full process without writing any changes, and reopen completed runs to see exactly what they covered. * Dry runs show every App, Element, Task, and Table in scope, along with the admins responsible for each object. * Reopen any completed run—dry run or real deployment—for an audit trail of what was included. * Use the overview before and after a deployment to confirm scope without relying on memory or separate notes. ## Stay in the loop # Upcoming Features Source: https://docs.elementum.io/release-notes/upcoming-features See what we're working on at Elementum We're always trying to improve our platform for our customers. Here, you can get an inside look at what's currently in beta at Elementum. Remember, this list is provided as a heads-up—not as an invitation to test or a promise of what capabilities may be included. Most customers will not see these features until general availability. For what's available today, see the [most recent release notes](/release-notes/september-2026). ## What to expect **Heads-up, not a commitment.** The information below explains how we treat beta features and why delivery and availability can change. * **Currently being tested.** These features are in active development and testing. Behavior and scope may change. * **No guaranteed delivery date.** We do not commit to a specific release date for any feature listed here. * **No guarantee of delivery.** Priorities shift based on resources and customer needs. A feature in beta may be delayed, changed, or not released to General Availability. * **Limited availability.** Some features may be tested by select customers before being released to General Availability. Broader access is not guaranteed until a feature is generally available. * **Labs badge.** Experimental features available in the platform but still being validated are marked with an orange **Labs** badge in the Elementum UI. Treat these the same way—behavior, scope, and availability may change before General Availability. ## Features in beta This list is updated as new beta features become available to give you an idea of upcoming improvements likely to occur in Elementum. The colored badges indicate the area of Elementum where you will see the update. ### Customizable Voice Agent Authentication Emails Org Settings Authentication emails sent when users request a PIN or one-time password from a voice agent can be customized with your organization's branding and messaging. This gives users a consistent, recognizable experience when authenticating with your voice agents. ### A2A on Agent Gateway Intelligence Clients can connect to agents through the Agent Gateway using standard A2A requests, with authentication, streaming, and conversation timeouts configured at the gateway. A2A skills can be defined on the gateway using the same configuration available on individual agents. ### Org-Scoped Deployment Org Settings Deployment configuration in the target environment is shared across org admins rather than tied to whoever clicked Deploy, so any admin can pick up a deployment that is waiting on configuration and finish it. The Deployments page shows each environment's most recent deployment state at a glance—Needs Configuration, Deploying, Deployed, or Failed—and configuration progress persists across sessions and handoffs. ### Portals v1 Org Settings Org admins can create and manage portals from a new Portals page in Org Settings under Gateways, each with a name, description, icon, and shareable URL slug. Portals are built from managed views—set one as the homepage and add views from any app as menu items—so users signed in with their Elementum credentials see only the portal's branded top bar and menu, with items filtered by each view's access policy. ### Snowflake Postgres CloudLink Org Settings Org admins can add Snowflake Postgres as a CloudLink provider under Admin > CloudLinks, connecting Elementum directly to a Snowflake Postgres database with password or key pair authentication over SSL. Builders can then select the connection when creating an Element or App, so records live in the Postgres database instead of a separate warehouse copy. ### Custom Transactional Email Templates Org Settings Org admins can customize the four transactional emails Elementum sends on their behalf—welcome, password reset, email verification, and access link—from a new Email Templates tab under Admin > Settings > Communication. Each template's title, body, safety note, call-to-action label, and per-template colors are editable, with dynamic variables like organization name and expiration, a live preview, and a per-template reset to the Elementum default. ### Dynamic Approvals: Delegation Apps Approval delegation can read approver availability from Microsoft Outlook, fall back to an approver's manager when no delegate is set, and honor a per-process delegation depth limit from 0 to 2. Approval routing adjusts to who is actually available without requiring every approver to configure a delegate in Elementum. ### Current User Field Conditions Apps Field conditions on user fields can target Current User, and field conditions on group fields can target Current User's Groups, so a single layout adapts to whoever is viewing the record. Show, Hide, Enable, Disable, and Require actions apply per viewer automatically, without a separate layout for each person or team. ### Post-Deployment Unconfigured Elements Handling Apps Deployed elements with incomplete configuration are automatically placed in maintenance mode, so end users see an Under Maintenance page in the list view instead of a partially configured element. Admins see a banner on the element details page until setup is finished, and both the banner and maintenance mode clear on their own once configuration is complete. ### Automations: Search Table Records Action Automations A new Search Table Records action in the Automations action picker lets an automation look up data directly from a table instead of an app. Automation builders can source records from tables to drive downstream steps, expanding beyond app-only lookups. ### Automations: Run In Parallel Operator Automations A Run In Parallel operator in the Automation Builder lets admins define multiple branches of tasks that execute simultaneously. Running branches at the same time reduces end-to-end runtime for automation steps that do not need to happen in sequence. ### Roll-Up Widget Apps App administrators can configure a Roll-Up widget with a top-level filter and a custom hierarchy of tables or aspects, choosing which measures roll up and how they sum at each level. Reviewers see the summed total at the top and can drill down one level at a time to the underlying detail records driving that total. ### Data Entry View Apps App administrators can configure a no-code Data Entry view that turns any app into an editable grid, choosing which fields are editable and how rows are filtered, sorted, and grouped. Users type or paste values directly into cells, save all edits at once, and see per-line and roll-up totals recalculate live as they work. ### Dynamic Approvals: SLAs Apps Dynamic Approvals can be configured with an SLA policy that sets targets for each step in the process and sends alert emails to approvers at a configurable time before the deadline. When an SLA breaches, the approval workflow can branch on expiration to determine what happens next. ### Dynamic Approvals: Segregation of Duties Apps Built-in compliance rules for Dynamic Approvals prevent the person who requested an approval from approving it, and prevent any single user from appearing more than once in the same approval chain. These rules help enforce segregation-of-duties requirements across approval workflows without additional configuration. ### Dynamic Approvals: Workflow Inspector Apps Clicking an inflight approval opens a side panel with the full details of the approval process, including the current step, the assigned approvers, and progress so far. The panel is available from the Record Details page, the My Approvals page, and the approvals list on a record. ### Dynamic Approvals: Expiration Outcomes Apps A new approval-process-level setting decides what happens when a step in a Dynamic Approval process fails to complete: reject, cancel, approve, or hold open. Approval processes conclude in a predetermined way instead of stalling in a pending state when a step expires. ### Dynamic Approvals Apps A new Dynamic Approvals approval type lets app administrators route each request to the right user or group based on rules and record data, rather than hard-coding approver IDs. Chains can span multiple sequential steps with concurrent approvers at each step, and per-rule filters decide which approvers apply so approval processes adapt to the record instead of getting stuck. **Who can configure it:** App Administrators. **Where to find it:** **App** → **Workflows & Processes** → **Approval Processes**. **Configuration steps:** 1. Open your App and go to **Workflows & Processes** → **Approval Processes** in the left navigation menu. 2. Click **Create New** and choose the **Dynamic Approval** option. 3. Enter a name for the approval process and click **Save**. 4. Use the **Table filter columns** dropdown to select the fields the approvals will be filtered on. 5. Click **Add Step** to build the approval as it progresses. For each step, configure the approver type, the users, and the preconditions that must be met, then save your changes for that step. 6. Repeat the previous step for each step the approval should follow. 7. Select **Settings** in the top-right corner to configure the approval name, expiration outcome, delegation depth, whether the approval can be started manually, locked fields, and SLAs. **Behavior notes:** * Steps run in the order you add them, and each step can have concurrent approvers who act at the same time. * Save your changes for each step individually before moving on to the next one. * Per-step preconditions decide whether a step applies, so the approval process adapts to the record instead of stalling on approvers who aren't relevant. * The **Settings** panel controls process-level options, including the expiration outcome that determines what happens when a step fails to complete, delegation depth, manual start, locked fields, and SLAs. ### cXML Webhook Trigger Automations You can now create a cXML Webhook Integration in Company Settings with the credentials required for cXML invoice event types, then use it as a trigger in automations. The trigger supports the synchronous responses that cXML requests require. ## Closed beta These features are available to a limited set of customers by invitation and are not broadly available yet. * **Elementum Development Kit (EDK)** — A code-first toolkit for building Elementum in TypeScript as an alternative to building in the platform. Represent Apps, Elements, Automations, Agents, Skills, Flows, Search Tables, and Approval Chains as typed source, then follow a Terraform-like lifecycle: pull existing entities into a local workspace, author changes with typed `@catalog` references, preview a structural diff with `plan`, and apply approved changes. Packaged coding-agent playbooks teach AI coding agents the EDK's conventions, so you can describe an outcome in plain language and delegate the authoring from your editor or CLI. Get started with the [EDK documentation](/edk/getting-started) to install the toolchain, authenticate, and bootstrap an organization workspace. ## Stay in the loop # Launch Your Elementum Learning Path Source: https://docs.elementum.io/support/elearning-courses Self-paced, role-based training courses to help your team get productive on Elementum. The Elementum Customer Learning Management System (LMS) offers structured, self-paced training that your team can start the moment they're provisioned. Courses are organized into role-based paths so each user only takes what's relevant to their work. Self-register and start learning at customers.lms.elementum.ai ## What to Expect * **Self-paced** — Start anytime and work through courses on your own schedule. No scheduling or registration deadlines. * **Role-based paths** — Separate tracks for platform administrators and app builders, so users only learn what they need. * **Hands-on outcomes** — Builder courses include labs where you configure a real environment and build a working app rather than just watching videos. ## Available Learning Paths Two 101-level paths are available today, with additional content in development. **For platform administrators.** Covers the core admin functions needed to keep Elementum running smoothly — managing access, securing your configuration, and connecting Snowflake through Secure CloudLink. The three courses build sequentially, so by the end you'll have a fully configured environment. Courses: * Understanding Access Management * Configuring Security and Access * Connecting Snowflake with Secure CloudLink **Outcome:** A secure, connected Elementum environment ready for your organization to build on. *3 courses · self-paced* **For app builders and developers.** Starts with how AI and data work together in Elementum, then walks through platform navigation before moving into two hands-on labs. You'll build a real customer support app, add automations, and bring in agents to make the app intelligent. Courses: * Understanding AI and Data in the Workplace * Platform Navigation and Core Concepts * Building Your First App: Customer Support (Hands-On Lab) * Adding Workflow Automations to Your Apps (Hands-On Lab) * Adding Agents to Your Apps **Outcome:** A working app in Elementum — built by you, with automations and agents in place — ready to expand into your next use case. *5 courses · self-paced* ## Get Started Self-register at [customers.lms.elementum.ai](https://customers.lms.elementum.ai/) to access the course catalog. For questions about the program or to request team enrollment, contact [education@elementum.com](mailto:education@elementum.com). # AI FAQ Source: https://docs.elementum.io/support/faq/faq-ai Frequently asked questions about AI providers, services, and compliance in Elementum ## AI Provider Configuration Only verified domain users can configure AI Providers. A verified domain user is a user whose email address belongs to one of your organization's approved [email domains](/administration/access-overview). This restriction applies to all provider operations, including connecting a new provider (OpenAI, Anthropic, Snowflake Cortex, Gemini, Amazon Bedrock, or Custom), editing credentials or endpoint configuration, adding or removing models, and deleting a provider. **Elementum employees cannot create or modify AI Providers or Models in any customer org.** Because Elementum staff identities do not belong to your organization's approved email domains, they are excluded from provider configuration by the same control. Any change to your AI Provider configuration is the action of a verified domain user from your organization and is attributable to them in the audit log. This restriction supports AI governance and audit requirements by ensuring provider credentials are managed exclusively by personnel governed under your organization's identity policies. It is enforced platform-wide and cannot be bypassed by role assignment. *** ## Related Documentation How providers, services, and agents fit together Connect providers and create LLM or Embedding services Configure approved email domains, groups, and policies Role definitions and the User Invite Policy # Objects FAQ Source: https://docs.elementum.io/support/faq/faq-apps Frequently asked questions about Elementum Objects, including Apps, Elements, Tasks, Tables, and Services. ## Apps ### Access & Visibility * **App Access Required**: Apps are only visible to users who have access to records within that app. * **Check Access Policy**: Ensure the user has an Access Policy configured for the app. * **No Access = No Visibility**: If a user lacks proper access, the app won't appear in their app list. * **Role-Based Access**: Features are only visible to users with appropriate role permissions. * **Organization Admin Setup**: Roles and permissions are configured by Organization Admins. * **Permission Check**: Verify the user has a role that includes the necessary permissions. *** ### Dashboards & Updates * **Home Page Dashboards**: These are user-specific and don't sync across users. * **Shared Dashboard Limitation**: When you share a dashboard, it creates a copy for the other user. * **App Dashboards**: Use App Dashboards for a single source of truth that updates for all users. *** ### Relationships & Connections * **Record Access Required**: Relationships are only visible to users with access to the related records. * **Permission Check**: Verify the user has access to both the source and target records. * **Hidden Relationships**: If access is missing, relationships won't be visible even if they exist. *** ### Deleting Apps Deleting an app is permanent. The app and all of its data cannot be recovered after deletion. 1. Open the app you want to delete. 2. In the left sidebar, locate the **Admin Settings** section. 3. Click the More icon (three dots) next to **Admin Settings**. 4. Select **Delete \[App Name]** from the dropdown. 5. Confirm the deletion when prompted. *** ### Managing Records There is no bulk delete action for records inside an App or Element. Records must be deleted one at a time from the record's detail page. See [Delete a Record](/workflows/create-a-record#delete-a-record) for the steps. If you need to remove every record in an App, deleting the App itself permanently removes the App and all of its records. See [How do I delete an app?](#deleting-apps) above. Records cannot be moved between objects, whether App to App, App to Element, or Element to Element. Each object has its own record details layout, field configuration, and relationships, so a record from one object is not compatible with the structure of another. To relocate data, recreate the record in the target object. You can do this manually, through [Bulk Import](/workflows/create-a-record#bulk-import), or with a [Create Record automation](/workflows/create-a-record#automations) that reads from the source object and writes into the destination. On a record, each value in a multi-select field appears as its own badge with the option's configured icon and label, in the order the values were saved. This lets you read the full set at a glance instead of seeing only the first value with a "+N" counter. Long lists stay compact: the field collapses to about two lines and shows an inline **Show more** / **Show less** control that reports how many values are hidden. This is display only — it does not change how you edit the field or which values are stored, and it applies to the record view. On the record details page, long titles use the full header width and wrap up to three lines instead of truncating to one line with an ellipsis. Status appears next to the record ID so it does not take width away from the title. To edit the title, click it to enter edit mode, then confirm or cancel. Clicking away discards the draft instead of saving it. Confirming without changing the text does not create a record update. This behavior applies to the record details header only — list columns, board cards, and mobile layouts are unchanged. See [Edit a Record Title](/workflows/create-a-record#edit-a-record-title) for the steps. *** ## Elements Elements and Tables organize and act on data for different purposes. Here are some examples of when you would use each: **Use Elements when:** * You're managing a vendor master list — each vendor has a unique ID, you need to track changes, relate vendors to purchase orders, and control who can edit vendor records. * You're building a customer database — you need validated fields (email format, required phone number), relationships to orders/tickets, and audit trails. * You're storing configuration data like approval thresholds or SLA definitions that workflows reference during execution. **Use Tables when:** * You need a cross-functional dashboard — joining customer data (from an Element) with order data (from Snowflake) and support tickets (from Tasks) into a single analytical view. * You want to trigger automations based on data conditions — Tables feed Data Mines, which monitor for things like "claims over \$10,000" or "inventory below reorder threshold" and fire workflows. * You're exposing data to BI tools — Tables can create Snowflake Views that Power BI or Tableau can query directly. * Your data doesn't have a natural unique identifier or you're working with aggregated/analytical datasets. It depends on how the Element is connected to Snowflake. **CloudLink-backed Element:** If the Snowflake table that powers the Element is updated from an external source on a schedule — for example a monthly load — then yes. After that update, the Element shows whatever is in Snowflake. Records you created in Elementum that are not in the source load will no longer appear. **Element populated by a Data Mine:** If the Element is not CloudLink-backed, and a [Data Mine](/data/data-mining) processes matching warehouse rows into the Element (typically through a Create Record automation), then no. Records you create manually in that Element stay in the Element. The next Data Mine run does not remove them. **Read/write access:** A CloudLink-backed Element can be set up with read/write access. In that case, no — records you create or edit in Elementum are written back to the Snowflake table, so the next refresh does not remove them. If you are not sure which pattern your Element uses, check whether it is mapped to a warehouse table through a [CloudLink](/administration/setup-cloudlink), or whether it stores its own records and is filled by a Data Mine and automations. *** ## Need More Help? If you can't find the answer you're looking for, check out our [support documentation](/support) or contact our team for assistance. # Automations FAQ Source: https://docs.elementum.io/support/faq/faq-automations Frequently asked questions about building automations in Elementum, including how to chain automations and share output between them. ## Chaining Automations The simplest pattern is to bridge the two automations through a field on a record. The first automation writes its result to a field with an [Update Record Fields action](/workflows/automation-actions-reference#update-record-fields), and the second automation reads that field. **Set up the producer automation** 1. Add an **Update Record Fields** action at the end of the first automation. 2. Point it at the record you want to use as the bridge (often the record the automation is running on). 3. Map the value or variable you want to expose into a field on that record — a dedicated Text, Number, or JSON field works well. **Set up the consumer automation** You have two options, depending on when the second automation should run: * **Fire automatically when the field changes** — Configure the second automation with a [Record is Updated trigger](/workflows/automation-triggers-reference#record-is-updated). Use **Add Changed Condition** to restrict it to changes on the bridge field so the automation does not run every time an unrelated field is edited. All fields on the updated record, including the bridge field, are available as variables in downstream actions. * **Read the field on demand** — If the second automation runs on its own schedule, from an [Automation Button](/workflows/automation-buttons), or via webhook, have it look up the record with a **Search Records** action and reference the bridge field from the search result. **When to use this pattern** * The two automations run under different triggers, schedules, or teams and should stay independent. * You want the output persisted and visible on the record for reporting, audit, or manual review. * The consumer may need to run more than once against the same producer output, or long after the producer finished. If you want a single, synchronous call — where the caller waits for the callee and reads its outputs directly — use the [Run Automation action](/workflows/automation-actions-reference#run-automation) against a helper automation that has an [On-Demand Trigger](/workflows/automation-triggers-reference#on-demand-trigger). That avoids the round-trip through a record field, but couples the two automations into one execution. See [Automation Chaining](/workflows/automation-best-practices#automation-chaining) for the trade-offs. *** ## Related Documentation Overview of triggers, actions, and how automations run Reference for every trigger, including Record is Updated Reference for every action, including Update Record Fields and Run Automation Patterns for composable, efficient automations # MFA FAQ Source: https://docs.elementum.io/support/faq/faq-mfa Frequently asked questions about Multi-Factor Authentication in Elementum ## General Questions Multi-Factor Authentication (MFA) is a security feature that requires two forms of verification when you log in: 1. **Something you know**: Your password 2. **Something you have**: A time-based code from your authenticator app Even if someone discovers your password, they cannot access your account without also having access to your authenticator device. MFA significantly reduces the risk of unauthorized account access. Benefits include: * **Protection against password breaches**: If your password is compromised in a data breach, attackers still can't access your account * **Defense against phishing**: Even if you accidentally enter your password on a fake site, attackers can't log in without your authenticator code * **Compliance**: Many security standards and regulations recommend or require MFA * **Peace of mind**: Know that your account and data are protected by an additional security layer MFA is currently **optional and user-controlled**. You can enable or disable it at any time from your Account Settings. Your organization may have policies recommending or requiring MFA for certain roles. Check with your administrator for your organization's specific requirements. Admin-enforced MFA (where organizations can require MFA for all users) is planned for a future release. If your organization uses SSO with an Identity Provider (like Okta, Azure AD, or OneLogin), your MFA experience depends on your setup: * **IdP-level MFA**: Your Identity Provider may already enforce MFA during SSO login. In this case, Elementum MFA may be redundant. * **Elementum MFA + SSO**: You can enable Elementum MFA in addition to SSO, adding another layer of security. * **SSO-only organizations**: If SSO is enforced and local login is disabled, Elementum MFA options may not be available. Check with your administrator to understand your organization's authentication configuration. *** ## Setup Questions Elementum MFA works with any authenticator app that supports the TOTP (Time-based One-Time Password) standard, including: * **Google Authenticator** (iOS, Android) * **Microsoft Authenticator** (iOS, Android) * **Okta Verify** (iOS, Android) * **1Password** (iOS, Android, Desktop) * **Authy** (iOS, Android, Desktop) * **Duo Mobile** (iOS, Android) * **LastPass Authenticator** (iOS, Android) * Many others We recommend choosing an app that supports **cloud backup** or **multi-device sync** (like Microsoft Authenticator, Authy, or 1Password) for easier device transitions. Each MFA setup is tied to **one authenticator entry**. However, depending on your authenticator app: * **Apps with sync** (Microsoft Authenticator, Authy, 1Password): Your codes automatically sync across devices signed into the same account * **Apps without sync** (Google Authenticator): Codes exist only on the device where you scanned the QR code If your app supports sync, you effectively have MFA access on multiple devices. If not, you'll need to use the specific device where MFA was set up. To switch your primary MFA device, disable MFA while you have access, then re-enable it on your preferred device. If you can't scan the QR code (camera issues, using desktop authenticator, etc.): 1. Click **Can't scan? Enter code manually** below the QR code 2. Copy the displayed secret key 3. In your authenticator app, choose **Enter setup key manually** or similar 4. Enter the account name (e.g., "Elementum") and paste the secret key 5. Ensure **Time-based (TOTP)** is selected as the key type 6. Save and use the generated code to verify setup No. MFA currently supports **only TOTP authenticator apps**. SMS and email-based verification are not available. TOTP apps are generally more secure than SMS (which can be intercepted through SIM swapping attacks) and more reliable than email (which can have delivery delays). Hardware security keys are **not currently supported**. Only TOTP-based authenticator apps are supported. Support for hardware security keys may be considered for future releases. *** ## Usage Questions You'll be prompted for your authenticator code: * **Every new login**: When you enter your username and password * **After session expiration**: When your session times out due to inactivity * **After logging out**: When you explicitly log out and log back in You will **not** be prompted: * While actively using Elementum within a session * When switching between pages or apps within Elementum * If you're already logged in and open a new browser tab The most common cause of rejected codes is **time sync issues**. Try these steps: 1. **Enable automatic time** on your device: * iOS: Settings > General > Date & Time > Set Automatically * Android: Settings > System > Date & time > Automatic 2. **Wait for a fresh code**: If your current code is nearly expired, wait for the next one 3. **Verify the correct entry**: Make sure you're using the code for Elementum, not another service 4. **Force time sync** in your authenticator app (if available) No. MFA applies only to **interactive login** through the Elementum web interface. API access using API keys or service account credentials is **not affected** by MFA. API authentication continues to work as before. This is standard practice—API calls are typically automated and can't interactively provide MFA codes. MFA adds one additional step to login: entering a 6-digit code. For most users, this adds only a few seconds. Tips for a smooth experience: * Keep your authenticator app easily accessible * Use Face ID/Touch ID to unlock your authenticator quickly * Enter codes promptly when they appear (they're valid for 30 seconds) *** ## Recovery Questions If you lose access to your authenticator device (phone lost, broken, or reset): 1. **Contact your organization administrator** 2. **Verify your identity** through your organization's process 3. **Administrator requests MFA removal** from Elementum Support 4. **Once MFA is disabled**, log in with your password only 5. **Immediately re-enable MFA** on your new device **Backup codes are not currently available.** This is why we recommend using an authenticator with cloud backup capability. **No, backup codes are not currently available.** To protect yourself: * Use an authenticator app with **backup/sync features** (Microsoft Authenticator, Authy, 1Password) * Know your organization's **recovery process** before you need it * Consider setting up your authenticator on multiple devices if your app supports sync Backup codes are planned for a future release. Currently, **no**. If you lose access to your authenticator and can't generate codes, you must: 1. Contact your organization administrator 2. Complete identity verification 3. Have them request MFA removal from Elementum Support Self-service recovery options (like backup codes) are planned for future releases. **Before** disposing of or resetting your old phone: 1. Log into Elementum using your old phone's authenticator 2. Go to **Account Settings** > **Security** 3. **Disable MFA** 4. Set up your authenticator app on your new phone 5. **Re-enable MFA** and scan the new QR code **If you already switched** and can't access your old authenticator: * If your app has cloud backup, restore on your new device * If not, follow the lost device recovery process *** ## Administrator Questions **Not currently.** MFA is currently user opt-in only. Admin-enforced MFA is on the roadmap for a future release. This will allow administrators to: * Require MFA for all users * Require MFA for specific roles * Set grace periods for compliance * Monitor enrollment status Currently, administrators can encourage adoption through communication and policy, but cannot technically enforce it. There is **no dedicated MFA enrollment report** currently available. Administrators can: * Review the **Activity Log** for MFA enablement/disablement events * Manually track adoption through user communications * Contact Elementum Support for assistance with adoption data Bulk MFA reporting is planned for future releases. When a user loses authenticator access: 1. **Verify the user's identity** through your established process (manager confirmation, HR verification, security questions, etc.) 2. **Contact Elementum Support** with: * User's email address * Confirmation that identity was verified * Your administrator credentials/authorization 3. **Support disables MFA** for the user's account 4. **Notify the user** to log in and re-enable MFA No. [Service accounts](/administration/service-accounts) are API-only accounts that cannot be used for interactive login. MFA does not apply to service accounts. *** ## Security Questions TOTP (Time-based One-Time Password) MFA is a well-established security standard (RFC 6238) used by major platforms worldwide. Key security properties: * **Codes are time-limited**: Valid for only 30 seconds * **Codes are one-time use**: Cannot be reused even within the validity window * **Secret is device-bound**: The secret key never leaves your authenticator device during normal use * **Offline generation**: Codes are generated locally without network communication * **No shared database**: Elementum doesn't store your actual codes, only verifies them While no security measure is perfect, TOTP MFA significantly raises the bar for attackers. For MFA, Elementum stores: * **Your MFA enrollment status** (enabled/disabled) * **An encrypted secret key** used to verify your codes * **Timestamps** of MFA events (enable, disable, successful/failed verifications) Elementum does **not** store: * Your actual authenticator codes * Access to your authenticator app or device * Your device information (beyond what's in normal access logs) MFA cannot be bypassed through the normal login flow. However: * **Account recovery**: Administrators can request MFA removal for account recovery (after identity verification) * **Session hijacking**: If an attacker compromises an active session, MFA won't help (it protects login, not existing sessions) * **SSO bypass**: If your organization uses SSO, attackers who compromise your IdP credentials may not need Elementum MFA MFA is one layer in a security strategy—it works best alongside strong passwords, session management, and security awareness. *** ## Current Limitations The following features are **not currently available** for MFA: | Feature | Status | | ---------------------------- | -------------------------------- | | Backup codes | Not available | | SMS verification | Not supported | | Email verification | Not supported | | Hardware security keys | Not supported | | Admin enforcement | Not available | | Multiple device registration | Single setup (use app with sync) | | Enrollment reporting | Not available | | Conditional MFA (risk-based) | Not available | These features may be added in future releases. *** ## Related Documentation Complete setup and usage guide Single Sign-On setup guide *** *Last updated: January 2025* # Connect AI Agents to the Docs Source: https://docs.elementum.io/support/mcp-server Give AI tools like Cursor, Claude, and ChatGPT real-time access to the Elementum documentation through our Model Context Protocol (MCP) server. ## Overview The Elementum documentation is published with a built-in **Model Context Protocol (MCP) server**. MCP is an open standard that lets AI assistants — including Cursor, Claude, and ChatGPT — read a live source of information and use it to answer questions. When you connect an AI tool to the Elementum docs MCP server, the assistant can: * Search the full documentation in real time instead of relying on stale training data * Return answers grounded in current Elementum guidance, with links back to the source pages * Reference the docs while it helps you build apps, write automations, or troubleshoot issues The server is hosted at: ``` https://docs.elementum.io/mcp ``` No account or credentials are required — the Elementum documentation is public, so any MCP-compatible client can connect. *** ## Connect an AI Tool Pick the tool you use below. Each one asks for the same thing: a **name** (whatever you want to call it, for example `elementum-docs`) and the **URL** `https://docs.elementum.io/mcp`. 1. Open the command palette with `Cmd/Ctrl + Shift + P` and search for **Open MCP Settings**. 2. Select **Add custom MCP** to open `mcp.json`. 3. Add the Elementum docs server to the configuration: ```json theme={null} { "mcpServers": { "elementum-docs": { "url": "https://docs.elementum.io/mcp" } } } ``` 4. Save the file. Cursor connects automatically and the new server appears in **MCP Settings**. 1. Open **Settings** in Claude Desktop and go to the **Connectors** page. 2. Select **Add custom connector**. 3. Enter the following: * **Name**: `Elementum Docs` * **URL**: `https://docs.elementum.io/mcp` 4. Select **Add**. Claude connects to the server and the docs become available in new chats. Run the following command in your terminal: ```bash theme={null} claude mcp add --transport http elementum-docs https://docs.elementum.io/mcp ``` Claude Code registers the server and makes it available in your next session. 1. In ChatGPT, open **Settings** → **Connectors** (available on paid plans that support custom MCP connectors). 2. Select **Add custom connector** and enter: * **Name**: `Elementum Docs` * **URL**: `https://docs.elementum.io/mcp` 3. Save the connector and enable it for the conversations where you want the assistant to consult the docs. Any client that supports the MCP **Streamable HTTP** transport can connect. Provide the server URL in whatever configuration format the client uses: ```json theme={null} { "mcpServers": { "elementum-docs": { "url": "https://docs.elementum.io/mcp" } } } ``` Refer to your tool's documentation for the exact location of its MCP configuration file. *** ## Using the Docs From Your AI Tool Once connected, ask the assistant questions as you normally would. When a question relates to Elementum, the assistant will query the MCP server and cite the relevant docs pages in its response. Example prompts: * "Using the Elementum docs, explain how assignment rules differ from approval processes." * "Walk me through setting up a CloudLink to Snowflake. Link to the steps in the Elementum docs." * "How do I build an automation that runs on a record update? Check the Elementum docs." If an answer looks out of date, ask the assistant to re-query the docs. MCP reads the live site, so updates to the documentation are reflected immediately. *** ## Troubleshooting Confirm the URL is entered exactly as `https://docs.elementum.io/mcp` with no trailing slash or extra path segments. Check that your network allows outbound HTTPS requests to `docs.elementum.io`. Most clients require you to explicitly mention the connector or include a phrase like "check the Elementum docs" in your prompt. Verify the connector is enabled for the current conversation in your tool's settings. Open the MCP settings in your tool and delete the `elementum-docs` entry (or whatever name you used). The assistant will stop querying the docs on its next turn. *** ## Related Resources * [API Reference](/api-reference/api-introduction) — connect agents directly to Elementum's REST API * [Agents Overview](/ai-agents/ai-overview) — build AI agents inside the Elementum platform * [Help & Resources](/support/resources) — other support channels # Platform Status Source: https://docs.elementum.io/support/platform-status Stay informed about the current status of Elementum’s platform and services through our real-time status page ## What is the Status Page? Our [Platform Status Page](https://status.elementum.io/) provides real-time information about the health and performance of all Elementum services. This page is your go-to resource for: * **Current System Status**: See which services are operational, experiencing issues, or under maintenance * **Historical Uptime**: View performance metrics over the past 90 days * **Incident Updates**: Get detailed information about any ongoing issues or maintenance * **Service Components**: Monitor individual service areas like Core, API, Automations, and Agents ## Why Monitor Platform Status? ### Proactive Issue Awareness Instead of wondering if a problem is on your end or ours, check the status page first. This helps you: * **Verify Service Health**: Confirm if Elementum services are running normally * **Plan Around Maintenance**: Be aware of scheduled maintenance windows * **Understand Impact**: Know which specific services might be affected during incidents * **Reduce Support Tickets**: Check status before contacting support for system-wide issues ### Business Continuity When you're experiencing issues, the status page helps you: * **Assess Scope**: Determine if the problem is isolated to your instance or affecting all users * **Communicate with Stakeholders**: Provide accurate information about service status * **Plan Workarounds**: Understand which features might be temporarily unavailable * **Track Resolution**: Monitor incident progress and estimated resolution times ## Available Services The status page monitors these key service areas: Main application functionality, user interface, and core features REST API endpoints and integration services Workflow automation engine and trigger systems AI agent services and intelligence features ## Status Indicators The status page uses clear visual indicators to communicate service health: * **🟢 Operational**: Service is running normally with no issues * **🟡 Degraded Performance**: Service is experiencing performance issues but remains functional * **🟠 Partial Outage**: Some features or regions are experiencing issues * **🔴 Major Outage**: Service is experiencing significant disruption * **🔵 Maintenance**: Planned maintenance is in progress ## Subscribe to Notifications Stay informed about platform status without constantly checking the status page. You can subscribe to receive email notifications for: * **Incident Creation**: When a new issue is identified * **Status Updates**: Progress updates during incident resolution * **Resolution Notifications**: When issues are resolved * **Maintenance Alerts**: Scheduled maintenance notifications ### How to Subscribe 1. Visit [status.elementum.io](https://status.elementum.io/) 2. Click **Get email notifications** at the top of the page 3. Enter your email address 4. Verify your email with the OTP sent to your inbox 5. You'll receive notifications for all future incidents and updates **Privacy**: Your email is only used for status notifications. We don't share your information or send marketing emails. ## Programmatic Access via API For developers and automated systems, you can programmatically access status information through our REST API endpoints. All endpoints return JSON data and don't require authentication. **Summary** - Complete status overview ``` GET https://status.elementum.io/api/v2/summary.json ``` **Status** - Overall indicator (`none`, `minor`, `major`, `critical`) and description ``` GET https://status.elementum.io/api/v2/status.json ``` **Components** - Individual service statuses (`operational`, `degraded_performance`, `partial_outage`, `major_outage`) ``` GET https://status.elementum.io/api/v2/components.json ``` **Status**: `Investigating`, `Identified`, `Monitoring`, `Resolved`, `Postmortem`\ **Impact**: `None`, `Minor`, `Major`, `Critical` ``` GET https://status.elementum.io/api/v2/incidents/unresolved.json # Current issues GET https://status.elementum.io/api/v2/incidents.json # 50 most recent ``` **Status**: `Scheduled`, `In Progress`, `Verifying`, `Completed`\ **Impact**: `None`, `Minor`, `Major`, `Critical` ``` GET https://status.elementum.io/api/v2/scheduled-maintenances/upcoming.json # Planned GET https://status.elementum.io/api/v2/scheduled-maintenances/active.json # In progress GET https://status.elementum.io/api/v2/scheduled-maintenances.json # 50 most recent ``` ```javascript theme={null} // Check if all systems are operational fetch('https://status.elementum.io/api/v2/status.json') .then(response => response.json()) .then(data => { console.log('Status:', data.status.description); console.log('Indicator:', data.status.indicator); }); ``` **For automated monitoring:** See the [Datadog Integration Setup](#benefits-of-datadog-integration) appendix below for complete instructions on setting up proactive monitoring with alerting. **API Notes**: Public endpoints, no authentication required. JSON responses with CORS headers, no rate limits. ## Integration with Support The status page works alongside our other support resources: * **Check Status First**: Always verify platform status before contacting support * **Reference in Tickets**: Include status page information when reporting issues * **Follow Incident Updates**: Use status updates to track resolution progress * **Escalate Appropriately**: Contact support if status shows operational but you're still experiencing issues ## Need Help? If you have questions about the status page or need assistance with platform issues: * **Email Support**: [support@elementum.elementum.io](mailto:support@elementum.elementum.io) **Pro Tip**: Bookmark [status.elementum.io](https://status.elementum.io/) in your browser for instant access to platform status information. *** ## Appendix: Datadog Integration Setup Monitor Elementum's platform status programmatically using Datadog Synthetic tests. This setup automatically alerts your team when services experience issues, providing proactive incident awareness. **Goal**: Alert whenever the platform status indicator isn't `none` (i.e., any degraded/partial/outage condition). ### Create the Test 1. Navigate to **Datadog** → **Synthetic Monitoring & Testing** → **New test** → **New API test** → **HTTP** 2. Configure the request: * **Method**: `GET` * **URL**: `https://status.elementum.io/api/v2/status.json` ### Add Assertions After clicking **Send**, add these assertions: 1. **Status code** → **is** → `200` 2. **Header** `content-type` → **matches regex** → `application/json` 3. **Body** → **JSONPath** → **Path**: `$.status.indicator` → **Operator**: **is** → **Value**: `none` The key assertion is `$.status.indicator is none`. When the indicator becomes `minor`, `major`, or `critical`, this assertion fails and triggers your alert. ### Configure Monitoring * **Locations**: Select 1-3 managed locations near your users * **Frequency**: Set to every 1-5 minutes based on your needs * **Alert conditions**: Configure "Alert if failing for 2 minutes in at least 2 locations" to avoid false positives ### Set Up Notifications Configure alerts to your preferred channels. Use Datadog's template variables to include failure details in your messages. **Goal**: Include which specific components are affected in your alerts for better incident response. ### Step 1: Status Check * **Method**: `GET` * **URL**: `https://status.elementum.io/api/v2/status.json` * **Assertion**: `$.status.indicator is none` (same as Option A) ### Step 2: Component Analysis * **Method**: `GET` * **URL**: `https://status.elementum.io/api/v2/summary.json` * **Extract Variable**: * **Type**: JSONPath * **Path**: `$.components[?(@.status!='operational')].name` * **Variable Name**: `AFFECTED_COMPONENTS` The `summary.json` endpoint provides comprehensive context including overall status, component statuses, and current incidents—perfect for detailed alert messages. ### Use in Notifications Reference the `AFFECTED_COMPONENTS` variable in your notification templates to automatically include which services are impacted. **Goal**: Different alert priorities for different severity levels (degradation vs. outages). ### Approach 1: Single Test with Routing * Use the simple Option A setup * Route all alerts to a primary responder * Failure details will show the actual indicator value (`minor`/`major`/`critical`) for manual triage ### Approach 2: Multiple Tests for Precise Paging **Degradation/Partial Alert**: * **URL**: `https://status.elementum.io/api/v2/status.json` * **Assertion 1**: `$.status.indicator is none` * **Assertion 2**: `$.status.indicator is not critical` * **Result**: Alerts on `minor` or `major` but not `critical` **Critical Outage Alert**: * **URL**: `https://status.elementum.io/api/v2/status.json` * **Assertion**: `$.status.indicator is critical` * **Result**: Only alerts on critical outages for high-priority paging If you prefer using Datadog Agent checks over Synthetics, you can use the HTTP Check integration: ```yaml theme={null} # datadog.yaml configuration init_config: instances: - name: elementum_status url: https://status.elementum.io/api/v2/status.json method: get content_match: '"indicator":"none"' reverse_content_match: false timeout: 10 headers: Accept: application/json ``` This approach flips to DOWN when it finds `"indicator":"(minor|major|critical)"` in the response. ### Benefits of Datadog Integration * **Rich Context**: Include affected components and severity in alerts * **Integration Ready**: Works with your existing Datadog alerting workflows * **Customizable**: Adapt alert severity and routing to your operational needs # Help & Resources Source: https://docs.elementum.io/support/resources Get help and support for Elementum ## Need Help? We're here to help you get the most out of Elementum. Here are the best ways to get support: Check real-time platform health and subscribe to incident notifications Review our customer support policies, response times, and system availability Contact our support team directly to report issues or request features Give Cursor, Claude, ChatGPT, and other AI tools live access to the Elementum docs via MCP Self-paced, role-based training paths to get your admins and app builders up and running Send suggestions, corrections, and ideas for improving these docs ## AI Docs Assistant The AI Docs Assistant is an in-platform chat tool that answers questions about Elementum features and surfaces how-to guidance without leaving your workspace. ### What you can do with the Docs Assistant * Ask natural-language questions about Elementum features, configuration, and best practices * Get how-to guidance and informational content pulled directly from the Elementum documentation * Browse Quick-link topics to jump straight into the most popular articles * Follow up on previous answers within the same chat session for additional context ### Open the Docs Assistant 1. Click the Help icon **Help** icon in the Elementum navigation bar. 2. Select a Quick-link topic to view a popular article, or type a question into the chat to start a conversation. Be specific when asking questions. Including the feature name, the action you're trying to take, or an error message helps the assistant return the most relevant guidance. ## Documentation Feedback Help us improve the docs by sending suggestions, corrections, and ideas to [feedback@elementum.elementum.io](mailto:feedback@elementum.elementum.io). Screenshots and links to specific pages are always welcome. Here are the kinds of feedback we're looking for: * **Flag what's unclear** — Found a confusing paragraph or a missing step? Send it our way — even a screenshot helps. * **Suggest examples** — Have a workflow pattern other partners would benefit from? We want it in the docs. * **Report doc bugs** — Broken links, code that no longer matches the UI, outdated screenshots — please report them. * **Share use cases** — Tell us where Elementum is fitting into your stack so we can document the patterns that matter. For product issues or platform incidents, use [Email Support](mailto:support@elementum.elementum.io) instead. The documentation feedback inbox is for the docs site itself. ## Self Help Resources

    Follow our quick start guide to get started with a new app.

    Need help integrating with our API? Check out our API documentation for detailed guides and examples.

    Experiencing issues? Visit our troubleshooting section for common problems and solutions.

    ## Response Times * **Email Support**: We typically respond within 24 hours during business days * **Documentation**: Available 24/7 for self-service support * **FAQ**: Answers to common questions in the [FAQ](/support/faq/faq-apps) section ## Before Contacting Support **Check Platform Status First**: Before reaching out to support, always check our [Platform Status Page](/support/platform-status) to verify if there are any known platform issues or maintenance activities that might be affecting your experience. To help us assist you faster, please have the following information ready: * Your Elementum workspace URL * A clear description of the issue you're experiencing * Any error messages you're seeing * Steps to reproduce the problem * Your browser and operating system information ## Stay in the loop Subscribe to hear about new releases and what's coming next. We send brief, infrequent emails — no spam. # Date and Time Handling Source: https://docs.elementum.io/support/troubleshooting/date-time-handling This guide explains how Elementum handles date and time values throughout the platform, particularly when integrating with external data sources. **Critical**: Elementum's platform **assumes all dates are in UTC (Coordinated Universal Time)**. Incorrect timezone handling can cause display inconsistencies across your platform. ## UTC Standard Elementum's platform uses UTC as the foundation of our date/time handling strategy: All timestamps stored in Elementum's databases are in UTC All API communications use UTC for consistency UI displays convert UTC to the user's local timezone for presentation ## External Data Integration When importing data from external sources like Snowflake: ### Requirements for Date/Time Fields **All date/time values should be in UTC format** Data imported with mixed timezone formats will cause display inconsistencies Local timezone dates without proper UTC conversion will display incorrectly ### Common Issues The most frequent issue occurs when: * ❌ Some date fields contain UTC timestamps * ❌ Other date fields contain local timezone timestamps * ❌ All are treated as UTC by the platform * ❌ UI displays show incorrect times for users in different timezones **Example**: For a user in EDT (UTC-4): ```bash theme={null} # Correct behavior True UTC timestamp: 14:00 → Displays as: 10:00 ✓ # Incorrect behavior Local EDT timestamp: 14:00 → Displays as: 10:00 ✗ # Should display as: 14:00 ``` ## Best Practices
    * Convert any local timestamps to UTC before importing * Include timezone offset information if available
    * Use ISO 8601 format when possible (`YYYY-MM-DDTHH:MM:SSZ`) * Ensure consistency across all data sources
    * Configure all date columns to use UTC timezone * Convert any local timestamps during ETL processes * Don't mix UTC and local timezone values in the same dataset
    ## Troubleshooting If dates appear incorrect in the Elementum UI, follow these steps: Check the original timestamps in your data source (e.g., Snowflake) Verify that timestamps are consistently in UTC format Convert any non-UTC timestamps to UTC in the data source Re-import the data after standardization # General Troubleshooting Source: https://docs.elementum.io/support/troubleshooting/general-troubleshooting Common issues and solutions for the Elementum platform, including bulk imports on Snowflake-backed objects and GraphQL API configuration. Use this guide to diagnose and resolve common issues on the Elementum platform. If your issue is not covered here, contact [Elementum Support](https://elementum.ai/support). ## Bulk Import on Snowflake-Backed Objects To bulk import on an object that is based on a Snowflake table, Elementum must be granted the correct permissions to create and update records in Snowflake. If these permissions are missing, the import will continue to fail silently — no error is displayed in Elementum. Confirm that the Elementum service account has been granted `CREATE` and `UPDATE` privileges on the target Snowflake table. Once the correct permissions are in place, re-run the bulk import. ### Resolving "String is too long and would be truncated" Errors When writing to a Snowflake-backed object, you may see an error like: ``` DML operation to table failed on column with error: String '' is too long and would be truncated ``` This means the value being written is longer than the maximum length defined for that column in Snowflake. Snowflake does not truncate data automatically — it rejects the operation instead. Note the column name and the specific value referenced in the error message. These tell you exactly which field is too long. Trace the value back to its source — for example, the record being imported, the field mapping in your automation, or the upstream Data Mine query. Update the source data so the value fits within the column's character limit, then retry the operation. For automations, review the field mapping to confirm the source field's values stay within the expected length. If shortening the value is not an option, reach out to a database administrator with access to `information_schema.columns` and ask them to confirm the column's defined maximum length: ```sql theme={null} SELECT table_schema, table_name, column_name, character_maximum_length AS defined_max_characters FROM information_schema.columns WHERE table_name = 'YOUR_TABLE_NAME' AND column_name = 'YOUR_COLUMN_NAME'; ``` The same administrator can typically increase the column length in Snowflake if a larger limit is required. ## Triggering a GraphQL API To trigger a GraphQL API from Elementum, configure the request with the following settings: GraphQL APIs require the `POST` HTTP method. Set the URL to the GraphQL endpoint you want to call. Select **JSON** as the body format and enter the GraphQL payload. Configure the response type as **JSON** to properly parse the result. # Agent Task Automation Source: https://docs.elementum.io/workflows/agent-task-automation Bridge structured and unstructured workflows by combining deterministic automation with intelligent agent autonomy The **Run Agent Task** automation action lets you transition between structured, deterministic automation steps and autonomous agent actions within a single workflow. This combines the reliability of [automations](/workflows/automation-system) with the adaptability of [AI agents](/ai-agents/agents-tools-and-deployment). **New to Automations?** Check out the [Automation System](/workflows/automation-system) guide first to understand how event-driven workflows work in Elementum. ## How It Works Traditional automation excels at structured, deterministic processes: "When X happens, do Y." AI agents excel at unstructured tasks requiring reasoning, judgment, and problem-solving. Run Agent Task combines both approaches in a single workflow: 1. Start with **structured automation** (trigger detection, data gathering) 2. Hand off to an **autonomous agent** (analysis, research, decision-making) 3. Return to **structured automation** (use agent output in subsequent actions) ``` Record Updated (structured) → Run Agent Task (autonomous intelligence) → Update Record Fields (structured) → Send Email Notification (structured) ``` * Excellent at deterministic tasks * Struggles with tasks requiring judgment * Can't handle "figure it out" scenarios * Limited to predefined logic paths * Excellent at complex reasoning * Can handle ambiguous tasks * Less predictable for deterministic steps * Harder to integrate into existing processes * **Structured reliability** — Use automation for data gathering, record updates, notifications, and integrations * **Intelligent autonomy** — Use agents for research, analysis, evaluation, and tasks requiring reasoning * Transitions between both within a single workflow ## Configure a Run Agent Task To add a Run Agent Task to your workflow, open your Apps icon App, click **Automations**, and add the **Run Agent Task** action to an automation that already includes a [trigger](/workflows/automation-triggers-reference). ### Action Name Provide a descriptive name for the task within your automation workflow. ``` "Research Customer Industry" "Evaluate Contract Risk" "Analyze Support Ticket Complexity" ``` ### Object Selection After naming the action, choose the Object the agent has access to. This determines which data the agent can read and act on when executing the task. ### Agent Selection Select an agent you've already built to execute this task. For more on creating and configuring agents, see [Agent tools, deployment, and integrations](/ai-agents/agents-tools-and-deployment). After selecting the agent, click **Configure Task and Test** to proceed to the task definition. ### Start URL When the selected agent is a [Browser Use Agent](/ai-agents/agents-experience#browser-use-agents), the configuration modal shows an optional **Start URL** field. This is the web address the agent's sandboxed browser opens on when the task runs, giving the agent a defined starting point instead of a blank page. * **Only appears for Browser Use Agents** — The field is hidden for Native Agents and every other agent type, where it has no effect. If you don't see it, confirm the selected agent is a Browser Use Agent. * **Optional** — Leave it blank to let the agent navigate from its instructions alone. When set, the sandboxed browser loads this URL before the agent begins working. * **When to set it** — Point the agent directly at the portal, form, or dashboard it needs to act on — for example, a vendor login page or a government filing form. Starting on the right page reduces navigation steps and makes runs more reliable. ### Task Definition The task definition tells the agent what to accomplish. It has three critical components: **context**, **objective**, and **success criteria**. Because agents in Run Agent Task operate in a **headless environment** — with no user available for follow-up questions — your task definition must be self-contained with all necessary context provided upfront through [value references](/workflows/automation-actions-reference). Every task definition should include: 1. **Context** — All relevant data via value references 2. **Objective** — What the agent should accomplish 3. **Success criteria** — How the agent knows it has completed the task, including specific deliverables and format ``` Task: "Analyze the support ticket from {{customer.name}} regarding {{ticket.subject}}. Customer tier: {{customer.tier}}, previous tickets: {{customer.past_tickets}}. Objective: Determine issue complexity and routing. Success: Provide: - Complexity rating (Low/Medium/High) - Estimated resolution time in hours - Recommended team (General/Specialist/Engineering) - 2-3 sentence reasoning for recommendations" ``` **Vague task (bad):** ``` Task: "Research this customer" ``` **Complete task (good):** ``` Task: "Research {{customer.company}} (industry: {{customer.industry}}, size: {{customer.employees}} employees, location: {{customer.location}}). Focus on their competitive landscape, recent news, and decision-making structure. Use our product category ({{product.category}}) to identify relevant talking points." ``` **Vague success criteria (bad):** ``` Task: "Analyze this contract and let me know what you think" ``` **Clear success criteria (good):** ``` Task: "Analyze this contract for {{customer.name}}. Success criteria: - Identify any terms that deviate from our standard template - Rate overall risk as Low/Medium/High - Flag any must-negotiate items - Provide recommended approval authority based on risk and value" ``` Since agents can't ask clarifying questions, provide everything they need upfront: * **Use value references extensively** — Include all relevant record fields, related data, and historical context * **Include business context** — Customer segment, strategic importance, revenue impact, relationship tenure * **Anticipate agent needs** — Think about what an informed human would need: business rules, comparative data, success thresholds, constraints * **Be specific but not restrictive** — Give clear direction while allowing intelligent interpretation ``` Task: "Evaluate support ticket #{{ticket.id}} from {{customer.name}}. Customer details: - Tier: {{customer.tier}} - Account age: {{customer.age_days}} days - Lifetime value: ${{customer.lifetime_value}} - Previous tickets: {{customer.ticket_count}} Ticket details: - Subject: {{ticket.subject}} - Description: {{ticket.description}} - Reported by: {{ticket.reporter_name}} ({{ticket.reporter_role}}) Success: Determine urgency (Critical/High/Medium/Low), estimated effort (hours), recommended team, and whether customer success should be notified." ``` ### Output Type Choose how the agent returns its work: Returns a simple narrative response. Best for summaries, explanations, and recommendations where you don't need to branch on specific values in downstream actions. Define specific fields with types, similar to [AI File Reader](/workflows/elementum-intelligence-file-reader). The agent returns data in exactly the structure you define, which you can reference directly in subsequent automation steps. **Defining fields:** * **Field Name** — Variable name for use in subsequent actions * **Field Type** — text, number, checkbox, date, list, etc. * **Description** (optional but recommended) — Helps the agent understand what you want **Example configuration:** ``` Fields: 1. risk_score (number): Overall risk rating from 1-10 2. risk_level (text): Low/Medium/High categorization 3. key_risks (list): Specific risk factors identified 4. mitigation_required (checkbox): Whether mitigation actions are needed 5. reasoning (text): 2-3 sentence explanation of assessment ``` **Using output in subsequent actions:** Once the agent task completes, its output becomes available as value references: ``` IF run_agent_task.risk_level = "High" OR run_agent_task.mitigation_required = true → Start Approval Process (Legal team) → Send Message to Teams: "High-risk contract: {{run_agent_task.reasoning}}" OTHERWISE → Update Record Fields (auto-approved) → Send Email Notification: "Contract approved: {{run_agent_task.reasoning}}" ``` Design output fields to match how you'll use them downstream: * **For routing logic** — Use categorical fields like `risk_level` (Low/Medium/High) that work well in IF conditions * **For calculations or thresholds** — Use numeric fields like `satisfaction_score` (1-10) * **For human review** — Use narrative fields like `summary`, `reasoning`, `recommendations` **Avoid:** * Fields that are too sparse (a single text blob is hard to use programmatically) * Fields that are too granular (`risk_factor_1` through `risk_factor_20` is overwhelming) ### File Inputs Run Agent Task can pass files directly to the agent for processing — use this in place of the [AI File Reader](/workflows/elementum-intelligence-file-reader) when you want broader model support and richer file handling inside the agent's reasoning. The **Files** section is located below the Task Description field in the action configuration. Expand it to reveal the file input area — do not paste file references into the Task Description text box itself. 1. Expand the **Files** section below the Task Description. 2. Click **Add**, select **Attachment** type → **One or many files** → set the source to **Attachment Trigger** (when using an Attachment is Added trigger). 3. In the Task Description, tell the agent what to do with the file (e.g., "Summarize the attached invoice and extract line items"). File handling depends on the agent's selected model — choose one that supports the file types you intend to send. **The agent must use a multimodal model.** If your agent uses a non-multimodal model (one without vision/file support), the platform skips file delivery entirely — the agent will respond in milliseconds without reading the file. Always confirm your agent's model supports file input (GPT-4o, ChatGPT 5, Claude Sonnet, Gemini, or equivalent) before building the automation. Check the model in **Admin → \[Your App] → Intelligence → Agents → \[Your Agent] → Overview**. **Setting the attachment source correctly is critical.** When using an Attachment is Added trigger, the Files section must reference **Attachment Trigger** as the source — this passes the specific file that fired the trigger to the agent. Using a record reference instead silently delivers zero file bytes and the agent cannot read the file. There is no error message; the agent simply responds without file context. #### Expected execution behaviour A successful file-processing run completes in 3–8 seconds and shows 2 completed actions (Run Agent Task + the downstream action) in the execution history. If the task completes in under 2 seconds, the agent likely did not receive the file — see [Troubleshooting file inputs](#troubleshooting-file-inputs) below. #### Differences from Agent Chat Run Agent Task is **headless**: the agent processes the file in a single pass using only the Task Description for guidance. It cannot ask follow-up questions. A vague description (e.g., "Look at this file") forces the agent to guess intent, which produces different results from the same file in an interactive Agent Chat. To match Agent Chat results, write a Task Description that mirrors the question you would ask in chat, and include relevant context via value references. The **Test & Preview** screen may not handle attachments the same way as an interactive Agent Chat session. If you see different results between Test & Preview and Agent Chat, try providing a more specific Task Description. To test how the agent handles a file conversationally, use the agent's chat interface instead. For a side-by-side comparison, see [Agent Chat vs Run Agent Task](/ai-agents/agents-interacting#agent-chat-vs-run-agent-task). ### Testing and Error Handling Before deploying, test your agent task using the **Test & Preview** feature: 1. Fill in value references with actual data 2. Run the agent task 3. Verify the output format and quality 4. Adjust task definition if needed Test with multiple scenario types: typical cases, edge cases, ambiguous cases, and varying data quality. After deployment, review the first 10–20 runs manually, monitor the `run_agent_task.success` field, and refine your task definition based on real-world performance. The system includes built-in retry logic (up to 3 attempts) when agents don't provide correctly formatted structured output: 1. Agent attempts to provide structured output 2. If format is incorrect, system returns error to agent with details 3. Agent tries again with error context 4. Repeats up to 3 times Always check `run_agent_task.success` before using agent output in downstream actions: ``` Run Agent Task ↓ IF run_agent_task.success = true → Normal processing flow OTHERWISE → Error handling: - Post Comment: "Agent task failed: {{run_agent_task.error_message}}" - Send Message to Teams: "@admins Agent task error" - Make Assignment: Route to manual review ``` Design workflows that remain functional even if the agent task fails: ``` Run Agent Task: Personalization analysis ↓ IF run_agent_task.success = true → Send Email: Personalized message with {{run_agent_task.recommendations}} OTHERWISE → Send Email: Standard template (still functional) ``` If your agent isn't processing uploaded files correctly, check these common issues: **Agent task completes in under 2 seconds with no file content** The agent did not receive the file. Verify both: 1. **Attachment source** — Open the automation, click **Edit** on the Run Agent Task, and confirm the Files section references **Attachment Trigger** (not a record reference). 2. **Agent model** — Confirm the agent uses a multimodal model on the agent's Overview page. **Agent responds "I don't have access to the attached file"** Same root cause — the file was not delivered. Fix the attachment source or switch to a multimodal model. **Execution history shows only 1 completed action** The Run Agent Task step failed or produced no usable output, causing downstream tasks to be skipped. Check the task's output in the Execution Details panel for an error message. ## When to Use Run Agent Task ### Ideal Use Cases Use Run Agent Task when a step in your workflow requires reasoning, judgment, or synthesis of information. **Scenario:** Tasks requiring information gathering and synthesis ``` New Lead Created → Run Agent Task Task: "Research {{lead.company}} to identify: - Industry and market position - Recent news or developments - Competitive landscape - 3-5 key talking points for our sales team Success: Provide actionable sales intelligence" Output Type: Structured Fields: industry, company_size, recent_news, talking_points, research_confidence ``` **Scenario:** Decisions requiring multiple factors and reasoning ``` Contract Uploaded → AI File Analysis → Run Agent Task Task: "Evaluate this contract with terms {{contract.terms}} and value {{contract.value}}. Consider our standard terms, risk tolerance, and relationship with {{customer.name}}. Success: Provide risk assessment (Low/Medium/High), key concerns, and approval recommendation." Output Type: Structured Fields: risk_level, key_concerns, approval_recommended, negotiation_points ``` This pattern pairs well with [AI File Reader](/workflows/elementum-intelligence-file-reader) for extracting structured data before agent evaluation. See the document review example in [Workflow Examples](#workflow-examples) below. **Scenario:** Evaluating quality, completeness, or appropriateness of content ``` Application Submitted → Run Agent Task Task: "Review this grant application from {{applicant.name}} for {{project.title}}. Application content: {{application.content}} Grant criteria: {{grant.criteria}} Success: Evaluate completeness, alignment with criteria, and provide score (1-10) with feedback." Output Type: Structured Fields: completeness_score, criteria_alignment, overall_score, strengths, improvements_needed ``` **Scenario:** Enhancing records with synthesized information ``` Customer Record Created → Run Agent Task Task: "Enrich data for {{customer.company}} in {{customer.industry}}. Success: Provide company size estimate, key decision makers' typical titles, common pain points in their industry, and recommended product fit." Output Type: Structured Fields: company_size_estimate, decision_maker_titles, industry_pain_points, product_recommendations ``` **Scenario:** Tasks requiring sequential reasoning and proactive action ``` Complex Issue Detected → Run Agent Task Task: "Diagnose this system issue: {{issue.description}} Recent changes: {{system.recent_changes}} Error logs: {{system.errors}} Success: Provide root cause analysis, step-by-step resolution plan, and prevention recommendations." Output Type: Structured Fields: root_cause, resolution_steps, estimated_fix_time, prevention_measures ``` ### When NOT to Use Run Agent Task Use standard [automation actions](/workflows/automation-actions-reference) instead when: * **Deterministic logic** — Simple IF/THEN logic, calculations, or predefined rules. Use IF conditions or Run Calculation instead. * **Direct data operations** — Creating, updating, searching, or relating records with known values. Use Create Record, Update Record Fields, or Search Records instead. * **Standard classifications** — Categorization with clear, predefined categories. Use [AI Classification](/ai-agents/ai-automations) instead. * **API integrations** — Direct calls to external systems with structured parameters. Use Send API Request instead. **Decision rule:** Does this task require reasoning, judgment, or synthesis of information? If yes, consider Run Agent Task. If no, use standard automation actions. ## Workflow Examples These examples demonstrate the structured → agent → structured pattern in complete workflows. Each combines standard [automation actions](/workflows/automation-actions-reference) with Run Agent Task. **Scenario:** Route support tickets based on nuanced assessment, not just keywords. ``` Support Email Received ↓ AI Classification: Categorize ticket type ↓ Search Records: Find customer ↓ Find Related Records: Get customer's recent tickets and products ↓ Run Agent Task: "Intelligent Ticket Assessment" Task: "Assess support ticket from {{customer.name}} about {{ticket.subject}}. Ticket content: {{ticket.body}} Customer tier: {{customer.tier}} Recent tickets: {{related_tickets.summaries}} Customer products: {{customer.products}} Success: Determine complexity (1-5), required expertise (General/Product/Engineering), urgency (Low/Medium/High/Critical), and whether this is part of a pattern." Output Type: Structured Fields: complexity_score (number), required_expertise (text), urgency (text), pattern_detected (checkbox), pattern_description (text), estimated_resolution_hours (number) ↓ IF run_agent_task.pattern_detected = true → Add Watcher: Customer Success Manager → Post Comment: "Pattern detected: {{run_agent_task.pattern_description}}" ↓ IF run_agent_task.urgency = "Critical" → Make Assignment: Senior Support (immediate) → Send Message to Teams: "@support-leads Critical ticket: {{ticket.subject}}" ELSE IF run_agent_task.required_expertise = "Engineering" → Make Assignment: Engineering Team → Start Approval Process: Engineering time allocation OTHERWISE → Make Assignment: General Support ↓ Update Record Fields: - Complexity: {{run_agent_task.complexity_score}} - Estimated Hours: {{run_agent_task.estimated_resolution_hours}} ↓ Send Email Notification: Customer confirmation with estimated timeline ``` This workflow uses [AI Classification](/ai-agents/ai-automations) for basic categorization and Run Agent Task for nuanced assessment, then feeds agent output into standard routing logic. **Scenario:** Automated first-pass contract review for a legal team. ``` Contract Attachment Added ↓ AI File Analysis: Extract contract data ↓ Search Records: Find customer and relationship history ↓ Run Agent Task: "Contract Risk Assessment" Task: "Review contract from {{customer.name}} with value {{contract.value}}. Extracted terms: {{ai_file_analysis.terms}} Standard terms: {{company.standard_contract_terms}} Customer relationship: {{customer.relationship_years}} years, LTV: ${{customer.lifetime_value}} Success: Assess risk (Low/Medium/High), identify deviations from standard, flag must-negotiate items, and recommend approval authority." Output Type: Structured Fields: risk_level (text), deviations (list), must_negotiate (list), recommended_approver (text), business_justification (text), expedite_recommended (checkbox) ↓ Update Record Fields: Add risk assessment and recommendations ↓ IF run_agent_task.risk_level = "High" → Start Approval Process: Legal + CFO → Send Message to Teams: "#legal High-risk contract requires review" ELSE IF run_agent_task.risk_level = "Medium" → Start Approval Process: Legal only OTHERWISE (Low risk) → IF contract.value < $10000 Update Record Fields: Auto-approved → OTHERWISE Start Approval Process: Manager only ``` This pairs [AI File Reader](/workflows/elementum-intelligence-file-reader) for data extraction with Run Agent Task for risk assessment that requires judgment. **Scenario:** Provide personalized order handling based on customer history. ``` Order Created ↓ Search Records: Get customer history ↓ Run Agent Task: "Analyze Order Personalization" Task: "Analyze order from {{customer.name}} for {{order.items}}. Customer history: {{customer.past_orders}}, lifetime value: ${{customer.ltv}}, preferences: {{customer.preferences}}. Success: Identify upsell opportunities, special handling needs, personalized message suggestions, and estimated satisfaction impact of personalization." Output Type: Structured Fields: upsell_items (list), special_handling (text), personalized_message (text), satisfaction_impact (text), include_sample (checkbox) ↓ IF run_agent_task.include_sample = true → Update Record Fields: Add free sample to order ↓ IF run_agent_task.upsell_items has values → Send Email: Personalized confirmation with recommendations OTHERWISE → Send Email: Standard confirmation ↓ Create Record: Log personalization actions for future learning ``` ## Advanced Patterns For complex workflows, break work into sequential agent tasks where each builds on the previous: ``` Data Collected ↓ Run Agent Task: "Initial Analysis" → Analyze raw data and identify key themes ↓ Run Agent Task: "Deep Dive" → Task: "Based on initial themes {{agent_task_1.themes}}, conduct detailed analysis..." ↓ Run Agent Task: "Recommendations" → Task: "Given analysis {{agent_task_2.findings}}, provide strategic recommendations..." ``` Use this when a single agent task would be too complex — breaking into stages improves output quality. Use agents only when intelligence is needed, falling back to standard actions for straightforward cases: ``` Record Updated ↓ IF simple_condition = true → Standard processing (fast, deterministic) OTHERWISE → Run Agent Task (intelligent assessment) → Use agent insights for decision ``` This is the same pattern shown in the support ticket example in [Workflow Examples](#workflow-examples), where [AI Classification](/ai-agents/ai-automations) handles simple categorization and Run Agent Task handles complex cases. Combine agent intelligence with human oversight using [approval processes](/workflows/approval-processes): ``` Contract Submitted ↓ Run Agent Task: "Contract Assessment" ↓ IF run_agent_task.risk_level = "Low" AND run_agent_task.confidence > 0.9 → Auto-approve (agent sufficient) OTHERWISE → Start Approval Process (human review) → Context: Agent provided {{run_agent_task.reasoning}} ``` Run Agent Task integrates with other [automation actions](/workflows/automation-actions-reference): * **AI File Reader** — Extract structured data from documents, then pass to an agent for evaluation and recommendations. See the document review example in [Workflow Examples](#workflow-examples). * **API Requests** — Use agent output to determine API endpoints or parameters, or feed API response data into an agent for synthesis. * **AI Classification** — Use classification for basic categorization, then route complex cases to Run Agent Task. See the support ticket example in [Workflow Examples](#workflow-examples). ## Agent Management ### Agent Deletion Protection When you attempt to delete an agent that's used in automations, the system prevents deletion and shows a list of automations using that agent with direct links to each one. Before deleting an agent: 1. Check which automations use it 2. Update those automations to use a different agent or action 3. Test the updated automations 4. Then delete the agent ## Getting Started Checklist 1. **Identify a use case** where a workflow step requires reasoning or research 2. **Design the workflow** using the structured → agent → structured pattern 3. **Create or select an agent** with appropriate capabilities — see [Agent tools, deployment, and integrations](/ai-agents/agents-tools-and-deployment) 4. **Write a task definition** with complete context and [clear success criteria](#task-definition) 5. **Define output fields** if using [structured output](#output-type) 6. **Test with real data** using the Test & Preview feature 7. **Implement [error handling](#testing-and-error-handling)** with success field checks 8. **Deploy and monitor** — review early executions, then iterate based on results ## Next Steps See all available automation actions including Run Agent Task details Learn about other AI-powered automation capabilities Understand how agents work and integrate with workflows General automation and workflow best practices # Populate Dropdown Fields from External APIs Source: https://docs.elementum.io/workflows/api-powered-dropdowns Configure dropdown fields that fetch options dynamically from external APIs ## Overview API-powered dropdown fields retrieve their selection options from external APIs at runtime, rather than from a static list of values maintained within Elementum. This enables use cases where dropdown options need to reflect data from third-party systems such as ERPs, CRMs, or custom internal services. In Elementum, an API-powered dropdown is a **Dynamic** dropdown field that references an API Element. The API Element is built on top of an API CloudLink and exposes one or more API Actions that fetch data from the external system. The dropdown calls a selected API Action at runtime to populate its options. *** ## Prerequisites Before configuring API-powered dropdown fields, ensure the following: * **Admin access** to the app where you want to add the field * **API endpoint details** for the external system: * Endpoint URL * HTTP method (GET, POST, or PUT) * Authentication credentials (if required) * Response format (JSON) *** ## Step 1: Create an API CloudLink Follow [Connect a REST API via CloudLink](/administration/connect-rest-api-cloudlink) to set up the connection. In short: 1. Navigate to Settings icon **Organization Settings** > **CloudLinks**. 2. Click **+ CloudLink** and choose **API**. 3. Enter a **Name** and **Base URL**, select an **Authentication** method, and provide the credentials. 4. Click **Save**. API CloudLinks power dropdowns and API Elements only. AI services (OpenAI, Gemini, Snowflake Cortex, etc.) cannot be attached to a CloudLink configured with **API** as the connection type—use a CloudLink connected to a supported data warehouse instead. ## Step 2: Create an API Element Create a new Elements icon Element connected to the API CloudLink you created in Step 1, and define the Element's fields to match the structure of the API response. The Element's data is populated by the API at runtime rather than being stored in Elementum's database. ## Step 3: Configure API Actions on the Element Configure the API Actions required to interact with the API CloudLink through the Element. Each API Action defines how to call the external system — the endpoint path, HTTP method, request parameters, and how the response maps to the Element's fields. At minimum, configure one API Action that returns the list of records used to populate the dropdown's options. ## Step 4: Add a Dynamic Dropdown Field to a Record Layout 1. In your app's **Configuration** > Record Details Layout icon **Record Details Layout**, add a new **Dropdown** or **Multi-Select** field. 2. In the field configuration, set **Dropdown Type** to **Dynamic**. 3. In the related object selector on the right side of the page, choose the API Element you created in Step 2. 4. Select the **API Action** to use for populating the dropdown. 5. Fill out the remaining field options, including any variable mappings the selected API Action requires (see below). ### Variable mappings If the selected API Action requires input parameters, map them to fields on the current record or to static values: | Mapping Type | Description | | ---------------- | ------------------------------------------------------------------------------- | | **Record Field** | A field value from the current record is passed as a variable to the API Action | | **Static Value** | A fixed value is passed to the API Action | This allows the dropdown options to change based on other field values on the record. ### Supported configurations The following dynamic-dropdown configurations are supported: | Configuration | Supported | Notes | | ------------------------------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | Parent/child dynamic dropdowns that reference **different** objects | Yes | The child dropdown is filtered by the parent's selected value via a variable mapping on the API Action | | Parent/child dynamic dropdowns that reference the **same** object | Yes | Both dropdowns can target the same Element. Use distinct variable mappings or API Actions so each dropdown filters its options independently | When configuring a parent/child relationship, the child dropdown must be mapped to a field on the current record (typically the parent dropdown's value) under **Variable Mappings**, so that the API Action retrieves child options scoped to the parent's selection. ### Referencing the selected value in a calculation Dynamic dropdowns are referenced in calculations with the same `HANDLE."FieldName"` syntax as any other field. The value is the selected option, as a single text value for single-select fields. See [Referencing a dynamic dropdown field](/data/calculations-troubleshooting#referencing-a-dynamic-dropdown-field) for the pattern and the multi-select limitation. *** ## Cloud Credentials for API Connections API-powered features store authentication credentials securely through the CloudLink system. To manage API credentials: 1. Navigate to Settings icon **Organization Settings** > **CloudLinks** 2. Select or create an **API** CloudLink 3. Configure credentials in the credential editor: * **Basic Auth**: Username and password * **Bearer Token**: API token * **OAuth 2.0**: Token URL, client ID, client secret, and optional scope Credentials are encrypted at rest and are never exposed in the UI after initial configuration. *** ## Considerations * API responses are subject to a configurable timeout. If the external API does not respond within the timeout period, the dropdown displays an error * Consider the latency of your external API. Dropdowns that take several seconds to load create a poor user experience * For high-traffic fields, ensure your external API can handle the request volume * If the API returns an error or is unreachable, the dropdown displays an empty state with an error indicator * Verify your API endpoint is accessible from Elementum's servers (firewall rules, IP allowlisting may be required) * Dynamic dropdowns on API Elements fetch data according to the Element's configured refresh behavior * Use OAuth 2.0 or Bearer Token authentication for production integrations. Avoid Basic Auth over non-HTTPS endpoints * API credentials are stored encrypted and are not retrievable after configuration * Elementum sends requests server-side; API endpoints are not exposed to end users' browsers *** ## Troubleshooting | Issue | Resolution | | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Dropdown shows no options | Verify the API CloudLink is reachable and the API Action returns a valid JSON response. Confirm the API Action is the one selected on the dropdown field and that its response is mapped to the API Element's fields | | Authentication errors | Confirm the CloudLink credentials are correct. For OAuth, verify the token URL, client ID, and client secret, and that the OAuth scope grants read access | | Dropdown loads slowly | Check the external API's response time. Consider adding caching on the API side or reducing the response payload size | | Options appear but display incorrectly | Review the API Action's response mapping on the API Element. Ensure the field used as the option label is mapped to the correct property in the response | | Variable mappings not working | Ensure the mapped source fields on the current record have values. Empty source fields result in empty or null parameters in the API Action request | # App Health Source: https://docs.elementum.io/workflows/app-health Monitor automation performance and system health App Health provides real-time monitoring and insights into your automation performance and system health. This dashboard helps administrators track system performance, identify issues, and optimize automation efficiency. Health monitoring is also available on Elements, where it appears as **Element Health** in the left navigation menu. ## Overview The App Health dashboard gives you a quick health overview with real-time error tracking and detailed drill-down insights to help you: * **Monitor System Performance:** Track overall system health and identify potential issues * **Automation Health Tracking:** View automation success/failure rates and performance metrics * **Error Detection:** Get real-time error tracking with detailed diagnostic information * **Performance Optimization:** Identify bottlenecks and optimize automation efficiency * **Resource Management:** Monitor system resource usage and capacity ## Getting Started Navigate to the object you want to monitor. Click **Overview** under **App Health** (or **Element Health**) in the left navigation menu. Check the calendar view for recent green (success) and red (failure) indicators to get a snapshot of automation performance. Click on a failed execution to view its timestamp, triggering entity, and error details. Use this information to diagnose and resolve the issue. Set up alert thresholds and notification routing so your team is notified when failure rates or execution times exceed acceptable levels. Schedule regular reviews — daily health checks and weekly trend analysis — to catch issues early and identify optimization opportunities. ## Automation Health The Automation Health section provides comprehensive monitoring of all automation activities: ### Health Metrics The Overview gives you a quick glance at your automation performance with the following metrics: * **Successful Executions:** Count of automations that completed successfully * **Failed Executions:** Count of automations that encountered errors * **Performance Trends:** Visual calendar view showing automation health over time ### Health Calendar The health calendar provides a visual representation of automation performance over time: * **Green indicators:** Successful automation runs * **Red indicators:** Failed automation runs * **Daily aggregation:** See patterns in automation success/failure * **Monthly overview:** Track long-term trends and seasonal patterns ### Detailed Automation History Click on the red squares in the calendar — days with failed automations — to drill into the details for that day. Each entry includes: * **Execution Timestamps:** When each automation ran * **Record:** The record that triggered the automation * **Automation Name:** Which automation was involved * **Automation Status:** Whether the run succeeded or failed For deeper insight into failed automations, see [Interventions](#interventions). ## Interventions The **Interventions** page lets you investigate failed automations, assign them for review, and track resolution progress. It surfaces key failure statistics at a glance and provides a structured workflow for triaging errors. ### Summary Cards At the top of the page, four cards provide a real-time snapshot of automation failures: * **Needs Review:** Total number of interventions awaiting investigation * **New in Last 24h:** Recent failures with a comparison to the previous period * **Error Rate (7d):** Percentage of failed runs over the last seven days, along with total run count * **Most Errors:** The automation with the highest failure count, helping you prioritize fixes ### Active Interventions Below the summary cards, the Active Interventions table lists every failed automation run with the following details: * **Status:** Current triage state (e.g., Needs Review) * **Assigned To:** Assign a team member to investigate the failure * **Record:** The record type and source that triggered the automation * **Automation & Action:** The automation name and the specific action that failed * **Error:** The error message describing what went wrong, with **Resolve** and **Ignore** actions Use the search bar and the **All Statuses** and **All Assignees** filters to narrow down the list. For bulk operations, select multiple interventions and use **Mark All As Resolved** or **Ignore All**. ## Best Practices for App Health Monitoring * **Daily Health Checks:** Review automation health metrics daily * **Weekly Performance Reviews:** Analyze trends and identify optimization opportunities * **Monthly Capacity Planning:** Assess system capacity and growth requirements * **Quarterly Performance Audits:** Comprehensive review of automation efficiency * **Error Prevention:** Use error patterns to prevent future issues * **Performance Tuning:** Optimize slow-running automations * **Capacity Management:** Plan for system growth and peak usage * **Documentation Updates:** Keep automation documentation current * **Threshold Setting:** Configure alerts for critical performance metrics * **Escalation Procedures:** Define response procedures for different alert types * **Notification Routing:** Ensure alerts reach the appropriate team members * **Alert Fatigue Prevention:** Balance alert sensitivity with usefulness ## Integration with Automation System App Health integrates seamlessly with the [Automation System](/workflows/automation-system) to provide: * **Unified Monitoring:** Combined view of automation design and performance * **Context-Aware Insights:** Performance data linked to specific automation configurations * **Optimization Recommendations:** Actionable suggestions based on health data * **Troubleshooting Support:** Direct links from errors to automation configuration # Approval Processes Source: https://docs.elementum.io/workflows/approval-processes Configure and manage review and sign-off workflows in your applications Approvals are a key feature in Elementum that enable structured review and sign-off workflows. Users can request approvals manually, or automations can start approval processes automatically based on specific triggers and conditions. ## Overview The approval system provides flexible workflow management where: * Users can initiate approval requests for critical decisions * Automations can automatically trigger approval processes based on data changes or business rules * App Admins can configure automations to listen for approval events and move processes forward * Multiple approval types support different business scenarios ## How Approvals Work Users can request approvals directly through the application interface when they need sign-off on: * Financial transactions above threshold amounts * Document submissions requiring legal review * Status changes that affect project timelines * Resource allocations for team assignments Automations can automatically start approval processes when: * Specific data thresholds are met (e.g., expense over \$5,000) * Attachments are added to records requiring review * Workflow stages are reached in business processes * Business rules are triggered by data changes App Admins can write automations that listen for approval events and automatically move processes forward when the right people have recorded approvals or denials. ## Common Approval Scenarios **Scenario:** Purchase orders over \$1,000 require manager approval **Configuration:** * Trigger: Amount field > \$1,000 * Approver: Direct manager * Locked fields: Amount, vendor, description **Scenario:** Legal documents need review before execution **Configuration:** * Trigger: Document type = "Contract" * Approver: Legal team group * Required approvals: 2 of 5 legal team members **Scenario:** Employee vacation requests require supervisor approval **Configuration:** * Trigger: Manual request submission * Approver: Employee's supervisor * Delegate: Department head (when supervisor unavailable) **Scenario:** Budget modifications need finance and department head approval **Configuration:** * Trigger: Budget variance > 10% * Approvers: Finance Manager → Department Head * Sequential approval required ## Approval Configuration ### Set Up Approval Processes 1. Click **Approval Processes** under **Workflows and Processes** in your app. 2. Click **Create New**. 3. Enter a name and assign it to a stage in your workflow. 4. Click **Save**. ### Basic Settings **Purpose:** Unique identifier for the approval process **Best Practice:** Use descriptive names that clearly indicate the purpose **Examples:** * "Purchase Order Approval - Over \$1K" * "Legal Document Review" * "Employee Onboarding Sign-off" **Purpose:** Link approval to specific workflow stage **Best Practice:** Align approvals with logical business process stages **Examples:** * "Review" stage for document approvals * "Pending Approval" stage for purchase orders * "Manager Review" stage for time-off requests **Purpose:** Restrict field modifications during the approval process **Best Practice:** Lock fields that shouldn't change during review **Examples:** * Amount and vendor fields for purchase orders * Contract terms for legal documents * Request dates for time-off approvals Enable the **Automated approval** toggle if the process is meant to be started by automations. When enabled, users will not be able to manually start this process. ### Approval Types **Sequential approver workflow** where each approver must act before the next can proceed. Each step in the chain can be assigned to a **user**, a **group**, or a **dynamic manager**. The dynamic manager option automatically sets the approver to a custom number of manager levels above the requester, based on the reporting hierarchy defined in [Org Structure](/administration/org-structure). **Best for:** * Budget approvals requiring multiple levels * Document reviews with hierarchical sign-off * Project milestone approvals **Example Configuration:** 1. Direct Manager 2. Department Head 3. Finance Director 4. CFO (for amounts > \$10,000) **Dynamic approver selection** where users choose approvers at runtime. **Best for:** * Project-specific approvals * Cross-departmental reviews * Flexible approval routing **Example Use Case:** User submits expense report and selects appropriate approvers based on expense categories and amounts. ### Linked Record Approvals Run an approval template multiple times on a single record, with each instance tied to a specific linked record. Use this to handle sign-off per line item—such as one approval per purchase order, budget line, or deliverable—instead of bundling everything into a single record-level approval. **Enable Linked Record Approval:** 1. In your app, open **Approval Processes** and click **Create New**. 2. Toggle on **Linked Record Approval**. 3. Select the target linked object the approval should run against. 4. Configure the remaining approval details (name, stage, approvers, and rules) as you would for a standard approval process. Once enabled, the approval template can be run multiple times on the same record—once per linked record—either manually or through an automation. **Manual requests:** When **Linked Record Approval** is turned on, requesting approval on a record displays a **Linked Line Item Record** field. Choose the specific linked record from the dropdown to start an approval instance tied to that line item. **Automated requests:** Use the **Start Approval Process** automation action to trigger approvals based on business rules: 1. Select the **Record** the approval applies to. 2. Set **Approval Process** to the linked-record-enabled template (for example, *Line Item Approvals*). 3. In the **Linked \[Object] Record** field (for example, **Linked PO Line Items Record**), choose the linked record from the dropdown. 4. Enter an **Approval Process tag** to uniquely identify this approval instance. Tags allow automations to differentiate between each approval chain on the same record—using the linked record's ID is recommended. Pair this action with a loop that iterates over linked records to start an independent approval instance for each one. ### Button Customization Customize the approval interface to match your business terminology. Here are some examples: **Approve Option:** "Authorize" (9/20 characters) **Deny Option:** "Reject" (6/20 characters) **Approve Option:** "Sign Off" (8/20 characters) **Deny Option:** "Send Back" (9/20 characters) **Approve Option:** "Grant" (5/20 characters) **Deny Option:** "Decline" (7/20 characters) ### Add Approvals to Your Layout To display approvals in your workflow, add the Approvals component to your record layout: 1. Open your object and click **Record Details Layout** under **User Interface** in the object's menu. 2. In the layout builder, go to the **Components** tab. 3. Find and drag the **Approvals** component to your desired section. 4. The page automatically saves your layout changes. To trigger approvals automatically based on business rules, use the **Start Approval Process** automation action. See the [Actions Reference](/workflows/automation-actions-reference) for configuration details. ## Advanced Features ### Approval Delegates Approval delegates act on your behalf when you are unavailable. You can enable or disable delegation from your user settings. 1. Click your profile icon in the bottom left corner. 2. Click **Approvals**. 3. Use the dropdown to search for the user who will take action on your behalf. 4. Click **Save** in the popup. 1. Click your profile icon in the bottom left corner. 2. Click **Approvals**. 3. Click **Clear**. Set approval delegates before planned absences to ensure business continuity and prevent approval bottlenecks. ### Group Approvals When you select a group as a step in an approval chain, you can configure how many members need to act before the step is resolved: * **Approvals required** — The number of group members who must approve for the step to pass. * **Denials required** — The number of group members who must deny for the step to be rejected. ### Automation Integration Automations can automatically manage approval processes based on business rules and conditions. See the [Actions Reference](/workflows/automation-actions-reference) for full details on the **Start Approval Process** action. **Automation Actions:** **Trigger Examples:** * Purchase order amount exceeds \$1,000 * New employee record created * Contract upload detected * Budget variance threshold reached **Configuration Example:** IF Amount > \$1,000 THEN Start "Purchase Order Approval" **Trigger Examples:** * Small amounts within delegation authority * Pre-approved vendor purchases * Routine maintenance requests * Employee data updates **Configuration Example:** IF Amount \< \$100 AND Vendor = "Approved Vendor" THEN Auto-approve "Purchase Order Approval" **Trigger Examples:** * Requests exceeding budget limits * Invalid or incomplete data * Policy violations detected * Duplicate submissions **Configuration Example:** IF Amount > Budget\_Remaining THEN Auto-deny "Purchase Order Approval" WITH Reason "Exceeds available budget" **Trigger Examples:** * Underlying data changes significantly * Requestor cancels original request * Deadline passes without action * Higher priority conflicts arise **Configuration Example:** IF Original\_Amount != Current\_Amount THEN Cancel "Purchase Order Approval" WITH Reason "Purchase order amount changed" ## Approval Workflow States **Active approval requests** requiring action from assigned approvers. **Information Displayed:** * Approval summary and context * Current position in approval chain * Deadline information (if configured) * Attached documents and relevant data * Previous approver comments **Historical record** of completed approvals for audit and reference. **Information Tracked:** * Approval outcomes and timestamps * Approver information and comments * Approval chain progression * Time taken for each approval step * Final approval status and completion date ## Email Notifications and Approval Links When an approval request is created, approvers receive email notifications containing **Approve** and **Deny** buttons for quick action directly from their inbox. Approval links in email notifications expire after 5 days. After expiration, the links will no longer be valid. ### Completing Approvals After Link Expiration If an approval email link has expired, approvers can still complete the approval through the platform: 1. Log into Elementum 2. Navigate to **Home > My Approvals** 3. Locate the pending approval request 4. Complete the approval or denial from the list 1. Log into Elementum 2. Open the record that requires approval 3. Complete the approval or denial directly from the record details Approval requests remain active in the platform regardless of email link expiration. The 5-day expiration only affects the convenience links in email notifications. ## Best Practices * **Clear Approval Names:** Use descriptive names that indicate purpose and scope * **Logical Stage Assignment:** Link approvals to appropriate workflow stages * **Realistic Timelines:** Set achievable approval deadlines with buffer time * **Lock Critical Fields:** Prevent data changes during approval processes * **Appropriate Permissions:** Ensure only authorized users can modify approval settings * **Audit Trails:** Maintain complete records of all approval actions * **Configure Delegates:** Ensure business continuity with proper delegation * **Clear Instructions:** Provide context and guidance for approvers * **Timely Notifications:** Keep stakeholders informed of approval status * **Monitor Performance:** Regularly review automated approval triggers and outcomes * **Test Thoroughly:** Validate automation logic before production deployment * **Document Rules:** Maintain clear documentation of approval automation rules ## Troubleshooting Common Issues **Possible Causes:** * Automation trigger conditions not met * Insufficient user permissions * Incorrect stage assignment **Solutions:** * Verify trigger conditions and data values * Check user roles and permissions * Confirm approval is assigned to correct workflow stage **Possible Causes:** * Email notification settings disabled * Approver not active in system * Delegate settings interfering **Solutions:** * Enable email notifications in user settings * Verify approver account status * Review delegate configuration **Possible Causes:** * Incorrect group membership * Conflicting approval/denial thresholds * Group members lacking permissions **Solutions:** * Verify group membership and roles * Review threshold settings for logical consistency * Confirm group member permissions # Assignment Rules Source: https://docs.elementum.io/workflows/assignment-rules Automatically assign work to the right team members using configurable routing strategies Assignment Rules distribute work to team members based on configurable strategies. When combined with the [Automation System](/workflows/automation-system), assignments happen automatically as work arrives, helping balance team workload and reduce manual routing. ## Prerequisites Before using Assignment Rules, your app or task must have two specific field types. You can add these through the [Layout Builder](/workflows/layouts). Assignment Rules are configured under **Workflows & Processes** in the left navigation menu of an App or Task. * **Assignment Group** field (group type) — Defines the pool of users who can receive assignments * **Assignee** field (user type) — The individual user who receives the assignment The Assignment Group field must be populated with users before running a Make Assignment automation. An empty Assignment Group causes the automation to fail. This is the most common cause of assignment issues. ## Assignment Strategies Assignment strategies determine how work is distributed among team members. ### Distributed Work Evenly distributes assignments across all available team members to balance workload. **Best for:** * Teams with similar skill levels * Work that requires consistent distribution * Preventing uneven assignment loads * Customer support and general task routing **Example:** Support tickets are distributed among all available agents so that no single agent receives a disproportionate share. ## Set Up an Assignment Rule 1. Open your app or task and select **Assignment Rules** under **Workflows & Processes** in the left navigation 2. Click **+ Rule** to create a new rule 3. Enter a **Title** — use a descriptive name (e.g., "Support Ticket Assignment") 4. Optionally add a **Description** explaining when the rule applies 5. Select an **Assignment Strategy** (e.g., Distributed Work) ## How Assignment Rules Execute Assignment Rules run through the [Make Assignment action](/workflows/automation-actions-reference#make-assignment) in the Automation System: 1. An event occurs (e.g., a new record is created or a status changes) 2. An automation containing the Make Assignment action triggers 3. The action checks that the Assignment Group field contains users 4. The configured Assignment Rule applies its strategy to select a user 5. The selected user is written to the Assignee field The Make Assignment action will fail if the Assignment Group field is empty at the time of execution. ## Advanced Patterns Combine Assignment Rules with automation conditions to route work to different groups: * Route high-priority issues to a senior support group while sending standard issues to general support * Assign leads to different sales teams based on region or deal size Chain automations to escalate unresolved work through assignment tiers — for example, assigning to Level 1 support first and re-assigning to Level 2 if unresolved after a set period. * **Edit a rule** by selecting it from the Assignment Rules list and updating its configuration * **Rule priority**: When multiple rules could apply, the most specific rule takes precedence. Manual assignments always override automatic rules. ## Troubleshooting **Assignment failures or no assignments happening:** * Verify the Assignment Group field is populated with users before the automation runs * Confirm both the Assignment Group and Assignee fields exist in your app * Ensure the automation containing the Make Assignment action is published * Check automation logs for error details **Uneven distribution:** * Review current team member workloads * Verify the assignment strategy matches your use case * Check whether manual assignments are skewing distribution ## Related Features * [Automation System](/workflows/automation-system) — Event-driven workflows that trigger assignments * [Make Assignment Action](/workflows/automation-actions-reference#make-assignment) — The automation action that executes assignment rules * [App Health](/workflows/app-health) — Monitor automation execution and performance # Actions Reference Source: https://docs.elementum.io/workflows/automation-actions-reference Complete reference guide for all automation actions with configuration details, conditions, and walkthrough examples This reference covers every action available in the Elementum automation builder. Each section explains what the action does, how to configure it, and walks through a realistic scenario so you can see how it works in practice. New to automations? Start with the [Automation System](/workflows/automation-system) guide to learn how triggers, conditions, and actions fit together. ## Inspect Trigger and Action Outputs While Building As you build an automation, every trigger and action lists the variables it produces in an **Outputs** section at the bottom of its configuration pull-out. Each entry shows the variable name (for example, `textResult`, `result.project_name`, `create_record.id`) and its data type (Text, Decimal, Date, and so on), with a checkbox next to each one. Use this section to: * **Confirm available variables** — Verify the exact name and type of every output before referencing it in a later step. * **Select which outputs to expose** — Toggle the checkbox next to each variable to control whether it's surfaced to downstream actions. * **Catch missing values early** — If a variable you expect isn't listed, the step isn't producing it yet (a script may need to be re-executed so its output schema picks up the new property, an action may need to be re-tested, and so on). Checking the Outputs section as you configure each step is the fastest way to confirm that variable names match what you expect — without having to publish and run a full automation trace. ## Logic Actions Logic actions control which path your automation takes. They let you branch based on data values, check multiple criteria, and loop through collections of records. ### If / Otherwise If / Otherwise The **If** action creates a decision point. You define a condition, and the actions nested beneath it only run when that condition is true. **Otherwise If** adds additional branches, and **Otherwise** catches everything that didn't match a previous branch. #### How Conditions Work Each condition compares a value from your automation (a field on the trigger record, an output from a previous action, or a variable) against a target value using an operator. A single condition has three parts: | Part | What it means | Example | | ------------ | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | | **Value** | The data you want to check — select from trigger fields, action outputs, or variables | `trigger.priority` | | **Operator** | How to compare the value | `equals`, `does not equal`, `greater than`, `contains`, `is empty` | | **Target** | What you're comparing against — a static value, another field, or a variable | `"Critical"` | #### Combining Multiple Conditions When a single comparison isn't enough, add more conditions to the same If block. You connect them with **AND** or **OR**: * **AND** — Every condition must be true. Use this when you need all criteria met. * **OR** — At least one condition must be true. Use this when any one criterion is enough. **Example**: Route only high-value enterprise tickets to the priority queue: | Condition | Operator | Target | Connector | | --------------- | ------------ | ------------ | --------- | | `customer_tier` | equals | `Enterprise` | AND | | `order_amount` | greater than | `10000` | — | Both must be true for the actions beneath this If to run. #### Condition Groups When your logic mixes AND with OR, use **condition groups** to control evaluation order — similar to how parentheses work in math. Without groups, the automation evaluates conditions strictly top to bottom, which can produce unexpected results. Groups let you say "evaluate these conditions together first, then combine the result with the rest." **Scenario**: You want to escalate a support ticket when the customer is Enterprise tier AND the issue is either Critical priority OR has been open for more than 48 hours. Without condition groups, you'd have no way to express "Critical OR open 48+ hours" as a unit. With groups: | Group | Condition | Operator | Target | Connector | | ----------- | --------------- | ------------ | ------------ | --------- | | — | `customer_tier` | equals | `Enterprise` | AND | | **Group 1** | `priority` | equals | `Critical` | OR | | **Group 1** | `hours_open` | greater than | `48` | — | This reads as: customer is Enterprise **AND** (priority is Critical **OR** hours open is greater than 48). To create a condition group in the automation builder, click **Add Condition Group** in the If action's configuration panel. Drag conditions into or out of groups to restructure your logic. #### Building Multi-Branch Decisions Use **Otherwise If** and **Otherwise** to handle different outcomes in a single automation instead of building separate automations for each scenario. An order comes in and needs different approval paths depending on the amount: 1. **If** `order_amount` is greater than `10,000` — route to CFO for approval 2. **Otherwise If** `order_amount` is greater than `1,000` — route to the department manager 3. **Otherwise** (all remaining orders) — mark as auto-approved Elementum checks branches top to bottom and runs the **first one that matches**: * A \$15,000 order matches the first If, so it goes to the CFO. The remaining branches are skipped. * A \$3,000 order fails the first If (not greater than 10,000), matches the Otherwise If, and goes to the department manager. * A \$500 order fails both conditions, so it falls through to Otherwise and is auto-approved. **Variables**: Each If and Otherwise If outputs a boolean (`true` or `false`) that downstream actions can reference to check which branch ran. ### Repeat for Each Loops through a collection of records or data items and runs the same set of actions on each one. **Collection sources**: | Source | What to select as **Collection** | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | **Search Records** or **Find Related Records** | The action's matching-records output | | **Execute Script** | One array **property** on the script's result — not the whole result. See [From an Execute Script array](#from-an-execute-script-array). | | Multi-select field on the trigger record | The field itself. See [Multi-value fields → In Repeat for Each](/data/multi-value-fields#in-repeat-for-each). | **Configuration**: | Field | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Collection** | The list to iterate over — a previous action's collection output, an array property returned by Execute Script, or a multi-select field on the trigger record | | **Actions** | Drag actions inside the Repeat for Each block to run them on every item | **Variables**: Inside the loop, you have access to: | Variable | Description | | ----------------- | --------------------------------------------------------------------------------------------------------------- | | `item` | The current record or data item in the loop, with all its fields accessible (e.g., `item.email`, `item.status`) | | `index` | The current iteration number (starting from 0) | | **Is First Item** | Checkbox reference — `true` on the first iteration, `false` otherwise | | **Is Last Item** | Checkbox reference — `true` on the final iteration, `false` otherwise | #### From an Execute Script array Execute Script must return a JavaScript object, with the list on a named property. Repeat for Each then points at that property. ```javascript theme={null} return { participants: [ { name: "Alex Kim", email: "alex@example.com" }, { name: "Jordan Lee", email: "jordan@example.com" } ] }; ``` On the script's **Result** tab, that value is this JSON: ```json theme={null} { "participants": [ { "name": "Alex Kim", "email": "alex@example.com" }, { "name": "Jordan Lee", "email": "jordan@example.com" } ] } ``` Set **Collection** to `participants`. Inside the loop, `item` is one object from that array, so inner actions reference `item.name` and `item.email`. The script cannot return a JSON string, a bare array, or an array stored as a string. The Output Schema also has to declare each item property or those references resolve blank. See [Execute Script → Returning an array for Repeat for Each](#returning-an-array-for-repeat-for-each). An automation runs at the end of each day to send shipping confirmations for all orders placed that day. 1. **Search Records** finds all orders with `status = "Ready to Ship"` and `created_date = today` 2. **Repeat for Each** iterates over the search results 3. Inside the loop, for each order: **Run Calculation** computes the shipping cost, **Update Record Fields** sets the shipping amount and changes status to "Shipped", and **Send Email Notification** sends a confirmation to the customer Each iteration adds execution time, especially if the loop body includes API calls or AI actions. Filter your collection as tightly as possible before entering the loop — use specific Search Records conditions rather than searching broadly and filtering inside the loop. *** ## Record Actions Record actions create, update, search, and manage records and their relationships. Creates a new record in a specified element or table, populating fields from trigger data, action outputs, or static values. **Configuration**: | Field | Description | | ------------------ | ----------------------------------------------------------------------------------------------------------------------- | | **Action Name** | A descriptive name for this action | | **Element/Table** | Which element or table to create the record in | | **Field Mappings** | Map fields on the new record to values — select from trigger variables, previous action outputs, or enter static values | **Variables**: Outputs the new record ID and all field values, accessible as `create_record.id`, `create_record.{field_name}`, etc. When a customer sends an email to your support address, automatically create a support ticket: 1. **Email Received** trigger fires 2. **Search Records** finds the customer by `trigger.sender_email` 3. **Create Record** creates a new Support Ticket with: * Subject → `trigger.subject` * Customer → `search_records.customer` * Description → `trigger.body` * Status → `"New"` * Source → `"Email"` Set all field values in the Create Record action itself rather than creating the record and then immediately updating it with a separate Update Record Fields action. This saves an extra round-trip and makes the automation faster. Modifies one or more field values on an existing record. **Configuration**: | Field | Description | | ------------------ | ---------------------------------------------------------------------------------------- | | **Action Name** | A descriptive name for this action | | **Record** | Which record to update — typically the trigger record or a record from a previous action | | **Field Mappings** | Map fields to new values from trigger data, action outputs, or static values | **Variables**: Outputs the updated record with its new field values. After AI classifies a support ticket, update the ticket with the classification results: 1. **AI Classification** analyzes the ticket description and returns `category` and `confidence` 2. **Update Record Fields** sets: * Category → `ai_classification.category` * Priority → `ai_classification.confidence > 0.8 ? "High" : "Normal"` (via a preceding Run Calculation) * Classification Confidence → `ai_classification.confidence` Consolidate multiple field updates into a single Update Record Fields action instead of using several in a row. Each action that touches the record adds latency. Establishes a relationship link between two records, enabling cross-record data access in views and subsequent automation steps. **Configuration**: | Field | Description | | ----------------- | ---------------------------------- | | **Action Name** | A descriptive name for this action | | **Source Record** | The record to relate from | | **Target Record** | The record to relate to | | **Relationship** | The relationship type to create | **Variables**: Outputs relationship details and connected record information. **When to use**: After creating a new record that needs to be linked to an existing one — for example, linking a newly created project record to the customer who requested it. Queries a table and returns records matching your criteria, making them available as variables for downstream actions. **Configuration**: | Field | Description | | ----------------- | -------------------------------------------------------------------------------------------- | | **Action Name** | A descriptive name for this action | | **Element/Table** | Which element or table to search | | **Conditions** | Filter criteria using the same condition builder as If actions — value, operator, and target | | **Sort** | Order the matching records by one or more fields, each ascending or descending | | **Limit** | Cap the number of records returned, between 1 and 500 | Conditions in Search Records work the same way as [If conditions](#how-conditions-work): pick a field, choose an operator, and set a target value. You can add multiple conditions with AND/OR connectors and use condition groups for complex queries. **Matching a list of values**: The **is in** operator returns every record whose field value matches one of a list of values, so you can pull all matching records in a single condition instead of chaining multiple `equals` conditions with OR. It is available on Text, HTML, Number, and Decimal fields, and the list can be built at runtime — an **Execute Script** action that outputs a list of text or numbers can feed its output directly into the operator's target. **Sorting results**: Under **Sort**, open the **Select Field** dropdown in the **Add Sort** section and choose the field to sort results by, then use the direction control on the sort row to switch that field between ascending and descending order. Repeat **Add Sort** to sort by more than one field — drag the handle on a row to change its priority, or use the delete icon to remove it. When multiple sort fields are configured, results are ordered by the first field, then by each subsequent field in the order listed. **Limiting results**: Under **Limit**, enter the maximum number of records to return — any value between 1 and 500 — using the field or its up and down stepper controls. The limit caps how many records the action returns, so only the top records in your chosen sort order pass to downstream steps such as **Repeat for Each**. Sorting and the limit apply to the records that match your filter conditions; they do not change which records qualify, only their order and count. **Variables**: Outputs matching records as a collection. Use `search_records.{field_name}` to access the first result, or feed the collection into a **Repeat for Each** to process multiple matches. When processing an incoming email, find the customer record to link with the new ticket: 1. **Search Records** on the Customers element 2. Condition: `email` equals `trigger.sender_email` 3. If a match is found, use `search_records.customer` in the Create Record action to link the ticket to the customer Use **Search Records** when you're looking up records by exact field values — email addresses, IDs, status values. Use **AI Data Search** when the input is natural language or free-form text — a ticket description, a customer question — and you want semantically similar results rather than exact matches. Initiates a configured approval workflow for a record, sending notifications to designated approvers. **Configuration**: | Field | Description | | -------------------- | --------------------------------------------------------- | | **Action Name** | A descriptive name for this action | | **Approval Process** | Select an existing approval process configured in the app | | **Record** | The record to submit for approval | The approval process itself (approvers, stages, escalation rules) is configured separately under the app's [Approval Processes](/workflows/approval-processes) settings. This action starts that process for a specific record. **Variables**: Outputs the approval process ID and current status. Changes the status of an active approval process, advancing or halting the workflow. **Configuration**: | Field | Description | | --------------- | ------------------------------------------------------ | | **Action Name** | A descriptive name for this action | | **Status** | The new status to set — Approved, Rejected, or Pending | **Variables**: Outputs the new approval status and workflow state. Subscribes one or more users to a record so they receive in-platform notifications when the record changes. **Configuration**: | Field | Description | | --------------- | ------------------------------------------------------------------------------------------------------- | | **Action Name** | A descriptive name for this action | | **Record** | The record to add watchers to | | **Users** | Which users to subscribe — from a previous Search Users action, a static user, or a field on the record | **When to use**: When someone needs visibility into a record's progress without being the assignee — for example, adding a department manager as a watcher on all high-priority issues. Prevents changes to specified fields on a record, protecting data integrity after a process completes. **Configuration**: | Field | Description | | --------------- | ---------------------------------- | | **Action Name** | A descriptive name for this action | | **Record** | The record to lock fields on | | **Fields** | Which fields to lock | **When to use**: After an approval process completes, lock the approved values (price, terms, quantities) so they can't be changed without going through the approval process again. Assigns a record to a specific user or team. **Configuration**: | Field | Description | | --------------- | --------------------------------------------------------------------------------- | | **Action Name** | A descriptive name for this action | | **Record** | The record to assign | | **Assignee** | A user or team — from a Search Users result, a static value, or a field reference | **When to use**: After classification or routing logic determines who should handle a record. Often paired with an If action or AI Classification to route to the right team based on the record's content. Route support tickets to the right team based on AI classification: 1. **AI Classification** categorizes the ticket as Technical, Billing, or General 2. **If** `ai_classification.category` equals `"Technical"` → **Make Assignment** to Technical Support team 3. **Otherwise If** `ai_classification.category` equals `"Billing"` → **Make Assignment** to Billing team 4. **Otherwise** → **Make Assignment** to General Support queue Returns all records related to a given record, making them available for downstream actions. **Configuration**: | Field | Description | | ---------------- | ------------------------------------ | | **Action Name** | A descriptive name for this action | | **Record** | The record to find relationships for | | **Relationship** | Which relationship type to follow | **Variables**: Outputs a collection of related records. Feed into a **Repeat for Each** to process each one, or access the collection's count to make decisions. **When to use**: When you need context from linked records before making a decision — for example, pulling a customer's order history before classifying a support ticket's priority. Compiles data into a formatted Excel or PDF [report](/data/reports) file that subsequent actions can reference. Generate Report creates the file but does not save it to a record. Use **Save Attachment** after this action to persist the file, or include it in a **Send Email Notification** as an attachment. **Configuration**: | Field | Description | | --------------- | ----------------------------------------------- | | **Action Name** | A descriptive name for this action | | **Report** | Select an existing report configured in the app | **Variables**: | Variable | Type | Description | | ------------------ | ---- | ------------------------------------------------------------------------------------------------------ | | `generated_report` | File | The report file (Excel or PDF) for use in Save Attachment, Send Email, or other file-accepting actions | Generate and distribute a monthly performance report: 1. **Time-Based** trigger fires on the first of each month 2. **Generate Report** creates the Sales Performance Summary 3. **Save Attachment** attaches the report to the monthly reporting record 4. **Send Email Notification** sends the report to stakeholders with the file attached *** ## Elementum Intelligence Actions Intelligence actions use AI to analyze, classify, summarize, transform, and search your data. They accept unstructured input and return structured output that subsequent actions can use. Passes a task to a configured AI agent, which works autonomously and returns structured or text output. This is the most flexible intelligence action — use it when the other specialized actions (Classification, Summarization, etc.) don't cover your needs. **Configuration**: | Field | Description | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for the agent task | | **AI Agent** | Select an existing agent or create a new one | | **Start URL** | (Browser Use Agents only) Optional web address the agent's sandboxed browser opens on when the task runs. Hidden for Native Agents and other agent types | | **Task Definition** | What the agent should accomplish — supports `{{value_references}}` from trigger data and previous actions | | **Output Type** | **Text** (free-form response) or **Structured** (specific fields you define) | | **Output Fields** | (Structured mode only) The fields the agent should return, with names and types | **Variables**: | Variable | Description | | -------------------------------- | -------------------------------------------- | | `run_agent_task.success` | Boolean — whether the task completed | | `run_agent_task.error_message` | Error details if the task failed | | `run_agent_task.{custom_fields}` | Your defined output fields (Structured mode) | The agent runs in a headless environment with no user interaction, so the task definition must include all necessary context. Built-in retry logic (up to 3 attempts) handles cases where the agent doesn't return output in the expected format. For a detailed guide on using this action, see the [Agent Task Automation Guide](/workflows/agent-task-automation). Reads an uploaded document and extracts structured data into fields you define, without manual parsing. **Configuration**: | Field | Description | | ----------------- | -------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **File** | The file to analyze — from a trigger attachment, Read File output, or file field | | **Output Fields** | The specific data points to extract, with field names and types | **Variables**: Outputs each extracted field as an individual variable. Automatically process uploaded invoices: 1. **Attachment is Added** trigger fires when a PDF is uploaded to a vendor record 2. **AI File Analysis** extracts: vendor name, invoice number, line items, total amount, due date 3. **Create Record** creates an Invoice record with the extracted values 4. **If** `total_amount` is greater than `5000` → **Start Approval Process** Cleans, normalizes, and reformats input data into a consistent format. **Configuration**: | Field | Description | | ------------------------------- | ------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Input** | The data to transform — from trigger fields, action outputs, or variables | | **Transformation Instructions** | What transformation to apply | **Variables**: Outputs the transformed data in the specified format. **When to use**: When incoming data is inconsistent — addresses in different formats, phone numbers with or without country codes, company names with varying abbreviations — and you need it standardized before writing to records or sending to external systems. Assigns a category or label to input content based on meaning and context, returning the result with a confidence score. **Configuration**: | Field | Description | | --------------- | --------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Input** | The content to classify — from trigger fields, action outputs, or variables | | **Categories** | The set of categories the AI should choose from | **Variables**: Outputs the selected `category` and a `confidence` score (0–1). Use the confidence score in a downstream If action to handle low-confidence classifications differently — for example, routing to a human reviewer when confidence is below 0.7. Classify incoming support emails and route them: 1. **Email Received** trigger fires 2. **AI Classification** analyzes `trigger.body` against categories: Bug Report, Feature Request, Billing Question, General Inquiry 3. **If** `category` equals `"Bug Report"` AND `confidence` is greater than `0.8` → **Make Assignment** to Engineering 4. **Otherwise If** `category` equals `"Billing Question"` → **Make Assignment** to Finance 5. **Otherwise** → **Make Assignment** to General Support Distills lengthy input into a concise summary. **Configuration**: | Field | Description | | --------------- | ---------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Input** | The content to summarize — from trigger fields, action outputs, or variables | **Variables**: Outputs the `summary` text. **When to use**: When a downstream action needs a brief version of long-form content — for example, generating a one-line ticket description from a multi-paragraph customer email, or creating an executive summary from a detailed report before sending it via Teams. Runs a semantic search against an AI Search table and returns contextually relevant results. Unlike Search Records (which matches exact field values), AI Data Search finds results by meaning. **Configuration**: | Field | Description | | ------------------- | -------------------------------------------------------------------------------------------------- | | **AI Search Table** | Select a configured AI Search table (Element or Table) | | **Query** | The search query — supports `{{value_references}}` for dynamic queries based on the current record | **Variables**: Outputs the search results for use in subsequent actions. **When to use**: When the search input is natural language — a customer's question, a ticket description, or any free-form text — and you want the most relevant matches by meaning rather than exact field values. *** ## Communication Actions Communication actions send notifications, messages, and updates to users inside and outside of Elementum. Sends an in-platform notification about a record to specified users. No external email is sent — notifications appear within Elementum. **Configuration**: | Field | Description | | --------------- | ------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Record** | The record to notify about | | **Recipients** | Users to notify — from a Search Users result, static users, or field references | **When to use**: For internal status updates that don't warrant an email — for example, notifying a team that a record is ready for review. Sends a formatted email with dynamic content from automation variables. Supports up to 25 recipients and multiple attachment sources. **Configuration**: | Field | Description | | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **From Display Name** | The sender name that appears to recipients | | **Sending Domain** | The verified email domain to send from. Use the selector to choose between any domain configured for your organization so a single org can send mail from multiple entities. | | **From** | The email address prefix (before the selected sending domain, for example `support` for `support@yourdomain.com`) | | **Bcc** | Blind carbon copy recipients (up to 25 total) | | **Subject** | Email subject line — supports `{{value_references}}` | | **Notification Body** | Email content with HTML formatting — supports `{{value_references}}` | | **Email Attachments** | Optional files to include | **Email Attachments** can come from three sources: | Source | Description | | --------------- | ----------------------------------------------------------------------------------- | | **Record** | Files from specific file fields on the trigger record | | **Attachments** | All files from the attachments block on the trigger record | | **File** | Files from the workflow context — such as a generated report from an earlier action | You can combine multiple attachment sources in a single email. Total attachment size is limited to 25MB. If attachments exceed this limit, the email will fail to send. For transactional emails only. Marketing use may result in restrictions or loss of access. Adds a timestamped comment to a record, creating a visible log of what the automation did. **Configuration**: | Field | Description | | --------------- | -------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Record** | The record to comment on | | **Comment** | The comment text — supports `{{value_references}}` | **Variables**: Outputs the comment ID and timestamp. **When to use**: To create an audit trail on the record itself. Especially useful for logging AI decisions — for example, posting "AI classified as Bug Report with 92% confidence" so users can see why the ticket was routed a certain way. Writes an update directly to a record's **Updates** section — the same place a manually posted update appears. Grouped with the other Communication actions in the automation builder. **Configuration**: | Field | Description | | ------------------ | ---------------------------------------------------------------------------------------------- | | **Action Name** | A descriptive name for this action | | **Record** | The record to post the update to — typically the trigger record | | **Update Content** | The text of the update — supports `{{value_references}}` that resolve when the automation runs | **Behavior notes**: * The update posts to the record's **Updates** section, the same place a manually posted update appears. * Updates post as plain text only, with no rich formatting or attachments. * Any trigger can drive this action. **When to use**: When an automation should leave a human-readable update on the record's timeline — for example, posting a status change or a summary of what the workflow did so watchers see it in the Updates feed. Posts a message to a Microsoft Teams channel. **Configuration**: | Field | Description | | --------------- | ------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Channel** | The Teams channel to post to | | **Message** | Message content — supports `{{value_references}}` | **Variables**: Outputs message delivery status and channel information. **When to use**: For real-time team notifications — critical issue alerts, escalation notices, or workflow completion updates that need immediate visibility in your team's collaboration space. Sends a one-way direct message to specific users in Slack. Recipients cannot reply to the DM to reach an agent. **Configuration**: | Field | Description | | ------------------- | ----------------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Users** | The users who receive the Slack direct message | | **Title** | Message title — supports `{{value_references}}` for values from the trigger record | | **Contents** | Message body — supports `{{value_references}}` for values from the trigger record | | **Add Link Button** | Optional. When enabled, the DM includes a clickable button that opens the URL you specify | **Behavior notes**: * These are one-way notifications. Recipients cannot reply to the DM to reach an agent. * The action targets specific users as a direct message. Use a channel post when the notification should be visible to everyone in a Slack channel instead. **When to use**: For time-sensitive alerts and updates that need to reach people in Slack as a direct message. Triggers an outbound phone call from a configured AI agent. The call runs asynchronously — the workflow continues immediately without waiting for the call to complete. **Configuration**: | Field | Description | | ---------------------- | -------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **AI Agent** | Which agent will conduct the call | | **Phone Service** | Phone service provider | | **Phone Number** | Number to call — from a record field, action output, or static value | | **Related Record** | (Optional) Record this call relates to, for context | | **Additional Context** | (Optional) Extra information for the AI agent | | **Default Language** | Language for the conversation | **Variables**: Outputs call initiation status and call ID. The workflow does not pause for the call to complete. Use the **Agent Conversation Ended** trigger in a separate automation to process call outcomes like transcripts, sentiment analysis, or follow-up actions. Kicks off an agent-led email conversation from inside an automation so you can collect data, deliver information, or follow up with recipients without blocking the workflow. The agent handles replies asynchronously while the rest of the automation continues. **Prerequisites**: * Add the ability to respond over email to the assigned agent's instructions so it knows how to handle the conversation. **Configuration**: | Field | Description | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Agent** | Which agent will own the conversation | | **Trigger Record** | Record the conversation is about — typically the record from the automation trigger | | **Email Participants** | Recipients of the conversation (users, groups, or value references) | | **First Message** | The opening message the agent sends. Choose to author it directly or have the agent generate it from instructions. Supports `{{value_references}}` so you can pull dynamic values from the trigger record | | **Additional Instructions** | Extra guidance for the agent during the conversation. Supports `{{value_references}}` | | **Conversation Timeout** | How long the agent waits for replies before ending the conversation (1–4 days) | | **Follow-Up Behavior** | (Optional) What the agent should do if a recipient hasn't replied by a specific date and time | **Variables**: Outputs conversation status and the conversation ID for downstream actions. **Behavior notes**: * The workflow does not pause while the email conversation is in flight — subsequent actions run immediately. * The agent can still run its configured tools while handling email responses, so it can look up records, take actions, or pull in additional context as the conversation progresses. * Use the **Agent Conversation Ended** trigger in a separate automation to react to the conversation outcome (for example, update the trigger record, post a comment, or kick off a follow-up workflow). *** ## File Actions File actions process documents, extract text content, and manage file storage on records. **File Size Limits**: Elementum supports file uploads up to **250MB** per file. Email attachments have a lower limit of 25MB due to email provider restrictions. Extracts the text content of an uploaded file, making it available as a variable for downstream actions. Supports PDF, DOC, DOCX, TXT, CSV, and Excel formats. **Configuration**: | Field | Description | | --------------- | ----------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **File** | The file to read — from a trigger attachment, file field, or previous action output | **Variables**: Outputs the file content as text and file metadata. **When to use**: When you need the text content of a file for AI analysis, script processing, or conditional logic — for example, reading a contract PDF before passing its content to AI File Analysis or an Execute Script action. Extracts text from multiple files simultaneously, returning their contents as an array without needing a Repeat for Each loop. **Configuration**: | Field | Description | | --------------- | ------------------------------------------------------------------------------------------------------ | | **Action Name** | Descriptive name for this action | | **Files** | The files to read — from a trigger's attachment collection or a file field that accepts multiple files | **Variables**: Outputs an array of file contents and processing results. Saves a file to the attachments block on a specified record. Files generated or received during an automation are not persisted automatically — this action is required to keep them. The file source and target record can belong to different apps or element types, so you can copy files across apps within a single automation. Files provided by users during agent interactions can also be saved to a record using this action. Use this action after **Generate Report** to attach the generated file to a record. Without this step, the report exists only as a temporary reference within the automation. This action processes one file at a time. When an email includes multiple attachments, use a **Repeat for Each** action to save each one individually. **Configuration**: | Field | Description | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **File** | The file to save — from a generated report, email attachment, API response, agent-provided file, or a file field on any record in the automation | | **Record** | Which record to attach the file to — can be any record in the automation, including records from a different app or element type than the file source | Copy a file from one app's record to another app's record: 1. **Record is Updated** trigger fires on a Contracts record 2. **Search Records** finds the related Vendor record in a different app 3. **Save Attachment** saves the contract PDF from the Contracts record to the Vendor record Save a file a user provided during an agent interaction: 1. **Run Agent Task** receives a file from the user (for example, a scanned receipt) 2. **Save Attachment** saves the agent-provided file to the relevant Expense record Extracts files from a ZIP archive and makes the individual files available for subsequent actions. **Configuration**: | Field | Description | | --------------- | -------------------------------- | | **Action Name** | Descriptive name for this action | | **File** | The ZIP file to extract | **Variables**: Outputs a list of extracted files. *** ## Data Actions Data actions perform calculations, run scripts, set variables, and invoke other automations. Executes custom JavaScript in a secure, sandboxed environment. Your code receives named input values and returns a result object that subsequent actions can reference. **When to use it**: Reach for Execute Script when a step is fundamentally *logic* — validating, transforming, or assembling data — and no single native action handles it cleanly. When a native action already covers the need, use that instead: it's easier to read in the builder and easier to maintain. | Reach for Execute Script when you need to… | Example | | -------------------------------------------- | --------------------------------------------------------------------------- | | Validate or normalize several fields at once | Apply defaults, trim values, and collect a list of errors before continuing | | Assemble a request payload from many fields | Map trigger and record values into one JSON body for a Send API Request | | Parse or reshape an API response | Pull specific numbers, flags, or messages out of a returned object | | Transform a collection | Join, filter, slice, or re-type a list before handing it to another action | | Route on a computed value | Derive a status or `valid` flag for a later If / Otherwise If branch | | When you only need to… | Prefer | | ---------------------------------- | ----------------------------------------------- | | Look up records | [Search Records](#search-records) | | Call an HTTP API | [Send API Request](#send-api-request) | | Write a value back to a record | [Update Record Fields](#update-record-fields) | | Branch on a single field | [If / Otherwise If / Otherwise](#logic-actions) | | Evaluate a straightforward formula | [Run Calculation](#run-calculation) | | Apply natural-language judgment | [Run Agent Task](#run-agent-task) | **Configuration**: | Field | Description | | --------------- | ---------------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Inputs** | Named values from triggers, previous actions, or static values | | **Code** | JavaScript that processes inputs and returns a result object. Click **Execute** to test. | When you add an Execute Script action, the code editor starts with a template: ```javascript theme={null} /** * Access your input values from the `input.parameters` object * Example: * const { recordType, id, title } = input.parameters; **/ return {}; ``` As you add input parameters in the sidebar, they are automatically added to the example destructuring statement, showing you which variables are available. **Accessing Inputs**: All inputs are available exclusively through the `input.parameters` object. They are not injected as standalone variables into the script scope — referencing a parameter name directly (without `input.parameters.`) returns `undefined`. ```javascript theme={null} // Correct — access via input.parameters const myValue = input.parameters.myParameterName; // Incorrect — standalone variables are not injected // myParameterName → undefined // inputs → undefined ``` **Working with Record Inputs and Field Mappings**: When an input parameter contains records (from a Search Records or Find All action), any field mapping aliases you configure in the Inputs panel become properties on each record object — they are not injected as top-level variables. ```javascript theme={null} const records = input.parameters.allFoundRecords; // Each record has field mapping aliases as properties const total = records.reduce((sum, record) => sum + record.amount, 0); return { total: String(total) }; ``` In this example, `allFoundRecords` is the parameter name and `amount` is the field mapping alias for the Amount field. Access the parameter through `input.parameters.allFoundRecords`, then access mapped fields as properties on each record (`record.amount`). Field mappings apply to record-based inputs — records from Apps, Elements, and Tasks. Inputs sourced from elsewhere don't expose mapped field aliases; if the mapping panel offers nothing to map, pass the value you need as an explicit input instead. **Guarding against null inputs**: Inputs that hold a list — collections from Search Records, multi-select field values, mapped record arrays — can arrive as `null` rather than an empty array when the source has no data. Calling `.map()`, `.forEach()`, or `.reduce()` on `null` throws `Cannot read property 'map' of null` (or the equivalent for the method you used) and stops the action. Coalesce to an empty array before iterating: ```javascript theme={null} const items = input.parameters.yourList ?? []; const result = items.map(item => /* ... */); ``` Apply the same guard to any nested list you pull off a record — for example, `record.tags ?? []` — before iterating that. **Coercing input types**: Values reach the script as text more often than you might expect — a number typed into a static input, a checkbox reference, or a JSON string from an earlier action all arrive as strings. Convert before you compare or calculate, or a downstream If branch can silently never match because it's testing the string `"true"` against a boolean. ```javascript theme={null} const count = Number(input.parameters.count); // "12" → 12 const isUrgent = /^(true|yes|1)$/i.test(String(input.parameters.urgent ?? "")); let payload = {}; try { payload = JSON.parse(input.parameters.rawJson ?? "{}"); // guard malformed JSON } catch { payload = {}; } return { count, isUrgent, payload }; ``` Wrap every `JSON.parse` in a `try`/`catch` so a malformed string returns a controlled value instead of throwing and stopping the action. For the same reason, prefer returning a result that signals the problem — for example `{ valid: false, user_message: "…" }` that a later If branch can check — over throwing when input simply fails validation. For the runtime shape of a multi-select field input (an array of objects with named properties, not an array of primitive strings) and how the mapping panel controls which properties are exposed, see [Multi-value fields → In Execute Script](/data/multi-value-fields#in-execute-script). **Execution Environment**: * Server-side, isolated sandbox — consistent behavior between testing and production * No access to file system, network, or external resources * Execution timeout: 10 seconds * Statement limit: 50,000 JavaScript statements * Console output captured (maximum 20 KB) **Built-in Utilities**: Encode and decode Base64 strings directly in your scripts. ```javascript theme={null} const encoded = btoa("Hello, World!"); const decoded = atob("SGVsbG8sIFdvcmxkIQ=="); return { encoded, decoded }; ``` Useful for preparing data for APIs that expect Base64-encoded payloads, or decoding Base64 content from external systems. Parse CSV strings into structured data using the built-in `csvParse` utility. ```javascript theme={null} const csvContent = input.parameters.fileContent; const rows = csvParse(csvContent); return { totalRows: rows.length, firstRow: rows[0], columnNames: Object.keys(rows[0]) }; ``` Useful for processing CSV content from the Read File action before creating or updating records. **Variables**: | Variable | Type | Description | | ------------ | ---- | ------------------------------------------- | | `result` | JSON | The object returned by your JavaScript code | | `textResult` | Text | JSON string representation of the result | The script must return a JavaScript object. Arrays, null, undefined, and primitive values are not valid return values. Wrap arrays in an object property if needed. **Output Schema**: The Output Schema is generated automatically from the object your script returns. After you click **Execute**, the **Outputs** panel reads the result and lists each top-level property — along with its type — so downstream actions can reference those properties by name. To refresh the schema after changing the script, click **Execute** again. The schema updates to match the new return value. Nested properties on array items are not always inferred; if a later Repeat for Each needs `item.name` or similar, spell those out as described in [Returning an array for Repeat for Each](#returning-an-array-for-repeat-for-each). If a top-level property you expect isn't appearing in downstream actions, run **Execute** once more — the schema rebuilds from the latest result. If **Execute** fails with an error like `The field at path '/testJavaScriptExecution/outputSchema/properties[N]/...' was declared as a non null type...` (where `[N]` is the index of the offending property), your script returned `null` (or a property of the returned object was `null`) for the test inputs you provided. The schema generator can't infer a type from a null value. Fix it one of two ways: * **Add null handling to the script** — provide default values or guard clauses so every property in the returned object always has a non-null value. For example, `return { items: rows ?? [], count: rows?.length ?? 0 }`. * **Provide test values for every input** — open the **Inputs** panel and supply a representative test value for each parameter so the script's happy path runs and returns real data. You can't save the action while the Output Schema has errors — any schema mismatch (including the null-type error above) blocks the **Save** button until it's resolved. #### Returning an array for Repeat for Each Return a JavaScript object with the list on a named property. That property must be a real array of objects — not a JSON string, and not a bare array: ```javascript theme={null} return { participants: [ { name: "Alex Kim", email: "alex@example.com" }, { name: "Jordan Lee", email: "jordan@example.com" } ] }; ``` If the source arrives as text, parse it first so `participants` is an array. Wrap `JSON.parse` in `try`/`catch` as shown under **Coercing input types** above. In the Output Schema, set `participants` to **Array**, **Item Type** **Object**, and add a child property for every field the loop will reference (`name`, `email`, and so on). Click **Execute**, then point Repeat for Each's **Collection** at `participants` — not at the whole result. Inside the loop, use `item.name` and `item.email`. If those child properties are missing from the schema, the loop still iterates but the references resolve blank. To loop over a multi-select field, point Repeat for Each at the field directly. See [Multi-value fields → In Repeat for Each](/data/multi-value-fields#in-repeat-for-each). **Using an output in a downstream action**: The Output Schema is generated automatically, but its inferred types are broad (string, number, object, array). Downstream inputs that require a specifically-typed value — a list of recipients, for example — often won't accept a raw script property from the value picker. When you hit that, return the payload as JSON from your script, add a **Read File** action configured with a [JSON File Reader](/workflows/json-file-reader) after Execute Script, and map the reader's typed variables into the downstream field. Calculate tiered discounts for an order: ```javascript theme={null} const orders = input.parameters.orderData; const discountTier = input.parameters.customerTier; const discountRates = { "Enterprise": 0.20, "Professional": 0.10, "Standard": 0.05 }; const discount = discountRates[discountTier] || 0; const subtotal = orders.reduce((sum, order) => sum + order.amount, 0); const discountAmount = subtotal * discount; return { subtotal: subtotal, discountPercent: discount * 100, discountAmount: discountAmount, total: subtotal - discountAmount, orderCount: orders.length }; ``` Analyze open tickets and compute statistics: ```javascript theme={null} const tickets = input.parameters.openTickets; const summary = tickets.map(ticket => ({ id: ticket.id, priority: ticket.priority, age: Math.floor( (Date.now() - new Date(ticket.createdAt).getTime()) / 86400000 ) })); return { tickets: summary, totalOpen: tickets.length, criticalCount: summary.filter(t => t.priority === "Critical").length }; ``` Aggregate a field across records returned by a Search Records action. The input parameter `lineItems` contains the found records, and the field mapping alias `amount` maps to the Amount field: ```javascript theme={null} const records = input.parameters.lineItems; const total = records.reduce((sum, record) => sum + (record.amount || 0), 0); return { total: String(total), count: records.length }; ``` Evaluates a mathematical or logical expression using values from triggers or previous actions. The expression language is the same one used in [Calculations](/data/calculations) — all functions on that page (for example, `DATEDIF`, `DATE`, `CONCAT`, `IF`, `ISBLANK`) are available here. **Configuration**: | Field | Description | | --------------- | ----------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Expression** | The calculation to evaluate — supports standard math operators and value references | **Referencing values in the Expression field**: Type `$` to open the variable value picker and select a value from the trigger or a previous action. The picker inserts a value reference (for example, `$specialistManager`). Do **not** use the `ELEMENT."FieldName"` syntax here — that form is only valid in [table calculated columns](/data/calculations), where the calculation runs against a record. Inside the Run Calculation action, references come from the workflow's variables, so `DATEDIF($specialistManager, NOW(), 'D')` is correct while `DATEDIF(YourElement."Specialist Manager", NOW(), 'D')` is not. **Variables**: Outputs the calculated value. **When to use**: For straightforward math — totaling order amounts, computing tax, determining percentages. For anything more complex (conditionals, loops, string operations), use **Execute Script** instead. Stores a value under a named variable that any subsequent action can reference. **Configuration**: | Field | Description | | ----------------- | ------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Variable Name** | The name to store the value under | | **Value** | The value to store — from trigger data, action outputs, or a static value | **When to use**: When you need to reference the same computed value in multiple downstream actions, or when you want to give a descriptive name to a value for readability. For example, storing the result of a calculation as `total_with_tax` so it's clear what the value represents when used later. Invokes a separate automation as a step in the current workflow, enabling reuse of shared logic. **Configuration**: | Field | Description | | --------------- | -------------------------------- | | **Action Name** | Descriptive name for this action | | **Automation** | Select the automation to invoke | **Variables**: Outputs the invoked automation's execution status. **When to use**: When the same sequence of actions is needed in multiple automations — for example, a "Notify Stakeholders" automation that sends Teams messages and emails. Instead of duplicating those steps everywhere, build it once and call it with Run Automation. *** ## User Actions User actions find users and user groups for assignments and notifications. Queries the user directory and returns matching users. **Configuration**: | Field | Description | | --------------- | ------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **Conditions** | Filter criteria — department, role, name, email, or other user attributes | **Variables**: | Variable | Type | Description | | -------- | ------------ | ------------------------------------------------------------ | | `users` | User (array) | All users matching the criteria | | `user` | User | The first matching user (convenient for single-user lookups) | | `count` | Number | Total matching users | Each user has sub-properties: `user.id`, `user.name`, `user.email`. To process multiple users from the `users` array, use a **Repeat for Each** action. Inside the loop, each `item` has `item.id`, `item.name`, and `item.email`. Queries the user group directory and returns matching groups. **Configuration**: | Field | Description | | --------------- | ------------------------------------------ | | **Action Name** | Descriptive name for this action | | **Conditions** | Filter criteria — group name or attributes | **Variables**: | Variable | Type | Description | | -------- | ------------- | -------------------------------------------------------------- | | `groups` | Group (array) | All groups matching the criteria | | `group` | Group | The first matching group (convenient for single-group lookups) | Each group has sub-properties: `group.id`, `group.name`. Search User Groups does not expose a member-count variable. To get a group's member count, use either option: * Run a **Search Users** action with a condition filtering by group membership — its `count` variable returns the member count directly. * Run a **Send API Request** action with `GET /groups/{groupId}/users` and reference `response.total` for the member count. **When to use**: When you need to assign a record to a team rather than a specific person, or when routing decisions depend on group membership. *** ## External Actions External actions connect your automations to third-party systems. Sends an HTTP request to any REST API and returns the response for downstream actions. **Configuration**: | Field | Description | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Action Name** | Descriptive name for this action | | **URL** | The API endpoint — supports `{{value_references}}` | | **Request Method** | GET, POST, PUT, or DELETE | | **Authorization Type** | Authentication method — see *Authorization options* below | | **Request Headers** | HTTP headers as key-value pairs — add entries with **+ Request Header** | | **Request Data** | Format of the request payload (shown for methods that send a body). Options: **JSON Input**, **Form Data URL Encoded**, **Multipart Form Data**, or **Custom Request Body** — see *Request Data types* below. | | **Response Type** | Format used to parse the response — **JSON** or **FILE** | | **Continue on Error Status** | When enabled, the automation continues even if the response status indicates an error (4xx or 5xx). Pair with a follow-up Execute Script that inspects `statusCode` and `response` to extract error details. | **Request Data types**: | Type | Body fields shown | | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **JSON Input** | A single **JSON Input** editor that accepts a JSON-formatted string. Includes a `{}` formatting button and an expand control. Use this for JSON request bodies — see the warning below for how to pass an Execute Script output safely. | | **Form Data URL Encoded** | A list of **Key** / **Value** text pairs. Add more with **+ Form Value**. Submitted with `Content-Type: application/x-www-form-urlencoded`. | | **Multipart Form Data** | A list of **Form Value** entries. Each entry has a **Key** field with a text/file toggle (the paperclip icon switches the value to a file reference; the **Tt** icon switches it back to text) and a **Value** input. Add more with **+ Form Value**. Submitted with `Content-Type: multipart/form-data` — used for file uploads. | | **Custom Request Body** | A **Content Type** input plus a **Custom Request Body** text area for the raw payload. Use this when you need full control over the Content-Type header and body shape. | All payload fields support `{{value_references}}`. Type `$` inside any of these fields to open the value picker. **Multipart Form Data currently sends a single part.** The action accepts one **Form Value** entry per request — either a text field or a file reference. Multipart bodies that combine several parts in the same request (for example, a metadata JSON part and a file part together) aren't supported today. If the receiving API requires a multi-part body, split the workflow into separate calls or use **Custom Request Body** with a manually constructed multipart payload. **Authorization options**: | Type | Description | | ---------------- | ------------------------------------------------------------------------------------------------------------------------- | | **No Auth** | No authorization header | | **Basic Auth** | Username and password, sent as Base64-encoded Authorization header. Credentials encrypted at rest. | | **Bearer Token** | Static token (encrypted at rest) or dynamic reference from a previous action output | | **OAuth** | Client Credentials flow — provide OAuth URL, Client ID, and Client Secret. Tokens are cached and refreshed automatically. | **OAuth Configuration**: | Field | Description | | ------------------ | --------------------------------------------------------------------------------------------------- | | **OAuth URL** | The token endpoint URL | | **Client ID** | Your OAuth client identifier (encrypted at rest) | | **Client Secret** | Your OAuth client secret (encrypted at rest) | | **Request Type** | How credentials are sent — *HTTP Basic* (Authorization header) or *Form URL Encoded* (request body) | | **Custom Headers** | Additional headers for the token request (optional) | **Variables**: | Variable | Type | Description | | -------------- | ------- | -------------------------------------------- | | `response` | JSON | Parsed JSON response body | | `success` | Boolean | Whether the request succeeded | | `textResponse` | Text | Raw text response body | | `statusCode` | Number | HTTP status code (200, 404, 500, etc.) | | `file` | File | Downloaded file (when response type is FILE) | When **JSON Input** is selected as the Request Data type, the editor expects a plain string containing valid JSON — not a structured JSON object. Mapping an object output directly to it — for example, the `result` output from an Execute Script action — causes the request to fail with `failed to convert input data to params`. To send a dynamic JSON payload, stringify the object inside the Execute Script action and reference the resulting string in the **JSON Input** editor: ```javascript theme={null} const payload = { order_id: order.id, total: order.total }; return { jsonPayload: JSON.stringify(payload) }; ``` Then map `jsonPayload` into the **JSON Input** editor. The script's `textResult` output is not a reliable substitute — it isn't a clean JSON string the receiving API can consume, and most endpoints will reject it as an invalid request body. For a multi-select field in the JSON body — as an array of strings, an array of objects, or a comma-separated string — see [Multi-value fields → Passing multi-select values into a JSON API body](/data/multi-value-fields#passing-multi-select-values-into-a-json-api-body). Check inventory before processing an order: 1. **Record is Created** trigger fires for a new order 2. **Send API Request** sends a GET to the inventory system with the product IDs from the order 3. **If** `send_api_request.success` equals `true` AND `response.in_stock` equals `true` → continue processing 4. **Otherwise** → **Update Record Fields** sets status to "Backordered" and **Send Email Notification** alerts the customer Enable **Continue on Error Status** on the Send API Request action, then add an Execute Script immediately after it. Pass the status code and response into the script to determine whether the call succeeded and extract useful error details. This prevents a single failed API call from stopping the entire automation. Invokes a pre-built custom function with input parameters for specialized processing. **Configuration**: | Field | Description | | --------------- | ------------------------------------ | | **Action Name** | Descriptive name for this action | | **Function** | Select the custom function to invoke | | **Inputs** | Input parameters for the function | **Variables**: Outputs the function result and any computed values. **When to use**: For specialized business logic or integrations that aren't covered by built-in actions — custom pricing algorithms, proprietary system integrations, or reusable processing routines. *** For design principles, performance strategies, and proven patterns, see [Automation Best Practices](/workflows/automation-best-practices). For trigger configuration and use cases, see the [Automation Triggers Reference](/workflows/automation-triggers-reference). # Automation Best Practices Source: https://docs.elementum.io/workflows/automation-best-practices Design principles, performance strategies, and proven patterns for building reliable automations Well-designed automations are reliable, efficient, and easy to maintain. This guide covers foundational design principles, performance optimization strategies, common patterns, and troubleshooting techniques to help you get the most out of Elementum's Automation System. ## Design Principles ### Event-Driven Thinking Design automations around events rather than tasks: * Think: "What event should trigger this process?" * Not: "What tasks do I need to automate?" For example, instead of "automate invoice processing," think "when an invoice attachment is added to a vendor record, extract the data, validate it, and route for approval." ### Strategic AI Usage Use AI actions where they add the most value: * **Information categorization** - Classify incoming data into predefined groups * **Content analysis** - Summarize or extract key details from unstructured text * **Decision-making based on data** - Route workflows based on AI-assessed criteria * **Transforming unstructured data** - Normalize inconsistent formats into structured fields Avoid using AI actions for tasks that can be handled by deterministic logic like IF conditions or calculations. ### Maintainable Automations * **Clear names** - Use descriptive automation and variable names that explain their purpose * **Document logic** - Add comments for complex conditions so others can understand the reasoning * **Plan for failures** - Account for external API failures and missing data scenarios * **Write defensive scripts** - When using Execute Script, always provide fallback default values for inputs, handle data parsing errors gracefully, and make sure the script returns all expected output fields with non-null values on every path — including error paths. Returning `null` for a property prevents the output schema from picking it up and causes downstream actions to fail on missing data. * **Test with real data** - Verify all automation paths using actual business data, including edge cases and error conditions ## Building Faster Automations Performance optimization is most relevant when immediate action is needed after an automation is triggered, such as real-time user-facing updates or time-sensitive workflows. For background processes where a few extra seconds don't matter, prioritize clarity and maintainability over raw speed. ### Minimize Record Interactions Updating fields on a record is one of the more time-consuming operations in an automation. Each interaction with the record adds latency, so reducing these touchpoints has a significant impact on overall speed. * **Batch field updates** - Instead of updating fields one at a time across multiple actions, consolidate all field changes into a single Update Record Fields action at the end of your automation. * **Use variables for intermediate data** - Store temporary values in variables rather than writing them to the record. Variables are held in memory during execution and are much faster to read and write. * **Touch the record once** - Structure your automation so it reads from the record at the beginning and writes back once at the end. This "read once, write once" pattern eliminates unnecessary round trips. ### Consolidate Logic into Execute Script Every action in an automation carries overhead. Chaining several Set Variable, Run Calculation, and other actions to implement what is fundamentally one logical step adds latency and makes the workflow harder to follow. * **Replace action chains with Execute Script** - If you have a sequence of Set Variable and Run Calculation actions with no platform operations between them, collapse them into a single [Execute Script](/workflows/automation-actions-reference#data-actions) action. The script can parse inputs, validate fields, compute values, and return all results at once. This is typically the highest-impact optimization you can make. Access all inputs through the `input.parameters` object — they are **not** injected as standalone variables. When an input contains records with field mappings, each mapped field alias becomes a property on the individual record objects: ```javascript theme={null} // Access inputs via input.parameters — NOT as standalone variables const records = input.parameters.allFoundRecords; // Field mapping aliases are properties on each record object const total = records.reduce((sum, record) => sum + record.amount, 0); return { total: String(total) }; ``` In this example, `allFoundRecords` is the parameter name assigned in the Inputs panel, and `amount` is the field mapping alias configured for the Amount field. Referencing `allFoundRecords` or `amount` directly (without `input.parameters` or the record accessor) will return `undefined`. * **Know when to split scripts** - Use separate scripts when a platform action (Send API Request, Search Records, AI Search) must happen between two blocks of logic, or when a single script would exceed roughly 200 lines and the halves are conceptually distinct. * **Avoid separate create and update actions** - If you need to create a record and then immediately update it, set all the necessary field values in the Create Record action itself. * **Reduce loop iterations** - Each line item processed adds time, especially if the loop body includes external calls to Snowflake or APIs. Filter or limit the scope of your data before entering a Repeat for Each loop. ### Choose the Right Search Strategy Not all search actions are interchangeable. Choosing the right one depends on the type of input. * **AI Search for natural language input** - When the search input comes from a user or contains free-text descriptions, use AI Search. It handles synonyms, partial matches, and variations that exact filters would miss. For example, a user searching for "lab gloves" will match "Laboratory Nitrile Gloves" through semantic matching. * **Search Records for system keys** - When looking up a record by a machine-generated identifier like a record ID, tracking code, or system-assigned key, use Search Records with an exact-match filter. These values have a guaranteed format and don't benefit from semantic matching. ### Design for Efficiency Structure your automation logic to avoid unnecessary work. * **Validate early and gate with Switch** - Place a validation step as the first action after the trigger. Check all required fields, formats, and business rules up front, then use a Switch action to route valid inputs to the main workflow and invalid inputs to an error output. This prevents expensive operations like API calls or record creation from running on bad data. * **Design automations as composable functions** - Break complex workflows into smaller, focused automations with On-Demand Triggers, and call them from other automations using Run Automation. When the same logic appears in multiple automations (e.g., calling an external API and parsing its response), extracting it into a shared automation means fixing bugs or updating integrations in one place. * **Use async handoffs for slow external calls** - If an automation makes a slow external API call (several seconds or more), consider splitting it into two automations: one that validates the input and creates a tracking record immediately, and a second that triggers on the record creation to handle the slow call in the background. The first automation returns quickly while the second processes asynchronously. ## Common Patterns Create connected automations for complete customer processes: ``` Lead Created → Qualification → Proposal → Contract → Onboarding → Support → Renewal ``` Combine AI decision-making with human approval: ``` Request Created → AI Classification → Route to Appropriate Approver → Decision → Notification → Next Steps ``` Chain multiple data processing steps: ``` Data Received → AI Analysis → Transform Data → Validation → Storage → Notification ``` Monitor conditions and escalate appropriately: ``` Condition Met → Assessment → IF Critical → Immediate Alert OTHERWISE → Standard Notification ``` ## Advanced Implementation ### Automation Chaining Building on the [composable design](#design-for-efficiency) approach, you can chain automations in sequence — where one automation's output feeds the next as input — to orchestrate multi-step workflows that span different teams or systems. ### Complex Variable Structures Beyond using variables for [intermediate data storage](#minimize-record-interactions), you can use Set Variable to build more complex data structures that evolve throughout your automation — aggregating results from loops, assembling payloads for API calls, or constructing dynamic content from multiple sources. ### Conditional Logic Trees Build complex decision trees using nested IF conditions with AND/OR operators for nuanced routing scenarios that go beyond simple branching. ### Structured Outputs from Execute Script When Execute Script returns an object, each top-level property is automatically exposed as an individual reference in the **Outputs** panel after you click **Execute**. You don't need to define the output schema manually or parse the result with a File Reader — downstream actions can reference each property by name as soon as the script runs. For automations that publish workflow outputs to external callers, wrap the script's returned properties in **Set Variable** actions and reference those variables in your published outputs. This creates a stable output contract: if you later change the script's internal logic or rename a returned property, the variable names and published outputs stay the same for any callers. ### Integration Patterns Coordinate across multiple external systems within a single automation. Use Send API Request actions to call services sequentially, storing each response in variables for use in subsequent calls. When calling external APIs, enable **Continue on Error Status** on the Send API Request action and add an Execute Script immediately after it. Pass the response status and body into the script so it can determine whether the call succeeded and extract a meaningful error message if it didn't. This prevents a single failed API call from stopping the entire workflow and gives downstream actions useful information about what went wrong. ## Troubleshooting * Automation is published (not draft) * Testing with correct event type * Record/data meets trigger conditions * Correct variable names being used * Previous action completed successfully * Accessing correct variable structure level * Input data is in expected format * Sufficient context provided * AI action receiving correct variables * Search scope is appropriate * Number of separate automations * Data processing efficiency * Whether field updates can be consolidated (see [Building Faster Automations](#building-faster-automations)) *** For complete action details and examples, see the [Automation Actions Reference](/workflows/automation-actions-reference). For trigger configuration and use cases, see the [Automation Triggers Reference](/workflows/automation-triggers-reference). # Automation Buttons Source: https://docs.elementum.io/workflows/automation-buttons Start automations from record details with configurable buttons so users can take actions without leaving the record ## Overview Automation Buttons let users start an automation directly from a record details page. Admins place buttons on the record layout and configure which automation runs when the button is pressed. Users see a clear running state, success or failure message, and can provide required inputs via a form when the automation needs them. An [On-Demand trigger](/workflows/automation-triggers-reference#on-demand-trigger) must be configured in an app's automation and the button added to the [Record Details Layout](/workflows/layouts) for the Automation Button to work. Automations using other trigger types (e.g. scheduled or event-based) cannot be invoked from a button. **Key Capabilities:** * **Buttons on Record Layout** - Admins add buttons to the record details layout with a label, button text, and icon * **Run On-Demand Automations** - Each button runs a chosen automation that has an [On-Demand trigger](/workflows/automation-triggers-reference#on-demand-trigger); the automation can be from the same Object or a different one * **Optional Conditions and Inputs** - Configure when the button can be pressed (e.g. based on record data) and which inputs are required; a form is presented to gather inputs before the automation runs * **Clear Feedback** - Success and failure messages when the automation completes; running status is shown while the automation is in progress * **One Run at a Time** - The user cannot trigger the same automation again until the current run finishes ## Set Up Automation Buttons ### Prerequisites Before setting up automation buttons, ensure you have: * **App Admin access** (or equivalent) to edit the app and its record details layout * **An automation with an [On-Demand trigger](/workflows/automation-triggers-reference#on-demand-trigger)** to run from the button (from this app or another Object). See [Automation System](/workflows/automation-system) to create automations * Familiarity with the [Layout Builder](/workflows/layouts) for placing the button on the layout ### Step-by-Step Configuration **To access:** Open your app and click Record Details Layout icon **Record Details Layout** in the left navigation. See [Layout Builder](/workflows/layouts) for how to work with layouts. 1. **Open the Record Details Layout** - Navigate to your app, open **Configuration** (or App settings), then open Record Details Layout icon **Record Details Layout** (or the layout where you want the button to appear). 2. **Add an Automation Button to the Layout** - In the layout builder, add the **Automation** button and place it in the section where you want it to appear for users. 3. **Set Button Label, Text, and Icon** - Open the button configuration, enter a **Label** (for your reference in the layout), set the **Button Text** that users will see (e.g. "Send for approval", "Generate report"), and optionally select an **Icon**. 4. **Select the Automation** - Choose the automation that runs when the button is pressed. It must use an [On-Demand trigger](/workflows/automation-triggers-reference#on-demand-trigger). You can select an automation from the current Object or from a different Object (e.g. another app or element). 5. **Configure Availability and Required Inputs** - If needed, configure when the button can be pressed (e.g. based on record data such as status). If the automation requires inputs, configure required inputs so a form is shown to the user before the automation runs. 6. **Save the Layout** - Save the record details layout so the button appears for users. **Using an automation from a different Object:** You can select an automation that belongs to another app or element. Use this when the same action (e.g. "Notify team") is reused across multiple record types. The automation still runs in the context of the current record. ### Button Configuration Options #### Button Appearance When adding an automation button to the layout, you can set: | Property | Description | | ----------- | ------------------------------------------------------------------ | | Label | Administrative label for the button (e.g. for layout organization) | | Button Text | Text shown on the button to users | | Icon | Optional icon displayed with the button | #### Choose the Automation Select the automation that runs when the button is pressed. The automation must use an [On-Demand trigger](/workflows/automation-triggers-reference#on-demand-trigger) — automations with other trigger types will not appear as options. You can choose an automation associated with the current Object (app or element) or an automation from a different Object. The automation runs in the context of the current record when the user clicks the button. #### When the Button Can Be Pressed The button can be available at any time, or you can configure visibility or eligibility based on record data (e.g. only when a status field has a certain value). When the automation requires input values, those can be marked as required; the user will see a form to provide them before the automation runs. ## How Buttons Work for End Users When a user opens a record that has an automation button: 1. **Click the button** - The button appears on the record details page where the admin placed it. 2. **Provide inputs (if required)** - If the automation needs inputs, a form is presented. The user fills the required fields and submits. 3. **Running state** - While the automation runs, a running status is shown. The user cannot trigger the automation again until the run completes. 4. **Completion** - When the automation finishes, a success message is shown on success or a failure message on failure. Only one run can be in progress at a time for a given button invocation. The button becomes available again after the automation completes (success or failure). ## Who the Automation Runs As An automation launched from a button runs under the **publisher's** permissions — the last user who published the automation — or as a service account if one is configured. It does **not** run as the user who clicked the button. Because of this, system fields like **Created By** and **Last Updated By** on records the automation creates or updates reflect the **publisher**, not the triggering user. This is the intended behavior. To capture who clicked the button, reference the **Triggered By** value made available by the [On-Demand trigger](/workflows/automation-triggers-reference#on-demand-trigger) inside the automation (for example, write it to a custom field on the record). ## Best Practices * Use short, clear button text so users understand the action * Choose automations that make sense in the context of the record (e.g. "Send for approval", "Generate report") * Configure required inputs only when the automation needs them; avoid unnecessary form steps * Test the button as an end user to confirm the form, running state, and success or failure messages behave as expected ## Troubleshooting **Possible causes:** * The layout was not saved after adding the button. Save the record details layout and refresh. * Your role may not have access to the layout or the button. Check app and layout permissions. **Check:** * The automation uses an [On-Demand trigger](/workflows/automation-triggers-reference#on-demand-trigger) — buttons only work with On-Demand automations * The correct automation is selected in the button configuration * The automation is published (not in draft) * Your user has permission to run the automation * If a form was shown, all required inputs were provided and submitted **Check:** * The button configuration specifies which inputs are required for the automation * The automation trigger or steps expect the inputs you configured * If you need to change required inputs, edit the button configuration in the layout and update the automation if needed This is the intended behavior. Automations launched from a button run as the **publisher** (or a configured service account), not as the user who clicked. To record the triggering user, reference the **Triggered By** value from the [On-Demand trigger](/workflows/automation-triggers-reference#on-demand-trigger) in a step that writes it to a field on the record. See [Who the Automation Runs As](#who-the-automation-runs-as). ## Related Features Design record page layouts and place automation buttons Learn how automations work and how to build them Trigger types including action-based invocation Configure forms and fields used for automation inputs # Overview Source: https://docs.elementum.io/workflows/automation-system Event-driven automation that monitors system events and executes predefined actions when conditions are met. Elementum's Automation System is an event-driven framework that responds to activities within your system. Automations monitor system events and execute predefined actions when specific conditions are met. Automations must be created within an App, Element, or Task. Navigate to **Automations** under **Workflows & Processes** in the left navigation menu of the object where you want to build. ## How Automations Work Every automation follows a listen-think-act pattern: 1. **Listen (Triggers)** - Monitor for specific events happening in your system 2. **Think (Conditions & AI)** - Evaluate the event and determine what should happen 3. **Act (Actions)** - Execute the appropriate response automatically ### Manual vs. Automated: Customer Support **Manual process**: Customer emails support → Email sits in inbox → Agent reads email → Agent searches for customer → Agent creates ticket → Agent assigns ticket → Agent sends confirmation **Automated process**: Customer emails support → Email Received trigger fires → AI analyzes email content → Search Records finds customer → Create Record generates ticket → AI Classification determines priority → Make Assignment routes to appropriate agent → Send Email Notification confirms receipt ## Triggers: Understanding Events Events represent activities within your system. Every interaction, data change, or scheduled occurrence can trigger an automation. **Record Events** * **Record is Created**: New data enters your system * **Record is Updated**: Existing data changes * **Approval Process Status Updated**: Approval workflows advance **Content Events** * **Attachment is Added**: Files uploaded to records * **Comment Added**: Team members communicate on records **Data Events** * **Schedule**: Run on a recurring cadence—hourly, daily, weekly, or monthly (see [Schedule an automation](#schedule-an-automation)) * **Data Mine**: Scheduled, condition-based reactions to CloudLink-backed table data * **Email Received**: Incoming emails that need processing **Time Events** * **Time-Based**: Fire relative to a date field on a record (for example, 7 days before a contract expiration date) * **Survey**: Responses submitted through forms **Workflow Events** * **On-Demand Trigger**: Custom triggers with inputs/outputs for complex workflows * **Agent Conversation Ended**: AI agent interactions complete with context For complete trigger details and configuration options, see the [Automation Triggers Reference](/workflows/automation-triggers-reference). ## Schedule an automation To run an automation on a recurring cadence (hourly, daily, weekly, or monthly), use the **[Schedule trigger](/workflows/automation-triggers-reference#schedule)**. Set a start date, time of day, timezone, and repeat interval, and the automation runs on that cadence going forward. Scheduled runs are approximate and may fire within 30 minutes of the configured time, so use the Schedule trigger for recurring work that does not need to start at an exact minute. If your recurring work is driven by CloudLink-backed table data—reacting when rows cross a threshold or change state—use a **[Data Mine](/data/data-mining)** instead. See [Schedule an automation with a Data Mine](/data/data-mining#schedule-an-automation-with-a-data-mine) for the trigger record pattern. The **Time-Based** trigger is **not** a recurring scheduler. It fires before, on, or after a date field on a specific record (for example, 7 days before a contract's expiration date). Use Time-Based when timing is tied to record data; use the Schedule trigger when you need a recurring cadence. ## AI Integration AI actions process information and make decisions within your automation workflows. Each action receives data through variables and produces structured outputs. * **AI Classification** - Categorizes unstructured data into predefined groups (e.g., routing support tickets by type) * **AI Summarization** - Condenses lengthy content into key insights (e.g., generating executive summaries from customer feedback) * **AI File Analysis** - Extracts structured information from documents (e.g., pulling vendor, amount, and due date from invoice PDFs) * **Transform Data with AI** - Cleans, normalizes, and enhances data (e.g., standardizing addresses and phone numbers) Variables control what information AI actions receive and what they return. For example: ``` Customer Data (variable) → AI Classification → Determines Customer Tier Contract Document (variable) → AI File Analysis → Key Terms Extracted ``` ## Build Your First Automation Select the event that starts the automation. For a customer support workflow, use **Email Received** to capture incoming requests. See the [Triggers Reference](/workflows/automation-triggers-reference) for all available triggers and configuration options. **AI Classification**: Analyze the email content and categorize it (Bug, Feature Request, General Support) — output stored as `email_category` **AI Summarization**: Create a brief summary of the customer issue — output stored as `issue_summary` **Search Records**: Find the existing customer using their email address — output stored as `customer_record` **Create Record**: Generate a support ticket using the customer record, category, and summary — output stored as `support_ticket` **Make Assignment**: Route to the appropriate team based on email category — output stored as `assigned_agent` **Send Email Notification**: Confirm receipt to the customer with the ticket number and assigned agent See the [Actions Reference](/workflows/automation-actions-reference) for all available actions and configuration options. ``` Email Received → AI Classification → AI Summarization → Search Records → Create Record → Make Assignment → Send Email Notification ``` Automations are saved in **Draft** status by default (indicated by a gray pill) and will not fire until published. To activate your automation, click **Publish** — the status pill turns green to confirm it is live. To deactivate a published automation, select the **More** icon in the top-right corner of the automation configuration page. ## Viewer Presence When more than one user opens the same automation configuration page, each viewer appears as a user icon in a bubble at the top of the page. Use this to coordinate edits, avoid overwriting each other's changes, or pull a teammate into a quick review without leaving the page. ## Validate Access Before Publishing Before publishing an automation, run a **Validate Only** check to confirm that the account responsible for running the automation has the roles and data access required for every object the automation touches. This prevents an automation from breaking after publish because the runtime account lacks access to a referenced element, table, or related record. **Which account is validated?** Validate Only checks the account that will execute the automation at runtime: * If a [service account](/administration/service-accounts) is attached to the automation, validation runs against that service account. * If no service account is attached, validation runs against **your own user account** (the publisher). If a Validate Only run reports failed checks and no service account is configured, the missing access belongs to your user — either ask an administrator to grant the listed roles and data access to your user, or attach a service account that already has them. To run a validation check: 1. Open the automation you want to check. 2. In the top-right corner, click the dropdown arrow next to **Publish**. 3. Select **Validate Only**. Elementum scans every action in the automation and lists each object it interacts with, along with the access level detected for the assigned account. Each object is reported as a passed or failed check. * **Passed Checks** — The account has sufficient access to the listed object for the automation to run. * **Failed Checks** — The account is missing roles or data access for the listed object. Click **Edit Access** next to the object to update permissions, then re-run the validation. If you don't have permission to manage permissions on the target object, **Edit Access** silently routes you to the home page instead of opening the access settings. Ask an administrator to update the object's permissions. Validate Only works for both regular users and service accounts. Running it before each publish — especially when a different user is publishing changes — helps catch access gaps before they cause runtime failures. ## Reorder Actions Reorganize your automation flows using drag-and-drop. Each action has a handle that lets you move it to a new position in the sequence. You can drag individual actions or entire logic blocks (such as If/Else) in one move. * **Real-time validation** -- The system flags broken variable references or dependencies as you reorder, so you can fix issues before saving. * **Undo** -- Click **Undo** to revert a reorder if the new arrangement breaks your flow. After reordering, review any actions that reference variables from earlier steps to confirm the dependencies are still valid. ## Automation Patterns ### Decision Tree Use IF conditions to create branching logic based on record data: ``` Record is Updated → IF customer tier = "Enterprise" → Send Message to Teams (priority channel) → Make Assignment (senior agent) OTHERWISE IF customer tier = "Standard" → Send Email Notification (standard response) → Make Assignment (general queue) ``` ### Data Processing Pipeline Chain multiple AI actions for complex data transformation: ``` File Uploaded → AI File Analysis → Transform Data with AI → AI Classification → Create Record → Send Email Notification ``` ### Approval Workflow Combine AI with human decision-making: ``` Record is Created → AI Classification → IF amount > $10,000 → Start Approval Process (CFO approval) → Send Message to Teams (finance team) OTHERWISE → Update Record Fields (auto-approved) ``` ## Variables Variables carry information between automation actions, connecting outputs from one step to inputs of the next. **Trigger variables** come from the initiating event: * `trigger.record_id` - ID of the record that triggered the event * `trigger.user_email` - Email of the user who caused the event * `trigger.timestamp` - When the event occurred **Action variables** are outputs from executed actions: * `search_result.customer_name` - Customer name from Search Records * `ai_classification.category` - Category from AI Classification * `new_record.record_id` - ID of newly created record Use descriptive variable names (`customer_priority_level` rather than `priority`), and use IF conditions to validate variable values before passing them to downstream actions. ## Actions Automations support a broad set of built-in actions across several categories. For complete details, examples, and configuration options, see the [Automation Actions Reference](/workflows/automation-actions-reference). Use IF conditions to branch behavior and Repeat for Each to loop over collections. Create, update, search, and relate records. Manage approvals, assignments, and field locking. Send email notifications, post Microsoft Teams messages, and add comments to records. Read files, extract structured data with AI analysis, and process ZIP archives. Run calculations, set variables, classify content, summarize text, and transform data with AI. Call external APIs and execute custom functions for specialized integrations. Classify, summarize, transform, and search data with AI. Run autonomous agent tasks. ## Monitoring and Debugging ### Automation Tracing Automation Tracing gives you a detailed view of each automation run so you can confirm success or diagnose failures. To access Automation Tracing, click the History icon **History** icon at the far right of an automation on the **Automations** page, or from the automation details page. From the tracing view, you can: * **Review each execution** — See start time, duration, automation version, and status for every run. * **Inspect actions within a run** — Click an execution to view which actions succeeded or failed. * **Examine action data** — Click an individual action to see its returned inputs and outputs. Use **Post Comment** actions to log progress at key points in your automation — this makes it easier to trace execution and verify that variables contain expected values at each step. You can also access automation history through [App Health](/workflows/app-health). #### Execution History Filters Long-running automations can accumulate hundreds of executions. Use search and filters in the execution history to narrow the list to the runs you care about. 1. In your app, open **Automations** and select the automation you want to inspect. 2. Click **Execution history**. 3. Use the search bar at the top of the page to find executions by the record an automation was run on. 4. Filter by execution **Status** (for example, **Succeeded** or **Failed**) to focus on a specific outcome. See [Execution Statuses](#execution-statuses) for what each status means. 5. Select a quick filter tile in the top-right corner — **1 week**, **1 month**, **3 months**, or **6 months** — to change the timeframe of execution data shown. 6. Select an execution to open the trace view and review action-level details. ### Execution Statuses Every automation run reports a status in the execution history and trace view. Use these statuses to confirm success or diagnose problems. | Status | Meaning | | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | **Queued** | The run has been accepted and is waiting to be dispatched to the execution engine. This is normally brief. | | **Running** (also shown as **In Progress**) | The run is actively executing its actions. | | **Succeeded** (also shown as **Success**) | The run completed without error. | | **Failed** | The run stopped because it encountered an error. | | **Cancelled** | The run was stopped before completing and did not finish its actions. | #### Troubleshooting a stuck "Queued" status A run should only stay **Queued** briefly before it moves to **Running**. If an automation stays **Queued** for an extended period (for example, several minutes) and never starts, the execution engine's registration for that automation version may be stale. This can happen when an automation is edited in place without a new version being published. Re-publishing the same active version does not resolve this. To force the engine to re-register the automation, publish a genuinely new version: make a small edit so the version number increments, then publish. New runs should then move out of **Queued** normally. #### Investigating a "Failed" run Open the run in the trace view to see which action failed and why. Common causes include: * References to records that are missing or no longer valid. * Field references that broke after a dependency was deleted or renamed (for example, a deleted stage). * Formatting errors in the output of actions that produce JSON. * An agent or action configured to use a deprecated AI model. A **Succeeded** status means the run finished without a fatal error, but it does not guarantee every action behaved as expected. If results look incomplete, review the trace for warnings such as tool-call timeouts. #### Troubleshooting a timed-out run (TIME\_OUT\_WF) A run stops with the timeout policy **`TIME_OUT_WF`** when it exceeds the maximum execution time of **1801 seconds (about 30 minutes)**. This usually means work is being repeated or expanding rather than one action being slow. Open the run in the trace view, look for actions that ran far longer than usual, and check the common causes: * **Duplicate records.** Check the source data for duplicates clogging the pipeline. Duplicates from the source element, a CloudLink-backed table, or **Search Records** and **Data Mine** steps make downstream actions process the same data repeatedly and inflate runtime. Deduplicate the input before the heavy actions. * **Large queries.** Reading big result sets from a CloudLink-backed table can dominate the run. Narrow the query with conditions or process the data in smaller batches. * **Slow external calls.** Call External API and custom function actions wait on the endpoint. Confirm it responds promptly and skip records that don't need the call. To resolve a timeout, reduce the work per run: deduplicate inputs, tighten trigger and search conditions, and split high-volume processing across multiple runs with a [Schedule trigger](/workflows/automation-triggers-reference#schedule) or [Data Mine](/data/data-mining). ### Version History Every published change to an automation is tracked as a version. To review past versions: 1. Open the **Automations** page under **Workflows & Processes** in the app's navigation menu. 2. Click the version number in the **Version** column for the automation you want to inspect. 3. Review the changes made in each version and the user who made them. 4. To revert to an earlier version, click the **Restore as Draft** icon next to that version. Restoring a version loads it as a draft. The reverted changes are not live until you publish the automation. ## Common Use Cases **Scenario:** Automatically extract and route invoices uploaded as PDF attachments **Trigger:** Attachment is Added (invoice PDF) **Flow:** ``` PDF Uploaded → AI File Analysis → Create Invoice Record → IF amount > $5,000 → Start Approval Process OTHERWISE → Update Record Fields (auto-approved) → Send Email Notification ``` **Scenario:** Welcome new customers and set up their accounts automatically **Trigger:** Record is Created (new customer) **Flow:** ``` New Customer Created → AI Classification → Generate Report (welcome packet) → Send Email Notification → Create Record (project) → Make Assignment (account manager) ``` **Scenario:** Score and route inbound leads based on fit and quality **Trigger:** Record is Created (lead form submission) **Flow:** ``` Lead Form Submitted → AI Classification → Update Record Fields (lead score) → IF score > 80 → Make Assignment (senior sales rep) → Send Email Notification (immediate follow-up) OTHERWISE → Make Assignment (lead nurturing queue) ``` **Scenario:** Alert stakeholders when a project status changes, with escalation for at-risk projects **Trigger:** Record is Updated (project status change) **Flow:** ``` Project Status Updated → AI Summarization → Generate Report → Send Message to Teams → IF status = "At Risk" → Send Email Notification (escalation) ``` *** ## Record work breakdown On record details, the **Automations and AI** panel shows a work breakdown bar that categorizes every automation action on the record as **AI**, **Computer**, or **Human Action**. Hover the bar to see exact percentages and action counts. * The breakdown appears automatically when a record has automation or AI activity to summarize. * Use it to see at a glance how much work on the record ran autonomously versus manually. * No configuration is required. *** For design principles, performance strategies, and proven patterns, see [Automation Best Practices](/workflows/automation-best-practices). For complete action details and examples, see the [Automation Actions Reference](/workflows/automation-actions-reference). For trigger configuration and use cases, see the [Automation Triggers Reference](/workflows/automation-triggers-reference). # Triggers Reference Source: https://docs.elementum.io/workflows/automation-triggers-reference Complete reference guide for all automation triggers with configuration examples and use cases Triggers define when an automation runs. Choosing the right trigger—and configuring its conditions precisely—determines whether your automation fires at the right moment, on the right records, every time. Looking to understand automation concepts? Start with the [Automation System](/workflows/automation-system) guide to learn about event-driven automation and AI integration. ## Record Record triggers fire based on activity on a record—data changes, attached files, comments, time-based schedules, and conversations. **Purpose**: Trigger when approval workflow statuses change. **How it works**: Monitors approval processes and fires when status transitions occur (Created, Step Approved, Cancelled, Denied, Final Approval). **Configuration**: * **Approval Process**: Select which approval process to monitor * **Status**: Choose specific status changes to trigger on: * Created: When approval process begins * Step Approved: When individual approval steps complete * Cancelled: When approval process is cancelled * Denied: When approval is rejected * Final Approval: When all approvals are complete * **Where conditions**: Additional filtering based on approval details **Variables Available**: * `trigger.status`: New approval status * All field values from the record being approved **Example Configuration**: ``` Trigger: Approval Process Status Updated Approval Process: Purchase Order Approval Status: Final Approval Where: Amount > $10,000 ``` **Common Use Cases**: * **Post-Approval Processing**: Execute purchase orders, contracts, or projects after final approval * **Rejection Handling**: Route denied requests back to originators with feedback * **Escalation Management**: Alert higher authorities when approvals are delayed * **Compliance Documentation**: Log approval decisions for audit trails * **Workflow Continuation**: Trigger next phase of business processes after approval **Example Automation**: ``` Purchase Order Approved → Send API Request (to procurement system) → Update Record Fields (order status) → Send Email Notification (to requestor) ``` **Purpose**: Trigger when files are uploaded to records. **How it works**: Fires when attachments are added to any record, providing access to file content and metadata for processing. This trigger fires regardless of how the attachment was added to the record. **Configuration**: * **No specific configuration required**: This trigger automatically monitors all file uploads * **Add Changed Condition**: Filter based on file type or record attributes * **Where conditions**: Specify criteria for which attachments should trigger the automation **File Size Limit**: The system supports attachments up to **250MB** per file. **How Attachments Get Added**: This trigger fires when attachments are added through any of these methods: * **Manual Upload**: Users adding attachments directly in the record layout * **Email Received**: Email attachments automatically added when creating records via email * **External API**: Third-party systems adding attachments via Elementum API endpoints * **Automation Actions**: Save Attachment action or Send API Request action downloading files * **File Fields**: When files are added to specific File Field types on records (note: File Fields are distinct from the attachments block) **Variables Available**: * `trigger.Name`: Original filename * `trigger.Description`: Attachment description * `trigger.Media Type`: File extension/format (e.g., "PDF", "DOCX", "PNG") * `trigger.URL`: File URL for access * `trigger.Size`: Size of uploaded file * All field values from the record the file was attached to **Example Configuration**: ``` Trigger: Attachment is Added Where: File Type = "PDF" AND Record Type = "Contract" ``` **Common Use Cases**: * **Document Processing**: Extract data from uploaded contracts, invoices, or reports * **File Validation**: Check file formats or content before processing * **Compliance Scanning**: Scan documents for sensitive information or compliance issues * **Workflow Initiation**: Start approval processes when key documents are uploaded * **Data Extraction**: Pull information from documents into record fields **Example Automation**: ``` PDF Attached → AI File Analysis (extract contract terms) → Update Record Fields (contract details) → Start Approval Process ``` **Purpose**: Trigger when comments are posted to records. **How it works**: Fires when team members add comments to records, with filtering options for conversation types and content. **Configuration**: * **Conversation Type**: Filter by comment channel: * Public Channel: Standard record comments * Other conversation types as configured * **Changed Fields**: Monitor fields that may change with comments * **Where conditions**: Filter based on comment content, author, or record attributes **Variables Available**: * `trigger.Message`: Full comment content * `trigger.Author`: User who posted the comment * All field values from the record the comment was added to **Example Configuration**: ``` Trigger: Comment Added Conversation Type: Public Channel Where: Comment contains "@escalate" ``` **Common Use Cases**: * **Keyword Monitoring**: React to specific keywords or mentions in comments * **Escalation Triggers**: Automatically escalate when certain phrases are used * **Notification Routing**: Alert specific team members based on comment content * **Documentation**: Log important comments for audit trails * **Workflow Advancement**: Move processes forward based on comment approvals **Example Automation**: ``` Comment Added (contains "approved") → Update Record Fields (status = approved) → Send Email Notification (to stakeholders) ``` **Purpose**: Trigger when AI agent conversations complete. **How it works**: Fires when agent interactions finish, providing access to conversation transcripts and metadata for further processing. **Configuration**: * **Conversation Type**: Filter by conversation channel: * Chat: Elementum chat conversations * Teams: Microsoft Teams conversations — for Teams setup and how this fits with agent routes, see [Agent Microsoft Teams Integration](/ai-agents/agents-teams-integration#agent-conversation-ended-trigger) * Voice: Phone call conversations * A2A: Agent-to-Agent protocol conversations — requires **Create a Record** and a **Conversation Inactivity Timeout** to be configured on the agent's Connections tab. See [A2A Conversation Settings](/ai-agents/agents-a2a-protocol#a2a-conversation-settings) for setup. * **Timeout Duration**: Set how long to wait after conversation inactivity before considering it ended * **Changed Fields**: Monitor specific fields that may change during conversations * **Where conditions**: Filter based on conversation attributes or outcomes **Variables Available**: * `trigger.Conversation Type` - Channel (Teams, Voice, etc.) * `trigger.transcript` - Full conversation transcript * All field values from the record the conversation was added to **Example Configuration**: ``` Trigger: Agent Conversation Ended Conversation Type: Voice Timeout Duration: 2 minutes Where: Call Duration > 5 minutes ``` **Common Use Cases**: * **Call Analytics**: Analyze phone conversations for sentiment, keywords, and outcomes * **Follow-up Automation**: Schedule follow-up tasks based on conversation content * **CRM Updates**: Update customer records with conversation summaries and next steps * **Quality Assurance**: Route conversations for review based on specific criteria * **Agent Performance**: Capture workflow statistics and grade agent performance * **Reporting**: Generate conversation reports and performance metrics **Example Automation**: ``` Phone Call Ended → AI Summarization (conversation highlights) → Update Record Fields (call notes, agent score) → Generate Report (performance metrics) → IF sentiment = negative → Make Assignment (senior support) ``` **Purpose**: Trigger when new records are added to your system. **How it works**: Fires immediately when a new record is created in any app, element, or task, providing access to all field data from the new record. **Configuration**: * **Keep data consistent**: Optional checkbox to lock user interaction during automation execution * **Add Changed Condition**: Filter which record creations should trigger the automation * **Where conditions**: Set criteria like field values, user who created the record, or other attributes **Variables Available**: * All field values from the new record **Example Configuration**: ``` Trigger: Record is Created Where: Customer Type = "Enterprise" AND Created By contains "sales" ``` **Common Use Cases**: * **Customer Onboarding**: Welcome new customers with account setup, documentation, and team assignments * **Lead Processing**: Qualify and route new leads based on source, value, or characteristics * **Project Initialization**: Create project templates, assign teams, and set up tracking when new projects are added * **Compliance Logging**: Document new record creation for audit trails and regulatory requirements * **Notification Workflows**: Alert stakeholders when critical records are created **Example Automation**: ``` New Customer Created → AI Classification (customer tier) → Create Record (project setup) → Make Assignment (account manager) → Send Email Notification (welcome) ``` **Purpose**: Trigger when existing records are modified. **How it works**: Fires when record field values change, with options to specify which field changes should trigger the automation. **Configuration**: * **Keep data consistent**: Lock user interaction during execution * **Add Changed Condition**: Specify which fields trigger the automation when changed * **Changed Fields**: Select specific fields to monitor (e.g., Status, Priority, Assigned User) * **Where conditions**: Additional criteria that must be met for the trigger to fire **Variables Available**: * All field values from the updated record **Example Configuration**: ``` Trigger: Record is Updated Changed Fields: Status, Priority Level Where: Record Type = "Support Ticket" ``` **Common Use Cases**: * **Status Change Workflows**: Route records through approval processes when status changes * **Escalation Management**: Alert managers when priority levels increase * **Progress Tracking**: Update related records when project milestones are reached * **Notification Cascades**: Inform stakeholders when critical fields are modified * **Data Synchronization**: Update external systems when key fields change **Example Automation**: ``` Support Ticket Updated (Status changed to "Escalated") → Search Users (find manager) → Send Message to Teams → Update Record Fields (escalation timestamp) ``` **Purpose**: Trigger when survey responses are submitted. **How it works**: Fires when survey forms are completed, providing access to response data for analysis and follow-up actions. **Configuration**: * **Survey**: Select which survey to monitor for responses * **Add Changed Condition**: Filter responses based on specific criteria * **Changed Fields**: Monitor specific survey fields * **Where conditions**: Set criteria for which responses trigger the automation **Variables Available**: * All the fields from the survey response * All the fields from the record the survey was added to **Example Configuration**: ``` Trigger: Survey Survey: Customer Satisfaction Survey Where: Overall Rating <= 2 ``` **Common Use Cases**: * **Response Processing**: Analyze and categorize survey responses * **Follow-up Actions**: Trigger follow-up based on response content * **Alert Systems**: Alert teams to negative feedback or critical responses * **Data Analysis**: Process survey data for reporting and insights * **Customer Service**: Route dissatisfied customers to support teams **Example Automation**: ``` Low Survey Score → Search Records (find customer) → Create Record (follow-up task) → Make Assignment (customer success team) ``` **Purpose**: Trigger an automation relative to a date or date-time field on a record. Time-Based is **not** a recurring scheduler. It fires once per record, relative to that record's date field — for example, 7 days before a specific contract's expiration date. To run an automation on a recurring schedule (hourly, daily, weekly, or monthly), use the [Schedule trigger](#schedule). **How it works**: Monitors a selected date or date-time field and fires the automation before, after, or exactly on the field's value. When a record is created or updated, the system calculates the target time based on your configured offset and schedules the automation to run at that time. **Configuration**: * **Select Field**: Choose a date or date-time field from the app to monitor (calculated fields are excluded) * **Related To**: Choose the timing relationship: * **Before**: Fire the automation a specified amount of time before the field value * **After**: Fire the automation a specified amount of time after the field value * **On**: Fire the automation at the exact date/time of the field value * **Quantity**: Number of time units (shown for Before and After only, minimum 5 for minutes) * **Increment**: Time unit — Minutes, Hours, or Days (date-only fields only support Days) * **Where conditions**: Additional criteria to filter which records should trigger the automation Time-based triggers are checked on a polling interval. There may be a delay of up to a few minutes between the scheduled time and when the automation actually starts. **Variables Available**: * All field values from the record **Example Configuration**: ``` Trigger: Time-Based Field: Contract Expiration Date Related To: 7 Days Before Where: Status = "Active" ``` **Common Use Cases**: * **Renewal Reminders**: Notify account managers before contracts or subscriptions expire * **Deadline Alerts**: Send reminders before task due dates * **Follow-up Scheduling**: Trigger follow-up actions a set time after an event * **SLA Monitoring**: Alert teams when response deadlines are approaching * **Escalation Timers**: Escalate unresolved items after a specified period **Example Automation**: ``` 7 Days Before Contract Expiration → Search Records (find account manager) → Send Email Notification (renewal reminder) → Create Record (renewal task) ``` ## Workflow Start Workflow Start triggers initiate automations from external inputs, scheduled data conditions, or on-demand requests. **Purpose**: Run an automation on a recurring schedule—hourly, daily, weekly, or monthly—independent of any record activity. **How it works**: You set a start date, a time of day, and a timezone, then choose how often the automation repeats. From the start date forward, Elementum runs the automation on that cadence. Because the Schedule trigger is not tied to a record, automations typically begin by searching for or creating the records they need to act on. Scheduled times are **approximate**. A run may fire within **30 minutes** of the configured time. Use the Schedule trigger for recurring work that does not depend on starting at an exact minute, rather than for time-critical, to-the-minute execution. **Configuration**: * **Starts on**: The first date the schedule is eligible to run. Runs begin on or after this date. * **Time of day**: The target time for each run, interpreted in the selected timezone. * **Timezone**: The timezone the time of day is evaluated in (for example, America/Denver). * **Repeats**: How often the automation runs. Each frequency exposes its own settings: * **Hourly**: Runs every *N* hours. Set **Repeat every** *N* **Hours**. * **Daily**: Runs every *N* days at the configured time. Set **Repeat every** *N* **Days**. * **Weekly**: Runs on the **days of the week** you select (Monday through Sunday) at the configured time. Set **Repeat every** *N* **Weeks** to run, for example, every other week. * **Monthly**: Runs on a chosen **Day of month** at the configured time. Set **Repeat every** *N* **Months**. Months that do not contain the selected day (for example, day 29, 30, or 31 in shorter months) are **skipped**. * **Repeat every**: The interval between runs for the selected frequency. After you configure the schedule, a summary describes exactly when the automation will run, for example: * *Every hour starting at 12:00 AM on June 11, 2026* (Hourly) * *Daily at 9:00 AM, starting June 11, 2026* (Daily) * *Weekly on Monday, Wednesday, and Friday at 10:03 AM, starting June 11, 2026* (Weekly) * *Monthly on the 29th at 10:03 AM, starting June 11, 2026* (Monthly) **Variables Available**: * The Schedule trigger does not provide a record context. Use a [Search Records](/workflows/automation-actions-reference) action early in the automation to load the records you want to process. **Example Configuration**: ``` Trigger: Schedule Starts on: June 11, 2026 Time of day: 9:00 AM Timezone: America/Denver Repeats: Weekly On: Monday, Wednesday, Friday Repeat every: 1 Week ``` **Common Use Cases**: * **Recurring reports**: Generate and distribute a status or metrics report every morning or every Monday. * **Periodic data syncs**: Push or pull data to an external system on a fixed cadence. * **Scheduled reminders**: Notify owners of open items on a daily or weekly basis. * **Maintenance routines**: Clean up, archive, or recalculate records on a monthly schedule. * **Off-peak batch processing**: Search for records meeting a condition and process them in bulk at a quiet time of day. **Example Automation**: ``` Every Monday at 9:00 AM → Search Records (open tasks due this week) → Generate Report (weekly summary) → Send Email Notification (to team) ``` **Purpose**: Trigger when a [Data Mine](/data/data-mining) run finds rows that match (or no longer match) your criteria on a [CloudLink](/administration/setup-cloudlink)-backed [Table](/data/tables). **How it works**: On each scheduled Data Mine evaluation, Elementum tracks per-row state (matched vs. unmatched). Your automation runs when a row **transitions**—for example when it newly satisfies your filters or when it stops satisfying them—not on every scan where nothing changed for that row. See [Data Mining](/data/data-mining). To run an automation on a simple recurring cadence (hourly, daily, weekly, or monthly), use the [Schedule trigger](#schedule) instead. Reach for a Data Mine when the cadence is driven by CloudLink-backed table data—for example, reacting when rows cross a threshold. See [Schedule an automation with a Data Mine](/data/data-mining#schedule-an-automation-with-a-data-mine). **Configuration**: * **Select a Data Mine**: Choose which Data Mine to monitor * **Trigger Options**: * **Trigger when data meets requirement**: Fire when specific data conditions are met * **Trigger when data no longer meets requirement**: Fire when conditions are no longer satisfied **Variables Available**: * All the fields from the record the data mine was triggered for **Example Configuration**: ``` Trigger: Data Mine Data Mine: Customer Satisfaction Survey Results Trigger when: Average Score < 3.0 ``` **Common Use Cases**: * **Data Processing**: Process newly collected external data * **Alert Systems**: Alert teams when data thresholds are crossed * **Report Generation**: Create reports from fresh data collections * **Integration Workflows**: Sync external data with internal systems * **Quality Monitoring**: Monitor data quality and completeness **Example Automation**: ``` Customer Data Collected → Transform Data with AI (standardize) → Update Record Fields → Generate Report (data quality summary) ``` **Purpose**: Trigger when emails are received at configured addresses. **How it works**: Monitors dedicated email addresses and fires when new emails arrive, providing access to email content, attachments, and sender information. **Configuration**: * **Email Address**: Configure or create new email addresses to monitor * **Create New Email**: Generate dedicated email addresses for specific automations * **Email Format**: Typically follows pattern like `testing@elementum.elementum.io` **Variables Available**: * `trigger.email_id` - Unique email identifier * `trigger.sender_email` - Email address of sender * `trigger.sender_name` - Name of sender (if available) * `trigger.subject` - Email subject line * `trigger.body` - Email content (text and HTML) * `trigger.attachments` - Array of attached files * `trigger.timestamp` - When email was received **Example Configuration**: ``` Trigger: Email Received Email Address: support@yourcompany.elementum.io ``` **Common Use Cases**: * **Support Ticket Creation**: Convert emails into support tickets automatically * **Lead Capture**: Process inquiry emails into lead records * **Invoice Processing**: Handle vendor invoices sent via email * **Document Processing**: Process emailed documents and attachments * **Customer Communication**: Route customer emails to appropriate teams **Example Automation**: ``` Email Received → Search Records (find customer by email) → Create Record (support ticket) → AI Classification (priority) → Make Assignment (appropriate team) ``` **Purpose**: Trigger when a message is received in a connected Slack channel. **How it works**: Fires when a new message arrives in Slack, providing access to the message content and sender information for use in subsequent automation steps. **Configuration**: * Select **Slack Message Received** as the trigger and click **Save**. No additional configuration is required. **Common Use Cases**: * **Support Intake**: Convert Slack messages into support tickets or records * **Team Notifications**: React to messages in team channels to kick off workflows * **Keyword Routing**: Route messages to the appropriate team based on content * **Incident Response**: Start incident workflows when alerts post to Slack * **Knowledge Capture**: Log Slack messages to records for audit or reference **Example Automation**: ``` Slack Message Received → AI Classification (intent) → Create Record (support ticket) → Make Assignment (appropriate team) ``` **Purpose**: Create custom triggers with configurable inputs and outputs. **How it works**: Allows creation of reusable automation components that can be triggered manually or by other automations with custom parameters. **Configuration**: * **Configure Inputs**: Define input parameters that can be passed to the automation * **Input Name**: Descriptive name for the parameter * **Field Type**: Data type (Text, Number, Date, etc.) * **Default Value**: Optional default value * **Required**: Whether the input is mandatory * **Multiple**: Whether multiple values are allowed **Variables Available**: * All configured input parameters as variables * **Triggered By** — the user who initiated the run (e.g. the user who clicked an [Automation Button](/workflows/automation-buttons)). Use this value reference in subsequent steps to record who started the automation, for example by writing it to a custom field on the record. The automation itself still runs under the **publisher's** permissions (or a configured service account), so system fields like **Created By** and **Last Updated By** continue to reflect the publisher rather than the triggering user. * `Triggered By's Name` — full name of the user who triggered the automation * `Triggered By's Email` — email address of the triggering user * `Triggered By's ID` — unique identifier of the triggering user * `Manager's Name` — full name of the triggering user's manager * `Manager's Email` — email address of the triggering user's manager * `Environment` — the environment the automation was triggered in **Example Configuration**: ``` Trigger: On-Demand Inputs: - Customer ID (Text, Required) - Priority Level (Text, Default: "Normal") - Due Date (Date, Required) ``` **Common Use Cases**: * **Reusable Workflows**: Create automation templates that can be used across multiple processes * **Manual Processing**: Allow users to trigger specific workflows with custom parameters * **Integration Points**: Create endpoints for external systems to trigger automations * **Batch Operations**: Process multiple items with consistent logic * **Custom Business Logic**: Implement specialized workflows that require input parameters **Example Automation**: ``` On-Demand Trigger (Customer Onboarding) → Create Record (project) → Make Assignment (account manager) → Generate Report (welcome packet) ``` Automations can also be started from **record details** using automation buttons. Admins add buttons to the layout that run a chosen automation when the user clicks; required inputs are collected via a form. See [Automation Buttons](/workflows/automation-buttons) for setup and behavior. **Purpose**: Trigger an automation when an external system sends an HTTP request to Elementum. **How it works**: When you add a Webhook trigger to an automation, Elementum provides a unique URL. External systems (other applications, middleware, or scripts) POST to that URL to start the automation. The request body you send is available inside the automation so you can create or update records, run AI steps, or call other systems based on the payload. **Configuration**: * Create an automation and select **Webhook** as the trigger. * Save or publish the automation to get the **webhook URL**. Use this URL as the endpoint your external system will call. * **Custom Response** (optional): Define a custom response body returned to the caller when the webhook is invoked. Supported formats: JSON, cXML, or TEXT. Use this when the calling system expects a specific response format. See [Webhook Trigger Custom Response Bodies](/release-notes/previous-releases#march-2026) for details. **What you can pass in**: * **Method**: **POST**. Send the payload in the request body. * **Headers**: Set `Content-Type: application/json` (or the format your automation expects) so the payload is parsed correctly. * **Body / payload**: Send a JSON (or other supported) body. Structure the payload to match what your automation expects. The payload is available to subsequent steps in the automation (e.g. via [JSON File Reader](/workflows/json-file-reader) or value references), so you can pass identifiers, field values, or event data that the automation uses to create records, update fields, or trigger other actions. **Variables Available**: * The webhook request body is available to the automation. Use value references or the JSON File Reader to read specific keys and use them in Create Record, Update Record Fields, Send API Request, or other actions. **Security**: A webhook endpoint can be called without authentication, but this is **not recommended** for production use. To secure your webhook, use **Bearer authentication** by including an access token in the `Authorization` header of your request. Obtain a token through the standard Elementum API authentication flow described in [Request an Access Token](/api-reference/endpoints/access-token/request-an-access-token). ``` Authorization: Bearer ``` The webhook URL itself is unique per automation and acts as a shared secret. Even when using Bearer authentication, restrict access to the URL and avoid exposing it in public clients. **Common Use Cases**: * **Inbound integrations**: Receive events from ERP, CRM, or other systems (e.g. order created, case updated) and create or update records in Elementum. * **Activity and event pipelines**: Send activity or audit events from external systems into Elementum to trigger workflows, create tasks, or update records. * **Middleware and APIs**: Use Elementum as the target of webhooks from Zapier, custom APIs, or data pipelines so that incoming payloads drive automations. **Example**: External system sends: `POST https://your-instance.elementum.io/webhook/...`\ `Content-Type: application/json`\ Body: `{"orderId": "12345", "status": "shipped", "customerId": "C-001"}` The automation can parse this payload and use the values to create a record, update a record, or call another API. *** ## Quick Trigger Reference * **Record** — Approval Process Status Updated, Attachment is Added, Comment Added, Agent Conversation Ended, Record is Created, Record is Updated, Survey, Time-Based * **Workflow Start** — Schedule, Data Mine, Email Received, Slack Message Received, On-Demand Trigger, Webhook Trigger *** ## Choose the Right Trigger **Use Record triggers when**: * The automation responds to something that happens on or to a specific record * You need access to the record's field values inside the automation * The event is user-initiated or time-relative to a record's data **Use Workflow Start triggers when**: * The automation is initiated externally (inbound email, webhook, data condition) * The workflow doesn't have a single originating record at the point it fires * You need an on-demand entry point callable by users or other automations **Single Trigger Automations**: * Focused, specific responses to events * Easier to debug and maintain * Clear cause-and-effect relationships **Multiple Trigger Automations**: * Consolidated logic for similar events * Reduced automation sprawl * Shared processing for related triggers ### Configuration Best Practices 1. **Be specific with conditions** — Use "Where" conditions to filter triggers precisely, avoiding unnecessary automation executions. 2. **Consider performance impact** — Avoid overly broad triggers that fire frequently without adding value. 3. **Plan for scale** — Design triggers that will work efficiently as your data volume grows. 4. **Test thoroughly** — Verify triggers fire under expected conditions and don't fire when they shouldn't. *** ## Troubleshooting Common Issues ### Trigger Not Firing **Check**: * Automation is published (not in draft mode) * Trigger conditions are correctly configured * "Where" conditions are not too restrictive * Field names match exactly (case-sensitive) **Check**: * Test data meets all trigger conditions * Required fields have values * Data types match expected formats * User permissions allow trigger execution **Check**: * Scheduled triggers have correct time zones * Time-based conditions use appropriate date formats * System maintenance windows don't conflict ### Unexpected Trigger Behavior **Solutions**: * Add more specific "Where" conditions * Use "Changed Fields" to limit update triggers * Consider consolidating similar triggers * Implement rate limiting where appropriate **Solutions**: * Verify all conditions are necessary * Check for conflicting conditions * Test with simplified trigger configuration * Review automation execution history *** Ready to build automations with these triggers? Visit the [Automation System](/workflows/automation-system) guide for complete workflow examples and the [Actions Reference](/workflows/automation-actions-reference) for available actions. # Conversations Source: https://docs.elementum.io/workflows/conversations Threaded discussions on a record across two channels — internal Comments and external-facing Customer Chat Conversations are threaded discussions attached to a record, so the discussion, the participants, and the record data all stay together. Every conversation belongs to one of two channels: * **Comments** — the internal channel, for discussion among your team. * **Customer Chat** — the external-facing channel, where external **Limited Users** (your customers) and internal users exchange messages. Both channels are governed by the **Conversations** and **Messages** [permissions](/administration/roles-permissions). ## Comments channel Comments are for internal discussion on a record. * **@mentions grant access** — Mentioning a user in a comment grants that user access to the record. * **Attachments** — Files added to comments can be [public or private](/workflows/file-uploads-attachments#public-attachment-links). Private attachments require the recipient to be logged into Elementum; public attachments can be opened without logging in. * **Notification preferences** — Each user controls which comment notifications they receive by email in their [profile settings](/administration/profile#notifications). * **Reply by email** — An email reply is only processed when it comes from a known, **active** sender who is either a participant of that conversation or has policy-based access to the record. Watcher status is not checked: a non-participant with record access can reply, while someone without an active account or access cannot. Replies that don't meet these conditions are dropped on the back end and are not processed. ## Customer Chat channel Customer Chat is the external-facing channel. It lets external Limited Users (your customers) and internal users exchange messages in the context of a specific record, separate from internal-only comments. ### Participation and notify resources * **Notified Users** — The **Notified Users** list defines who is engaged in a Customer Chat, including external **Limited Users** (your customers) and any internal users you add. Internal **watchers** on the record also receive Customer Chat messages without being on the Notified Users list. * **Message delivery** — When a message is posted, notifications go to everyone on the Notified Users list plus the record's internal watchers. Senders are not notified of their own messages. If the Notified Users list is empty, no one is notified — not even watchers. ### What Customer Chat supports * **External and internal messaging** — External Limited Users and internal users post messages on the same record, keeping customer-facing communication distinct from internal comments. * **Attachments** — Attach files to a Customer Chat message. See [File Uploads & Attachments](/workflows/file-uploads-attachments) for how files are handled. * **Outbound email notifications** — Notify participants by email when a new message is posted. The body and footer support rich text, the subject and header are plain text, and all four can include value references to record data and the new message. * **Custom sending domain (optional)** — Send notification emails from your own branded domain. * **Notified Users list** — Maintain the list of notify resources who receive Customer Chat notifications, including both existing organization users and new external customers. ### Enable Customer Chat Customer Chat is enabled per object. 1. Open the **Details** page for your object. 2. Toggle **Customer Chat** on. 3. Optionally, set a **custom display name** so the channel appears with a label that fits your process instead of the generic "Customer Chat". The availability of some Customer Chat configuration options can depend on your Elementum edition. If you don't see a setting described here, check with your administrator about your plan. ### Configure email notifications Once Customer Chat is enabled, customize the email that participants receive when a new message is posted: * **Body** and **Footer** support rich text. **Subject** and **Header** are plain-text, single-line fields. * All four fields can include **value references** that pull in data from the record and from the new message, so each notification reflects the specific conversation. #### Custom email domain If you want notification emails to come from a branded domain, you can configure your own sending domain. This requires adding Elementum's **CNAME** and **TXT** records to your domain's DNS. Work with your administrator and DNS provider to set this up. ### Manage Notified Users Add notify resources to the **Notified Users** list directly in the Customer Chat panel on a record. You can add existing organization users or invite new external customers. Two separate permission layers apply: * **Adding existing organization users** is governed by the **Update Conversations** permission on the user's [role](/administration/roles-permissions) — not by the invite policy. * **Inviting brand-new external users** into the organization is governed by the organization's **User Invite Policy** (**Org Settings → General**), which can be set to: * **Only Admins can invite** * **Allow any email domain** * **Allowed email domains only** (restricted to approved managed domains) Administrators always bypass the invite policy. Non-administrators also need the **Create Organization Users** permission before they can attempt an invite. ### Canned Responses Canned Responses are pre-written reply templates that speed up and standardize common replies. They are available **only inside Customer Chat** — not in the Comments channel. * **Plain text** — Canned Responses are plain text and do not support value references. * **Visual distinction** — Customer Chat and Canned Response messages appear with a distinct background color, making them easy to tell apart from internal comments. * **Read-only for some roles** — Users with the **Content Viewer** role can see the list of Canned Responses and Notified Users but cannot add or modify them. Use Canned Responses when the same questions or updates come up repeatedly, when replies should follow a consistent tone or include required information, or when you want to reduce the time it takes to respond. ### Settings configured by Elementum Some Customer Chat behaviors are configured by Elementum on the back end and are not self-serve in the UI. Contact your Elementum representative to change: * **Inline images** — how images embedded in the body of an inbound email are handled. Regular file attachments are always processed and need no configuration. * **Email reply content** — whether inbound email replies capture only the latest reply or the full email thread. ### How email replies are logged An inbound email reply is logged when it is a reply to a specific conversation, or when the record has a **Comments** channel for it to land in — as long as the sender is active and has access. A plain email reply lands in the internal Comments channel, so it is still logged even when Customer Chat is turned off. ## Access and permissions Both channels are controlled by the **Conversations** and **Messages** permissions on a [role](/administration/roles-permissions): * **Create Conversations** / **View Conversations** — Start a conversation and see that one exists. * **Update Conversations** — Required to add existing organization users to a Customer Chat, and to modify conversation participants and metadata. * **Create Messages** / **View Messages** — Post and read messages. * **Update Messages** / **Delete Messages** — Edit or remove individual messages, typically reserved for the author or an admin. For external collaboration, roles such as **External Create** and **External Update** let people read and post to conversations on records they can access. ## Related documentation * [Roles & Permissions](/administration/roles-permissions) — Configure Conversations and Messages permissions and external-user roles * [File Uploads & Attachments](/workflows/file-uploads-attachments) — File size limits, public vs. private attachments, and how files are stored * [Custom Email Domains](/administration/custom-email-domains) — Set up a branded sending domain * [Profile Settings](/administration/profile#notifications) — Control which comment notifications you receive * [Notifications](/administration/notifications) — How notification settings resolve across organization, app, and user levels # Create a Record Source: https://docs.elementum.io/workflows/create-a-record All the ways to create records in objects, like Apps and Elements, from manual entry to automated workflows, plus how to edit a record title and delete a record when your role allows it Records are the individual data entries that live inside your objects, like Apps and Elements. Elementum provides several ways to create records depending on whether you need manual input, automated processing, or high-volume data ingestion. Manually create records from the UI with a single click Capture structured input through custom create forms Create records without app or task access via the Services portal Automatically generate records in response to system events Let AI Agents create records during conversations and tasks Import large volumes of records from spreadsheets and files Create records programmatically through the REST API **Real-time collaboration** -- When viewing a record, you can see who else is on the page. Avatars appear at the top of records in Apps, Elements, and Tasks when teammates are present, and the field they are actively editing is highlighted. Indicators disappear automatically when a user leaves or goes idle. ## Create Record Button The most direct way to create a record is through the **Create Record** button in the top right corner of the object page. Clicking this button opens the create form configured for that object, allowing you to fill in field values and save a new record. ### Create Record Button in Related Items You can also create related records from a record's detail page using the Relationships section. This allows users to create a new related record directly from the context of an existing one, linking the two records automatically. To show the Create a Record button for related records: 1. Navigate to the record detail layout settings 2. Add the Relationships component The layout will automatically save. View the Relationships section within the Record details to see the Create a Record button that relates to the current record. The Create Record Button on detail pages pre-populates the relationship to the parent record, so users don't need to manually link the new record back. For more on configuring buttons and related items on detail pages, see [Showing Relationships](/data/showing-relationships). ### Create Button in Layouts The **Create Button** field type can be added to [Layouts](/workflows/layouts) to provide a dedicated action trigger for record creation within specific views. This is useful when you want to surface record creation in a particular context or workflow stage. 1. Open the Record Details Layout for the App, Element, or Task 2. Add the Create Button field ## Forms The [Form Builder](/workflows/form-builder) provides a drag-and-drop interface for designing custom record creation forms. Forms give you control over which fields users see, how they are organized, and what validation is required when creating a new record. ### How Forms Work When a user clicks the Create Record button, the system presents the create form configured for that App or Element. The form determines: * **Which fields appear** and in what order * **Which fields are required** before the record can be saved * **Default values** that pre-populate automatically * **Validation rules** that enforce data quality at the point of entry * **Conditional logic** that shows or hides fields based on other selections ### Create a Form For step-by-step instructions on designing forms, see [Form Builder](/workflows/form-builder). ### Integration with Workflows Records created through forms can automatically trigger downstream processes: * **Automations** fire on the [Record is Created](/workflows/automation-triggers-reference) trigger * **Approval processes** route the new record for review * **Notifications** alert relevant team members * **Assignment rules** assign ownership based on record data ## Services A user without access to an app or task can create records through Services in Elementum. Services must be [enabled by the app admin](/workflows/services#enabling-services-on-an-app-or-task) on the App or Task. 1. Open **Services** in the left navigation menu. 2. Choose the category in which the app or task lives. 3. Click **Request** on the applicable object. 4. Fill out the required fields. 5. Click **Save**. Return to **Services** and select **My Requests** in the menu to see the status of previous requests. ## Automations The [Automation System](/workflows/automation-system) can create records automatically in response to system events using the **Create Record** action. This eliminates manual data entry for repetitive processes and ensures records are created consistently. ### How It Works Automations follow a trigger → action model. When a triggering event occurs, the automation executes a sequence of actions that can include creating one or more records with pre-defined field values. ``` Trigger Event → Evaluate Conditions → Create Record → Continue Workflow ``` ### Common Triggers for Record Creation | Trigger | Use Case | | ----------------------- | -------------------------------------------------------------------------------------------------- | | **Email Received** | Create a support ticket from an incoming email | | **Record is Created** | Generate related records when a parent record is added (e.g., onboarding tasks for a new customer) | | **Record is Updated** | Create a follow-up record when a field changes to a specific value | | **Attachment is Added** | Process an uploaded document and create a record from its contents | | **On-Demand** | Create records when a user clicks an [Automation Button](/workflows/automation-buttons) | | **Survey** | Generate records from submitted survey responses | ### Configuring the Create Record Action 1. Open an automation in your App 2. Add a **Create Record** action to your automation 3. Select the target object (App, Element, or Task) 4. Map field values using variables from the trigger, prior actions, or static values 5. Save the automation The Create Record action outputs the new record's ID and field values, which can be referenced by subsequent actions in the same automation using the `new_record.record_id` variable. For a full list of available actions, see the [Actions Reference](/workflows/automation-actions-reference). For trigger details, see the [Triggers Reference](/workflows/automation-triggers-reference). ### Example: Support Ticket from Email ``` Email Received → Search Records (find existing customer) → Create Record (Support Ticket) - Title: email.subject - Description: email.body - Customer: search_result.record_id - Priority: "Medium" → AI Classification (set priority based on content) → Make Assignment (route to appropriate agent) → Send Email Notification (confirm receipt) ``` ## Agents [AI Agents](/ai-agents/agents-tools-and-deployment) can create records as part of their interactions with users. Agents use the **Create Record Tool** to add new records during conversations across channels like Microsoft Teams, Slack, and phone. ### Create Record Tool The Create Record Tool is configured within an Agent's toolset and allows the Agent to create records in a specified App, Element, or Task based on information gathered during a conversation. To configure the Create Record Tool for an Agent: 1. Open the Agent's configuration and navigate to **Tools** 2. Add a **Create Record** tool 3. Provide a name and description so the Agent understands when to use it 4. Set the **Tool Start Message** (what the Agent says when it begins creating the record) 5. Choose the **Run As** mode to determine whose permissions are used 6. Select the target App, Element, or Task 7. Define **required fields** and **optional fields** with descriptions to guide the Agent 8. Choose which **return fields** are sent back to the Agent after creation Field descriptions are important — they help the Agent understand what information to collect from the user before creating the record. For example, a "Priority" field description might say "The urgency level: Low, Medium, High, or Critical." ### Automatic Record Creation via Integrations Some Agent integrations create records automatically when conversations begin: * **Microsoft Teams**: When a user starts a conversation with an Agent in Teams, a record is automatically created with user information, conversation metadata, and Teams context. See [Teams Integration](/ai-agents/agents-teams-integration). * **Slack (Full Conversations mode)**: In Full Conversations mode, a record is created when a Slack conversation starts, capturing user info and channel context. Quick Answers mode does not create records. See [Slack Integration](/ai-agents/agents-slack-integration). ## Bulk Import When you need to create many records at once, Elementum supports bulk import through file-based processing and direct data upload. ### Bulk Import on Apps and Elements You can import records directly into an App or Element by uploading a spreadsheet file. The platform maps columns in your file to fields in the target object and creates records for each row. 1. Open your object in List view. 2. Click **Bulk Import** 3. Download the template that matches your situation 4. Add the data into the Excel file. 5. Open the Bulk Import window again in your object. 6. Upload the updated file. **Important notes** * **New records**: Leave the ID field empty for new entries. Elementum automatically creates new IDs. * **Created by**: This field is populated automatically with the user who uploaded the file. You do not need to include it as a column in your import file. * **Triggering automations**: Only **Admins** (organization or app) can run automations on bulk upload. Users with these roles must select the **Trigger Automations** checkbox in the Bulk Import window. For all other roles, automations will not run on imported records. * **File size limit**: Bulk uploads are capped at **100 MB**. The more fields you populate per row, the fewer records a single file can contain. For larger datasets, split the data across multiple files or use the [File Reader](/workflows/file-reader-overview) automations or the [API](#api). * **Snowflake-backed objects**: The Snowflake role associated with the connection must have `CREATE` and `UPDATE` permissions on the underlying table. Missing permissions can cause silent import failures. See [Troubleshooting](/support/troubleshooting/general-troubleshooting) for details. * **Duplicate detection during import**: Bulk Import does not provide a built-in deduplication option, and automations triggered on imported rows run in **parallel** (one per row). A duplicate-check automation that uses **Search Records** cannot reliably detect duplicates that exist only within the same file, because two identical rows are processed simultaneously and neither finds the other yet. To prevent in-file duplicates, either de-duplicate the file before upload, or use the [File Reader Automations](#file-reader-automations) pattern below for sequential row processing. ### File Reader Automations For more control over the import process, use [File Readers](/workflows/file-reader-overview) within automations. The [Table File Reader](/workflows/table-file-reader) processes Excel and CSV files row by row, allowing you to transform, validate, and deduplicate data before creating records. **Example: Bulk Import Workflow** ``` Attachment Added (Excel file) → Table File Reader (extract rows) → Repeat For Each row: → Transform Data (format fields) → Search Records (check for duplicates) → IF no match found: → Create Record (new entry) OTHERWISE: → Update Record (merge data) → Send Email Notification (import summary) ``` This approach gives you the ability to handle deduplication, data transformation, and error handling as part of the import process. ## API For programmatic record creation, the Elementum [REST API](/api-reference/api-introduction) provides a dedicated endpoint to create records in Apps, Elements, and Tasks. ``` POST /{recordType}/{alias} ``` The API is useful for integrating external systems, building custom applications, or scripting batch operations. See the [Create a Record](/api-reference/endpoints/records/create-a-record) endpoint documentation for request format and authentication details. ## Choosing the Right Method | Method | Best For | | ------------------------ | ---------------------------------------------------------- | | **Create Record Button** | One-off manual record creation by users | | **Forms** | Structured manual entry with validation and guided input | | **Automations** | Event-driven record creation without user intervention | | **Agents** | Conversational record creation via Teams, Slack, or phone | | **Bulk Import** | Loading large datasets from spreadsheets or external files | | **API** | System-to-system integration and programmatic creation | ## Edit a Record Title On a record's detail page, the title appears in the header and can wrap up to three lines so you can read longer titles without hovering. Status appears next to the record ID, which keeps more of the header width available for the title. To change the title: 1. Click the title in the record header to enter edit mode. 2. Edit the text. 3. Confirm to save, or cancel to discard your changes. Clicking away from the title without confirming discards the draft — it does not save. Confirming without changing the text does not create a record update in the history. Title wrapping and the confirm-to-save edit flow apply to the record details header only. List columns, board cards, and mobile layouts are unchanged. ## Delete a Record To delete a record from an App, Element, or Task: 1. Open the record in the object. 2. Click the **More** icon in the top right corner. 3. Click **Delete Record**. 4. Confirm in the popup. Deleted records are removed permanently. There is no way to recover them. You only see **Delete Record** when your user has a role that includes **Delete Records** (for example **App Admin** or organization **Admin**, or a [custom role](/administration/roles-permissions#custom-roles) with **Delete Records** enabled). See [Roles & Permissions](/administration/roles-permissions) for how permissions are assigned. ### Bulk Deleting Records There is no bulk delete action for records within an App or Element. Records must be deleted one at a time using the steps above. If you need to remove every record in an App, deleting the App itself permanently removes the App along with all of its records. See [How do I delete an app?](/support/faq/faq-apps#deleting-apps) for the steps and warnings. ## Moving Records Between Objects Records cannot be moved between objects, including from one App to another, from an App to an Element, or between Elements. Each object has its own record details layout, field configuration, and relationships, so a record in one object is not compatible with the structure of another. To relocate data from one object to another, recreate the record in the target object. You can do this manually, through [Bulk Import](#bulk-import), or with a [Create Record automation](#automations) that reads from the source object and writes into the destination. # Elementum Intelligence File Reader Source: https://docs.elementum.io/workflows/elementum-intelligence-file-reader AI-powered document analysis for complex text, image, and PDF documents with custom system prompts The Elementum Intelligence File Reader uses AI to read and analyze text-based, image, and PDF documents. Configure custom system prompts to extract specific information and leverage multimodal AI Services like [OpenAI](/ai-agents/openai-setup) and [Google Gemini](/ai-agents/gemini-setup) to power intelligent document processing in [automation workflows](/workflows/automation-system). ## Key Features * **AI-Powered Analysis** — Uses advanced AI models to understand document content and extract structured information. * **Multimodal Support** — Process text documents, images, and PDFs with the same AI-powered approach. * **Custom System Prompts** — Configure specific instructions to extract exactly the information you need. * **Testing Interface** — Test your system prompts and field extraction before deploying in automations. ## AI Provider Support The Elementum Intelligence File Reader works with multimodal AI Services: ### Supported AI Providers **Best for**: Advanced reasoning and complex document analysis **Supported Models**: * **o3** - Maximum intelligence for complex document analysis * **o4-mini** - Fast processing for routine document tasks * **GPT-4 Omni** - Balanced performance for general document processing **Capabilities**: Text analysis, image recognition, PDF processing, complex reasoning **Best for**: Cost-effective multimodal document processing **Supported Models**: * **Gemini 2.5 Pro** - Advanced document analysis and large responses * **Gemini 2.5** - General-purpose document processing * **Gemini 1.5 Flash** - Speed-optimized document analysis **Capabilities**: Text analysis, image recognition, PDF processing, multimodal understanding To use Elementum Intelligence File Reader, you must first configure an AI Provider and create an AI Service. See [AI Services](/ai-agents/ai-services) for setup instructions. ## Supported Document Types The Elementum Intelligence File Reader can process various document formats: * **PDF** - Text-based and scanned PDFs * **DOC/DOCX** - Microsoft Word documents * **TXT** - Plain text files * **RTF** - Rich text format * **HTML** - Web pages and HTML documents * **JPG/JPEG** - Compressed images with text * **PNG** - Portable network graphics * **TIFF** - Tagged image format * **BMP** - Bitmap images * **GIF** - Graphics interchange format * **Scanned documents** - AI can read text from scanned pages * **Multi-page PDFs** - Process entire documents or specific pages * **Mixed content** - Documents with text, images, and tables * **Handwritten text** - Basic handwriting recognition capabilities ## Creating an Elementum Intelligence File Reader **Required Setup**: * AI Provider configured ([OpenAI](/ai-agents/openai-setup) or [Gemini](/ai-agents/gemini-setup)) * AI Service created for document processing * Access to test documents for validation In your application, go to **File Readers** section Click **+ File Reader** and select **Elementum Intelligence** from the document type options **Name**: Enter a descriptive name (e.g., "Contract Analysis AI") **Description**: Optional description for your team **AI Service**: Select your configured AI Service Write a custom system prompt that instructs the AI on what information to extract **Example**: "Extract the contract parties, effective date, termination date, and key obligations from this document." Configure the fields you want the AI to populate based on your system prompt **Example Fields**: contract\_parties, effective\_date, termination\_date, key\_obligations Upload test documents to validate that the AI extracts the correct information ## System Prompt Configuration ### Writing Effective System Prompts The system prompt instructs the AI on how to analyze documents and what information to extract: **Simple Extraction**: ``` Extract the following information from this document: - Customer name - Order date - Total amount - Product descriptions Return the information in the specified fields. ``` **Best for**: Simple, straightforward document analysis **Complex Analysis**: ``` Analyze this legal contract and extract: - All parties involved (companies and individuals) - Contract effective date and termination date - Key financial terms and payment schedules - Important obligations and deliverables - Risk factors and penalty clauses For dates, use YYYY-MM-DD format. For financial amounts, include currency symbols. For obligations, provide detailed descriptions. ``` **Best for**: Complex documents requiring detailed analysis **Medical Reports**: ``` Extract key information from this medical report: - Patient demographics (name, age, gender) - Diagnosis and conditions - Treatment recommendations - Medications prescribed - Follow-up instructions Maintain medical terminology accuracy. Flag any critical or urgent findings. ``` **Best for**: Specialized domain documents ### System Prompt Best Practices * **Be specific** — Clearly define what information to extract and in what format. * **Provide context** — Explain the document type and purpose to help the AI understand context. * **Define formats** — Specify date formats, number formats, and text formatting requirements. * **Handle edge cases** — Include instructions for missing information or unusual formats. ## Field Configuration Configure output fields that match your system prompt requirements: ### Field Types and Configuration **Text Fields**: * **Text** - General text content * **Long Text** - Extended text content * **Email** - Email addresses with validation * **Phone** - Phone numbers with formatting * **URL** - Website addresses **Date and Time**: * **Date** - Date values (YYYY-MM-DD) * **DateTime** - Date and time values * **Time** - Time values only **Numeric Fields**: * **Number** - Integer values * **Decimal** - Floating point numbers * **Currency** - Monetary values * **Percentage** - Percentage values **Structured Data**: * **JSON** - Complex structured data * **Array** - Multiple values in a single field * **Boolean** - True/false values * **Enum** - Predefined options **Validation**: * **Required** - Field must be populated * **Optional** - Field can be empty * **Default Value** - Value to use if not found * **Format Validation** - Ensure data meets format requirements ## Testing and Validation Always test your Elementum Intelligence File Reader with representative documents before using in production automations. Upload test documents similar to production, review extracted data for accuracy and format, test edge cases (missing info, unusual formats, poor quality), and refine the system prompt based on results. Test across different layouts, quality levels, and file formats to validate consistent extraction. ## Using in Automations ### Integration with Automation Workflows The Elementum Intelligence File Reader integrates with [automation workflows](/workflows/automation-system) for sophisticated document processing: ``` Document Upload → Elementum Intelligence Reader → AI Classification → Create Record → Start Process ``` ### Common Automation Patterns **Trigger**: Email Received (contract attachment) **File Reader**: Extract contract terms, parties, dates **Actions**: * AI Classification to determine contract type * Create Record with extracted contract data * Start Approval Process for contract review * Send Email Notification to legal team **Trigger**: Attachment Added (invoice PDF) **File Reader**: Extract vendor, amounts, line items **Actions**: * Search Records to find existing vendor * Run Calculation to validate amounts * Update Record Fields with invoice data * Start Approval Process based on amount **Trigger**: Document Upload (application form) **File Reader**: Extract applicant information **Actions**: * Transform Data to standardize formats * AI Classification to assess application quality * Create Record for applicant * Send Email Notification with next steps ## Best Practices * **Prompt engineering** — Use clear, specific language; include formatting instructions and examples of desired output; specify handling of edge cases. * **Document quality** — Use high-quality documents when possible to improve AI accuracy. * **Validation testing** — Test extensively with real documents before production deployment. * **Error handling** — Implement automation logic to handle extraction errors gracefully. * **Avoid** — Overly complex or ambiguous prompts, missing format specifications, unclear field definitions, and insufficient testing. ## Advanced Features * **Multi-document processing** — Configure automations to handle multiple uploads; use AI to understand relationships and validate consistency across documents. * **Dynamic field extraction** — Use AI Classification to detect document type, then route to the appropriate reader or prompt for optimized extraction. * **AI search integration** — Use extracted data for indexing and search; build searchable knowledge bases from document insights. ## Error Handling and Troubleshooting ### Common Issues **Symptoms**: AI extracts incorrect or incomplete information **Causes**: * Unclear system prompt * Poor document quality * Inappropriate AI model selection * Insufficient context in prompt **Solutions**: * Refine system prompt with more specific instructions * Improve document quality before processing * Try different AI models for better results * Add more context and examples to prompts **Symptoms**: File Reader fails to process documents **Causes**: * AI service unavailable * Document format not supported * File size too large * Network connectivity issues **Solutions**: * Verify AI service configuration * Check supported document formats * Optimize document size * Implement retry logic in automations **Symptoms**: Same document types produce different extraction results **Causes**: * Ambiguous system prompt * Variable document quality * Model temperature settings * Insufficient training examples **Solutions**: * Make system prompts more specific * Standardize document formats * Adjust AI model parameters * Provide more examples in prompts ### Validation Strategies Implement validation in automations: required-field checks, format validation (dates, numbers, emails), range checks for numeric fields, and cross-field validation for consistency. ## Performance Optimization * **Processing** — Use appropriate AI models for task complexity; optimize document size and format; use faster models for simple extraction. * **Cost** — Choose cost-effective models for routine tasks; optimize prompts to reduce token usage; use batch processing and monitor usage. ## File Reader Comparison **Choose Elementum Intelligence when**: * Processing complex, unstructured documents * You need intelligent content understanding * Working with various document formats * Requiring custom field extraction logic * Handling documents with mixed content types **Consider alternatives when**: * Processing simple text extraction ([Text File Reader](/workflows/text-file-reader)) * Working with standard business forms ([Purchase Orders Reader](/workflows/purchase-orders-file-reader)) * Handling structured data files ([Table File Reader](/workflows/table-file-reader)) * Processing JSON data ([JSON File Reader](/workflows/json-file-reader)) ## Next Steps Configure AI providers and services to power your document processing Learn how to integrate AI document processing with automation workflows Set up OpenAI for advanced document analysis capabilities Configure Google Gemini for cost-effective multimodal document processing *** *The Elementum Intelligence File Reader brings the power of AI to document processing, enabling sophisticated extraction and analysis of complex documents. Use it when you need intelligent understanding of document content beyond simple text extraction.* # File Reader Overview Source: https://docs.elementum.io/workflows/file-reader-overview Transform documents and data files into structured information for your automation workflows File Readers understand how your files are formatted and extract data to use in automations. They process different document types and transform unstructured content into structured information that can be used throughout your workflow. **Maximum File Size**: File Readers can process files up to **250MB** in size. This limit applies to all file types and reader types. Processing time may vary based on file size and complexity. ## File Reader Types Elementum provides specialized File Readers for different document formats and use cases: Extract raw text from images, text documents, and PDFs using OCR technology Process purchase orders with OCR trained specifically on PO fields and formats Read Excel and CSV files with support for thousands of rows and multiple sheets AI-powered document analysis for complex text, image, and PDF documents Parse JSON data with AI-assisted field detection and automatic type mapping ## How File Readers Work ### Integration with Automations File Readers are used within [automation workflows](/workflows/automation-system) to process documents when specific events occur: ``` Document Uploaded → File Reader Processes → Structured Data → Automation Actions ``` **Example Workflow:** 1. **Email Received** trigger fires with PDF attachment 2. **File Reader** action processes the PDF 3. **Create Record** action uses extracted data 4. **Send Email Notification** confirms processing ### Processing Pipeline Documents are uploaded or received through triggers like Email Received or Attachment Added File Reader analyzes the document using OCR, AI, or structured parsing Extracted information is mapped to defined fields with appropriate data types Structured data flows into subsequent automation actions ## Choose the Right File Reader **Text-Based Documents** * **Text File Reader**: Simple OCR extraction * **Elementum Intelligence**: AI-powered analysis with custom prompts **Structured Business Documents** * **Purchase Orders Reader**: Specialized for PO processing * **Elementum Intelligence**: Custom business document analysis **Data Files** * **Table File Reader**: Excel and CSV processing * **JSON File Reader**: JSON data parsing **Document Processing Automation** ``` PDF Invoice → Purchase Orders Reader → Create Record → Start Approval Process ``` **Data Import Workflows** ``` CSV Upload → Table File Reader → Transform Data → Update Records ``` **Intelligent Document Analysis** ``` Contract PDF → Elementum Intelligence Reader → Extract Key Terms → Create Alerts ``` **Need flexible, prompt-driven analysis instead of fixed field extraction?** If your documents vary in structure or you need summarization, classification, or open-ended reasoning, consider using [Run Agent Task](/workflows/agent-task-automation#file-inputs) with a multimodal agent instead of a File Reader. File Readers are best when you need the same named fields extracted consistently from every document. ## Performance Comparison | Feature | Text File Reader | Elementum Intelligence | Purchase Orders | | --------------- | ---------------- | ---------------------- | --------------- | | **Speed** | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | | **Accuracy** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | | **Flexibility** | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | | **Cost** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ## File Reader Configuration ### Basic Setup 1. **Navigate to File Readers** in your App 2. **Click + File Reader** to create a new reader 3. Enter a **name** 4. **Select Document Type** based on your needs 5. Follow the steps for File Reader setup (uploading a file, configuring fields, etc.) 6. **Test with Sample data** to validate accuracy **Always test File Readers** with sample documents before using in production automations. This ensures accurate field extraction and proper data mapping. ### Field Configuration All File Readers support configuring fields for extraction: Available across all reader types: * **Text** - String values * **Number** - Integer values * **Decimal** - Floating point numbers * **Date** - Date values with format detection * **Boolean** - True/false values Specific to certain reader types: * **Address** - Structured address information * **Phone** - Phone number formatting * **Email** - Email validation * **Currency** - Monetary values ## Common Integration Patterns Automate document handling from receipt to completion: ``` Email Received → File Reader → AI Classification → Create Record → Route for Approval ``` Process batch data uploads systematically: ``` File Upload → Table File Reader → Transform Data → Validate → Update Records ``` Extract insights from complex documents: ``` Document Upload → Elementum Intelligence Reader → AI Summarization → Create Insights ``` ## Best Practices ### Choose the Right Reader Select specialized readers for better accuracy: Purchase Orders Reader for POs, Table Reader for spreadsheets. ### Test with Real Data Use actual business documents during testing to ensure accurate field extraction. ### Validate Field Types Ensure extracted data types match your automation requirements. ### Handle Errors Gracefully Use IF conditions in automations to handle missing or invalid data. ## Advanced Features Table File Readers can process multiple Excel sheets: * Configure field mapping across sheets * Use cell references for dynamic data * Handle complex workbook structures Elementum Intelligence Readers provide: * Custom system prompts for specific extraction needs * Multimodal AI support (text, images, PDFs) * Advanced field detection and validation Process multiple documents efficiently: * Use **Repeat For Each** actions for document batches * Configure error handling for failed extractions * Implement progress tracking for large volumes ## Error Handling ### Common Issues and Solutions **Symptoms**: Inaccurate text extraction from images or PDFs **Solutions**: * Use higher resolution source documents * Consider Elementum Intelligence Reader for better accuracy * Implement validation checks in automations **Symptoms**: Expected fields return empty values **Solutions**: * Verify field names match document structure * Test with multiple sample documents * Use IF conditions to handle missing data **Symptoms**: Data type mismatches in automation actions **Solutions**: * Review field type configurations * Use Transform Data actions for type conversion * Implement data validation steps ## Next Steps Learn how to integrate File Readers with automation workflows Configure AI providers for Elementum Intelligence File Readers Follow proven patterns for document processing workflows Get help with common File Reader issues *** *File Readers transform your documents into structured data that powers intelligent automation workflows. Choose the right reader type for your documents and integrate them seamlessly with your business processes.* # File Uploads & Attachments Guide Source: https://docs.elementum.io/workflows/file-uploads-attachments Complete guide to working with files and attachments in Elementum Learn successful strategies about working with files and attachments in Elementum, including size limits, upload methods, and best practices. **File Size Limit**: Elementum supports file uploads up to **250MB** per file across all upload methods. Note that email attachments have a lower limit of 25MB due to email service provider restrictions. ## Understanding Files in Elementum Elementum provides multiple ways to work with files, each designed for specific use cases. Understanding the differences will help you choose the right approach for your needs. ### File Fields vs Attachments Component **Purpose**: Store a specific file in a designated field on a record **Use Cases**: * Invoice file field on invoice records * Contract document field on contract records * Photo field on product records **Characteristics**: Single file per field, structured storage **Purpose**: General-purpose file and link storage area for multiple items **Use Cases**: * Supporting documents for a record * Multiple files uploaded by email * User-added supplementary files * Links to external resources or related records **Characteristics**: Multiple files and links, flexible storage Both File Fields and the Attachments component support files up to 250MB per file. They are complementary: use File Fields for structured, specific files and the Attachments component for general-purpose file storage. *** ## Where attachments are stored Attachment files are stored in Elementum-managed cloud storage — separate from any connected data warehouse. If you use a [Snowflake CloudLink](/administration/connect-snowflake-to-elementum) (or a [BigQuery](/guides/connect-bigquery-to-elementum) or [Databricks](/guides/connect-databricks-to-elementum) CloudLink), Elementum does not write attachment files, blob columns, or a dedicated attachments table into your warehouse. | What | Where it lives | | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | **File contents** — the bytes of the PDF, image, spreadsheet, and so on | Elementum-managed cloud storage | | **Attachment metadata** — name, description, media type, size, URL, uploader, timestamps | Elementum's platform; available through automations and the [REST API](/api-reference/api-introduction) | | **Other record fields** — text, numbers, references, and so on | The connected warehouse table for warehouse-backed apps, or Elementum's platform for platform apps | Attachments are tied to the lifecycle of their record. When a record is deleted, its attachment files are also removed from Elementum-managed storage. If you need to keep files after the record goes away, archive them out to your own storage first (see [Long-term archival](#accessing-attachments-for-analytics-or-external-systems) below). ### Accessing attachments for analytics or external systems Because attachment files aren't materialized in your warehouse, plan analytics and integrations around Elementum's API and automations instead of warehouse queries: * **Attachment inventories and reporting** — List attachments on a record through the [REST API](/api-reference/api-introduction), or use the **Attachment is Added** [automation trigger](/workflows/automation-triggers-reference) to push metadata into your reporting system as new files arrive. * **Downloading a file programmatically** — Use the attachment's `URL` returned by the API or trigger. That URL requires an authenticated Elementum session; for recipients who don't have an Elementum account, use [public attachment links](#public-attachment-links). * **Long-term archival** — Copy files to your own storage from an automation (**Attachment is Added** → **Send API Request** to your archive endpoint) before the source record is deleted. *** ## Methods for Adding Files to Records There are six primary ways to add files and links to records in Elementum. Each method serves different scenarios and integration needs. ### Manual Upload in Layouts **How it works**: Users directly upload files in the record details. **Best for**: * User-initiated file uploads * Interactive workflows requiring document submission * Ad-hoc file additions to existing records **Implementation**: 1. Add a File field to your [layout](/workflows/layouts) for specific files 2. Add the Attachments component for general file storage 3. Configure field visibility and permissions as needed * Employee uploading resume during onboarding * Customer submitting proof of purchase * Team member attaching project deliverables *** ### Adding Links to Attachments **How it works**: Users can add external links to a record's Attachments section, providing quick access to related web resources without uploading a file. **Best for**: * Referencing related records or external resources * Linking to documents stored in third-party systems * Providing quick access to relevant URLs from within a record **Steps to add a link**: 1. Navigate to the record where you want to add the link and locate the **Attachments** section. 2. Click the **Add Link** button in the upper-right corner of the Attachments section. 3. In the dialog that appears, fill in the **Label** (a descriptive name for the link) and **URL** (the full URL to the external resource). 4. Click **Save** to add the link to the record's attachments. The link will appear in the Attachments section alongside any uploaded files. Links added to the Attachments section are a convenient way to cross-reference related records or external resources without duplicating files. For example, you can link to a customer record, a Confluence page, or a shared drive document. *** ### Email Received Trigger **How it works**: When automations create records from emails, any email attachments are automatically added to the new record. **Best for**: * Email-to-record workflows * Support ticket systems * Document collection via email **Configuration**: ``` Email Received Trigger → Create Record (Support Ticket) → Email attachments automatically saved to record ``` Multiple attachments are supported. Use "Repeat for Each" action to process multiple attachments. Access attachments via `trigger.attachments` variable. * Support tickets with customer-submitted screenshots * Invoice processing from emailed PDFs * Document collection via dedicated email addresses *** ### Send API Request Action **How it works**: Download files from external APIs and save them as attachments using automation actions. **Best for**: * Integration with external systems * Automated file collection from APIs * Scheduled file downloads **Configuration**: ``` Automation Trigger → Send API Request (download file) → Save Attachment (store to record) ``` **Setup Notes**: * Set response type to FILE in Send API Request action * Use Save Attachment action to store the downloaded file * Supports various authentication methods (Bearer, OAuth, Basic Auth) - Downloading reports from external reporting systems - Fetching documents from cloud storage APIs - Retrieving generated files from third-party services *** ### External API Integration **How it works**: Third-party systems add attachments via Elementum's REST API endpoints. **Best for**: * System-to-system integrations * Custom applications adding files to Elementum * Automated workflows in external systems **API Endpoint**: ``` POST https://api.elementum.io/v1/elements/testelement/TTE-11/attachments Authorization: Bearer Content-Type: multipart/form-data ``` **Requirements and usage**: * Requires OAuth 2.0 authentication * Supports files up to 250MB * Returns attachment metadata upon success * Replace `elements`, `testelement`, and `TTE-11` with your specific values * See [API Documentation](/api-reference/api-introduction) for details - CRM system attaching contracts to customer records - Document management system syncing files - Custom applications uploading generated reports *** ### File Fields in Records **How it works**: Users or automations populate specific File field types on records. **Best for**: * Structured file storage with specific meaning * Required documents in workflows * Single file per field requirements **Configuration**: 1. Create a File field in your Element definition 2. Add the field to your layout 3. Set field as required or optional **Characteristics**: * One file per field (unlike Attachments component) * Field-specific permissions and validations * Can be referenced in automations and reports - "Invoice PDF" field on invoice records - "Employee Photo" field on employee records - "Contract Document" field on contract records *** ## Previewing attachments On the record details page, open an attachment in the side-by-side preview panel or full-screen preview. Supported preview formats include: * Word, PowerPoint, and OpenDocument files: DOCX, PPTX, PPT, ODT, ODS, ODP * Single- and multi-page TIFF scans * Formats Elementum already supported for preview (such as PDF and common image types) Office and OpenDocument attachments, along with TIFF scans, render as PDFs in the preview so page navigation works the same across formats. A `/preview` API endpoint returns any supported attachment as a PDF. *** ## Public Attachment Links By default, attachments on records are private and require users to be logged into Elementum to access them. However, you can make individual attachments publicly accessible so that recipients of notifications (such as email or Slack messages) can view or download the file without needing to log in. This is especially useful when notifications are sent to external stakeholders, vendors, or collaborators who may not have an Elementum account. ### Making an Attachment Public 1. Navigate to the record and open the **Attachments** section. 2. Locate the attachment you want to make public. 3. Click the Public visibility icon **visibility icon** next to the attachment. 4. The attachment is now public. When this record's notifications include the attachment, recipients can access it without logging in. To revert an attachment to private, click the visibility icon again. Private attachments require the recipient to log into Elementum before they can be accessed. The public visibility setting applies per attachment. You can choose which specific files on a record are publicly accessible and which remain private. Each public attachment link included in a notification is valid for **30 days** from the time the notification is sent. ### When to Use Public Links * **External collaboration**: Share files with vendors, customers, or partners who receive Elementum notifications but do not have platform accounts * **Streamlined access**: Allow notification recipients to open attachments directly from their email or Slack message without an extra login step * **Selective sharing**: Keep sensitive attachments private while making general reference documents publicly accessible on the same record Public attachments can be accessed by anyone who has the link. Only make attachments public when the file content is appropriate for access without authentication. Sensitive or confidential documents should remain private. *** ## File Size Limits Summary Understanding file size limits is critical for designing reliable workflows and setting user expectations. | Operation | Maximum Size | Notes | | -------------------------------------- | ------------ | ------------------------------------------ | | **File Field Upload** | 250MB | Per file | | **Attachments Component** | 250MB | Per file, multiple files supported | | **Email Attachments (Email Received)** | 250MB | Per file (system limit) | | **Email Attachments (Send Email)** | 25MB | Total size of all attachments in one email | | **API Upload** | 250MB | Per file | | **File Reader Processing** | 250MB | Per file | | **Survey File Upload** | 250MB | Per file | The 25MB limit for **sending** email attachments is due to email service provider restrictions and is separate from the 250MB system-wide limit for file storage. *** ## Working with Files in Automations Automations provide powerful capabilities for processing and managing files automatically. ### Accessing File Information **Email Received Trigger**: ``` trigger.attachments - Array of attachment objects trigger.attachments[0].name - Filename trigger.attachments[0].mediaType - File type trigger.attachments[0].url - File URL ``` **Attachment is Added Trigger**: ``` trigger.Name - Filename trigger.Description - Attachment description trigger.Media Type - File extension/format trigger.URL - File URL trigger.Size - File size ``` ### Processing Files Extract text content from PDFs, DOC, DOCX, TXT, CSV, and Excel files. **Example**: ``` Attachment Added → Read File → Extract text content → Use in AI Classification or Update Record Fields ``` Use AI to intelligently analyze documents and extract structured data. **Example**: ``` Contract PDF → AI File Analysis → Extract: Parties, Dates, Terms, Obligations → Update Record Fields with structured data ``` Process multiple files simultaneously for batch operations. **Example**: ``` Multiple Reports Uploaded → Read Bulk File → Process all files → Aggregate data ``` Save files to specific records programmatically. The file source and target record can belong to different apps or element types, enabling cross-app file workflows. Files provided by users during agent interactions can also be saved to a record. **Example — email attachments**: ``` Email with PDFs → Repeat for Each (attachment) → Save Attachment to Customer Record ``` **Example — cross-app file copy**: ``` Record Updated (Contracts App) → Search Records (Vendor in another App) → Save Attachment (contract PDF → Vendor record) ``` **Example — agent-provided file**: ``` Run Agent Task (user provides a receipt) → Save Attachment (receipt → Expense record) ``` ### Receiving Files from Agent Interactions When a user hands a file to an agent during a conversation, the agent can invoke an automation that persists the file to a record. The handoff is set up on the automation's [On-Demand Trigger](/workflows/automation-triggers-reference), which needs a **File Input** variable so the trigger can receive the file the agent passes in. **Configuration steps**: 1. Create an automation with an **On-Demand Trigger**. 2. In the trigger's **Trigger Inputs** panel, click **+ Add Input** and add an input with **Field Type** set to **File**. Mark it **Required**. 3. Add any other inputs the automation needs — for example, a **Title** text input to name the new record. 4. Click **Save** on the trigger, then add downstream actions such as **Create New Record** and **Save Attachment** that reference the File Input variable to persist the file on the target record. 5. Publish the automation and add it as a tool on the agent so the agent can call it and pass along the file the user provided. The same **File Input** trigger variable works for any caller that can pass a file — not only agents. Other automations, [Automation Buttons](/workflows/automation-buttons), and external systems using the on-demand endpoint can invoke this automation and provide a file the same way. ### Sending Files via Email When sending emails with attachments in automations, you can attach files from multiple sources: **Attachment Sources**: * **Record File Fields**: Attach files from specific file fields on the trigger record * **Attachments Block**: Attach all files from the record's attachments component * **Workflow File Fields**: Attach files from file fields available in the workflow context Remember: Total email attachment size is limited to **25MB** when sending emails. If you exceed this limit, the email will fail to send. *** ## Best Practices ### File Size Management * Display file size limits in your forms and interfaces * Include size limits in survey instructions * Provide clear error messages when limits are exceeded * Use File Readers for structured data extraction * Process large files asynchronously when possible * Consider file size when designing email workflows * Keep email attachments under 25MB total * For larger files, use File Fields or direct uploads * Consider providing download links instead of attaching large files ### File Organization * Create specific File fields for important documents (e.g., "Contract", "Invoice") * Use meaningful field names that indicate file purpose * Set File fields as required when documents are mandatory * Use the Attachments component for supplementary files * Allow users to add multiple supporting documents * Leverage attachments for email-based file collection * Encourage meaningful file names from users * Use automation to rename files based on record data * Include dates or identifiers in file names for easier searching ### Security & Compliance * Use "Attachment is Added" trigger to validate file types * Block or flag unexpected file types * Implement virus scanning for sensitive environments * Configure field-level permissions for sensitive files * Use record-level permissions to control file access * Audit file access through activity logs * Review which attachments are set to [public visibility](#public-attachment-links) and ensure only non-sensitive files are shared publicly * Never commit files with credentials or secrets (.env, credentials.json) * Use AI File Analysis to scan for sensitive information * Implement approval workflows for sensitive document types *** ## Troubleshooting Common Issues **Symptoms**: File upload fails or times out **Solutions**: * Verify file is under 250MB size limit * Check internet connection and upload speed * Try uploading a smaller file to isolate the issue * Review browser compatibility (test different browsers) **Symptoms**: "Email failed to send" errors in automation logs **Solutions**: * Verify total attachment size is under 25MB * Check that all referenced file fields contain valid files * Ensure file URLs are accessible * Review email service provider status **Symptoms**: File Readers fail to extract data correctly **Solutions**: * Verify file format is supported (PDF, DOC, DOCX, TXT, CSV, Excel) * Check file size is under 250MB * Test with a simpler file to rule out corruption * Review File Reader configuration and field mappings **Symptoms**: API returns errors when uploading files **Solutions**: * Verify OAuth token is valid and not expired * Check Content-Type header is set to multipart/form-data * Ensure file size is under 250MB * Review API error message for specific issues *** ## Related Documentation Learn about file-related automation actions like Read File, AI File Analysis, and Save Attachment Understand the Email Received and Attachment is Added triggers for file workflows Explore File Reader types and how to extract data from documents Review API endpoints for programmatic file uploads and management Configure File fields and Attachments component in your record layouts Use Upload File question type in surveys for collecting files from respondents *** ## Summary * **File Size Limit**: 250MB per file (25MB for email sending) * **Six Upload Methods**: Manual, Add Link, Email, API Action, External API, File Fields * **Two Storage Types**: File Fields (structured) and Attachments Component (flexible) * **Public Links**: Make individual attachments accessible to notification recipients without login * **Automation Support**: Read, analyze, and process files in workflows * **Best Practice**: Choose the right method for your use case and set clear expectations Start with manual uploads and the Attachments component for simple use cases, then expand to automated file processing as your workflows mature. # Configure Record Creation Layout Source: https://docs.elementum.io/workflows/form-builder Create custom forms to start new workflows and create records manually The Form Builder provides a visual drag-and-drop interface for designing custom record creation forms. Build forms that allow users to manually start new workflows and create records tailored to your specific business processes. ## Overview The Form Builder allows you to design forms that users will use to manually create new records and initiate workflows. By dragging fields from your available field library into organized sections, you can create structured forms that capture exactly the information needed to start your business processes. The forms created here directly influence what a user sees when they manually create a record within an object or when they create a request within [Services](/workflows/services). The Form Builder automatically saves your progress as you work, so you never lose your form configuration. ## Getting Started ### Creating a New Form 1. Open the app, element, or task that needs a form. 2. Click Form Builder icon **Form Builder** under **User Interface** in the left navigation menu. 3. Add sections to organize your form structure 4. Drag fields from the field library to your sections 5. Configure field properties and validation rules 6. Preview your form to test the user experience ### Form Structure for Record Creation Create forms are organized into **sections** that contain **fields**. This hierarchical structure helps create logical groupings of related information needed to start a new workflow or create a record. ``` Create Form ├── Section 1 (e.g., "Basic Information") │ ├── Field 1 (e.g., "Title") │ ├── Field 2 (e.g., "Customer") │ └── Field 3 (e.g., "Owner") └── Section 2 (e.g., "Details") ├── Field 1 (e.g., "Description") └── Field 2 (e.g., "Priority") ``` ## Working with Sections ### Adding Sections 1. Drag the **Section** option from the **Add** menu onto your form. 2. Edit the section title as needed. 3. Drag fields into the section. ### Section Management * **Reorder sections**: Drag sections up or down using the grip handle * **Rename sections**: Click on the section title to edit To drag a section or field, click and drag on the grip handle. Do not drag from the section or field label. Deleting a section will also remove all fields within that section. This action cannot be undone. ## Field Configuration ### Available Field Types The Form Builder supports the fields configured in your Record Details Layout icon [Record Details Layout](/workflows/layouts). Available field types include: * **Text fields**: Single-line text input for titles, names, IDs * **Multi-line text**: Large text areas for descriptions and detailed information * **Dropdown menus**: Selection from predefined options like status, priority, category * **Date fields**: Date and time pickers for deadlines, start dates * **Number fields**: Numeric input with validation for quantities, budgets * **Status fields**: Predefined status options for workflow states * **User fields**: Team member selection for ownership and assignments * **Relationship fields**: Links to other records for dependencies ### Adding Fields to Sections 1. Locate the desired field in the **Fields** panel 2. Drag the field into your target section 3. The field automatically appears in the section 4. Configure the field properties by clicking the More icon **More** icon ### Field Properties Each field can be customized with the following properties: #### Layout Options * **Full Width**: Makes the field span the entire section width * **Grid Position**: Controls field positioning within the section #### Validation Rules * **Required Field**: Makes the field mandatory for record creation * **Helper Text**: Adds guidance text below the field ## Form Preview ### Live Preview Mode The Form Builder includes a live preview feature that allows you to: * See exactly how your create form will appear to users * Test field interactions and validation * Check mobile responsiveness * Validate form flow and user experience for record creation ### Testing Your Form 1. Click **Preview** to enter preview mode 2. Fill out fields to test validation rules 3. Check required field indicators 4. Verify section organization and flow 5. Test on different screen sizes Always test your create forms in preview mode before deployment to ensure users can efficiently create records and start workflows. ## Best Practices ### Form Design * **Logical grouping**: Organize related fields into sections that make sense for record creation * **Clear labeling**: Use descriptive section and field names that users understand * **Progressive disclosure**: Start with essential fields needed to create the record, add optional ones later * **Consistent spacing**: Maintain uniform field spacing and sizing ### Field Organization for Record Creation * **Required fields first**: Place mandatory fields at the top of sections * **Natural flow**: Order fields in a logical sequence that follows your business process * **Minimal sections**: Avoid creating too many small sections that fragment the creation process * **Related fields together**: Group dependent fields in the same section ### User Experience for Manual Record Creation * **Clear instructions**: Use helper text for complex fields that users might not understand * **Reasonable defaults**: Set sensible default values where appropriate to speed up record creation * **Mobile-friendly**: Ensure forms work well on mobile devices for field users * **Validation feedback**: Provide clear error messages to prevent incomplete records ## Advanced Features ### Integration with Workflows Forms built with the Form Builder can be integrated with: * **Approval processes**: Route newly created records through approval workflows * **Automation rules**: Trigger actions when records are created through the form * **Notifications**: Send alerts when new records are created * **Data pipelines**: Connect form data to external systems ## Troubleshooting ### Common Issues **Fields not appearing in sections** * Ensure the field is properly dragged into the section boundary * Check that the field type is compatible with the section configuration **Preview not updating** * Refresh the preview mode * Check for unsaved changes in the form builder **Validation rules not working** * Verify that required fields are properly marked * Test validation logic in preview mode * Check for conflicting validation rules For additional support with the Form Builder, visit our [Support Center](/support) or check the [FAQ section](/support/faq/faq-apps). # JSON File Reader Source: https://docs.elementum.io/workflows/json-file-reader Parse JSON data intelligently with AI-assisted field detection and automatic type mapping The JSON File Reader transforms raw JSON data into structured, usable objects within your automation workflows. With AI-powered analysis and intelligent type detection, it automatically understands your JSON structure and suggests appropriate field mappings for use in [automation workflows](/workflows/automation-system). ## Key Features * **AI-Assisted Analysis** – Analyzes JSON structure and suggests field types and mappings * **Intelligent Type Detection** – Recognizes dates, numbers, text, and boolean values automatically * **Live Preview** – See how your JSON will be parsed before saving your configuration * **Multiple Input Sources** – Works with API responses, file uploads, and direct JSON input ## Supported JSON Formats The JSON File Reader handles flat and nested objects, arrays, and mixed types—including API responses, configuration files, data exports, and webhook payloads. JSON can come from: * **Text Value Reference** – Direct input or paste * **API Request Actions** – Responses from external APIs * **Data Transform Actions** – Output from other automations * **Record Triggers** – JSON fields from record updates ## Creating a JSON File Reader In your application, go to **File Readers** section Click **+ File Reader** and select **JSON** from the document type options **Name**: Enter a descriptive name (e.g., "API Response Parser") **Description**: Optional description for your team The system analyzes your JSON and suggests field types and mappings, with a live preview of parsed data. Use sample data to validate field extraction and type detection before saving. ## Configuration Options ### Field Type Mapping The system automatically detects and maps field types: * **Text** (default for strings) * **Date** with format selection * **DateTime** with timezone support * **Number** for numeric strings * **Decimal** for precise calculations * **Boolean** for true/false values * **Number** (integer values) * **Decimal** (floating point, default for numbers) * Automatically detected and mapped as boolean type * Handles true/false, 1/0, and yes/no variations ### Date Format Recognition The system supports various date formats: * ISO 8601 standard formats * Common regional formats (MM/DD/YYYY, DD/MM/YYYY) * Custom format specification * Automatic timezone detection ## Working with JSON Data ### Simple JSON Objects ```json theme={null} { "name": "John Doe", "age": 30, "active": true, "created_date": "2024-01-15T10:30:00Z" } ``` Field types (Text, Number, Boolean, DateTime) are detected automatically from the structure. ### JSON Arrays ```json theme={null} { "cars": [ { "name": "Model Y", "year": 2024, "electric": true } ] } ``` Use **Repeat For Each** actions to iterate through JSON arrays. Configure the File Reader to parse the array, add the action, set the array field as the iteration source, then process items inside the loop. ## Using in Automations Use the JSON File Reader in [automation workflows](/workflows/automation-system). Example flow: ``` API Response → JSON File Reader → Transform Data → Update Records → Generate Report ``` ### Common Automation Patterns **Trigger**: API Request Action (JSON response) **File Reader**: Parse API response data **Actions**: * Transform Data to clean values * Create Record with parsed data * Update Record Fields with new information * Send Email Notification with results **Trigger**: Webhook Received (JSON payload) **File Reader**: Extract webhook data **Actions**: * AI Classification to determine event type * Search Records to find related entries * Update Record Fields with webhook data * Post Comment with processing status **Trigger**: File Upload (JSON config) **File Reader**: Parse configuration data **Actions**: * Transform Data to validate settings * Update Record Fields with configuration * Start Approval Process if required * Generate Report with config summary ### File Reader Actions 1. **Create Action** - Add a File Reader action to your automation 2. **Select Type** - Choose your configured JSON File Reader 3. **Configure Input** - Connect your JSON source 4. **Map Output** - Use the parsed fields in subsequent actions ## Best Practices * **Data Validation** – Validate critical fields before processing to prevent automation failures * **Consistent Structure** – Maintain consistent JSON structures across related automations for reliable processing * **Type Accuracy** – Choose appropriate field types during configuration to ensure accurate data handling * **Testing** – Test with sample data before deploying to production environments ## Advanced Features ### Nested Object Handling The JSON File Reader handles complex nested structures: ```json theme={null} { "user": { "profile": { "name": "John Doe", "preferences": { "theme": "dark", "notifications": true } } } } ``` Access nested values using dot notation: `user.profile.name`. For varying JSON structures, you can use **AI Classification** to determine structure type before **Dynamic Field Mapping** and the JSON File Reader, so parsing adapts to the data format. ## Error Handling and Troubleshooting ### Common Issues **Symptoms**: JSON parsing fails with syntax errors **Causes**: * Missing brackets, quotes, or commas * Malformed JSON structure * Invalid characters in JSON **Solutions**: * Check for syntax errors using JSON validators * Verify JSON structure matches expected format * Use Transform Data to clean JSON before parsing * Implement IF conditions to handle malformed data **Symptoms**: Expected fields return null or empty values **Causes**: * Field names don't match JSON keys (case-sensitive) * Optional fields missing in source JSON * Nested object path incorrect **Solutions**: * Verify field names match exactly (case-sensitive) * Use Branch actions to handle optional fields * Check nested object paths and dot notation * Add default values for missing fields **Symptoms**: Data type mismatches in automation actions **Causes**: * Field types don't match JSON data types * String values expected as numbers * Date format not recognized **Solutions**: * Ensure field types match the actual data * Use Transform Data for type conversion * Configure date formats properly * Implement data validation steps ### Validation Strategies Validate critical JSON fields (e.g., with Branch actions) before processing to ensure data quality and prevent automation failures. Use required-field checks, format validation (dates, numbers, emails), range checks for numbers, and pattern matching where the structure is predictable. ## Performance Optimization * Map only the fields you need instead of parsing the full JSON. * Use appropriate field types and process large payloads in batches when possible. * For very large JSON, limit size or use streaming; clear variables after use. ## Comparison with Other File Readers ### When to Use JSON File Reader Use the JSON File Reader for API responses, webhooks, configuration files, and other structured JSON. **Consider alternatives when**: * Processing unstructured documents ([Text File Reader](/workflows/text-file-reader)) * Working with business forms ([Purchase Orders Reader](/workflows/purchase-orders-file-reader)) * Handling spreadsheet data ([Table File Reader](/workflows/table-file-reader)) * Requiring AI-powered analysis ([Elementum Intelligence Reader](/workflows/elementum-intelligence-file-reader)) ## Next Steps Learn how to integrate JSON File Readers with automation workflows Enhance JSON processing with AI classification and analysis Process structured data from spreadsheets and CSV files Upgrade to AI-powered document analysis for complex data extraction # Layout Builder Source: https://docs.elementum.io/workflows/layouts Design, organize, and manage workflow data and features with layouts # Layouts: Building Your Workflow UI Elementum layouts let you visually design how users interact with workflow data and features. Layouts combine **Fields** (your workflow's state/data) and **Components** (Elementum-powered workflow features) into clear, actionable interfaces. ## Access the Layouts Builder Once you click Create on a new object, you are automatically redirected to the Record Details Layout. To make edits later, open your app, element, or task. Click **Record Details Layout** under **User Interface** in the left navigation menu. Changes in the record details layout are saved automatically. You may need to refresh to see the updates in your object records. ## Manage Workflow Stages At the top of the Record Details Layout, manage the Workflow Stages by clicking the **+** button to add more or the **Edit** icon next to a stage to rename. Click the **Delete** icon next to a stage to remove it. This is only available if you have multiple stages. To reorder your stages, click the stage circle and drag to the desired order. Each stage can have its own layout and fields. Click on the stage at the top of the page to arrange the layout. **Bring AI into your workflow UI** Admins can add an **Agent Button** (star icon) to any section of the layout. This lets users access an AI Agent designed to provide insights, suggestions, or actions tailored to that part of the workflow. 1. Toggle the star icon to enable Elementum Intelligence for a section 2. Select or create an Agent to assist users with context-specific help 3. Configure the Agent to match the needs of each workflow stage or section [**Learn how to build and configure agents**](/ai-agents/agents-experience) and [**configure agent tools, channels, and integrations**](/ai-agents/agents-tools-and-deployment). ## Fields and Components Click the **+** icon in a section or in the right panel to create and add Fields and Components. If you create the item in the panel, you'll still need to drag it to your layout to see it in record details. To add a section, hover over the break in the field and click **+ Section**. Sections group fields and components for clarity (e.g., "Header", "Invoice Data"). All items can be dragged to a new location in your layout. Click the **Delete** icon next to any item to remove it from your layout. Field types can be reused in a stage. Components cannot. If the item pulls in a list of data from a table or object, adjust the Display settings within the editor to apply to all future record details views. ## Fields: Your Workflow State Fields are the core data elements of your workflow. When you add a field, you're defining a piece of state that's dynamically stored in your database. Fields are reusable and can be organized into sections. ### Field Types | Type | Description | | ----------------- | -------------------------------------- | | Automation Button | Run automations directly from a record | | Calculation | Computed fields | | Checkbox | Boolean (true/false) | | Create Button | Action triggers | | Date | Date only | | Date Time | Date and time | | Decimal | Numeric values with decimals | | Dropdown | Predefined selection options | | File | File upload field (250MB max per file) | | Groups | Assign teams | | JSON Field | Structured data | | Multi-Select | Multiple choice selections | | Number | Numeric input | | QR Code | Generate and display QR codes | | Relate Button | Create relationships | | Related Items | Linked records | | Rich Text | Formatted content, descriptions | | Text | Basic string input | | User | Assign individuals | **Number vs Decimal**: Choose based on whether fractional precision matters. * **Number** rounds a fractional value down to a whole number. Use Number for counts, quantities, or IDs where whole values are all that make sense. * **Decimal** preserves fractional precision. Use Decimal anywhere fractional precision matters — currency with cents, percentages, ratios, or scores. When building automations that move data between the two, map Number → Decimal, not the reverse. Going the other direction loses precision, so budget time for a TEXT/VALUE workaround if you need it. **File Fields vs Attachments Component**: File fields are specific fields on a record for storing a single file (like "Invoice File" or "Contract Document"), while the Attachments component provides a general-purpose area for multiple file uploads. Both support files up to 250MB. **Rich Text Fields**: Rich Text fields render both HTML and Markdown. To insert code, click the **Insert Quote** icon in the editor toolbar. ### Dependent (cascading) dropdowns A **Dynamic** dropdown populates its options from the records of another Object. To make a child dropdown show only options that match a parent field's value (for example, filtering State/Province by the selected Country): 1. Create and save the child Dynamic dropdown first, choosing its **source Object**. The relationship setting appears only when editing an existing field, and the source Object is locked once set. 2. Reopen the field (**Admin** > your app > the field) and enable **Configure Relationships**. 3. Choose the **parent field**, then map it to the matching field on the child's source Object. This mapping filters the child's options by the parent's selected value. The filter field cannot be a JSON field, a Dynamic child cannot sit under a Stage-type parent, and a static child requires a static parent. To source options from an external API instead of an Object, see [Populate Dropdown Fields from External APIs](/workflows/api-powered-dropdowns). Two separate dropdowns that share one option list cannot hide a value in the second field once it is picked in the first — option-level exclusion between peer fields is not supported. To let users pick two different values, use a single **Multi-Select** field; to keep two separate fields, add a conditional rule that flags the record when both hold the same value. ### Field Options When adding many of the fields, the following toggles are available: | Toggle | Description | | ----------------- | ---------------------------------------------------------------- | | Required | Must be filled out on creation | | Required on close | Must be filled out for the record to be placed in a close status | | Show on Create | Appears when the Create button is used to add a record | | Locked on Create | Cannot be edited after creation | | Full width | Spreads across the entire section rather than the automatic size | Fields added to a record details layout can be used for filtering and search in the object views. ### Mark statuses as closed A **Status** field is a Dropdown field whose **Treat this field as** setting is **Status**. You can mark more than one option in a Status dropdown as closed — for example `Closed-Good`, `Closed-Bad`, `Canceled`, and `Complete` — instead of being limited to a single closed status. Every value marked as closed shows the same closed indicator and is recognized as closed across reports, filters, dashboards, and automations. App Administrators configure closed statuses from the Record Details Layout: 1. Open **App** → **User Interface** → **Record Details Layout**. 2. Click the **Status** field to open the **Edit Dropdown Field** editor. 3. In the **Static Dropdown** panel on the right, click the **Edit** icon next to a status value. 4. Toggle on **Mark as Closed** to treat that value as a closed status. 5. Repeat steps 3–4 for each additional status value that should be recognized as closed. 6. Click **Save**. The same steps apply to any static Dropdown field where **Treat this field as** is set to **Status**, not only the system-required Status field. *** ## Components: Elementum Workflow Features Components are first-class, pre-built workflow modules managed by Elementum. Unlike fields, components are not just data—they provide interactive features and logic. ### Common Components * **Activity Log**: Track all record activity * **Approvals**: Manage approval workflows * **Attachments**: Upload and view multiple files (250MB max per file) * **Related Tasks**: Link and manage tasks * **Relationships**: Show related records * **Surveys**: Collect structured feedback * **Update Feed**: Display record updates Admins can also add **automation buttons** to the record details layout. These buttons let users run a chosen automation directly from the record (e.g. "Send for approval", "Generate report"). See [Automation Buttons](/workflows/automation-buttons) for configuration and behavior. *** ## Dynamic Record Details Layout Dynamic layouts are available for **apps** only. Other objects, such as elements and tasks, do not currently support the dynamic Record Details Layout or its conditional visibility rules. The Record Details Layout can render as a **dynamic layout** whose fields, sections, and components appear based on conditional visibility rules. Rules can be driven by other field values, the record's stage, or user and group permissions, so the same record can show different information depending on who is viewing it and its current state. The dynamic layout supports rich content types—attachments, tags, assignees, and rich text—alongside standard fields, letting you shape the record view to match your workflow instead of a one-size-fits-all page. The dynamic layout coexists with the static layout: you can build and preview it while the static layout stays active for users, then activate the dynamic layout when you're ready. App Administrators build a dynamic Record Details Layout as follows: Open **App** → **User Interface** → **Record Details Layout** and switch to **Dynamic Layout** at the top of the page. Click **Import** in the top-right corner to bring in the field configuration from the static layout, then click **Import and Replace**. Add or update components and fields as needed. In the **Edit** popup for a field, section, or component, open the **Conditional Visibility** tab. Edit the filters to control when that item is visible—based on other field values, stage, or user and group permissions—then click **Save**. Click **Layout Inactive** at the top of the page to make the dynamic layout the active layout for your users. Conditional visibility rules are evaluated per user and per record, and a dynamic layout must be set to active before its rules apply to the live record details page. *** ## Example: Invoice Management Layout ```mermaid theme={null} graph TD; A[Header Section] -->|Fields| B[Status, ID, Title, Updated by, Updated on, Attachment] A -->|Component| C[Configure Intelligence] D[Invoice Data] -->|Fields| E[Invoice Summary, Invoice File, Invoice Number, Supplier Name, PO Number, Invoice Total, Spend Category, Ship To Address, Service Start, Service End, PO Line Memo, PO Line Type, Approver, Payment Terms] F[Invoice to PO Matching] -->|Fields| G[Add Field Here] ``` # Managed Views Source: https://docs.elementum.io/workflows/managed-views Configure admin-managed List, Kanban, Calendar, Dashboard, and Agent views that users across your organization can share. Managed views are admin-configured views of an object's records. They are defined by an App Admin and shared with specific users or groups, creating a single source of truth for how people track work in an object. Managed views are available on **Apps**, **Elements**, **Tasks**, and **Tables**. Only App Admins can create and edit them. Users with access can apply ad hoc filters and sorting when browsing a managed view, but cannot change the underlying view definition. ## View Types App Admins can create the following view types as a managed view: * **List** — Column-based record listings with filters, sort, grouping, and row density controls. * **Kanban** — Card-based workflow boards grouped by a status or category field. * **Calendar** — Date-based record visualization. * **Dashboard** — Metrics, charts, and summary widgets for at-a-glance reporting. * **Agent** — A full-page embedded chat experience. See [Attach an Agent to a View](#attach-an-agent-to-a-view). ## Create a Managed View 1. Open the object (App, Element, Task, or Table) where you want to create the view. 2. Select **Managed Views** under the **User Interface** section of the left navigation menu. 3. Click **+ Create New View** and select a view type from the dropdown: List, Kanban, Calendar, Dashboard, or Agent. 4. Enter a name in the **Create View** field. 5. Configure the view using the tabs at the top (described below). 6. Click **Save View**. ## Configuration Tabs Each managed view is configured through a set of tabs. Available tabs depend on the view type. | Tab | Description | | --------------- | ----------------------------------------------------------------------------------------- | | General | Name the view and toggle whether users can create records from this view. | | Display As | Change the view type (for example, switch a List to a Kanban). | | Columns | Choose which fields display and set column visibility and row density defaults. | | Sort | Define the default sort order. | | Filters | Define default filters that scope the records shown. | | Agent | Attach an agent to the view. See [Attach an Agent to a View](#attach-an-agent-to-a-view). | | Access Policies | Grant data access to specific groups or users. | To disable record creation globally across all managed views, use the record-creation toggle at the object level. To control it per view, use the toggle in the **General** tab of that view. ## Share Access Managed views are not automatically visible to other users. After saving a view, share it with the users or groups who should see it: 1. In the **Managed Views** list, hover over the view you want to share. 2. Click the Share access icon **Users** icon. 3. Select the users or groups who should have access. Users and groups with access see the managed view in their view list for that object. ## How Managed Views Behave for Users * Only App Admins can create or edit managed views. Users with access cannot modify the view definition. * Changes an admin makes to a managed view propagate to every user with access immediately. * Record-level permissions on the underlying object still apply. Users only see records they are entitled to, even when a view's filters would otherwise return more. * Users can apply ad hoc filters and sorting on top of a managed view to focus on specific records, but those adjustments are local to their session and do not change the view for anyone else. * Users who want a persistent layout of records across apps can build a [Workspace](/getting-started/home-page#workspaces) on their home page and pin filtered widgets to it. Home page Workspaces are configured by individual users — and can be shared with other users or groups — but do not change the managed view definition. ## Widget Column Layouts On any **Dashboard** view that includes a Table Widget, App Administrators can set the default column layout everyone with access to the widget sees. Individual users can still adjust their own layout on top of the org default, and reset back to the admin-defined view at any time. ### Set the org default layout Configuration happens on the widget itself, not on the view's **Columns** tab. 1. Open the Dashboard view that contains the Table Widget you want to configure. 2. Click the More icon **More** icon on the Table Widget and select **Display Settings**. 3. At the top of the **Display Settings** popup, select the **Everyone** tab to manage the layout for all users with permission to view the widget. 4. Choose which columns are **Visible** or **Hidden** and arrange them in the order you want. 5. Click **Save for Everyone** to publish the layout as the org default. ### How the org default behaves for users * Individual users can still adjust their own column view on top of the org default from the same **Display Settings** popup. Their changes are visible only to them. * If a user has personalized the layout, they can return to **Display Settings** and click **Reset to Default** to restore the admin-defined view. **Reset to Default cannot be undone.** If a user wants their previous personalized layout back, they will need to recreate it manually. ## Attach an Agent to a View Attach an [agent](/ai-agents/agents-experience) to a managed view so users can interact with the agent in the context of the records they are viewing. There are two ways to surface an agent: ### Attach an agent to an existing view Add an agent to any existing List, Kanban, Calendar, or Dashboard managed view to render a chat box at the top of the view. 1. Open the managed view in edit mode. 2. Go to the **Agent** tab. 3. Enable **Agent** and select the agent you want to attach. 4. Click **Save View**. Users with access to the view see a chat box above the records. ### Create an Agent view Choose **Agent** as the view type when creating a new managed view to provide a full-page embedded chat experience with no record list. 1. Click **+ Create New View** and select **Agent** as the view type. 2. Enter a name and select the agent to attach. 3. Configure **Access Policies** to control who can open the view. 4. Click **Save View**. ### Behavior Notes * Agents respect the permissions of the viewing user. Responses reflect only the records that user can access. * Each view references a single agent. Swap agents by editing the view's **Agent** tab configuration. * Agent views do not render a record list. Use them when the primary interaction is conversational. ## Customize an Agent view When you create or edit an **Agent** managed view, choose between a **Standard** layout and a **Custom** layout. **Standard** is the existing full-page agent chat experience. **Custom** adds branding, a tailored starting-actions area, and a configurable content section below the chat for a portal-like experience. App Administrators configure this from **Managed Views** under **User Interface** in the left navigation menu of the App, Element, Task, or Table. 1. Click **+ Create New View** and select **Agent**, or open an existing Agent managed view in edit mode. 2. Select the agent to attach on the **Agent** tab. 3. Choose **Standard** or **Custom** for the Agent view layout. 4. If you choose **Custom**, configure the **Image**, **Header**, and **Subheader** for the branded chat experience, and the **JSON** section that defines the custom content area below the chat. 5. In the custom content area, build out cards, lists, and static text to support the agent workflow. 6. Configure **Access Policies** and click **Save View**. **Standard** preserves the Agent managed view experience you already use today. **Custom** changes how starting actions appear on the agent and adds the full custom content section beneath the chat. Elementum validates the JSON configuration for the custom content section. ## Add a picklist option from a List view Users with permission to create records in the element referenced by a dynamic picklist column can add a missing option without leaving the List view. 1. In the **List view**, click a dynamic picklist cell. 2. Begin typing a new picklist option. 3. Press **Enter**. 4. Fill out the required fields in the **Create** modal to complete the record creation process. The **Create** modal opens with the record name pre-filled from what you typed. For picklists with simple equals filters, the matching field is pre-filled and locked so the new record automatically satisfies the column's criteria. The new record is created in the element the dynamic picklist references, not the element backing the current List view. Once saved, it becomes a selectable option in every dynamic picklist that references the same element. ## Related Documentation * [Layout Builder](/workflows/layouts) — Configure the record details layout that opens when a user selects a record from a view. * [Filtering](/getting-started/fundamentals/filtering) — Filter and sort reference used across views. * [Building Agents](/ai-agents/agents-experience) — Create and configure the agents you attach to a view. * [Groups](/administration/groups) — Manage the groups you share views with. # Object Data Access Source: https://docs.elementum.io/workflows/object-data-access Control who can view and edit records on an object through dynamic access policies and per-record sharing ## Overview Data Access controls who can view and edit **records** within your Elementum applications through two complementary systems: * **Policy-Based Access** — Dynamic access policies that determine which records users can see based on user roles, record criteria, and contextual conditions. Policies apply filtering rules across all records in an Object. * **Access Sharing** — Grants specific users or groups access to individual records through auto-sharing triggers or manual shares, providing record-level access control. Data Access applies to records across all Object types: Apps icon Apps, Elements icon Elements, Tasks icon Tasks, and Tables icon Tables. Instead of static permissions, Data Access creates dynamic filters that evaluate in real-time based on current user context and record data. *** ## Creating Access Policies 1. Go to your Apps icon **App** navigation 2. Under **Security**, click **Data Access** 3. Click **+ Policy** to create a new access policy 1. Choose **Users and Groups** that this policy applies to 2. Use the dropdown to select specific users or user groups 3. Multiple users and groups can be added to a single policy Users can be part of multiple policies. The system combines access from all applicable policies. Define when users should have access to records: 1. Click **Give access when** to start building conditions 2. Select the field to filter on 3. Choose the comparison operator 4. Set the value or condition ### Filter Operators Data Access supports filtering on all data types with appropriate operators for each type: `contains...`, `starts with...`, `is...`, `is not...` `equals`, `greater than`, `less than`, `between` `is after`, `is before`, `is between`, `is in the last X days` `is empty`, `is not empty`, `is true`, `is false` The available operators automatically adjust based on the field type you select. ### Default Policy Every app starts with a default policy that gives Internal Users access to all records. You can modify or delete this default policy as needed. *** ## Current User Variable You can filter records based on the **current user** viewing the data. This enables scenarios such as: * Showing users only records assigned to them * Displaying records where they are mentioned or involved * Filtering based on user attributes or group membership ### Examples **Scenario**: Users only see records assigned to them **Filter Setup:** * **Field**: `Assigned User` * **Operator**: `is...` * **Value**: `Current User` **Scenario**: Users only see records from their department **Filter Setup:** * **Field**: `Department` * **Operator**: `is...` * **Value**: `Current User's Department` **Scenario**: Users see records they created or are assigned to **Filter Setup (Condition Group):** * **Condition 1**: `Created By` `is...` `Current User` * **OR** * **Condition 2**: `Assigned User` `is...` `Current User` *** ## Advanced Filtering ### Multiple Conditions 1. Click **+ Condition** to add additional filter criteria. Each condition creates an AND relationship by default — all conditions must be true for access to be granted. 2. Click **+ Condition Group** to create OR logic, allowing complex boolean conditions such as "this OR that" scenarios. 3. Use **Clear All** to remove all conditions and start over. ### Complex Access Scenarios **Scenario**: Sales reps see leads in their territory that are active **Filter Setup:** * **Condition 1**: `Territory` `is...` `Current User's Territory` * **AND** * **Condition 2**: `Status` `is...` `Active` Both conditions must be true for access. **Scenario**: Managers see all records, regular users see only their own **Policy 1** (Managers): * **Users**: Manager Group * **Conditions**: (No conditions — access to all records) **Policy 2** (Regular Users): * **Users**: Staff Group * **Conditions**: `Assigned User` `is...` `Current User` **Scenario**: Users see records created in the last 30 days that involve them **Filter Setup:** * **Condition Group 1**: * `Created By` `is...` `Current User` * **OR** * `Assigned User` `is...` `Current User` * **AND** * **Condition 2**: `Created Date` `is after...` `30 days ago` *** ## Managing Access Policies In the **Data Access** section, you can: * View all active policies and their assigned users/groups * Edit existing policies by clicking the edit icon * Delete policies that are no longer needed * Test policies to verify they work as expected *** ## Access Sharing Access Sharing provides record-level access control, allowing you to grant specific users or groups access to individual records. While policy-based access applies filtering rules broadly, Access Sharing gives precise control over who can access each specific record. Access is granted through two mechanisms: * **Auto-Sharing** — Automatically grants access when users interact with records (becoming watchers, approvers, assignees, or being mentioned) * **Manual Sharing** — Explicitly grant or revoke access to specific users or groups for individual records Policy-based access determines "Can this user see records that match these criteria?" while Access Sharing determines "Can this specific user see this specific record?" Both systems work together — a user may gain access through policies, sharing, or both. ### Auto-Sharing Triggers Auto-sharing automatically grants record access to users based on their interactions with the record. App Admins can enable or disable each trigger type independently. When a user is added as a watcher to a record, they automatically gain access. Watchers typically receive notifications about record changes and updates. **Use case**: Enable for support teams who need access to cases they're monitoring. When a user is added to an approval workflow for a record, they automatically gain access to review and approve that record. **Use case**: Enable for approval processes where approvers need to view record details. When a user is @mentioned in a comment or description on a record, they automatically gain access to view the context of the mention. **Use case**: Enable for collaborative environments where team members reference each other. When a user is assigned to a record as an individual assignee, they automatically gain access to work on that record. **Use case**: Enable for task management where assignees need full record access. When a group is assigned to a record, all members of that group automatically gain access. **Use case**: Enable for team-based work where entire groups collaborate on records. Group assignee auto-sharing can grant broad access since all group members receive access. Use cautiously and audit regularly. #### Configuring Auto-Sharing Triggers 1. Go to your Apps icon **App** navigation 2. Under **Security**, click **Data Access** 3. Click the **Access Sharing** tab at the top of the page 1. Review the five toggle switches for each trigger type: * **Watchers** * **Approvals** * **Mentions** * **Individual Assignees** * **Group Assignees** 2. Toggle each switch to enable (on) or disable (off) that trigger type 3. Each trigger can be controlled independently 1. Changes are saved **immediately** upon toggling 2. Settings apply to **all new actions** in the app going forward 3. Changes are reflected in the **main Object activity log** 4. Existing shares remain unchanged Auto-sharing only grants access when a trigger is **enabled**. Disabling a trigger prevents new automatic sharing, but existing shares from past actions remain until manually removed. ### Access Audit Page The Access Audit Page shows all users and groups who have access to records in your app through auto-sharing or manual shares. To access it, go to your Apps icon **App** navigation, then under **Security**, click **Data Access** and select **Audit Page**. The audit page displays: * All users and groups with record access * The number of records each user or group has access to The Audit Page shows access grants from Access Sharing only. Users may have additional access through policy-based Data Access. #### Reviewing and Removing Access From the **Audit Page**, click on a user or group to open a modal with their access details, including the list of records, access source (trigger type or manual share), and a search field to filter by name or handle. 1. Locate the record you want to revoke access to 2. Click the **remove** or **revoke access** button next to the record 3. Confirm the removal when prompted — access is revoked immediately Removing access immediately affects the user's ability to view and interact with the record. If a user regains access through an enabled auto-sharing trigger (e.g., being reassigned), they will receive access again automatically. ### External Tag on a Record The **External** tag next to a record's handle indicates that the record has been shared with at least one external user, either directly or through a group that includes one. It is a privacy indicator that someone outside your company can see the record. #### How a user is classified as external Internal versus external classification is driven by **email domain**. An Org Admin configures which domains are treated as internal (for example, `@yourcompany.com`). Any user whose email is on a domain that is not on that list — for example, an invited supplier or partner — is flagged as external, even though the user is still a member of your Elementum organization. See [System-managed Groups](/administration/groups#system-managed-groups) for how the **External Users** group is maintained. #### What to keep in mind * Classification is based on email domain and your org's configured internal-domain list, not on which company a user "really" belongs to. * If a legitimate company domain has not been added to the internal list, your own employees can appear as external. If you see the **External** tag on a record that is only shared with colleagues, the internal-domain configuration usually needs updating — it does not necessarily mean an outside party has access. *** ## Best Practices Always test your access policies before deploying to production to ensure users can access the data they need. * **Start restrictive** — Begin with limited access and add permissions as needed rather than starting permissive * **Audit regularly** — Periodically review access policies to ensure they still align with business needs * **Document policies** — Record why specific access policies were created and their intended purpose * **Test from user perspectives** — Verify policies from different user roles to ensure the experience is intuitive ### Common Pitfalls **Problem**: Users can't access data they need for their job **Solution**: * Use condition groups to create multiple access paths * Consider user workflows when designing policies * Test with actual user scenarios **Problem**: Multiple policies create unexpected access patterns **Solution**: * Document policy interactions * Use clear naming conventions for policies * Conduct regular policy reviews and cleanup **Problem**: Complex policies slow down data loading **Solution**: * Keep conditions simple when possible * Index fields used in access policies * Monitor system performance after policy changes *** ## Troubleshooting ### Users Can't See Expected Data 1. Verify the user is included in the correct policy groups 2. Ensure filter conditions match the actual data values 3. Verify that user attributes (used in Current User variables) match expected values 4. Review all policies that might apply to the user ### Policy Not Working as Expected **Check**: Verify AND/OR logic between conditions **Solution**: Use condition groups to create proper boolean logic **Check**: Ensure filter values match field data types **Solution**: Verify text fields use text operators, dates use date operators, etc. **Check**: Verify user has the required attributes set **Solution**: Update user profiles with necessary field values # Purchase Orders File Reader Source: https://docs.elementum.io/workflows/purchase-orders-file-reader Process purchase orders with OCR trained specifically on PO fields and formats The Purchase Orders File Reader uses OCR trained on purchase order documents to extract structured data from PO forms. It understands common PO layouts and field types for use in [automation workflows](/workflows/automation-system). ## Key Features * **Specialized OCR** — Trained on purchase order layouts and field patterns for accurate extraction. * **Pre-Configured Fields** — Common PO fields ready for extraction with smart field detection. * **Structured Output** — Extracts vendor, order, and shipping information into defined fields for automation. * **Automation Ready** — Integrates with [automation workflows](/workflows/automation-system) for procurement and vendor management. ## Purchase Order Fields The Purchase Orders File Reader can extract standard PO fields automatically: ### Primary Purchase Order Fields * **Tax Payer ID** - Vendor tax identification number * **Vendor Name** - Company or individual vendor name * **Vendor Address** - Complete vendor address * **Vendor Phone** - Contact phone number * **Vendor URL** - Website or online portal * **PO Number** - Purchase order number * **Order Date** - Date the order was placed * **Payment Terms** - Payment conditions and terms * **Total** - Total order amount * **Discount** - Applied discount amount * **Receiver Name** - Delivery recipient name * **Receiver Address** - Delivery address * **Address** - General address field ### Additional Available Fields * **Invoice Receipt Date** - When invoice was received * **Invoice Receipt ID** - Internal invoice tracking number * **Customer Number** - Customer identification * **Account Number** - Account reference number * **Due Date** - Payment due date * **Delivery Date** - Expected delivery date * **Amount Due** - Outstanding amount * **Amount Paid** - Paid amount * **Subtotal** - Pre-tax amount * **Tax** - Tax amount * **Service Charge** - Additional service fees * **Gratuity** - Tip or gratuity amount * **Prior Balance** - Previous account balance * **Shipping Handling Charge** - Shipping costs * **Vendor ABN Number** - Australian Business Number * **Vendor GST Number** - Goods and Services Tax number * **Vendor PAN Number** - Permanent Account Number * **Vendor VAT Number** - Value Added Tax number * **Receiver ABN Number** - Receiver's ABN * **Receiver GST Number** - Receiver's GST number * **Receiver PAN Number** - Receiver's PAN * **Receiver VAT Number** - Receiver's VAT number * **Receiver Phone** - Receiver contact information ## Create a Purchase Orders File Reader In your application, go to **File Readers** section Click **+ File Reader** and select **Purchase Orders** from the document type options **Name**: Enter a descriptive name (e.g., "Vendor PO Processing") **Description**: Optional description for your team Choose the fields you need from the available Purchase Order fields: **Core Fields**: PO Number, Vendor Name, Total, Order Date **Optional Fields**: Select additional fields based on your workflow needs Upload a sample purchase order to validate field extraction accuracy ## Using in Automations ### Integration with Procurement Workflows ``` Email Received → Purchase Orders Reader → Vendor Validation → Create PO Record → Start Approval Process ``` ### Common Automation Patterns **Trigger**: Email Received (with PO attachment) **File Reader**: Extract PO fields **Actions**: * Search Records to find vendor * Create Record for purchase order * Start Approval Process based on amount * Send Email Notification to procurement team **Trigger**: Attachment Added (invoice PDF) **File Reader**: Extract invoice details **Actions**: * Search Records to match with existing PO * Run Calculation to verify amounts * Update Record Fields with invoice data * Post Comment with matching results **Trigger**: Record Updated (receipt confirmation) **File Reader**: Process delivery receipt **Actions**: * Search Records for PO and invoice * Run Calculation to compare quantities * AI Classification to determine discrepancies * Send Message to Teams for resolution ### Approval Workflow Integration Combine PO processing with approval workflows: ``` PO Extracted → IF Total > $5000 → Start Approval Process (Manager) → ELSE → Auto-Approve → Update Status ``` ## Best Practices * **Field Selection** — Choose only the fields you need to optimize processing speed and accuracy. * **Document Quality** — Use clear, high-resolution PO documents for best extraction results. * **Validation Rules** — Implement validation checks for critical fields like PO numbers and amounts. * **Error Handling** — Plan for missing or incorrect field extraction in your automations. * **Document preparation** — Use standard PO templates, clear printing or high-quality scans, and consistent formatting; supports PDF, scanned, and image formats. ## Advanced Features ### Multi-Vendor Processing Handle purchase orders from different vendors with varying formats: * **Vendor-specific configuration** — Create separate PO readers for different vendor formats. * **Dynamic field mapping** — Use AI Classification to determine vendor type and apply the appropriate reader. * **Fallback processing** — Configure Text File Reader as fallback for unusual formats. ### Data Validation and Enrichment Enhance extracted PO data with additional processing: ``` PO Extracted → Transform Data (standardize formats) → Search Records (vendor validation) → AI Classification (risk assessment) ``` ### Integration with ERP Systems Connect PO processing with enterprise systems: **Send API Request**: Post PO data to ERP system **Field Mapping**: Match PO fields to ERP data structure **Status Updates**: Sync approval status back to Elementum **Error Handling**: Manage API failures and data conflicts **Search Records**: Validate vendor in master data **Create Record**: Add new vendors automatically **Update Record**: Maintain vendor information **AI Classification**: Assess vendor risk levels ## Error Handling and Troubleshooting ### Common Issues **Symptoms**: Expected fields return empty values **Causes**: * Non-standard PO format * Poor document quality * Unusual field placement **Solutions**: * Test with different PO formats * Improve document quality * Configure additional fields * Consider Elementum Intelligence File Reader for complex formats **Symptoms**: Financial amounts are wrong or missing **Causes**: * Multiple currency symbols * Unusual number formatting * Tax calculations in different locations **Solutions**: * Standardize PO templates * Use Transform Data to clean amounts * Implement validation calculations * Add manual review steps for large amounts **Symptoms**: Vendor details extracted incorrectly **Causes**: * Multiple addresses on document * Vendor name variations * Address formatting differences **Solutions**: * Configure multiple address fields * Use Search Records for vendor matching * Implement fuzzy matching logic * Maintain vendor master data ### Validation Checklist * PO number format and uniqueness * Vendor exists in approved vendor list * Amount fields are numeric and reasonable * Dates are valid and logical * Required fields are populated ## File Reader Comparison **Choose Purchase Orders Reader when**: * Processing standard purchase order documents * Need high accuracy for PO-specific fields * Working with procurement workflows * Handling vendor management processes **Consider alternatives when**: * Processing non-standard business documents ([Elementum Intelligence Reader](/workflows/elementum-intelligence-file-reader)) * Working with general text extraction ([Text File Reader](/workflows/text-file-reader)) * Handling structured data files ([Table File Reader](/workflows/table-file-reader)) ## Next Steps Learn how to integrate Purchase Orders Readers with procurement workflows Set up approval workflows for purchase order processing Process vendor catalogs and pricing spreadsheets Handle complex or non-standard purchase order formats # QR Code Scanner Source: https://docs.elementum.io/workflows/qr-code-scanner Scan QR codes directly from records to automatically populate fields without manual data entry ## Overview The QR Code Scanner enables users to scan QR codes from within the app and automatically populate designated fields with the extracted data. This eliminates manual typing and speeds up data entry for records that support QR code input. *** ## Access the QR Scanner On record pages that support QR code data input, a **Scan QR Code** button or icon appears next to fields configured to accept QR data. ## Setup Prerequisites Before using QR code scanning: * Your device must have a camera * The app must have camera permission enabled * The record page must have fields configured for QR input by an admin ### Add a QR Code Field to the Record Details Layout Before users can scan QR codes, an admin must add a **QR Code** field to the record details layout using the [Layout Builder](/workflows/layouts#layouts-building-your-workflow-ui). 1. Open Record Details Layout icon **Record Details Layout** for the target object 2. From the fields panel, drag a **QR Code** field into the desired section of the layout 3. Configure the field name and any associated settings The Record Details Layout automatically saves. Once added, the QR Code field appears on record pages with a **Scan QR Code** button that users can use to initiate scanning. ### Scan a QR Code 1. Navigate to a record page with QR scanning capability 2. Locate the **Scan QR Code** button associated with the target field 3. Click the button to open the scanner interface 4. Position the QR code within the scanner frame 5. Hold steady while the app reads the code 6. The extracted data automatically populates the designated field To scan QR codes on a mobile device, you must log in to Elementum through a mobile browser. QR code scanning is not supported in the mobile app. The QR scan button only appears on fields that have been configured by an admin to accept QR code input. See the [Layout Builder](/workflows/layouts#layouts-building-your-workflow-ui) documentation for setup instructions. *** ### Review and Edit Data After a successful scan: * The extracted information appears in the target field * Review the populated data for accuracy * Edit the data if needed before saving * Save the record to confirm the changes *** ## Best Practices * Ensure adequate lighting when scanning QR codes * Hold the device steady and position the code fully within the scanner frame * Verify populated data before saving, especially for critical fields * If scanning repeatedly fails, check that the QR code is not damaged or obscured *** ## Tips for Successful Scanning ### Good Lighting Ensure the QR code is well-lit. Avoid shadows or glare on the code surface. ### Steady Position Hold your device steady and keep the QR code still during scanning. ### Full Visibility Position the entire QR code within the scanner frame—don't crop edges. ### Clean Codes Use undamaged QR codes. Torn, smudged, or faded codes may not scan. *** ## Common Use Cases **Inventory Management** Scan product barcodes to quickly log items, update stock levels, or look up product details. **Asset Tracking** Scan asset tags to pull up equipment records, log maintenance, or transfer ownership. **Event Check-In** Scan attendee badges or tickets to record attendance and retrieve registration details. **Document Processing** Scan document identifiers to link physical documents with their digital records. *** ## Troubleshooting When a scan fails, the app displays a clear error message. You can retry the scan by clicking the scan button again, or enter the information manually in the field. The scan button only displays on fields configured by an admin for QR input. If you don't see the button: * Confirm you're on a record type that supports QR scanning * Contact your app admin to enable QR input for the field The app doesn't have camera access. Grant camera permission in your device settings and try again. If the camera opens but doesn't capture the code: * Ensure the QR code is fully within the frame * Improve lighting and avoid shadows or glare on the code * Check that the code isn't blurry or damaged * Try a different copy of the code if it may be damaged or obscured * Adjust the distance between your device and the code * Restart the scan by closing and reopening the scanner The code format wasn't recognized. Verify the QR code is valid and undamaged, then try again. If the scanned data doesn't match expectations: * Verify you scanned the correct QR code * Check that the QR code contains the expected data * Edit the field manually before saving *** ## Related Features Configure fields and forms for data entry Design record page layouts and field placement # Service Level Agreements Source: https://docs.elementum.io/workflows/service-level-agreements Define and enforce time-based targets for resolving records in your Elementum apps Service Level Agreements (SLAs) let you set time-based targets for how quickly records must be resolved. Each SLA defines the stages it applies to, the acceptable time to resolve, and optional alerts to notify teams before a deadline is missed. SLAs are configured per app. The SLA clock starts when a record is created and stops when the record is closed. ## Set Up an SLA 1. Open your app and select **SLAs** in the left navigation. 2. Click **+ SLA**. 3. Enter a **Title** and **Description**. 4. Check the **stages** the SLA applies to. 5. Click **Save**. ## Add Targets to an SLA After creating an SLA, select it from the Service Level Agreements page and click **+ Target** to define the resolution requirements. You can also edit or delete an SLA by selecting it from the Service Level Agreements page. ### Target Fields **Target Title** A descriptive name for the target (e.g., "24-Hour Resolution - Business Hours"). **Target Conditions** Filter which records the target applies to. The SLA will no longer evaluate a record once it is closed. **Acceptable Time to Resolve** The maximum amount of time allowed to resolve a record and meet the SLA. This is measured from the moment the record is initially created. Set the number and unit (minutes, hours, or days). **Scheduling** Configure when the SLA clock counts time: * **Time Zone** — Defaults to your organization's time zone. * **Working Days** — Choose from Monday–Friday (default), 7 Days/Week, or Custom to select specific days. * **Working Hours** — Set the start and end times for the business day (e.g., 8:00 AM to 5:00 PM). **Alerts** Set one or more alerts to notify your team as the SLA deadline approaches or after it passes. Each alert includes: * **Alert Title** — A label for the alert notification. * **Number and Increment** — How far in advance or after the deadline the alert fires (e.g., 24 hours). * **Before/After** — Whether the alert triggers before or after the deadline. Once your targets are configured, click **Save**. ## What Happens When an SLA is Breached An SLA target is breached when the deadline set by the **Acceptable Time to Resolve** passes without the record being closed. On breach: * **Configured alerts fire.** Each alert on the target sends a notification at the time you configured (before or after the deadline). If no alerts are configured on the target, no notification is sent. * **The SLA status changes.** The record's SLA status updates to reflect the breach and is visible on the record. * **The clock keeps running until the record is closed.** Breach does not stop evaluation. Alerts configured for time **after** the deadline continue to fire on their offsets. ## Related Features * [Assignment Rules](/workflows/assignment-rules) — Route records to the right team members automatically * [Approval Processes](/workflows/approval-processes) — Add review and sign-off steps to your workflows # Enable Record Creation through Services Source: https://docs.elementum.io/workflows/services Enable Services on Apps and Tasks for customer support, help desk, and self-service request portals in Elementum Services in Elementum add user-facing request intake and self-service to [Apps](/getting-started/build-an-app) and [Tasks](/workflows/tasks). When Services are enabled on an App or Task, external or internal users can submit requests through a portal or form; those submissions create or update records in that App or Task and can drive [automations](/workflows/automation-system) and downstream workflows. Services can only be enabled for Apps and Tasks—they are not a separate object type. ## Services Key Features Services provide request intake and self-service capabilities with the following features: * **User-facing portals** — Internal or external users submit requests through a dedicated portal or form, without needing access to the full app where work is tracked. * **Submission-driven workflows** — Submissions create or update records in the App or Task and can trigger [automations](/workflows/automation-system) that update other records, send notifications, or assign work, so intake and execution stay connected. * **Standardized intake** — [Layouts](/workflows/layouts) and [Form Builder](/workflows/form-builder) let you control which fields are required and how requests are structured, keeping intake data consistent. * **Self-service** — Requesters can submit and, when configured, track status without routing every request through a central team. * **Stages and layouts** — The App or Task keeps its existing [stage and layout](/workflows/layouts) model; you define the path (e.g., Submitted, Under Review, Fulfilled) and which fields appear at each step for both internal users and requesters. * **Integration with automations and approvals** — Connect Services to [notifications](/administration/notifications), [approval processes](/workflows/approval-processes), and [object data access](/workflows/object-data-access) so submissions flow into your existing workflows and permissions. Services are a capability on Apps and Tasks. Access to records in the App or Task (including submissions via the Service) is controlled via [object data access](/workflows/object-data-access) and [roles and permissions](/administration/roles-permissions). ### Example Use Cases * IT help desk portal — users submit tickets that become App records for tracking and resolution * Employee onboarding requests — new hires request equipment or access; submissions create onboarding App records * Customer support ticket system — customers submit issues that generate cases in an App * Equipment or resource request portal — requests flow into an App for approval and fulfillment ## Core Concepts When Services are enabled on an App or Task, it uses the same [stage and layout](/workflows/layouts) model: * **Stages** define the path a request follows (e.g., Submitted, Under Review, Fulfilled). * **Layouts** define which fields and components appear at each stage. * You can show different fields or components per stage so the experience matches where the request is in the process. When users submit requests through the Service (on an App or Task), those submissions create or update records in that App or Task: * Triggers (e.g., record created or stage changed) can fire [automations](/workflows/automation-system) that send [notifications](/administration/notifications), create or update other records, or assign [tasks](/workflows/tasks). * Your team works in the App or Task as usual; the Service provides the requesters’ entry point (portal or form). Services are often paired with the [Form Builder](/workflows/form-builder) or custom forms so requesters see a guided, standardized form instead of the full record layout. Configure which fields are required and how submissions are validated to keep intake data consistent. ## Enabling Services on an App or Task Services can only be enabled for [Apps](/getting-started/build-an-app) and [Tasks](/workflows/tasks). To turn on the Service experience for an existing App or Task: 1. Open the App or Task where you want to enable Services. 2. Click **App Details** or **Task Details**. 3. Click **Set Status Required** over the Services section. This is only required if you have not configured statuses in the [Record Details Layout](/workflows/layouts). 4. Adjust the **Services Settings**: * **Show in Services** — Toggle on to allow submissions to be created from the Services feature in Elementum. * **Open Status** — Automatic status when the request is submitted. * **Closed Status** — Select the status that aligns best with a closed state. After Services settings are enabled in your App or Task details, records can now be created by customers or your team without access to the app. ## Automations and Services When Services are enabled on an App or Task, automations run on the same records (submissions create or update records in that App or Task): * **Create or update records** when a submission is created or the record reaches a stage (e.g., "Submitted"). * **Update records** when approvals complete, when tasks are done, or when data in related records changes. * **Send notifications** to requesters or internal teams when a request is received or its status changes. * **Create Tasks** and assign them from submissions so work is tracked in the App or Task. Service accounts and [agents](/ai-agents/agents-experience) that create or update records in the App or Task need the appropriate [roles and permissions](/administration/roles-permissions). Use [service accounts](/administration/service-accounts) for automated actions and ensure their roles grant access to the App or Task and any related data. ## Related Documentation * [Best Practices](/getting-started/best-practices) – When to use Services vs. Apps vs. Tasks * [Build an App](/getting-started/build-an-app) – Create Apps and enable Services for request intake * [Tasks](/workflows/tasks) – Create Tasks and enable Services for request intake * [Layouts](/workflows/layouts) – Design stages and field layout for the App or Task * [Form Builder](/workflows/form-builder) – Build forms for request submission * [Automation System](/workflows/automation-system) – Trigger and actions for submission-driven flows * [Object Data Access](/workflows/object-data-access) – Control who can see and manage records in the App or Task # Surveys Source: https://docs.elementum.io/workflows/survey-system Streamline information gathering from external parties through survey workflows integrated into your business processes Surveys enable structured collection of critical information from external parties as part of your business workflows. Instead of untracked back-and-forth communications, surveys provide a consistent, auditable way to gather required data, approvals, or feedback from recipients. ## How Surveys Work in Workflows Surveys are created and linked to a workflow stage for organizational context, then sent manually to recipients each time information needs to be collected. Each send requires filling out delivery details — including expiration date, due date, reminder date, email subject, instructions, and recipients — before the survey is dispatched. ## Business Use Cases Collect vendor certifications, insurance documents, and compliance information during the onboarding process. **Example Survey Questions:** * Upload current insurance certificates * Confirm SOC 2 Type II compliance status * Provide W-9 tax documentation * Select preferred payment terms Gather customer feedback at key touchpoints to improve service delivery and identify improvement opportunities. **Example Survey Questions:** * Rate your satisfaction with the project delivery (1-5 scale) * What aspects of our service exceeded expectations? * Would you recommend our services to others? * Upload any supporting documentation Streamline 360-degree feedback collection from managers, peers, and direct reports. **Example Survey Questions:** * Rate communication effectiveness (Multiple Choice) * Describe key accomplishments this quarter * Identify areas for professional development * Set goals for the next review period Collect security questionnaires and compliance documentation from third-party vendors. **Example Survey Questions:** * Confirm data encryption standards * Upload penetration testing results * Describe incident response procedures * Provide security certification details Gather project status updates from team members or external contractors. **Example Survey Questions:** * Current project completion percentage * Identify any blocking issues * Upload project deliverables * Estimated completion date ## Adding Surveys to Your Layout Before configuring surveys, you need to add the Survey component to your record layout: 1. Click **Record Details Layout** under **User Interface** in your app menu. 2. In the layout builder, go to the **Components** tab 3. Find and drag the **Surveys** component to your desired section 4. The page automatically saves your layout changes The Survey component must be added to your layout before you can configure and use surveys in your workflows. For detailed information about layout management, see the [Layout Builder documentation](/workflows/layouts). ## Survey Setup Process ### Create a Survey 1. Click **Surveys** under **Workflows and processes** in your app menu. 2. Click **Create New**. 3. If you already have surveys, choose whether to start from an existing survey. Otherwise, continue with **Create New**. 4. Add the following details: * **Survey Title:** Clear identifier for internal tracking * **Stage:** Link the survey to a specific workflow stage for organizational context * **Description:** Internal context about survey purpose and expected outcomes * **Email Username:** Display name for survey sender * **Friendly Name:** Organization or department name * **Email Content Title:** Subject line for survey invitation * **Custom Button Text:** Call-to-action button label 5. Click **Next** and continue to the Survey Builder. The preview automatically updates as changes are made in the fields. ### Survey Builder Create multi-page surveys with various question types to gather comprehensive information: #### Page Management * **Add Page:** Click **Add Page** and enter the page name and description * **Edit Page Details:** Click the **Edit** (pencil) icon next to the current page name to update the page name, description, or page ordering after a page is added #### Question Types Available | Question Type | Best Use Case | Example | | ---------------------------- | --------------------------------------------------- | ------------------------------------- | | **Multiple Choice** | Multi-select; respondents can choose all that apply | "Select all services you use" | | **Short Answer** | Brief text responses | "Project name" | | **Yes/No** | Binary decisions | "Are you satisfied with the service?" | | **Date/Time** | Scheduling and deadlines | "When did the incident occur?" | | **Upload File** | Document collection | "Upload your insurance certificate" | | **Multiple Choice Dropdown** | Long option lists | "Select your country" | **File Upload Limits**: The Upload File question type supports files up to **250MB** per file. Uploaded files are saved as attachments to the survey response record. #### Question Configuration * **Required/Optional:** Control data collection requirements * **Helper Text:** Provide additional context or instructions * **Question Numbering and Placement:** Maintain logical flow with question numbering. To move a question to a different position on the current page or to a new page, use **Move Question**. When you are finished creating your survey, click **Preview**, then click **Activate**. If you need to edit a survey, return to the Surveys page. Click the **More** icon and **Edit**. ## Sending a Survey Surveys are always sent manually. Each time you send a survey, you will fill out the delivery details before dispatching it to recipients. 1. Add the **Surveys** component to your Record Details Layout. 2. Open any record. 3. Click **Send** in the Survey component. 4. Add the expiration date, due date, and reminder date. 5. Add an **Email Subject**. 6. Enter instructions for your recipients. 7. Add attachments (if desired). 8. Add your recipients. You can either choose a user or group in your Elementum org, or type an email address and click **Add**. 9. Click **Send**. ## Response Management 1. Open a record. 2. In the Survey component, click the **More** icon. 3. Select **View Results**. Results are scoped to the specific send batch associated with that record. For example, if you send a survey to 5 recipients in one batch and then send the same survey to 3 recipients in a second batch, opening the results from a record in the first batch will show only the responses from those 5 recipients — not the responses from the second batch. ### Real-time Tracking Monitor survey completion status and identify non-responders for follow-up communications. ### Completion Analytics * **Sent:** Total number of survey invitations sent * **Not Started:** Recipients who have not started the survey * **In Progress:** Recipients who started but have not submitted * **Completed:** Recipients who submitted the survey * **Responses by User:** View responses grouped by recipient * **Responses by Question:** View answers grouped by question ### Data Integration Survey responses automatically populate workflow data, enabling immediate processing and decision-making. ### Export Options Export survey results in various formats for analysis, reporting, or integration with external systems. ### Data Aggregation and Analysis Survey responses can be accessed through: * **Individual Response View:** Review each survey submission separately on the workflow record * **Response-Based Automations:** Trigger workflow actions when a survey response is received **Automating on Survey Response** When a survey response is received, you can configure an automation using the "Survey Complete" trigger. This enables: * Workflow progression based on survey responses * Conditional logic that adapts to different answer combinations * Integration with approval processes and notifications * Data validation and quality checks For detailed configuration instructions and examples, see the [Survey trigger in the Automation Triggers Reference](/workflows/automation-triggers-reference#survey). **What to do after a survey response is received?** Once your Survey Complete automation fires, you can: * **Update the record** with survey response data using automation actions * **Create new elements** and populate them with survey data, then link them to the original record * **Route workflows** based on survey responses (e.g., escalate negative feedback) * **Generate reports** or notifications based on the collected data ## Storing Survey Responses in an Element For structured, queryable storage of survey responses, create a dedicated Element and an automation that writes a new record each time a response is received. This makes response data available for reporting, further automation, and cross-record analysis. ### Step 1: Create a Response Element Create a new Element with fields that correspond to each question in your survey. 1. In your app, click **Elements** and then **Create New Element**. 2. Name the element to reflect its purpose (e.g., *Survey Responses — Vendor Onboarding*). 3. Add a field for each survey question, matching the field type to the question type: | Survey Question Type | Recommended Field Type | | ------------------------ | ---------------------- | | Short Answer | Text | | Multiple Choice | Multi-select or Text | | Yes/No | Boolean | | Date/Time | Date/Time | | Upload File | Attachment | | Multiple Choice Dropdown | Dropdown or Text | 4. Add a **Relationship** field to link each response record back to the originating workflow record. 5. Save the Element. ### Step 2: Create the Automation Create an automation that fires when a survey response is received and writes the response data into the Element. 1. In your app, click **Automations** and then **Create New Automation**. 2. Set the trigger to **Survey** and select the survey you want to capture responses from. 3. Add a **Create Record** action: * Select your response Element as the target. * Map each survey response field to the corresponding Element field. 4. Add a **Relate Records** action to link the newly created response record to the original workflow record. 5. Save and activate the automation. The Survey trigger makes all survey response fields available as variables for use in the Create Record action. Map these variables directly to your Element fields when configuring the action. Once active, every submitted survey response will automatically generate a new record in your response Element, with all answers captured as structured field data and linked back to the originating record. ## Best Practices * **Keep surveys concise:** Target 5-10 questions maximum for optimal completion rates * **Use clear language:** Avoid jargon and technical terms * **Logical flow:** Order questions from general to specific * **Mobile-friendly:** Ensure surveys work well on all devices * **Strategic timing:** Send surveys when information is most relevant * **Avoid survey fatigue:** Limit frequency to maintain response quality * **Follow-up strategy:** Implement automated reminders for incomplete surveys * **Clear value proposition:** Explain how responses will be used * **Reasonable deadlines:** Provide adequate time for thoughtful responses * **Incentives:** Consider offering incentives for complex or lengthy surveys ## Troubleshooting Common Issues * **Review email subject lines:** Make them compelling and clear * **Check timing:** Avoid busy periods or holidays * **Simplify questions:** Reduce complexity and cognitive load * **Add reminders:** Configure automatic follow-up messages * **Mobile compatibility:** Test surveys on various devices * **File upload limits:** Ensure file size limits (250MB maximum per file) are clearly communicated to respondents in your survey instructions * **Browser compatibility:** Test across different browsers and versions * **Question clarity:** Use beta testing to identify confusing questions * **Response validation:** Implement appropriate validation rules * **Duplicate prevention:** Configure settings to prevent multiple submissions # Table File Reader Source: https://docs.elementum.io/workflows/table-file-reader Read Excel and CSV files with support for thousands of rows and multiple sheets The Table File Reader processes Excel and CSV files, extracting structured data from spreadsheets with support for thousands of rows and multiple sheets. This reader handles both bulk data import and single-row processing with cell references across multiple sheets for use in [automation workflows](/workflows/automation-system). ## Key Features * **Multi-format support** — Process Excel (.xlsx, .xls) and CSV files with automatic format detection * **High-volume processing** — Handle thousands of rows with batch processing * **Multi-sheet support** — Extract data from multiple Excel sheets with cross-sheet cell references * **Flexible data mapping** — Use column names or cell references for field mapping and extraction ## Supported File Types The Table File Reader can process various spreadsheet formats: * **XLSX** - Modern Excel format (Excel 2007+) * **XLS** - Legacy Excel format (Excel 97-2003) * **Multi-sheet workbooks** - Extract from specific sheets or all sheets * **Complex formulas** - Processes calculated values * **CSV** - Comma-separated values * **TSV** - Tab-separated values * **Custom delimiters** - Configure custom separators * **UTF-8 encoding** - Full Unicode support * **Tabular data** - Structured rows and columns * **Report formats** - Header rows and summary data * **Template-based** - Data in specific cell locations * **Mixed formats** - Combination of structured and template data ## Processing Modes The Table File Reader supports two modes: * **Bulk data processing** — Process many rows using column names. Set the header row, data row range, and map column names to field names with appropriate types (Text, Number, Date). Use batch size and error-handling options for large files. Best for data imports, bulk updates, and ETL. * **Single-row processing** — Extract specific values using cell references (e.g., A1, B2, Sheet1!C3). Use sheet selection and cross-sheet references (Sheet1!A1, Sheet2!B2) for multi-sheet workbooks. Best for forms, template-based extraction, and multi-sheet reports. ### Field Mapping Examples **Column-based (bulk)**: Map source columns to fields (e.g., "Customer\_Name" → customer\_name, "Purchase\_Date" → purchase\_date with Date type). You can set header row, data start/end rows, skip columns, and default values for complex sheets. **Cell references (single-row)**: Map cells to fields (e.g., Customer Name → A2, Order Date → B2). For multi-sheet workbooks use sheet prefixes (e.g., Customer!A2, Finance!C2). ## Creating a Table File Reader In your application, go to **File Readers** section Click **+ File Reader** and select **Table Data** from the document type options **Name**: Enter a descriptive name (e.g., "Customer Data Import") **Description**: Optional description for your team **Processing Mode**: Choose between bulk processing or single-row processing **For Bulk Processing**: Map column names to field names **For Single Row**: Define cell references for each field Configure field types and validation rules Upload a sample Excel or CSV file to validate data extraction ## Using in Automations The Table File Reader works with [automation workflows](/workflows/automation-system). Typical flow: **File Upload** → **Table File Reader** → **Transform Data** (or **Repeat For Each** for bulk) → **Update Records** or **Create Record** → optional **Generate Report**. **Common patterns**: * **Bulk import** — Trigger on attachment; process rows with column mapping; Repeat For Each row → Transform Data → Search Records → Create or Update Record. * **Report processing** — Trigger on email with attachment; extract metrics with cell references; Run Calculation, Update Record, optional AI Classification or notification. * **Large files** — Use batch processing (e.g., 100 rows per batch), then Repeat For Each batch → Transform Data → Update Records. ## Best Practices * **File structure**: Use consistent column names and data formats; avoid merged cells in data areas; use standard date formats (e.g., YYYY-MM-DD). * **Performance**: Process large files in batches to avoid timeouts; use specific cell ranges instead of entire sheets; prefer CSV for very large datasets; minimize complex formulas in source files. * **Validation**: Add validation rules (required fields, data types, ranges) and plan for missing data and format errors. ## Advanced Features * **Multi-sheet workbooks**: Configure which sheets to process and use cross-sheet references (e.g., Sheet1!A1, Sheet2!B2). Handle missing sheets or invalid references in your workflow. * **Dynamic column detection**: Use with AI Classification to detect column types and map fields when file structure varies. * **Downstream processing**: Use **Transform Data**, **Run Calculation**, **Search Records**, and **IF** conditions in your automation to clean, validate, and deduplicate extracted data. ## Error Handling and Troubleshooting ### Common Issues **Symptoms**: Fields return empty values or incorrect data **Causes**: * Column names don't match configuration * Header row in wrong location * Data types incompatible **Solutions**: * Verify column names in source file * Check header row configuration * Adjust field types to match data * Use Transform Data to clean values **Symptoms**: Cell references return errors or empty values **Causes**: * Sheet names changed * Cell locations moved * Referenced cells are empty **Solutions**: * Verify sheet names and structure * Update cell references * Add IF conditions to handle empty cells * Use named ranges for stability **Symptoms**: Processing timeouts or memory errors **Causes**: * File too large for single processing * Complex formulas slow processing * Memory limitations **Solutions**: * Enable batch processing * Split large files into smaller chunks * Use CSV format for very large datasets * Process during off-peak hours Validate that required fields are populated, data types match expected formats, and dates/numbers are in valid ranges before processing. ## Integration Examples * **Customer data import**: Attachment Added (CSV) → Table File Reader (column mapping) → Transform Data → Search Records → Create or Update Record. * **Report processing**: Email Received (Excel attachment) → Table File Reader (cell references for metrics) → Run Calculation → Update Record → optional Generate Report. * **Multi-sheet workbook**: File Upload → Table File Reader (per-sheet configuration) → combine and process data → Create Record or analysis. ## File Reader Comparison **Choose Table File Reader when**: * Processing Excel or CSV files * Working with structured tabular data * Need to handle thousands of rows * Requiring multi-sheet processing **Consider alternatives when**: * Processing unstructured documents ([Text File Reader](/workflows/text-file-reader)) * Working with business forms ([Purchase Orders Reader](/workflows/purchase-orders-file-reader)) * Requiring AI-powered analysis ([Elementum Intelligence Reader](/workflows/elementum-intelligence-file-reader)) * Processing JSON data ([JSON File Reader](/workflows/json-file-reader)) ## Next Steps Learn how to integrate Table File Readers with data processing workflows Explore advanced data processing and analysis capabilities Perform calculations on extracted spreadsheet data Create analytics and reports from processed table data *** The Table File Reader supports processing Excel and CSV files at scale for data imports, report processing, and workflows that need structured tabular data extraction. # Tasks Source: https://docs.elementum.io/workflows/tasks Create, configure, and manage task-based workflows for assignments and follow-up work Tasks in Elementum let you manage assignable work items within your other objects (apps and elements). Like [Elements](/getting-started/fundamentals/core-concepts), Tasks are a type of workflow object: they have stages, layouts, fields, and can be driven by [automations](/workflows/automation-system). Use Tasks when you need to track who should do what, by when, and how it fits into a larger process. ## When to Use Tasks Tasks are suited to workflows where: * Work is assigned to specific users or groups * Items move through stages (e.g., To Do, In Progress, Done) * You want assignment and completion to trigger [automations](/workflows/automation-system) or [notifications](/administration/notifications) Tasks are first-class objects in Elementum. They integrate with [approval processes](/workflows/approval-processes), [assignment rules](/workflows/assignment-rules), and [agents](/ai-agents/agents-experience). [Object data access](/workflows/object-data-access) can be restricted at the task level so users only see tasks they are allowed to work on. Tasks are best used as simple workflow trackers or as a piece of your workflow in Elements and Apps. ## Core Concepts Tasks use the same [stage and layout](/workflows/layouts) model as other workflow objects: * **Stages** define the path a task follows (e.g., New → In Progress → Review → Complete). * **Layouts** define what fields and components appear at each stage. * You can show different fields or components per stage so the interface matches where the task is in the process. Tasks are designed for assignment: * Assign tasks to individual users or to groups. * Use [assignment rules](/workflows/assignment-rules) to automatically assign tasks based on conditions (round-robin, load, role, or custom logic). * Assignment can trigger [notifications](/administration/notifications) so assignees know when work is added to their queue. Automations can create, update, or complete tasks based on triggers in the same app or in related Elements: * **Create tasks** when a record reaches a stage, when data meets a condition, or when an [approval](/workflows/approval-processes) is requested. * **Update task fields or stages** when related data changes or when an agent or integration provides new information. * **Run Agent Task** can hand off to an [agent](/workflows/agent-task-automation) for analysis or decisions, then continue with structured automation (e.g., update the task or create a follow-up task). Service accounts and agents that create or update tasks need the appropriate [roles and permissions](/administration/roles-permissions) for the Task. Use [service accounts](/administration/service-accounts) for automated actions and ensure their roles grant access to the Task and any related data. ## Create a Task You'll first want to create a Task to add individual, related task records. 1. Open Tasks icon **Tasks** in the left navigation menu. 2. Click the More icon **More** icon. 3. Click **Create New Task**. 4. Fill out the fields: * **CloudLink** — Choose the CloudLink with the data you'll need for your Tasks. * **Name** — The display name for your Task group in Elementum. * **Namespace** — A unique identifier for your Task records. This cannot be changed later. * **Handle** — A short reference key that appears as a prefix in every record ID (e.g., VND-001). This cannot be changed later. * **Description** — Help others in your organization understand what the Task is for. * **Category** — Organizes all Tasks in your organization. Categories are managed by admins in Settings. 5. Click **Create**. From here, you'll set up the [Record Details Layout](/getting-started/build-an-app#step-2-design-your-layout), just like when creating apps. You can also add [automations](/workflows/automation-system). ## Create Task Records There are a few ways to create a record in your new Task. ### List View 1. Open the Task and click **Create** in the top right corner. 2. Fill the required fields and click **Save**. ### A Separate Record You can create or relate Task records to an Element, Task, or App record so they appear in the details. 1. Add the **Related Tasks** component in your object's [Record Details Layout](/workflows/layouts). 2. After you refresh, open a record in your object (Element, App, or Task). 3. Find the Tasks component. 4. Click either **Create a Task** or **Relate a Task** to connect an existing Task. Once you enter the required details, the Task record can be used for reference and automations. ## Related Documentation * [Layouts](/workflows/layouts) – Design task stages and field layout * [Assignment Rules](/workflows/assignment-rules) – Automate who gets assigned * [Approval Processes](/workflows/approval-processes) – Require sign-off on tasks or related records * [Automation System](/workflows/automation-system) – Trigger and actions for task lifecycle * [Agent Task Automation](/workflows/agent-task-automation) – Combine tasks with AI agents * [Object Data Access](/workflows/object-data-access) – Control who can see and work on which tasks # Text File Reader Source: https://docs.elementum.io/workflows/text-file-reader Extract raw text from images, text documents, and PDFs using OCR technology The Text File Reader uses Optical Character Recognition (OCR) to extract raw text content from images, text-based documents, and PDFs. This reader is ideal for simple text extraction when you need to convert visual content into text for use in [automation workflows](/workflows/automation-system). **Not a document viewer or editor.** Text File Reader uses OCR to extract text into named fields for an [automation](/workflows/automation-system). It does not open, display, or edit the original file. To preview an attachment, open it from the record — see [File Uploads & Attachments](/workflows/file-uploads-attachments). You configure a **name**, **description**, **output fields** (for example, `extracted_text` or `document_title`), and a **test** upload. There is no layout or annotation to set up because the reader doesn't render the file. It produces output when a [Read File action](/workflows/automation-actions-reference) runs it in an automation. Other readers have more to configure: * [Purchase Orders Reader](/workflows/purchase-orders-file-reader) — output fields, many pre-built for PO layouts * [Table File Reader](/workflows/table-file-reader) — processing mode plus column or cell mapping * [Elementum Intelligence Reader](/workflows/elementum-intelligence-file-reader) — output fields, a custom system prompt, and an AI Service ## Key Features * **OCR Technology** — Extracts text from images and scanned documents. * **Raw Text Extraction** — Plain text content without structure analysis. * **Automation Ready** — Integrates with [automation workflows](/workflows/automation-system) for document processing. ## Supported File Types The Text File Reader can process: * **PDF** - Text-based and scanned PDFs * **DOC/DOCX** - Microsoft Word documents * **TXT** - Plain text files * **RTF** - Rich text format documents * **JPG/JPEG** - Compressed image files * **PNG** - Portable network graphics * **TIFF** - Tagged image file format * **BMP** - Bitmap image files * Business letters and memos * Contracts and agreements * Forms and applications * Reports and documentation ## Create a Text File Reader In your application, go to **File Readers** section Click **+ File Reader** and select **Text** from the document type options **Name**: Enter a descriptive name (e.g., "Contract Text Extraction") **Description**: Optional description for team reference Configure the text fields you want to extract: **Field Name**: Descriptive name for the extracted text **Field Type**: Select "Text" for raw text extraction **Required**: Mark if this field must contain content Upload a sample document to validate text extraction accuracy ## Configuration Options ### Field Configuration The Text File Reader extracts content into configurable text fields: **Use Case**: Extract all text into one field **Configuration**: * **Field Name**: "extracted\_text" * **Field Type**: Text * **Description**: "Complete document text content" **Best for**: Simple text extraction, content analysis **Use Case**: Extract specific sections or types of content **Configuration**: * **Field 1**: "document\_title" (Text) * **Field 2**: "main\_content" (Text) * **Field 3**: "footer\_text" (Text) **Best for**: Structured text extraction, section-specific processing ### OCR Quality and Document Preparation OCR accuracy depends on document quality. For best results, use high-resolution images and clear text formatting. **Factors affecting OCR accuracy**: Image resolution (higher is better), text clarity and contrast, font size and style, document orientation, and background interference. Use documents with clear, dark text on light backgrounds, proper orientation, and good contrast. Optimize image resolution (300 DPI is typically sufficient) and consider splitting very large documents. ## Using in Automations ### Integration with Automation Workflows The Text File Reader integrates seamlessly with [automation workflows](/workflows/automation-system): ``` Email Received → Text File Reader → AI Classification → Create Record → Send Notification ``` ### Common Automation Patterns **Trigger**: Email Received (with PDF attachment) **File Reader**: Extract text from PDF **Actions**: * AI Classification to categorize content * Create Record with extracted text * Send Email Notification to confirm processing **Trigger**: Attachment Added **File Reader**: Extract text from image **Actions**: * AI Summarization to create brief summary * Post Comment with extracted content * Update Record Fields with text data **Trigger**: Record Created **File Reader**: Process uploaded document **Actions**: * Transform Data to clean text * Update Record Fields for searchability * Generate Report with text content ### File Reader Action Configuration When adding a File Reader action to your automation: 1. **Select File Reader Type**: Choose your configured Text File Reader 2. **Configure Input Source**: * File from Email Received trigger * Attachment from Record * Upload from user interaction 3. **Map Output Fields**: Use extracted text in subsequent actions 4. **Handle Errors**: Add IF conditions for missing or invalid content ## Best Practices * **Field Validation** — Implement validation checks in automations for critical text extraction. * **Error Handling** — Use IF conditions to handle cases where text extraction fails. * **Performance Optimization** — Consider file size limits and processing time for large documents. ## Advanced Features **Post-processing**: After extraction, use automation actions to clean text (Transform Data with AI), categorize content (AI Classification), or summarize (AI Summarization). **Batch processing**: Use a **Repeat For Each** action to iterate over multiple uploaded files, run the Text File Reader on each, then process the extracted text with subsequent actions. ## File Reader Comparison **Choose Text File Reader when**: * You need simple text extraction without structure * Processing scanned documents or images * Working with various document formats * OCR accuracy is sufficient for your use case **Consider alternatives when**: * You need structured data extraction ([Purchase Orders Reader](/workflows/purchase-orders-file-reader)) * Working with spreadsheets ([Table File Reader](/workflows/table-file-reader)) * Requiring AI-powered analysis ([Elementum Intelligence Reader](/workflows/elementum-intelligence-file-reader)) * Processing JSON data ([JSON File Reader](/workflows/json-file-reader)) ## Error Handling and Troubleshooting ### Common Issues **Symptoms**: Inaccurate or garbled text extraction **Causes**: Low image resolution, poor document quality, or unusual fonts and formatting. **Solutions**: Improve source document quality (see OCR Quality and Document Preparation) or use [Elementum Intelligence File Reader](/workflows/elementum-intelligence-file-reader) for complex documents. **Symptoms**: Text fields return empty values **Causes**: * Document contains only images/graphics * Text is embedded in unsupported format * OCR failed to detect text regions **Solutions**: * Verify document contains readable text * Use supported file formats * Test with different document samples **Symptoms**: File Reader action fails with timeout error **Causes**: * Document is too large * High complexity image processing * System resource limitations **Solutions**: * Reduce document size or resolution * Split large documents into smaller sections * Process during off-peak hours Always test your Text File Reader with representative sample documents before deploying in production automations. ## Next Steps Learn how to integrate Text File Readers with automation workflows Enhance text processing with AI classification and summarization Process structured business documents with specialized OCR Upgrade to AI-powered document analysis for complex extraction *** *The Text File Reader provides reliable OCR-based text extraction for a wide variety of document types. Use it for simple text extraction needs or as a foundation for more complex document processing workflows.* # Language Settings Source: https://docs.elementum.io/workflows/translations Localize your app with multi-language support using AI-powered translations ## Overview The Languages feature enables you to create multi-language versions of your apps, making them accessible to users worldwide. Elementum automatically translates field names using AI when you enable new languages, and provides tools for manual refinement. *** ## Prerequisites App Admin permissions are required to configure translations and manage language settings. Before setting up translations, ensure you have: Required to configure language settings and manage translations in your app Your app should be fully configured in your primary language (typically English) with all field names finalized Clear understanding of which languages your users need for optimal app experience *** ## Update Language Settings in Your App In the left navigation menu of your app, element, or task, click **Languages** under the **Configuration** section to access your language settings. Language settings are configured per object and apply to all users of that app, element, or task based on their regional preferences. ### Enable Languages for the First Time When setting up languages in your app for the first time, check the box next to each language you would like to use. To add or remove languages later, click the More icon **More** icon on the Languages page and select **Settings**. ### Edit Configured Languages To make changes to languages that are already configured in your app: Choose the language you want to edit from the dropdown at the top of the page. Type your edits directly into the translation fields as needed. Changes are automatically saved as you type. ### Add Additional Languages To add a new language to your app using an XLIFF file: Click the More icon **More** icon in the top right corner of the page and select **Download Language File**. Edit the XLIFF file to fit your industry terminology and business requirements. Back on the app's Languages page, click the More icon **More** icon and select **Upload Language File**. Add your edited XLIFF file and save changes. Review the fields now populated on the Languages page to verify accuracy. ### Managing Translations **Ongoing Management Tasks:** When you add new fields to your app: * **Automatic Translation**: If languages are enabled, new fields auto-translate * **Review Process**: Check AI translations for new fields * **Manual Adjustment**: Edit translations as needed for accuracy * **Update Professional Files**: Re-export XLIFF if using professional translations When you need to update existing translations: * **Direct Editing**: Modify translations directly in the interface * **Bulk Updates**: Use XLIFF export/import for major changes * **Version Control**: Keep track of translation changes over time * **User Communication**: Notify users of significant translation updates Regular translation quality checks: * **Native Speaker Review**: Have native speakers review translations periodically * **User Feedback**: Collect feedback from users about translation quality * **Consistency Audits**: Ensure consistent terminology across all fields * **Professional Updates**: Periodically refresh with professional translation services *** ## Set User Language Click your profile icon at the bottom of the left navigation menu. Click **Regional Settings**. Select your preferred language from the **Locale** dropdown. *** ## Language Display for Users **How Users See Translations:** Users control their language experience through their profile: * **Regional Settings**: Users set their preferred language in User Profile * **Automatic Application**: App immediately displays in selected language * **Personal Preference**: Each user can choose their own language independently * **Consistent Experience**: Language choice applies across all apps they access When users have non-English regional settings: * **Field Names**: All field labels appear in their selected language * **Forms**: Data entry forms show translated field names * **Record Details**: Field labels in record views are translated * **Lists and Tables**: Column headers and field names are localized **Language Switching:** * **Immediate Effect**: Language changes take effect immediately * **No Data Loss**: Changing languages doesn't affect stored data * **Consistent Interface**: All field names update to the selected language * **Fallback Handling**: Untranslated content falls back to default language ### Translation Scope Elementum translates most user-facing content automatically. Here's what is and isn't included in the translation system. **What Is Translated:** * Field names and labels ✅ * Custom field names ✅ * Form field labels ✅ * Record detail field names ✅ * System buttons (Save, Cancel, Delete, etc.) ✅ * Navigation menus ✅ * System messages and notifications ✅ * Help text and descriptions ✅ * Validation error messages ✅ **What Is Not Yet Translated:** * App Names ❌ * Section titles ❌ * Widgets on Workspaces ❌ * Workspace names and descriptions ❌ **Current Limitations**: While most of the interface is translated, App Names, Section titles, and Workspace elements remain in their original language. *** ## Troubleshooting ### Common Issues **Possible Causes:** * User regional settings not configured correctly * Language not enabled in app translation settings * Browser cache showing old content * Translation not completed for specific fields **Solutions:** * Verify user has correct regional language in User Profile * Confirm target language is enabled in app Translation settings * Clear browser cache and refresh the application * Check translation completion status for the language **Possible Causes:** * AI translation lacks business context * Technical terminology not translated appropriately * Industry-specific terms need manual adjustment * Cultural context not considered in AI translation **Solutions:** * Manually edit problematic translations in the interface * Use professional translation services for critical content * Create terminology glossaries for consistent AI translation * Gather feedback from native speakers and adjust accordingly **Possible Causes:** * File format corruption during download/upload * Translation software compatibility issues * Missing or incomplete translations in file * File encoding problems **Solutions:** * Re-download XLIFF files if upload fails * Verify translation software supports XLIFF 1.2 or 2.0 * Check that all required fields have translations * Ensure files are saved with UTF-8 encoding ### Best Practices for Success * **Language Priority**: Start with languages most needed by your user base * **Content Readiness**: Finalize all field names before enabling translations * **Resource Planning**: Budget for professional translation if needed * **User Communication**: Inform users about upcoming language support * **Phased Rollout**: Enable one language at a time to manage quality * **Quality Control**: Review all AI translations before making them live * **User Testing**: Have native speakers test the translated interface * **Feedback Collection**: Establish channels for translation feedback * **Regular Reviews**: Schedule periodic translation quality assessments * **User Feedback Integration**: Continuously improve based on user input * **Professional Updates**: Refresh professional translations periodically * **Documentation**: Maintain records of translation decisions and changes *** By implementing the Languages feature, you can make your Elementum apps accessible to users worldwide, improving user experience and expanding your app's reach to global teams and customers.