# Airtable Source: https://docs.equals.com/docs/airtable Example Javascript code for importing data from Airtable You can use Import Scripts to bring any data from your Airtable board directly into an Equals workbook. # Create an Airtable API Key and locate your Base ID To find your API key, navigate to your [account page](https://airtable.com/account). On your account overview page, under the API heading, there's a button that says "Generate API key." The base Id can be found in the URL of the API page of the base. In the URL, the base Id is immediately after `https://airtable.com/` and starts with `app`. (You can also locate the base id by navigating to the [Airtable Standard API](https://airtable.com/api) page and clicking on the Airtable base that you want to use.) # Add the key to a secret group Copy the the API key and base Id from the prior step. Then [create a new secret group](https://docs.equals.com/docs/secret-groups) and paste the key into a new secret named `airtable_api_key` and `airtable_base_id`. # Example code Once you've completed the prior steps, create a new workbook, add a new import script to a sheet and copy + paste the script below. Once pasted select your secret group in the toolbar (make sure the key in the secret group is called `airtable_api_key` and `airtable_base_id`). You'll want to modify the code below to reflect the table name and titles of the columns in the table you're importing. ``` const equals = require("equals"); const axios = require("axios"); const AIRTABLE_BASE_ID = equals.getSecret("airtable_base_id"); const AIRTABLE_API_KEY = equals.getSecret("airtable_api_key"); const TABLE_NAME = "Contacts"; const getData = async () => { const resp = await axios({ method: "get", url: `https://api.airtable.com/v0/${AIRTABLE_BASE_ID}/${TABLE_NAME}`, headers: { Authorization: `Bearer ${AIRTABLE_API_KEY}` } }); return resp.data; } const data = await getData(); equals.addHeaders(["First Name", "Last Name", "Title", "Company", "Email"]); for(const record of data.records) { equals.addRow([ record.fields["First Name"], record.fields["Last Name"], record.fields["Title"], record.fields["Company"], record.fields["Email"] ]); } ``` *** [Secret groups](/docs/secret-groups) [Auth0](/docs/auth0) # ARR Build Daily by Customer Source: https://docs.equals.com/docs/arr-build-daily-by-customer Understand and use the ARR Build Daily by Customer view This view aggregates Stripe invoice data to display each customer's total ARR for each day they are active, along with their contributions to each component of ARR (Gross New, Expansion, Contraction, Churn, Restart, and Net New). Each row represents a customer's contributions to ARR on a given day. This view also incorporates the impact of any invoice-level corrections or customer and domain-level exclusions made in your ARR Build. | Field | Data type | Description | | - | - | - | | Day | DATE | The specific calendar date. Useful for analyzing daily ARR trends. | | Week | DATE | The specific week (set to the Monday of that week). Helps in aggregating ARR data by week for easier comparison of WoW trends. | | Month | DATE | The specific month (set to the first day of that month). Allows for monthly trend analysis, a common timeframe for ARR reporting, and goal setting. | | Week beginning | BOOLEAN | Indicates whether a given date is the first day of a week (TRUE or FALSE). Useful for setting up reports or visualizations that depend on weekly summaries. | | Week ending | BOOLEAN | Indicates whether a given date is the end of a week (TRUE or FALSE). Allows for easy weekly data snapshots, making it easier to pull consistent weekly performance data. | | Month beginning | BOOLEAN | Indicates whether a given date is the beginning of a month (TRUE or FALSE). Provides a monthly "start" data point for monthly summaries and snapshots. | | Month ending | BOOLEAN | Indicates whether a given date is the end of a month (TRUE or FALSE). Provides a monthly "end" data point for monthly summaries and snapshots. | | Fiscal period | VARCHAR(16777216) | Specifies the fiscal period (as denoted by the first month in the quarter, or "Jan", "Apr", "Jul", and "Oct"). Essential for aligning ARR reporting with fiscal quarters for financial reporting and budget analysis. | | Month day | NUMBER(10,0) | Indicates the day number within a month (1-31). Useful for tracking and analyzing mid-month trends, seasonality, and other patterns based on day-in-month positions. | | Fiscal period day | NUMBER(10,0) | The day number within a fiscal period. Allows for detailed trend analysis within a fiscal quarter and for making time-based projections on a quarterly basis. | | Customer name | VARCHAR(256) | The name of the customer account as it appears in Stripe. Allows for customer-specific analysis and reporting on individual ARR contributions. | | Customer ID | VARCHAR(256) | A unique identifier for each customer as it appears in Stripe. Important for accurate aggregation and deduplication of customer records. Also enables accurate joins across tables. | | Currency | VARCHAR(256) | The currency associated with each invoice value. If you need help creating multi-currency ARR reporting, reach out to us using the messenger in the bottom-right corner of your workspace Home. | | Gross New ARR | NUMBER(38,12) | The ARR generated from a new customer within a given period. | | Expansion ARR | NUMBER(38,12) | The ARR generated from an existing customer who upgraded or expanded their usage within a given period. | | Contraction ARR | NUMBER(38,12) | The ARR lost from a customer who reduced their usage or downgraded within a given period. | | Churn ARR | NUMBER(38,12) | The ARR lost due to a customer canceling their subscription within a given period. | | Restart ARR | NUMBER(38,12) | The ARR from a customer who previously churned but who has returned within the restart cut-off window. | | Net New ARR | NUMBER(38,12) | The net change in ARR for the period (Gross New + Expansion - Contraction - Churn + Restart) associated with a given customer. | | Total ARR | NUMBER(38,12) | The cumulative ARR attributable to a given customer, up to and including a given period. | | Gross New customers | NUMBER(1,0) | Flags whether a given customer is considered a new customer for a given period. | | Expansion customers | NUMBER(1,0) | Flags whether a given customer is considered an expansion for a given period. | | Contraction customers | NUMBER(1,0) | Flags whether a given customer is considered a contraction for a given period. | | Churn customers | NUMBER(1,0) | Flags whether a given customer is considered a churn for a given period. | | Restart customers | NUMBER(1,0) | Flags whether a given customer is considered a restart for a given period. | | Net new customers | NUMBER(1,0) | Flags whether a given customer is considered a net new, gross new, churn, or restart customer for a given period. | | Total customers | NUMBER(1,0) | Flags the ongoing active status of a given customer, allowing for historical tracking of customer activity on any given day. | # How to use it The ARR Build Daily by Customer view is the foundation of your ARR reporting, enabling you to build downstream reports like: * Cohort analyses that measure net and gross retention rates * ARR forecasts that project future ARR growth based on historical trends * Pacing summaries that track progress against ARR goals ## Example: Identify customers that contribute to each component of ARR You can return a list of customers who contribute to each ARR component over a given period to build a deeper understanding of the drivers behind ARR growth and trends. Below are some sample SQL queries to help you get started. The output of each will be a list of customers associated with each component of ARR for the specified month, which you can edit as needed. Before running the queries, be sure to specify a `month` and `date` value. ### Gross New Customers ``` select \* from ARR_BUILD_DAILY_BY_CUSTOMER where gross_new_arr \<> 0 and month = date_trunc('month',current_date) -- current month -- and month = date_trunc('month',date '2024-01-01') -- specific month -- and month >= date '2024-10-01' -- more recent than a specific month ``` ### Expansion Customers ``` select \* from ARR_BUILD_DAILY_BY_CUSTOMER where expansion_arr \<> 0 and month = date_trunc('month',current_date) -- current month -- and month = date_trunc('month',date '2024-01-01') -- specific Month -- and month >= date '2024-10-01' -- more recent than a specific month ``` ### Contraction Customers ``` select \* from ARR_BUILD_DAILY_BY_CUSTOMER where contraction_arr \<> 0 and month = date_trunc('month',current_date) -- current month -- and month = date_trunc('month',date '2024-01-01') -- specific Month -- and month >= date '2024-10-01' -- more recent than a specific month ``` ### Churn Customers ``` select \* from ARR_BUILD_DAILY_BY_CUSTOMER where churn_arr \<> 0 and month = date_trunc('month',current_date) -- current month -- and month = date_trunc('month',date '2024-01-01') -- specific Month -- and month >= date '2024-10-01' -- more recent than a specific month ``` ### Restart Customers ``` select \* from ARR_BUILD_DAILY_BY_CUSTOMER where restart_arr \<> 0 and month = date_trunc('month',current_date) -- current month -- and month = date_trunc('month',date '2024-01-01') -- specific Month -- and month >= date '2024-10-01' -- more recent than a specific month ``` ## Example: Building ARR pacing summaries Create pacing summaries to assess progress against monthly or quarterly ARR targets. Before running the query, adjust the query to select the specific `month`, `current_date,` and reporting interval you are interested in. ``` -- Pull the monthly net_new total in terms of daily change with base as ( SELECT month , month_day , SUM(net_new_arr) AS net_new_arr FROM arr_demo_daily_customer arr where month >= date_trunc('month',current_date) - interval '6 months' -- in the last six months and month \< date_trunc('month',current_date) -- but exclude this month's partial data GROUP BY all order by 1,2 asc ), -- aggregate those into a running sum and total month amount per month aggregate as ( select \* , sum(net_new_arr) over (partition by month order by month_day asc) as running_sum , sum(net_new_arr) over (partition by month) as month_total , sum(net_new_arr) over (partition by month order by month_day asc) / sum(net_new_arr) over (partition by month) as percent_of_month_by_day from base ), -- take the avg pacing per day for the last 6 historical months historical_pacing as ( select month_day , avg(percent_of_month_by_day) as avg_percent_of_month_by_day from aggregate group by 1 order by 1 asc ), -- take the current month running total current_month_net_new as ( select distinct month , month_day , sum(net_new_arr) over (partition by month order by month_day asc) as net_new_arr from ARR_BUILD_DAILY_BY_CUSTOMER where month = date_trunc('month',current_date) ) -- calculate the end of month forecast based on current month attainment + historical pacing select a.month_day , a.avg_percent_of_month_by_day , b.net_new_arr as current_month_net_new_arr , b.net_new_arr / a.avg_percent_of_month_by_day as end_of_month_forecast from historical_pacing a join current_month_net_new b on a.month_day = b.month_day order by 1 asc ``` *** [Using your ARR Build views](/docs/using-your-arr-build-views) [ARR Build Invoice Items](/docs/arr-build-invoice-items) # Overview Source: https://docs.equals.com/docs/arr-build-get-started Put your ARR reporting on autopilot with your Equals ARR Build, workbooks, and dashboards When you sign up to use Equals for [ARR reporting](https://equals.com/arr-reporting/) and connect to Stripe, we automatically create an ARR Build for you that aggregates your ARR data based on your Stripe invoices. Once your initial sync with Stripe is complete, you'll find the following resources linked from the `Get started` page of your workspace: **ARR Build**: Here, you'll find your ARR Build `Configuration`, `Data corrections` and clean, analysis-ready tables (called `Views`) that display ARR movements for each customer each day they are active. The views can be queried from any workbook by workspace members with the right permissions. These views are stored and kept in sync with Stripe in your Equals Warehouse and are generated using default [configuration settings](https://docs.equals.com/docs/managing-your-arr-build#configuring-arr-build-logic), which you can adjust at any time to reflect how your business recognizes ARR. **ARR Overview workbook:** This is one of three workbooks auto-generated for you using data from your ARR [views](https://docs.equals.com/docs/understanding-and-using-your-arr-build) based on your ARR Build's [configuration settings](https://docs.equals.com/docs/managing-your-arr-build#configuring-arr-build-logic). By default, [queries](https://docs.equals.com/docs/building-queries) in this workbook are scheduled to pull fresh ARR Build data into your Equals workbook daily. From here, you can use spreadsheet [functions](https://docs.equals.com/docs/supported-functions), pivot tables, and more to perform in-depth ARR analysis. **ARR Overview dashboard:** This dashboard, which comes pre-built as part of your ARR Overview workbook, visualizes your aggregated ARR summary, which displays ARR movements by ARR component and reporting period. From here, you can [schedule your dashboard](https://docs.equals.com/docs/send-dashboards-to-email-and-slack) to distribute to Slack or email on a recurring basis. You can also make edits using the doc-like dashboard editor. In addition to your ARR Overview workbook, you'll get two other workbooks auto-generated using your ARR Build: 1. **Daily Pulse:** A daily snapshot of key ARR metrics and movements. 2. **Cohorts & Retention:** A cohorted view of ARR, including net revenue retention and logo cohorts. You can find all these workbooks from the `Get started` page of your workspace. On an ongoing basis, you can navigate to your workbooks from your workspace [Home](https://go.equals.com/home) and your ARR Build from your [Views](https://go.equals.com/views) page. To get started with your ARR Build in Equals, we recommend that you: 1. Customize your ARR Build [configuration settings](https://docs.equals.com/docs/managing-your-arr-build) to align with your business's unique revenue logic. 2. Make any needed [corrections](https://docs.equals.com/docs/managing-your-arr-build#managing-stripe-invoice-corrections) or [exclusions](https://docs.equals.com/docs/managing-your-arr-build#managing-customer-and-domain-exclusions) to account for edge cases in your ARR Build data. 3. [Schedule](https://docs.equals.com/docs/send-dashboards-to-email-and-slack) your ARR Overview, ARR Daily Pulse, or ARR Cohorts & Retention dashboards to deliver automatically to Slack or email. 4. Leverage your ARR Build to create downstream [ARR reporting and analysis](https://docs.equals.com/docs/understanding-and-using-your-arr-build). *** [Building and sharing analyses](/docs/building-and-sharing-analyses) [Managing your ARR Build](/docs/managing-your-arr-build) # ARR Build Invoice Items Source: https://docs.equals.com/docs/arr-build-invoice-items Understand the ARR Build Invoice Items view # What it is This view displays Stripe invoice data in a clean, structured format, breaking out every line item and discount within every invoice, along with any associated ARR contributions, into individual rows. This view is foundational to the [ARR Build Daily by Customer view](https://docs.equals.com/docs/arr-build-daily-by-customer), which layers on [data corrections and exclusions](https://docs.equals.com/docs/managing-your-arr-build#managing-stripe-invoice-corrections) to create a more refined and aggregated view of ARR by customer by day. # Data schema | Field | Data type | Description | | - | - | - | | Type | VARCHAR(17) | Specifies whether a given entry is an invoice line item or discount, helping to distinguish between revenue-generating items and deductions. | | Customer ID | VARCHAR(256) | Unique identifier for each customer as it appears in Stripe. Allows for linking multiple invoices to specific customers. | | Customer name | VARCHAR(256) | The name associated with the customer as it appears in Stripe. | | First payment date | TIMESTAMP | Date and time of the customer’s first successful payment, marked as paid in Stripe. | | Invoice ID | VARCHAR(256) | Unique identifier for each invoice as it appears in Stripe. Allows for tracking individual invoices and linking invoices to customer accounts. | | Invoice line item | VARCHAR(256) | Unique identifier for each line item within an invoice as it appears in Stripe. | | Invoice status | VARCHAR(256) | Shows whether the invoice is paid, open, or null (not applicable). Allows for tracking of overdue invoices and cash flow analysis. | | Product ID | VARCHAR(256) | Unique identifier for the product associated with an invoice line item. Useful for product-level revenue analysis. | | Product name | VARCHAR(256) | Descriptive name of the product or service billed. | | Invoice quantity | NUMBER(38,0) | The quantity of each product or service counted within the invoice line item. Important for calculating total billed amount and analyzing volume-based trends. | | Proration | BOOLEAN | Indicates whether the invoice amount is prorated. Relevant for accurately tracking mid-period changes in subscriptions or service levels. | | Description | VARCHAR(256) | Provides additional details about each line item as it appears in Stripe. | | Period start date | DATE | Start date of the service or billing period for the line item. | | Period end date | DATE | End date of the service or billing period for the line item. | | Currency | VARCHAR(256) | The currency used for the invoice. | | Price recurring | VARCHAR(256) | Shows whether the price is part of a recurring subscription. Helpful to distinguish recurring revenue from one-time fees. | | Amount | FLOAT | The billed amount for each line item before any discounts or adjustments. Useful for calculating gross revenue. | | Total ARR | NUMBER(38,12) | The line item’s contribution to Annual Recurring Revenue, as determined by your ARR configuration settings. | # How to use it The ARR Build Invoice Items view provides full visibility over your Stripe invoices, making it easy to track whether invoices have been paid and analyze the impact of discounting on revenue, among other analyses. ## Example: Track payment status by customer Run the starter query below to quickly identify unpaid invoices for a given customer, including the associated invoice amounts. ``` select customer_id , invoice_id , invoice_status , period_start_date , period_end_date , sum(amount) as amount from ARR_BUILD_INVOICE_ITEMS where invoice_status != 'unpaid' group by all limit 100 ``` ## Example: Analyze discounting trends Track the amount of discounting across customers to evaluate the impact of discounts on revenue and assess whether your promotional strategies are meeting business goals. To get started, run the starter query below. The output will display invoice and discount amounts by customer for each reporting period. From here, you can use SUMIFS formulas to look at the data in a number of ways, including: * Identify customers with the highest discount amounts * Compare total discounts to total invoice amounts to calculate the discount-to-invoice ratio * Track discount amounts by month or quarter to identify trends over time * Sum total invoice amounts with and without discounts to assess the impact of discounts on revenue ``` select customer_id , customer_name , invoice_id , period_start_date , sum(case when type = 'invoice_line_item' then amount end) as invoice_amount , sum(case when type = 'discount' then amount end) as discount_amount from ARR_BUILD_INVOICE_ITEMS group by 1,2,3,4 limit 100 ``` *** [ARR Build Daily by Customer](/docs/arr-build-daily-by-customer) [Data syncing overview](/docs/data-syncing-overview) # Auth0 Source: https://docs.equals.com/docs/auth0 Example Javascript code for importing data from Auth0 You can use Import Scripts to import data from your Auth0 account directly into an Equals workbook. # Create an Auth0 personal access token Follow [the instructions here](https://auth0.com/docs/secure/tokens/access-tokens/management-api-access-tokens) to create an Auth0 personal access token. You'll also want to write down your Client ID. # Add the key to a secret group Copy the access token from the prior step. Then [create a new secret group](https://docs.equals.com/docs/secret-groups) and paste the key into a new secret named `auth0_api_secret`. Create a second secret in the same group called `auth0_api_client_id` with your Client ID. # The code Once you've completed the prior steps, create a new workbook, add a new import script to a sheet and copy + paste the script below. Once pasted select your secret group in the toolbar (make sure the key in the secret group is called `auth0_api_secret`). ``` /* - https://auth0.com/docs/api/management/v2 - https://auth0.com/docs/api/management/v2#!/Users/get_users */ const equals = require("equals"); const axios = require("axios"); /* Page through the users and add ones that have not yet been seen to the spreadsheet Avoid PII */ const processAuth0UsersData = async () => { const accessToken = await getAccessToken(); const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}`, }; const perPage = 100; // set next page call as true so we make the initial call let makeNextPageCall = true; // set the initial page to be 0 let page = 0; equals.addHeaders(["user_id", "created_at", "updated_at", "last_login", "logins_count", "subscription_purchased", "user_metadata"]); while (makeNextPageCall) { // start with make next page call as false and only set to true if we need to make more makeNextPageCall = false; //console.log(page); await axios .get( equals.getSecret("auth0_api_host")&`/api/v2/users?page=${page}&per_page=${perPage}`, { headers } ) .then(response => { if (response.data.length > 0) { /* Add to spreadsheet */ let users = response.data; for(const user of users) { //console.log(user); equals.addRow([ user.user_id, formatDate(user.created_at), formatDate(user.updated_at), formatDate(user.last_login), user.logins_count ]); } } // we got all we can for this page, so make another page call // Limit is 1000 users: https://auth0.com/docs/manage-users/user-search/view-search-results-by-page#limitation if (response.data.length >= perPage && page < 10) { makeNextPageCall = true; page += 1; } }) .catch(error => { console.log(`error getting users: ${error}`); }); } }; const getAccessToken = async () => { const timestamp = new Date().getTime(); let accessToken = ""; const oauthTokenHeaders = { 'Content-Type': 'application/x-www-form-urlencoded', }; let clientId = equals.getSecret("auth0_api_client_id") let clientSecret = equals.getSecret("auth0_api_secret") let grantType = 'client_credentials' let audience = equals.getSecret("auth0_api_audience") const data = `client_id=${clientId}&client_secret=${clientSecret}&grant_type=${grantType}&audience=${audience}`; await axios .post(equals.getSecret("auth0_api_oauth_url"), data, { headers: oauthTokenHeaders, }) .then(response => { accessToken = response.data.access_token; }) .catch(error => { console.error(error); }); return accessToken; }; const formatDate = (gaDate) => { if (!gaDate) { return "" } //console.log(gaDate) const year = gaDate.slice(0,4); const month = gaDate.slice(5,7); const day = gaDate.slice(8,10); //console.log(`Boom = ${year}-${month}-${day}`) return `${year}-${month}-${day}` } await processAuth0UsersData(); ``` *** [Airtable](/docs/airtable) [Deputy](/docs/deputy) # Auto-expand Source: https://docs.equals.com/docs/auto-expand Update tables, charts, and pivot tables automatically with each query run Auto-expand enables tables, charts, and pivot tables to automatically update with each query run. This is useful for ensuring that analyses are up-to-date without the need to manually copy & paste data or expand ranges on charts and pivots. # Tables With auto expand, summary tables can update automatically as queried data expands. To enable auto expand: 1. Run a query. Create a summary table that aggregates data from the queried output over time. 2. Click on the icon that appears in the upper left corner of the first cell in the summary table. Or, select the summary table range and right-click to select "Auto expand" from the drop-down. 3. Set the query to run on a scheduled basis, or modify the query to return data for future time periods. The formulas and formatting in the summary table will be automatically copied horizontally or vertically to expand the table and include these future periods. To disable auto expand, click on the same icon. # Charts Charts will always automatically update in Equals when the source data is modified or changed. Charts require no additional setup for these changes to be reflected dynamically. For example, if a chart references queried data and the data changes after a query run, the chart will automatically update. Similarly, if the data in a table referenced by the chart is modified manually or via auto-expand, the chart will automatically update. # Pivot tables Pivots will always automatically update in Equals when the source data is modified or changed. Pivot tables, like charts, require no additional setup for these changes to be reflected. For example, if a pivot table references queried data and the data changes after a query run, the pivot will automatically update. Similarly, if the data in a table referenced by a pivot is modified manually or via auto-expand, the pivot table will automatically update. # FAQ ### Will auto-expanding tables, charts, and pivots update in my dashboard? Tables, charts, and pivots that are included in a dashboard will always reflect the source data. They will auto-expand if the source table or chart auto-expands. ### How often does auto-expand update the data in tables, charts, and pivots? Auto-expand updates the data in tables, charts, and pivot tables automatically whenever a query is run or whenever the underlying data changes. The frequency of updates depends on how often the query is scheduled to run. ### Is there a limit to the amount of data that can be auto-expanded? Equals does not impose limits on the amount of data that can be auto-expanded. However, your data will not auto-expand once it has reached the row or column limit available in your spreadsheet. *** [Calculated columns](/docs/calculated-columns) [Command bar](/docs/command-bar) # AWS RDS Source: https://docs.equals.com/docs/aws-rds Connect a Postgres, MySQL, or SQL Server database hosted on AWS AWS supports a number of database types (Postgres, MySQL, SQL Server, etc.). The instructions for each database type are the same. If your database is clustered, you will need to find the specific instance within the cluster you want to connect to. # Finding the database in AWS All of the following sections start from the database instance page in AWS. To find this: 1. Head to the RDS homepage by typing RDS in the search box at the top of the AWS console. 2. Ensure you are in the correct region in the top right (Virginia, Ohio, etc.) 3. Select the database you want to connect to from the list. If your database is part of a cluster, choose the specific instance within the cluster that you want to connect to. # Finding connection details You need five pieces of information to connect a database to Equals: host, port, username, password, database password. ## Host & Port 1. Find your database in AWS (first section above). 2. On this page, you can find the **`endpoint`** – which is the **`host`** – and **`port`** in the *Connectivity & security* section: ## Username, Password, Database name AWS only gives you the **`username`** and **`password`** for your database on creation, and the **`database name`** is set by you after creation. If you don’t have these details contact the person on your team that set up the database. # Allowing access from our IP You likely need to allow incoming connections from Equals’ IP address. There are two parts to enabling access from outside AWS: turning on *public access* and adding a security group rule. ## Turning on “public access” 1. Find your database in AWS (first section above). 2. On the database details page ensure that *Publicly accessible* is *Yes* under *Security*. If it is, continue with the next section. 3. If *Publicly accessible* is set to *No*, click *Modify* in the top right. 4. Scroll down to the *Connectivity* section and expand the *Additional configuration* subsection. Here you can enable public access: 5. Head to the bottom of the page and click *Continue* 6. Choose *Apply immediately* under *Schedule modifications* 7. Save your changes by clicking *Modify DB instance*, the changes will be applied in a couple of minutes. Note: you can still deny public access from all non-Equals IPs with security group rules. ## Adding a security group rule 1. Find your database in AWS (first section above). 2. Under the “Security” subsection within *Connectivity & security* click the security group. If the database is part of multiple security groups you should choose one specific to just this database – or create one if it doesn’t exist. 3. Once on the security group page, click *Inbound rules* in the tab bar and then *Edit inbound rules*. 4. On the *Edit inbound rules* page click *Add rule*. 5. Choose *Custom TCP* for *Type* and enter the port for your database under *Port range*. 6. For Source, choose *Custom* and then enter Equals’ IP address in the text field: `54.68.61.53/32`. 7. Click Save rules. Equals should now be able to connect to your database. *** [Connecting to SQL databases](/docs/connecting-sql-databases-to-equals) [AWS Redshift](/docs/aws-redshift) # AWS Redshift Source: https://docs.equals.com/docs/aws-redshift Connect an AWS Redshift warehouse # Finding your cluster in AWS 1. Open the AWS console and navigate to Redshift via the search in the top nav. 2. Ensure you are in the correct region in the top right (Ohio, Virginia, etc.). 3. Open the sidebar and click *Clusters*. 4. Choose the cluster you want to connect to from the list. # Finding connection details To connect Redshift to Equals you need five pieces of information: **`Endpoint`**, **`Port`** ,**`Database name`**, **`Username`**, and **`Password`**. The **`Schema`** field is optional. 1. Find your cluster in AWS, following the instructions above. 2. Once on the cluster details page you can find **`Endpoint`** under “General information”. 3. Navigate to *Properties* in the tab bar below *General information*. 4. Under *Database configurations* you can find the **`Database name`**, the **`Port`** (likely 5439), and the **`Username`** (called *Admin user name*). 5. Finally you need the **`Password`**. This was set when your cluster was created. If you don’t know the password ask the team member who set up your database. # Allowing access from our IP There are two steps to allowing access from our IP: enabling public access and creating an inbound security group rule. ## Enabling public access 1. Find your cluster in AWS, following the instructions above. 2. Navigate to *Properties* in the tab bar below *General information*. 3. Under *Network* and *Security settings*, ensure *Publicly accessible* is set to *Enabled*. If it is already enabled, you can skip to the next section. 4. Click *Edit* in the header of *Network* and *Security settings*. 5. At the bottom of the page check *Turn on Publicly accessible* and click *Save changes*. Note: it is not necessary to assign an elastic IP address. ​ ## Creating an inbound security group rule 1. Find your cluster in AWS, following the instructions above. 2. Navigate to *Properties* in the tab bar below *General information*. 3. Under *Network and security settings*, navigate to the *VPC security group*. 4. On the *Security group* page, click *Inbound rules* in the tab bar. 5. Click *Edit inbound rules*. 6. Add a rule, then set *Type* to *Redshift* and *Source* to *Custom*. Paste `54.68.61.53/32` in the *Source* text field. 7. Click *Save rules.* Equals should now be able to access your cluster. *** [AWS RDS](/docs/aws-rds) [Azure](/docs/azure-sql-server) # Azure Source: https://docs.equals.com/docs/azure-sql-server Connect a SQL Server databased hosted on Azure Azure supports both SQL Server and MySQL databases. The instructions here are for SQL Server databases only. # Finding the server in Azure 1. Sign into the Azure dashboard and search for SQL Servers in the search box at the top. 2. Once on the list of SQL Servers (note: you want servers not databases), choose the server you want to connect to from the list. # Finding your connection details 1. Find the server in Azure (instructions above). 2. Select the database you want to connect to at the bottom of the *Overview* page. 3. The **`database name`** is the name at the top of the page, not including the part in parentheses. 4. You can find the **`host`** under *Server name* in the *Essentials* section at the top of the page. 5. The **`port`** for SQL Server on Azure is always `1433`. 6. Click *Properties* in the left hand sidebar. You can find the **`user`** under *Server admin login*. 7. The **`password`** was set when you created the database. If you do not know the password, ask the person on your team that created the database. # Allowing access from our IP 1. Find the server in Azure (instructions above) 2. Select *Networking* under *Security* in the sidebar. 3. Ensure *Public network access* is set to *Selected networks*. If you changed this setting you need to save at the bottom of the page before continuing. 4. Under the *Firewall rules* section click *Add a firewall rule* 5. Name the rule `Equals` and enter `54.68.61.53` as the start and end IP. 6. Click *Save* at the bottom of the page. Equals should now be able to connect to your database. *** [AWS Redshift](/docs/aws-redshift) [BigQuery](/docs/bigquery-connection-guide) # BigQuery Source: https://docs.equals.com/docs/bigquery-connection-guide Connect a Google BigQuery warehouse from Equals To connect BigQuery to Equals you need to create a service account with the right permissions and then upload the resulting key to Equals. The easiest way to handle permissions is to grant Equals the BigQuery Data Viewer role and the BigQuery Job User role. If you need more discrete control over permissions, you can also choose to create a custom role and set the required permissions yourself. You can follow the instructions below or watch the 2-minute video walkthrough below. [Watch on YouTube](https://www.youtube.com/watch?v=oVCHXqBChHs) # Using predefined roles Predefined roles cover all required roles for Equals to work with BigQuery. ## Create a service account 1. In the top nav search type *Service accounts* and choose *Service accounts* under *Products & Pages*. 2. Click *Create Service Account* give your account a name like *Equals* and click *Create and Continue*. 3. Add role **`BigQuery Job User`**. 4. If you would like to grant access to all datasets, add role BigQuery Data Viewer. Otherwise, you can grant this role to the individual datasets you want to grant access to later. 5. Once you’ve added the appropriate roles, click *Continue*. ## Create Private Key 1. Select your service account you just created from the *Service accounts* list page. 2. Click *Keys* in the tab bar at the top, click *Add key* and then *Create new key*. 3. Select *JSON* in the modal and then click *Create* 4. A JSON file will be downloaded to your computer. Upload this file as the Private Key in Equals. Equals should now be able to connect to your BigQuery instance. # Using custom roles Custom roles give you more control over what Equals has access to. ## Create a custom role You need to create a custom role to grant a service account permissions to view your schema tables. We need access to these schema tables for querying in Equals to work. 1. In the top nav search type *roles* and choose *Roles* under *Products & Pages*. 2. Click *Create role* in the top nav 3. Name the custom role 4. Click on *Add permissions* 5. In the modal, search and add the following permissions: 1. If you plan to restrict access to specific datasets, add this permission. 1. `bigquery.jobs.create` Enables Equals to execute SQL queries against a BigQuery dataset or table. This is required at the service account level. 2. Follow instructions under the restricting access section to create a separate role that you can apply to specific tables and datasets in your project. ii. If you plan to give access to all datasets in your project, add the rest of these permissions at the service account level. 3. `bigquery.datasets.get` Enables Equals to see a dataset 4. `bigquery.tables.get` Enables Equals to see a table 5. `bigquery.tables.list` Enables Equals to get the tables on a dataset 6. Click *Create* ## Create a service account 1. In the top nav search type *Service accounts* and choose *Service accounts* under *Products & Pages*. 2. Click *Create Service Account* give your account a name like Equals and click *Create and Continue*. 3. You need to grant the service account access to the custom role you just created. 4. Once you’ve added the custom role, click *Continue*. ## Create a private key 1. Select your service account you just created from the *Service accounts* list page. 2. Click *Keys* in the tab bar at the top, click *Add key* and then *Create new key*. 3. Select *JSON* in the modal and then click *Create* 4. A JSON file will be downloaded to your computer. Upload this file as the Private Key in Equals. Equals should now be able to connect to your BigQuery instance. # Restricting access ## Specific datasets If you need to restrict access to specific datasets in your project, you can either: 1. Assign the pre-defined role you created to each dataset you want Equals to have access to. 2. Create a new custom role with these permissions and then assign it to each dataset you want Equals to have access to. 1. `bigquery.datasets.get` 2. `bigquery.tables.get` 3. `bigquery.tables.list` ## Tables in an allowed dataset If you need to restrict access to specific tables within a dataset, you’ll need to create two custom roles. The first role should include these permissions: 1. `bigquery.datasets.get` 2. `bigquery.tables.get` 3. `bigquery.tables.list` Assign this role to the dataset your table is in. The second role should include these permissions: 1. `bigquery.tables.getData` Assign this role to the tables you want to give Equals access to. # External tables If your project is using external tables, you’ll need to add these permissions. 1. If you’re using Pre-defined roles, add the **`BigQuery Connection User`** role to your service account. 2. If you’re using custom roles, add the `bigquery.connections.user` permission to your role. # Permissions errors ## Equals needs the `bigquery.jobs.create` permission The service account must have the `bigquery.jobs.create` permission to work. You have to apply this to the service account level. If you’re using Pre-defined roles the easiest way to do this is to give the service account the BigQuery Job User role. You’ll find the guide under Using Pre-defined Roles. If you’re using Custom Roles, make sure this permission is included in the Custom Role you’re using for the service account. You’ll find the guide under Using Custom Roles. ## Equals needs the `bigquery.connections.user` permission The service account must have the `bigquery.connections.user` permission to work. You have to apply this to the service account level. If you’re using Pre-defined roles the easiest way to do this is to give the service account the BigQuery Connection User role. You’ll find the guide under Using Pre-defined Roles. If you’re using Custom Roles, make sure this permission is included in the Custom Role you’re using for the service account. You’ll find the guide under Using Custom Roles. ## Equals doesn’t have access to any dataset in BigQuery This is likely due to an improper set up of permissions in BigQuery. Check the following: 1. Make sure your role has the `bigquery.jobs.create` permission at the service account level. 2. Make sure the other required permissions are set at either the service account level, or for specific datasets and tables if you’re restricting access. ## Missing dataset permission We have access to 1 or more datasets, but we don’t have adequate permissions on some or all datasets to generate schema. Check the following: 1. Make sure your role has the `bigquery.jobs.create` permissions at the service account level. 2. Make sure the other required permissions are set for all datasets you want us to have access to. *** [Azure](/docs/azure-sql-server) [DigitalOcean](/docs/digitalocean) # Building and sharing analyses Source: https://docs.equals.com/docs/building-and-sharing-analyses Create robust analyses that drive action with auto-distributed dashboards. It’s now time to dive into how to build an analysis. Remember, we’ll create separate and distinct tabs for it–our `Analysis tabs`. The most common type of analysis is a time-series analysis. Meaning, you’re evaluating some set of metrics over a time period. You might evaluate complementary metrics, visualize your data, or build a forecast or extrapolation. Here's Bobby one more time with what to expect to learn in this section of the guide. [Watch on YouTube](https://www.youtube.com/watch?v=X7iJDpoD6Gg) Before we jump into how to build a time-series analysis, you need to learn one simple formula. It will unlock and change how you use a spreadsheet forever–this is not an overstatement. # The MOST important function to know `SUMIFS` is the single most important and powerful function in a spreadsheet. It will unlock nearly any analysis for you. It’s a secret that most advanced spreadsheet-ers know about. Once you understand how to use it, you’ll clearly understand why we architected our `Data tabs` the way we did. ## How `SUMIFS` works `SUMIFS` works just like it sounds. It *SUMS* across a range *IF* certain criteria are met. It takes 3 arguments: 1. The range across which you want it to sum, known as the `sum_range` 2. The range across which you want it to check for the criteria, known as the `criteria_range` 3. The `criterion` for which you want it to check Putting it all together, we get`=SUMIFS( sum_range , criteria_range , criterion )`. This would return the sum of the `sum_range` when the row in the `criteria_range` matches the `criterion`. You can add as many `criteria_range` and `criterion` arguments as you’d like. It’s infinitely extensible. For example: `=SUMIFS( sum_range_1, criteria_range_1, criterion_1, criteria_range_2, criterion_2, criteria_range3, criterion_3…)` ## An example using `SUMIFS` Using a sample of our country revenue data introduced in the previous section, let’s imagine we want to calculate the total revenue owned by Sally Sales, the VP of Sales. This is easy using the `SUMIFS`: 1. We want the function to return a sum of revenue so our `sum_range` must reference column C because that’s where our revenue data lives. 2. Our criterion is “Sally Sales”, so our `criteria_range` needs to reference column D since that’s where we’ll check to see if the revenue being summed is owned by Sally Sales. Putting it together, our function then looks like, `=SUMIFS(C:C, D:D, "Sally Sales")`. That's simple, but let's explain how it works one level deeper. Imagine you are the spreadsheet. Evaluating this function would look something like the screenshot below, where you’re only summing the revenue values highlighted in column C (the `sum_range`) because the owner of that revenue (column D, the `criterion_range`) matches our `criterion`, *Sally Sales*. The returning value here is `$15,070 = $1,332 + $3,847 + $4,796 + $1,874 + $1,030 + $2,191`. Now let’s say we wanted to drill down further and only sum for revenue owned by *Sally Sales* in the *US*. To do so, we add another `criteria_range` and `criterion` to our original function: `=SUMIFS(C:C, D:D, "Sally Sales", B:B, “US”)` Which then evaluates as follows: `$7,912 = $3,847 + $1,874 + $2,191`. That’s the total revenue owned by Sally Sales in the US. We could extend our `SUMIFS` function yet again, and as many times as we’d like. Imagine we wanted to drill down and look at Sally Sales' total revenue in the US in January. You can imagine how we’d do that, although we’ll show you a trick to make date-parsing 10x easier in the next section. Now that you understand the fundamentals of how the `SUMIFS` function works, you see that we’ve architected our `Data tab` to make it easy to use it. # Advanced uses of `SUMIFS` and other related functions As you experiment and familiarize yourself with `SUMIFS` here are some deeper details to know: * In each example shown, the `criterion` has been a manual value. For example, “US” or “Sally Sales.” It does not have to be a manual value. Best practice is to never manually hard code values into your formulas. It can take a cell reference and use whatever the value of that cell reference is to evaluate. * `COUNTIFS` is another powerful function that takes the same arguments but returns a count of matching cells instead of the sum of values in the referenced range. You might use this if the range you are referencing is not a number but something like customer name. You can’t sum customer names, so you might be looking to count them. * Another fun one that doesn’t exist in Excel but is useful in Equals is the `COUNTUNIQUEIFS`function. It works just like `COUNTIFS()` but only counts unique values. For example, you could imagine using this to count the number of unique customers in a data set. * `SUMIF()` and `COUNTIF()` are other versions of the `SUMIFS` and `COUNTIFS` functions. They work the same way, but stupidly they reverse the arguments and only take one `criteria_range` and `criterion`, hence why they're not pluralized. For example, `=SUMIF(criteria_range, criterion, sum_range)`. Thanks, Excel, for making this confusing. 🙃 * `Criterion` can also be something conditional. So you can ask it to evaluate if it’s a match *and* if the value is greater than or less than a certain value. From the example above, let’s say we wanted to sum revenue in the US owned by Sally Sales in months that generated more than \$2,000. We’ll add another condition that looks like this: `=SUMIFS(C:C, D:D, "Sally Sales", B:B, “US”, C:C, “>2000”)`. # Working with dates It can be frustrating and tricky to work with dates in a spreadsheet. Formulas get complex and convoluted quickly, and date parsing is one of the most common areas of mistakes. Best practice is to keep things simple and modular. Now that we understand the `SUMIFS` function, we have some simple tools we can use to make working with dates easier. Let’s imagine from our example that we wanted to summarize revenue from our `Data tab` by month. We'll create a simple table like this in a new `Analysis tab`. We'll use the `SUMIFS` to return the total amount of revenue for each month. The `SUMIFS` function evaluates based on the referenced data in the`Data tab` like this: ## Modularize dates for more robust analyses That works. However, it's dangerous because it’s not very robust. Why? We’ve set everything to be conditional on an exact date–the first of every month. The problem with that is if our dataset referenced in the `Data tab` changes or if new rows get added where `Date` does not exactly adhere to the first of every month (a common issue here is a timestamp might return that’s not the exact same hour and second), our `SUMIFS`function will evaluate incorrectly. Best practice is to modularize our dates, and doing so is simple. To do this, we’ll expand our `Data tab` to extract month, year, and day as separate columns using some standard functions. We’ll use the `MONTH`, `YEAR`, and `DAY` functions. Each takes one cell reference as an input (a date) and then returns an integer representing the month, year, or day. Remember, if you're using Equals, these can be added alongside your live data set as [calculated columns](https://docs.equals.com/docs/calculated-columns) so they auto-expand as your data set expands. Now that we have the month, year, and day returned in three respective columns in our `Data tab` we can go back to our the summary table in our `Analysis tab`and make it more robust. We’ll do this by modifying our `SUMIFS` function to reference column F as the `criteria_range` for the month and column G as the `criteria_range` for the year. In this case, we don’t need to worry about the day because our analysis sums revenue by month. Now we know that no matter what format the date returns in the `Data tab`whether it’s the first of the month, end of the month, or a specific timestamp with hours and seconds, our `SUMIFS` function will evaluate correctly. That’s the most powerful way to ensure that dates don’t break your analysis. Now, for a couple of other simple things to make working with dates easier and build deeper analyses. ## Using functions to calculate specific dates Days and weeks are pretty simple to navigate. You can always `+1` or `+7` to a date and get the daily or weekly interval. Monthly intervals are trickier because they’re not consistent. But it’s often the most common way we look at analysis. There are two functions to make this easier. ### `EDATE` This function adds or subtracts a specific number of months from a date. To do so, change the second argument to the interval you want calculated. ### `EOMONTH` This function takes a date and returns the last day of the month within a given interval. So if we want the last day of any given month, it’s just `=EOMONTH(reference, 0)`. We can increment the `0` here to get the last day of the month for any increment of months beyond the referenced cell. # Locking rows and columns Using the spreadsheet's locking mechanism is one of the most powerful ways to build formulas and functions that scale as your dataset expands. By default, when you copy (or drag) a formula or function from one cell to another, references update, which can break your analysis. For example, if I were to copy the formula in cell `A2` below across, `B2` would reference `B1`, and `C2` would reference `C1` as you’d expect. However, there might be instances where we don’t want certain references in the formula to change and instead remain fixed. For example, let’s say we wanted to build a simple multiplication table that showed the product of a row and a column, i.e., across row 3: 1x1, 1x2, 1x3... You can see how copying that formula across the table won’t work. We wouldn’t get the product of the rows and columns; we’d get the product of the adjacent cells. This is **not** what we want. Instead of manually creating a formula for every calculated cell in the table, because copy/paste here doesn’t work, spreadsheets have a neat trick. You can lock references by placing a `$` next to the referenced column or row number you want to lock in the formula. Placing a `$` next to *both* the column letter and row number will lock to that exact cell, e.g., `$C$5`. Let’s say we wanted to make our formula in cell `B3` easily able to be copied across adjacent cells in row 3, we’d want to lock the reference to cell `A3` as follows. We’re only locking column A here because we’ll also want to copy this formula down later and change the row referenced. You’ll see now, as we drag our formula across row 3, `$A3` remains reference correctly. To complete filling our multiplication table, we must modify the reference to row 2 in this calculation. We want to lock row 2 like this: Now, this formula can be dragged across *and* down our table. There you go; you’ve written one formula that will work for all 25 cells in the table and is infinitely extensible if we want to make the multiplication table bigger. Finally, let’s say we wanted to multiply every value in the table by the same number – 10. To do so, instead of modifying the formula in every calculated cell, we'll create a new reference cell (i.e., a global filter) to add to our existing formula. And we’ll lock that new reference cell's rows and columns (i.e., `$D$1`), so every calculated cell in our multiplication table is multiplied by the same amount–`10` in the example below). We can copy one formula across our table, and all the references and results are correct. Again, this scales infinitely as you expand your multiplication table. Knowing how to lock rows and columns becomes handy as we build an analysis. # Setting up an Analysis tab This section will cover how to build a time series analysis. We’ll examine a set of metrics and compare them over time. Now that we understand the `SUMIFS` function and date parsing we can put together our analysis. As you can imagine, we’re going to rely heavily on `SUMIFS`. We’re going to architect our `Analysis tab` so that our formulas are robust, scalable, and reusable. The best practice for time series analysis is to set columns to represent the date period and rows to represent the dimensions. Depending on what you’re analysing and its purpose, you might choose to group certain dimensions together. For instance, from our revenue example earlier, if we were building an analysis that wanted to look into the performance of each VP of Sales, we’d probably organize things this way: Alternatively, if we were building an analysis to understand whether there are different patterns in sales by region instead of by the owner, we’d probably want to group our regions together. You’ll note that we’ve used the dimension names that match *exactly* how they appear on our `Data tab`. This will allow us to use the same `SUMIFS` function across our entire summary table. This means we only have to write *one* formula that can be used to calculate all of the highlighted cells below. Once we create the formula, it’s a simple copy and paste (or drag across and down). Similarly, that formula will continue to work as we expand our analysis over time, especially given we’ve locked our references appropriately using `$`. You’ll see this use of`SUMIFS` looks to sum column C (`Revenue`) in our `Data tab` when column B matches column B in our `Analysis tab`, and when the month and year in row 2 match the months and year columns (columns F and G) in our `Data tab`. From here, we can copy and paste (or drag) this formula across our entire table and a few simple `SUM` formulas to total revenue by region by month (i.e., rows 6, 10, and 14). You’ll see the formula in cell `C13` is the exact same as the original formula we entered in cell `C3`. Only the cell reference for the country (`$B13` vs. `$B3`) have been updated as we dragged the formula down the table. This is what we want, as it means the formula is correctly referencing the respective rows from our `Data tab` i.e., revenue from *Japan* instead of revenue from the `US` in *January 2021*. # Working with dynamic ranges Dynamic ranges are a powerful way to set up analysis so you don’t have to constantly rework a workbook to show you what you need. Because we set up our summary table as shown in the previous section to calculate from our dimensions and headers, we can use those to calculate the contents of our table as the dimensions and headers change over time. To do this, we'll use the `EDATE` function in our headers to make our time series analysis dynamic based on the date we want to start. Below, our summary tables start in January 2021 and show revenue by region for the next two months. If we modify cell `C2`, because the rest of our headers in row 2 use the `EDATE` function, the rest of the table automatically updates based on cell `C2`: If you want the table to always reflect the most recent 3 months, you can use the `TODAY` and `EDATE` function together. So in cell `C2` above, you could write `=EDATE(today(), -3)` and that would return the date 3 months ago from today. ## Using global filters If we wanted the table to show revenue figures for a specific VP of Sales dynamically, we must move our table down one row and put an input value in `C1`. We will also need to add that `criteria_range` and `criterion` to our `SUMIFS` function. Now you’ll see our table automatically update as we input the name of a specific VP of Sales into the global filter (cell `C1`). Remember, this is taking advantage of the `Input tab` we created in the previous section, which houses the names of all the VPs of sales and the regions they own. Dynamic ranges are a powerful way to set up analysis so you don’t have to constantly rework a workbook to show you what you need. For example, looking at six months of historicals might always be useful–no more. Create 6 columns and update the date fields across the columns; don’t continue to drag out the analysis and hide data. ### Auto-expanding summary tables Equals has a nifty feature called [Auto-expand](https://docs.equals.com/docs/auto-expand) that enables tables, charts, and pivot tables to automatically update with each query run. This is useful for ensuring that analyses are up-to-date without the need to manually copy and paste data or expand ranges on charts and pivots. # Sharing analyses Now that you've built an analysis that uncovers some meaningful insights, it's time to consider how to share them. Most companies' current state of analyses looks like this: A fancy new analysis is created, but it lives in yet another silo. No one logs into the BI tool to check what's changed, which takes forever to load. Ultimately, the analysis does not drive meaningful decisions and has no real impact. How do you avoid this? If you want your insights to drive accountability and action, you must ensure that they are presented clearly, accessed easily, and regularly updated. This is where [dashboards](https://docs.equals.com/docs/dashboards) can help. ## Building a dashboard Your analysis likely includes a lot of exploration and detail. But when it comes to thoughtfully presenting the insights, you need to take an editorial eye. That means crafting the business narrative to align with your audience's interests and areas of influence. What do your stakeholders care most about, and what are they focused on contributing to the business? Present only the tables, charts, and metrics from your analysis that tell a clear story without overwhelming the audience. Organize these elements in a logical order that guides stakeholders through your findings. Focus on only the most relevant views given their respective roles and responsibilities. ### Instantly turn spreadsheets into dashboards Every Equals workbook has an [embedded dashboard](https://equals.com/dashboards/). Building one is as simple as creating a doc–complete with tables, charts, cells, and AI-generated summaries. ## Distributing dashboards The key here is to create fast feedback loops. Launch something on Product Hunt? Introduce a new page into the onboarding flow? It's crucial to proactively check early indicators of impact so that the business can catch issues and capitalize on opportunities. Speed is a startup's competitive advantage, and it's your job to maximize speed to insight so the business can respond faster. That means: * **Deliver dashboards\_where\_ stakeholders are.** Push reports directly to your stakeholders where they are already working, including Slack and email. Embed them directly, no downloads or logins required. The more accessible your dashboards are, the greater the likelihood of engagement and timely action. * **Deliver dashboards\_when\_ stakeholders need them.** Schedule your dashboards to deliver at a regular cadence that matches the business's metabolism, whether hourly, daily, weekly or monthly. Create a culture of transparency and accountability by driving regular check-ins, highlighting what's changed, and assigning owners to chase down root causes and potential solutions. ### Report on autopilot In Equals, use the [dashboard scheduler](https://docs.equals.com/docs/send-dashboards-to-email-and-slack) to auto-distribute reports to either email or Slack on a custom schedule–hourly, daily, weekly, or monthly. Here's Bobby with a quick demo of how easy it is to build and automatically distribute a dashboard to stakeholders in Equals. [Watch on YouTube](https://www.youtube.com/watch?v=AoM3w6atVwQ) ### In Summary: * **Time-Series** is the most common type of of analysis. Use it to evaluate metrics over time, visualize data, and build forecasts. * **SUMIFS** is the most important and powerful function to learn for building robust analyses. It sums data based on multiple criteria and is the key to unlocking advanced analysis techniques. * Modularize dates using the **MONTH**, **YEAR**, **DAY**, **EDATE**, and **EOMONTH** functions to build scaleable analyses that don't break. * Utilize **\$** to lock references in formulas, so you only have to write a formula once, enabling scalable and reusable spreadsheet setups. * Present your insights using **dashboards** that are auto-distributed on a schdule to stakeholders in Slack or email, increasing visibility and encouraging timely decision-making. And that's a wrap. Now you know how to spreadsheet! 🎉 Please share this guide with your colleagues and peers if you found it useful. If anything didn't make sense or there are areas you'd like us to explore further, please let us know by sending us a message using the messenger in the bottom right of your screen. For now, happy spreadsheet-ing. *** What’s Next * [Learn more about Equals](https://equals.com) * [Visit our blog](https://wrap-text.equals.com/) # Calculated columns Source: https://docs.equals.com/docs/calculated-columns Attach columns to your queried data that expand with each query run Calculated columns are columns adjacent to queried output that contain a formula. This formula applies to the entire column and automatically expands and contracts as the data returned from a query changes. Calculated columns are useful for extracting details from your queried data that make summary tables easy to create. For example, using a calculated column to categorize dates into quarters (Q1, Q2, Q3...) or months into numbers (1, 2, 3...) will make it simple to set up a summary table that uses `SUMIFS` formulas. ## Enabling calculated columns Calculated columns are enabled by default, meaning that a new calculated column as added next to your output data when you run a query. To turn off this setting, go to *Settings > Personal*. When toggled off, a calculated column is not added by default, but you can always manually add one as well as notes columns. ## Adding calculated columns To add a calculated column or note column from the query builder, select `+ Add column`. You can also add calculated columns by right-clicking a column header in your connected sheet and choosing *Add calculated column*. Once added, calculated columns can be reordered directly from the query builder by dragging and dropping. From there, populate your calculated column by entering a formula into a cell beneath the header value. After hitting `Enter`, the formula will automatically expand to fill the column. # FAQ ### Can I create multiple calculated columns? To add another calculated column, it must be immediately adjacent to the last calculated column. ### How can I delete a calculated column? If you delete the formula in any of the cells of a calculated column, the light green shading will persist but the calculation will be removed. Right clicking on the column header will allow you to delete the calculated column. *** [Date matching formulas](/docs/date-matching-formulas) [Auto-expand](/docs/auto-expand) # Cell references Source: https://docs.equals.com/docs/cell-references Modify a SQL query by inputting values in your workbook Cell references allow you to modify a value in a SQL query by simply typing into the referenced cell in your workbook. This enables anyone with edit access to your workbook to modify specific values in your SQL queries, without the need to open up access to your query or create multiple versions of the same query. You can set up cell references to toggle values like dates, products, locations, plan type, and more. To get started, set up a live datasource [connection to a workbook](https://docs.equals.com/docs/building-queries-copy#connecting-to-a-datasource). Once you have a connection set up, you can refer to cells in your workbook to filter your queries by inputting values into those cells. Note: to use this functionality, you must write your query using the SQL editor. To get started: 1. Use the SQL editor to write a query that pulls data from a connected datasource. 2. Set up the condition in your SQL query that you want to use with a cell reference. 3. Click on "Insert Cell" in the SQL editor toolbar to insert a cell reference in your query. 4. Select the cell in your workbook to reference (in this case, cell `A1`). Type a value to filter your query on into the referenced cell and click *Run Query*. *** [Joins](/docs/joins) [Schema refreshes](/docs/schema-refreshes) # Charts Source: https://docs.equals.com/docs/charts Create professional and modern visualizations of your data With Equals, it's easy to create professional and modern-looking charts that can be shared individually or via a Dashboard. You can create the following chart types: * Line * Combo * Scatter * Area, stacked area, and 100% stacked area * Column, stacked column, and 100% stacked column * Bar, stacked bar, and 100% stacked bar * Pie # Creating charts To get started, select your date range, then go to `Insert > Chart` or use the shortcut `CMD`+`K` and type `Insert chart`. This will insert a default chart into your workbook and open the chart configuration panel. Charts have the following defaults for a clean look: * The title and legend are left-aligned * Y-axis labels but no line * Horizontal gridlines only * No data labels are displayed on series * 'Professional' style (more on styles here) You can modify these defaults and other settings, including: * **Type**: Select either Line, Scatter, Combo, Area, Column, Bar, or Pie. Stacked and 100% stacked variations are available for Area, Column, and Bar charts. * **X-axis**: Set a specific metric for your X-axis, which will define the data point intervals. * **Series Selection**: Click on the series from to edit how they are displayed in your chart. # Customizing Charts You can configure the look and feel of each aspect of your chart to suit specific use cases. There are 5 aspects of your chart that you can configure: 1. Chart 2. Series 3. X-axis 4. Left Y-axis 5. Right Y-axis ## Chart Here, you can configure your chart's style, colors, legend, and title. ### Styles First, choose from one of the two available *styles*: * **Modern**: A bold look and feel with rounded edges, smoothed lines, and grey axes. * **Professional**: A classic look with straight edges and lines, tick marks, and black axes. ### Colors Next, choose a *color scheme* for your chart. The options will vary based on your selected chart style: * **Bright** or **Cool** colors (Modern style) * **Business** or **Basic** (Professional style) * **Purple** or **Stone** for a monochromatic look (both styles) Once a color scheme has been applied to a chart, you can change the color of individual series from a set of defaults or add your own custom colors. You can also create your own custom colors schemes that are shared across your Equals Workspace. To do so, select *Add style* from the *Color* drop down, then hit the `+` icon to add your chosen set of colors. Once saved, your custom color scheme can be applied to charts in any Workbook and used by other members of your Workspace. ### Title & Legend Add a *Title* or a *Legend* and modify their position from the sidebar. ### Grid You can also choose to apply horizontal and vertical gridlines, as applicable based on the type of your chart, for better readability. ## Series In the `Series` section, you can configure the way series' from your selected data range are displayed in your chart. You can also drag and drop series to re-order them. To get started, click on a specific series to configure. * If a specific series has been selected, give it a *Name* that will be displayed in the chart's legend. * Select a *Color*. This will be set based on the chosen color scheme but can be modified to be any color. * Choose which *Axis* to chart your series on–the Left or Right Y-axis. * Add a *Trendline* for your chart series and choose from several mathematical models, including Linear, Logarithmic, Exponential, and Moving average * Decide whether to display *Labels* for each data point in your series and configure their format and positioning. ## Axes You can configure the appearance of each axis in your chart, including the X-axis, Left Y-axis, and Right Y-axis. In each section you can: * Add a *Title* for each axis * Choose to show show a *Line, Tick marks*, and/or *Labels* * Define the angle at which data labels will be displayed under *Slant label* * Normalize the way data is displayed by selecting *Log scale* or a specific *Scaling option*. You can also use *Limit* to define min/max values. # Updating charts If your chart is built on live data from an underlying [query](https://docs.equals.com/docs/queries), you can enable [auto-expand](https://docs.equals.com/docs/auto-expand) on the chart's data range to automatically refresh it each time the query is run. This will ensure that your charts are up-to-date without the need to manually copy and paste data or expand data ranges. To manually update your chart, you can manually insert data into the chart's selected data range. You can also adjust your data range to reflect new rows of data in your Workbook by selecting `Edit` in the top right corner of the chart, and then editing the `Data range` input. # Sharing charts There are a few options for sharing and distributing charts: * Add your chart to a [Dashboard](https://docs.equals.com/docs/building-and-sharing-dashboards) that can be auto-distributed to your team via Slack or email on a set schedule. * Download individual charts as a .PNG file by right-clicking and selecting *Download chart*. *** [Pivot tables](/docs/pivot-tables) [Filters and sorts](/docs/filters-and-sorts) # Command bar Source: https://docs.equals.com/docs/command-bar Save time by accessing all spreadsheet functions from your keyboard Equals has a built-in command bar to access any command *and* [AI Assist](https://docs.equals.com/docs/ai-assist) with a single keyboard shortcut. For a quick demo of the command bar and AI Assist in action, watch the video below. [Watch on YouTube](https://www.youtube.com/watch?v=9oX1y2JwR84) To use the command bar: 1. Press `Command` + `K` (`Control` + `K` if you use Windows) to open the command bar. 2. Type in any command, like "insert chart". You can also use auto-complete to discover new commands. 3. To access [AI Assist](https://help.equals.com/en/articles/7941959-ai-assist), select one of the three initial options: "write formula", "start chat", "generate sheet". # FAQ ### What can I do with the command bar in Equals? Access any functionality available in Equals from the command bar. From formatting changes, to inserting charts, to opening up a chat with AI Assist, or refreshing your queries, access anything without using your mouse (or memorizing shortcuts). ### Can I use keyboard shortcuts in Equals? Yes! The command bar is great for users who might not know all the spreadsheet shortcuts. If you already know the shortcuts, you can use them (and ALT mode) in Equals. ### Can I disable AI Assist if I don't want to use it? You can disable AI Assist for your workspace by navigating to the *Settings* page in Equals and clicking on the AI toggle. *** [Auto-expand](/docs/auto-expand) [AI Assist](/docs/ai-assist) # SQL Database Overview Source: https://docs.equals.com/docs/connecting-sql-databases-to-equals Learn how to find your SQL database connection details and grant Equals access from our IP address To connect to a SQL database within Equals, you'll first need to find your connection details and then grant access to your hosting provider from our IP address. ## Finding connection details To find the connection details for your SQL database, follow the specific setup guide for your hosting provider: **Datasources:** [Supabase](https://docs.equals.com/docs/supabase) [AWS RDS](https://docs.equals.com/docs/aws-rds), [Azure](https://docs.equals.com/docs/azure-sql-server), [BigQuery](https://docs.equals.com/docs/bigquery-connection-guide), [DigitalOcean](https://docs.equals.com/docs/digitalocean), [Railway](https://docs.equals.com/docs/railway), [AWS Redshift](https://docs.equals.com/docs/aws-redshift), [PlanetScale](https://docs.equals.com/docs/planetscale), [Snowflake](https://docs.equals.com/docs/snowflake), If your hosting provider is not listed above, below is an explainer of each field. | Field name | Description | | - | - | | Connection name | This is what your datasource will be listed as throughout Equals. | | Share with workspace | Give access to this datasource to all current and future members of your workspace. | | Host | An IP address or hostname by which we can connect to your database. | | Port | The port your database server is listening on. | | Database name | The name of the database we should connect to on the provided host. | | Username | The username to connect with. | | Password | The password to connect with. | | Default schema | (Postgres only, optional) Set the default schema for the connection. | | SSH Tunnel | Optionally you can connect through an SSH tunnel. | | SSH Username | The username to connect as on the host. | | SSH Private Key | The SSH Private Key we should connect with. | ## Allowing access from our IP When connecting to SQL databases (except for BigQuery) we will always connect from the IP address `54.68.61.53`. Some providers and set ups likely require granting access on a per-IP basis. Use the following guides to learn how: **Datasources:** [AWS RDS](https://docs.equals.com/docs/aws-rds), [Azure](https://docs.equals.com/docs/azure-sql-server), [DigitalOcean](https://docs.equals.com/docs/digitalocean), [AWS Redshift](https://docs.equals.com/docs/aws-redshift), [Snowflake](https://docs.equals.com/docs/snowflake) If your provider is not listed above follow your hosting provider's instructions for allowing connections from `54.68.61.53`. For MySQL, Postgres, and Redshift connections you may also connect through an SSH tunnel. *** [Data syncing overview](/docs/data-syncing-overview) [AWS RDS](/docs/aws-rds) # Create and edit dashboards Source: https://docs.equals.com/docs/create-and-edit-dashboards Build live dashboards with charts, tables, cells, AI Summaries and more Building a dashboard in Equals is as easy as creating a doc. To get started, navigate to the `Dashboard` tab in the bottom-left of your Equals workbook. You can add any chart, table (range of cells), or individual cell in your workbook to your dashboard. You can also add text headings, paragraphs, and auto-generated AI Summaries of selected tables and charts. ### Create and edit access Only worksace members with `Can edit` access to the workbook can create and edit its dashboard. See [Manage dashboard access and permissions](https://docs.equals.com/docs/manage-dashboard-access-and-permissions) for more information. # How to add objects to a dashboard There are two ways to add objects to your dashboard: ## Toolbar Like a Word or Google Doc, your dashboard has a toolbar at the top showing all the objects you can add. ## Inline Menu When you hover between objects on your dashboard, you'll see a `+` icon appears. Clicking this provides quick access to an inline menu for adding additional objects to your dashboard. # Moving objects on a dashboard Click, hold, and drag an object to move it into a different position on your dashboard. A purple bar will appear, indicating where you move the object to. # Adding and editing charts, tables, cells, AI Summaries, and text From the toolbar or inline menu, you can add any chart, table (range of cells), or individual cell in the workbook to its dashboard. Complement your data visualizations with editable text headings, paragraphs, and auto-generated AI Summaries of selected tables and charts. ### Refreshing data on dashboards Charts, tables, and cells will automatically refresh when the underlying data is updated–either manually or [automatically via a query](https://docs.equals.com/docs/query-scheduling). AI Summaries will automatically regenrate when the data in selected charts and tables are updated. They can also be manually re-generated via their `Options` menu. ## Charts You can add any chart from the same workbook to your dashboard. Just select one or more charts from your workbook and click `Save`. Embedded charts are live, meaning they will auto-update when the underlying data is updated. You can hover over charts to see specific data points. To make changes to a chart (e.g., type, style, etc.), right-click and select `Go to source`. From the right-click menu, you can also download or copy an image of the chart to your clipboard or delete the chart. ## Tables Add any range of cells to your dashboard by clicking `Table` in the toolbar or inline menu. You'll be taken to the last sheet you were on to select a range of cells to add. Existing tables are automatically identified on hover. You can click and drag to select any range of cells, too. Once added to your dashboard, you can manage the appearance of a table from its`Options` menu. There are numerous formatting options available to allow you to style them to suit the presented data best, including: * Add a header row and/or column to bold its contents, add a light background, and keep it fixed on scroll * Choose to alternate shading on rows and/or columns to improve the legibility of large tables * Hide grids for a cleaner appearance * Preserve the original formatting of the selected range of cells. If enabled, you will only have the option to enable a header column. All other formatting options will be disabled. Like charts, right-click to `Go to source` or `Delete` the table from the dashboard. ## Cells You can add any number of individual cells to your dashboard. This is particularly useful for highlighting top-level metrics and KPIs. Like adding a table, you'll be taken to the last sheet you were on to select a cell to add. Once added, you give the cell a title and choose to inherit or customize the format from the cell's source data. You can also abbreviate values, useful when reporting on revenue or KPIs with many insignificant integers. Enable `Show comparison` to select another cell in the workbook to compare against in relative or absolute terms. This is particularly handy when you're reporting on KPIs over different periods. ## AI Summaries Add AI Summaries for auto-generated analyses of selected tables and charts on your dashboard. First, select the tables and charts you want to generate an AI Summary–you can select more than one if you like. By default, a medium-length summary will be generated. You can change the length and provide custom instructions from the AI Summary's `Options` menu. AI Summaries are automatically regenerated when data in selected tables or charts are refreshed. You can also manually regenerate them at any time. ## Headings and Paragraphs Text headings (H1 and H2) and paragraphs can be added anywhere on a dashboard. Paragraph text can be formatted using Markdown, and cells in the workbook can be referenced in both paragraphs and headings. See [Format text and reference cells](https://docs.equals.com/docs/format-text-and-reference-cells-in-paragraphs) for more details. ### Spacers Add height-adjustable spacers to delineate sections and aid flow throughout a dashboard. # Resizing objects on a dashboard After selecting an object, click and hold any of the handles that appear to adjust the width or height. A dynamic size indicator will help you ensure objects are the exact size you want. Height and width measurements are calculated based on the number of dots on the underlying grid that appears when a dashboard is being edited. Note that resizing a chart or tables will not modify the size of the original chart or table in your workbook. ## Resizing charts You can adjust both the height and width of charts. ## Resizing tables, cells, AI Summaries, and paragraphs You can adjust the width of tables, cells, AI Summaries, and paragraphs. With tables, the column width ratios of the original table are maintained. To reduce the actual width of columns, you will need to resize the columns in the selected data range. ## Resizing spacers Spacers can only have their height adjusted. *** What’s Next * [Dashboard filters](/docs/dashboard-filters) * [Manage dashboard access and permissions](/docs/manage-dashboard-access-and-permissions) # Create views Source: https://docs.equals.com/docs/create-views Views are analysis-ready tables you can create, reuse, modify, and query from any workbook leveraging simple SQL queries. Views can only be created for data sources that **Equals Warehouse** supports. **How to create a view:** 1. Go to the Views section in the workspace homepage 2. Click New View in the top-right corner (image below) 3. Select a data source that has already been configured for your workspace 4. Write out your view in the View Editor popup window 5. Click Create View Screenshot2026 03 11at4 07 07PM **Creating dependencies between views:** * Follow the same steps outlined above to create a new view. * When writing your query, reference the table name of another view just as you would any other table in your schema. You can also use the Table Browser to locate and reference the view you want to use. * At any point while building your view, select Preview to validate the output. *(Note: you must preview the view at least once before saving.)* * Once everything looks correct, select Save and Rebuild to save your changes. * After the dependent view syncs, it will appear in the “Used By…” section of the referenced view. You can find this in the view details panel on the left side of the view editor as shown below. Screenshot2026 03 11at4 05 05PM **Joining Views:** Aside from dependencies, it’s also possible to join two separate Views together by inserting that logic into the view's SQL query. Since Views can only be created from datasources supported by the Equals Warehouse, they can only be joined if both Views are built from datasources supported by the Equals Warehouse. # CSV Source: https://docs.equals.com/docs/csv-files Query from a CSV file in Equals You can connect to and query any CSV file directly from your Equals workbook. 1. Head to the *Datasource* page from the Equals home screen 2. If you're yet to add a datasource, you will see a list of available datasources. Otherwise, click *New Datasource* in the top right corner. 3. Select *CSV File*, then give your datasource a name that will be used throughout Equals. 4. Upload your CSV file. 5. Select *Create datasource*. Now, you can navigate to a workbook and open the *Connections* panel to query data directly from your CSV. *** [Supabase](/docs/supabase) [Google Sheets](/docs/google-sheets) # Dashboard Edit and View modes Source: https://docs.equals.com/docs/dashboard-edit-and-view-modes A dashboard can be opened in one of two states: 1. **Edit mode:** Users with the right permissions can create and edit the dashboard and modify its settings 2. **View mode:** People with the right permissions can view the dashboard and apply filters but not edit it # Edit mode When users with `Can edit` [permission](https://dash.readme.com/project/equals/v1.0/docs/create-and-edit-dashboards) visit the `Dashboard` tab in a workbook, the dashboard will be in `Edit mode`. When in `Edit mode` users can: * [Add, modify, and remove cells, charts, tables, and text](https://docs.equals.com/docs/creating-and-editing-dashboards) * [Add and modify filters](https://docs.equals.com/docs/dashboard-filters) * [Change Dashboard settings](https://docs.equals.com/docs/dashboard-settings) * [Set up and modify scheduled sends](https://docs.equals.com/docs/send-dashboards-to-email-and-slack) * [Customize the appearance of the dashboard in View mode](https://docs.equals.com/docs/dashboard-edit-and-view-modes#customizing-view-mode) # View mode Anyone with either `Read only` or `Dashboard only` [permission in a workbook](https://docs.equals.com/docs/manage-dashboard-access-and-permissions#view-and-edit-access) can only open a dashboard in `View mode`. When in `View mode` viewers can: * [Apply dashboard filters](https://docs.equals.com/docs/dashboard-filters#applying-filters) * See when the dashboard's contents were last updated or when the least frequent [scheduled query](https://docs.equals.com/docs/query-scheduling) is set to run. What is displayed can be set by anyone with `Can edit` permission when in `Edit mode`. # Customizing View mode ### View mode URL Users with `Can edit` permission can create a cleaner looking URL for sharing in [Dashboard settings](https://docs.equals.com/docs/dashboard-settings). In `Edit mode` you can make the following customizations to the appearance of a dashboard when opened in `View mode`. ## Display a custom logo To toggle the display of a logo and select between your workspace's logo or a custom logo, click the logo on the left below the dashboard's toolbar while in `Edit mode`. ## Display a custom company name By default, the name alongside the logo is the name of your Workspace. You can change this by clicking the name to enter edit mode and typing in a new name. ## Display `Last updated` or `Schedule` Choose whether viewers see when the dashboard's contents were last updated or when the least frequent [scheduled query](https://docs.equals.com/docs/query-scheduling) is set to run. This option is available if your workbook contains at least 1 scheduled query. *** What’s Next * [Create and edit dashboards](/docs/create-and-edit-dashboards) # Dashboard filters Source: https://docs.equals.com/docs/dashboard-filters Use filters to change the data displayed in cells, charts, and tables on a dashboard # How dashboard filters work * Dashboard filters are only available in Workbooks with one or more [connected sheets](https://docs.equals.com/docs/building-queries#connecting-a-sheet-to-a-datasource). * The columns from tables queried in those connected sheets can be added as filters to the dashboard. * Cells, tables, and charts on a dashboard that use data in columns from connected sheets will update when a filter is applied on the dashboard. * To apply a dashboard filter, you need to open the dashboard in `View mode` (see [Applying filters](https://docs.equals.com/docs/dashboard-filters#applying-filters)). **Note on Date Filters:** At this stage, columns with data in a date format cannot be used as a filter. # Adding and editing filters in Edit mode ### Workbook edit permission required Only users with the [permission to edit a Workbook](https://docs.equals.com/docs/building-queries#connecting-a-sheet-to-a-datasource) can add filters to its dashboard. When editing a dashboard in a Workbook that has at least one connected sheet, click `Add filters to dashboard` beneath the dashboard's title. This will open a modal displaying all available columns from queried tables grouped by the connected sheet. Select one or more columns and click `Save` ## Renaming and adding more filters Once a filter has been added, you can rename it by clicking the filter and typing a new name into the `Filter name` field. You can add additional filters by clicking `+ Add filter`. To remove a filter, click the `x` icon next to its name. ## Combining columns into a single filter You can combine columns with the same data type from other connected sheets into a single filter. This makes it possible to apply one filter that updates all cells, charts, and tables based on the same data in multiple connected sheets. For example, if you have a `Customer ID` column on multiple connected sheets, you can add a single `Customer ID` filter to your dashboard. To do this, select an existing filter and click `+ Add column`. This will bring up the column browser, where you can select columns being queried in other connected sheets. Only one column per connected sheer can be combined into a single filter. To add or remove columns from a combined filter, select the filter and click `+ Add column` or `x`. # Applying and editing filters in View mode To apply filters, click `View` in the top-right of the dashboard. This will open the dashboard in a new tab in [View mode](https://docs.equals.com/docs/dashboard-edit-and-view-modes). From here, any filters you apply will only be visible to you. To remove a single filter, click the `x` icon next to its name. If more than one filter has been applied, you can remove all applied filters at once by clicking `Clear filters`. # Sharing a dashboard with filters applied ### Customizing a dashboard's URL You can give a dashboard a cleaner looking link fopr sharing by [editing its URL in Dashboard settings](https://docs.equals.com/docs/dashboard-settings). You can share a dashboard with specific filters already applied by doing the following: 1. Open a dashboard in `View mode`. 2. Apply one or more filters. 3. Copy the URL from your browser's toolbar. 4. Share that URL with other people. Anyone who opens the URL you share will see the dashboard in `View mode` with the same filters applied. From here, they can edit and apply filters without impacting anyone else's view. *** What’s Next * [Dashboard Edit and View modes](/docs/dashboard-edit-and-view-modes) * [Dashboard settings](/docs/dashboard-settings) # Dashboard settings Source: https://docs.equals.com/docs/dashboard-settings Customize a dashboard's URL and toggle the display of Equals branding in View mode Users with [permission to edit a Workbook](https://docs.equals.com/docs/manage-dashboard-access-and-permissions#view-and-edit-access) can edit its dashboard's settings by clicking `Dashboard settings` in the top-right of a dashboard. From here, you can: 1. Customize the URL used to open and share the dashboard in `View mode` 2. Toggle the display of Equals branding in the footer of the dashboard in `View mode` *** [Embed dashboards in Notion and more](/docs/embed-dashboards) # Overview Source: https://docs.equals.com/docs/dashboards Instantly turn spreadsheets into dashboards and auto-distribute up-to-date reports – in a few clicks Every Equals workbook has a built-in [dashboard](https://equals.com/dashboards/), making it easy to turn any analysis into a live report automatically distributed to stakeholders on a custom schedule. Learn about: * [Dashboard Edit and View modes](https://docs.equals.com/docs/dashboard-edit-and-view-modes) * [Creating and editing dashboards](/docs/create-and-edit-dashboards) * [Editing and applying dashboard filters](https://docs.equals.com/docs/dashboard-filters) * [Managing dashboard access and permissions](https://docs.equals.com/docs/manage-dashboard-access-and-permissions) * [Customizing branding and appearance for sharing](https://docs.equals.com/docs/dashboard-edit-and-view-modes#customizing-view-mode) * [Automatically sending dashboards to Slack and email](https://docs.equals.com/docs/send-dashboards-to-email-and-slack) * [Embedding dashboards in Notion and more](https://docs.equals.com/docs/embed-dashboards) # FAQ ### How much do dashboards cost? Dashboards are included in all [current paid subscriptions](https://equals.com/pricing). ### Can I have more than one dashboard in a workbook? At this stage, no. Every workbook has a single dashboard, but you can import data from one workbook into another workbook if you'd like to use that information in another dashboard. *** What’s Next * [Create and edit dashboards](/docs/create-and-edit-dashboards) # Data notes & edits Source: https://docs.equals.com/docs/data-notes-edits Make changes and add notes to queried data that persist after each query run Data edits and notes allow you to edit and add annotations to your queried data that persist after each query run and do not alter the underlying data in the datasource. # Setting a primary key To activate data notes and edits, first set a `primary table key`. This is a unique "id" column that will ensure your data notes & edits stay appended to the correct row across query refreshes. Click on the "..." in the SQL editor and select your key column from the dropdown. # Adding data edits With data edits, you can manually edit queried data. These edits will persist even after refreshing the query. To add data edits: 1. Run a query. Identify the cell that needs modification from the queried output. 2. Type into the cell that you would like to manually override. The cell will automatically turn yellow, indicating that a data edit has been added. 3. If you haven't already specified a primary key, a modal will pop up asking you to choose a column with unique ID values to append the data edit to. This will ensure the data edit is in the correct row after each query run. 4. To remove a data edit, right click on the edited cell, then select the option to `Reset` the cell back to its original value. # Adding data notes With data notes, you can add notes in the columns next to your queried data that will stay appended to the correct row even after refreshing your query. To add data notes: 1. Run a query. 2. From the query builder, select `Add column`, then select `Notes column`. This will add a new column to your queried data. 3. Type in your annotations into the new Notes column. Note: data notes will not write back to your datasource. 4. If you haven't already specified a primary key, a modal will pop up asking you to choose a column with unique ID values to append the data edit to. This will ensure the data edit is in the correct row after each query run. 5. Remove data notes by clicking on`...` button next to the column in your query builder, then select `Remove`. # FAQ ### Will data edits change the data stored in my database? Equals will never write back changes to your database, data edits will only persist in the sheet where they have been enabled. ### How do I know what to use as an identifier? In order to set up notes or edits, you'll need to specify a unique id. This unique id should be a value that does not have duplicates in the column. Equals will provide a warning if an id specified is not unique. If notes or edits are applied when using a non-unique id, that note/edit will apply to all instances where that id is present. ### Can I use data edits and notes simultaneously on the same sheet? Yes, you can use both data edits and notes simultaneously on the same sheet. By specifying a unique identifier column for both edits and notes, you can ensure that modifications and annotations persist accurately alongside the data without interference. *** [Schema refreshes](/docs/schema-refreshes) [Scheduling queries](/docs/query-scheduling) # Data Sync Overview Source: https://docs.equals.com/docs/data-syncing-overview Get an overview of supported datasources and their configuration within Equals With Equals you can connect directly to datasources to query live data from any workbook. These datasources include popular SaaS tools, SQL databases, and data warehouses. There are 2 types of datasource connections: ## Equals Warehouse When multiple supported datasources are connected to your workspace, they're automatically synced to your own Equals Warehouse (powered by Snowflake). This allows you to easily join, transform, and query raw data directly from any workbook. Equals Warehouse supported datasources include: * Amplitude * HubSpot * Intercom * Mixpanel * QuickBooks * Salesforce * Segment * Shopify * Stripe * Xero * Zendesk NetSuite is available as a datasource connection, however it is not currently supported by Equals Warehouse. You can query NetSuite data directly from Equals workbooks, but that data cannot be joined with other datasources or used in views for transformations. ## SQL databases and warehouses You can also connect directly to your own SQL databases and warehouses like PostgreSQL and Snowflake. The can be queried from any Equals workbook, however you cannot join that data with other datasources or use views to create data transformations. For more information on the pricing of datasources, see our [pricing page](https://equals.com/pricing/). # Connecting to Equals Warehouse datasources To set up the datasources listed below, follow the setup guide from your Equals dashboard: 1. Navigate to the *Datasources* page from the Equals home screen 2. Click *New* to create a new datasource connection 3. Follow the on-screen setup guide to connect your datasource. Note: When connecting to an Enterprise datasource, you'll be prompted to schedule a setup call with our team. **Datasources:** Hubspot, Intercom, Salesforce, Xero, Zendesk, Shopify, Amplitude, Mixpanel, Segment Some datasources require additional setup steps. To connect to these datasources, follow the specific setup guide linked below: **Datasources:** [Plaid](https://docs.equals.com/docs/plaid), [Quickbooks](https://docs.equals.com/docs/quickbooks), [Stripe](https://docs.equals.com/docs/stripe), [Netsuite](https://docs.equals.com/docs/netsuite) # Connecting to SQL databases and warehouses To connect to a SQL database within Equals, you'll first need to find your connection details and then grant access to your hosting provider from our IP address. ## Finding connection details To find the connection details for your SQL database, follow the specific setup guide for your hosting provider: **Datasources:** [Supabase](https://docs.equals.com/docs/supabase) [AWS RDS](https://docs.equals.com/docs/aws-rds), [AWS Redshift](https://docs.equals.com/docs/aws-redshift), [Azure](https://docs.equals.com/docs/azure-sql-server), [BigQuery](https://docs.equals.com/docs/bigquery-connection-guide), [DigitalOcean](https://docs.equals.com/docs/digitalocean), [Railway](https://docs.equals.com/docs/railway), [AWS Redshift](https://docs.equals.com/docs/aws-redshift), [PlanetScale](https://docs.equals.com/docs/planetscale), [Snowflake](https://docs.equals.com/docs/snowflake) If your hosting provider is not listed above, below is an explainer of each field. | Field name | Description | | - | - | | Connection name | This is what your datasource will be listed as throughout Equals. | | Share with workspace | Give access to this datasource to all current and future members of your workspace. | | Host | An IP address or hostname by which we can connect to your database. | | Port | The port your database server is listening on. | | Database name | The name of the database we should connect to on the provided host. | | Username | The username to connect with. | | Password | The password to connect with. | | Default schema | (Postgres only, optional) Set the default schema for the connection. | | SSH Tunnel | Optionally you can connect through an SSH tunnel. | | SSH Username | The username to connect as on the host. | | SSH Private Key | The SSH Private Key we should connect with. | ## Allowing access from our IP When connecting to SQL databases (except for BigQuery) we will always connect from `54.68.61.53`. Some providers and set ups likely require granting access on a per-IP basis. Use the following guides to learn how: **Datasources:** [AWS RDS](https://docs.equals.com/docs/aws-rds), [Azure](https://docs.equals.com/docs/azure-sql-server), [DigitalOcean](https://docs.equals.com/docs/digitalocean), [AWS Redshift](https://docs.equals.com/docs/aws-redshift), [Snowflake](https://docs.equals.com/docs/snowflake) If your provider is not listed above follow your hosting providers instructions for allowing connections from `54.68.61.53`. For MySQL, Postgres, and Redshift connections you may also connect through an SSH tunnel. *** [ARR Build Invoice Items](/docs/arr-build-invoice-items) [Databases and warehouses](/docs/connecting-sql-databases-to-equals) # Date filters Source: https://docs.equals.com/docs/date-filters ## Enable date filters for Dashboards For a smooth experience filtering your dashboard filter on date fields, Equals provides dedicated formulas to build summary tables and charts which automatically adjust to the filter period, breaking down your data by year, month, week, or day depending on the date range. To build a summary table that dynamically adjusts as date fields are filtered, drive its date headers with `FLEXHEADERS` and its body with `FLEXMATCH`. Tables built this way are called **flex tables**. #### 1. Use `FLEXHEADERS` for your date headers Put `FLEXHEADERS` in the first cell of your header row. It reads a date column and spills out period-start dates across the row (or column, if the vertical direction is specified). `=FLEXHEADERS(date_column, granularity, [num_periods], [start_date], [include_partial], [direction])` Examples: `=FLEXHEADERS(Sales!$A:$A, "month", 12)               // last 12 months` `=FLEXHEADERS(Signups!$A:$A, "week")                  // every week in the dataset` `=FLEXHEADERS(Sales!$A:$A, "month", 6, , FALSE)       // last 6 completed months (drops the in-progress one)` `=FLEXHEADERS(Sales!$A:$A, "day", 30, "2025-01-01")   // 30 days starting Jan 1` `=FLEXHEADERS(Sales!$A:$A, "day",365,,,"vertical") // The last 365 days in the data, laid out vertically.` granularity is one of "day", "week", "month", "year". #### The range moves with the data `FLEXHEADERS` is anchored to the data, not to a fixed window. As new rows arrive and time passes, the header row shifts forward — a "last 12 months" table always shows the 12 months ending at the most recent date in the column, without you editing anything. Pass `include_partial=FALSE` when you want to exclude the in-progress current period (e.g. "last 6 completed months" run mid-April returns Oct–Mar, dropping April). #### 2. Use `FLEXMATCH` in the body formulas In the body cells of your table, use `FLEXMATCH(header_ref)` inside `SUMIFS` / `COUNTIFS` / `AVERAGEIFS` in place of the usual `">="&B$1, "<"&EDATE(B$1,1)` pair. `=SUMIFS(Sales!$C:$C, Sales!$A:$A, FLEXMATCH(B$1), Sales!$B:$B, $A2)` `FLEXMATCH` automatically tracks whatever granularity `FLEXHEADERS` is currently rendering — day, week, month, or year — so the same template keeps working when the granularity changes. You only need to enter the template in one cell per row (or the top-left cell of the body, if both of your header axes are generated by a formula as shown below). The table tracks the body template and fills the rest of the table for you. #### 3. Tables will automatically update Once a summary table is backed by `FLEXHEADERS` + `FLEXMATCH`, you get a few things for free: * **It grows and shrinks automatically.** As the underlying data expands, the table adds columns; as it contracts (or is filtered), columns fall away. The formulas in the body re-evaluate on every change, and other content in the sheet will be moved to accommodate the new table size. * **Formulas that point into the table keep working.** References to cells inside the table follow rows and columns as the table reflows, so downstream formulas don't break. * **Charts follow the table.** A chart built from a flex table's range updates its series automatically as the table resizes — no need to re-select ranges after a filter is applied or new data arrives. #### 4. Add your date filters Date filters will be enabled for all dashboards on your workbook as soon as a table backed by `FLEXHEADERS` is created. When viewing the dashboard in View Mode, when a viewer picks a date range: * The flex table re-evaluates against the filtered data. * `FLEXHEADERS` recomputes its header row and will “zoom in” or “zoom out” where appropriate — e.g. a monthly table filtered down to a single month will flex to daily values. * The rest of the summary table, as well as any charts built on it, will adjust automatically. These changes are only for the viewer that filtered the data; the workbook will return to its original state when it is opened without a filter. If your dashboard includes a summary table or chart that doesn't use `FLEXHEADERS`, the underlying data is still filtered — but the table's header range stays static,so time periods where data has been filtered out will show zeros. Swap the static headers for `FLEXHEADERS` to make the table fully responsive. # Date matching formulas Source: https://docs.equals.com/docs/date-matching-formulas Three formulas make date-based comparisons easier and more intuitive. Use , , and to convert any date value into it’s respective week, month, or year. Previously, you'd need to: * Extract the week number and year from your date field in order to reference it in your formula. * Now, write your formula to match on both week number and year: `=countifs(D:D,weeknum(H2),E:E,year(H2))`. Now, you can: * Skip the calculated column and enclose the date value in a MATCHWEEK / MATCHYEAR formula: `=countifs(A:A,matchweek(F2),A:A,matchyear(F2))`. *** [Working with dates](/docs/working-with-dates) [Calculated columns](/docs/calculated-columns) # Deputy Source: https://docs.equals.com/docs/deputy Example Javascript code for importing data from Deputy You can use Import Scripts to import data from your Deputy account directly into an Equals workbook. # Create a Deputy Access Token Follow [the instructions here](https://developer.deputy.com/deputy-docs/docs/using-a-permanent-token) to create a Deputy access token. # Add the key to a secret group Copy the access token from the prior step. Then [create a new secret group](https://docs.equals.com/docs/secret-groups) and paste the key into a new secret named `deputy_api_key`. # Example code Once you've completed the prior steps, create a new workbook, add a new import script to a sheet and copy + paste the script below. Once pasted select your secret group in the toolbar (make sure the key in the secret group is called `deputy_api_key`). Note that you'll want to change the URL below to reflect your Deputy information. For example, [https://simonssambos.au.deputy.com](https://simonssambos.au.deputy.com/) is an installation called simonssambos and is present in the Australian geographic region. There are four possible regions for a Deputy installation currently: * AU (Australia) * EU (Europe) * UK (United Kingdom) * US (United States) More details can be found on the Deputy API page [here](https://developer.deputy.com/deputy-docs/docs/using-a-permanent-token) or by contacting their [API support team](https://developer.deputy.com/). ``` const equals = require("equals"); var axios = require('axios'); const apiKey = equals.getSecret("deputy_api_key"); var config = { method: 'get', url: 'https://simonsambos.au.deputy.com/api/v1/supervise/employee', headers: { 'Authorization': 'Bearer ${apiKey}' } }; const response = await axios(config) equals.addRows(response.data) ``` *** [Auth0](/docs/auth0) [Github](/docs/github) # DigitalOcean Source: https://docs.equals.com/docs/digitalocean DigitalOcean supports both Postgres and MySQL database types. The instructions for each type are the same. If your database is clustered, you will need to find the specific instance within the cluster you want to connect to. # Finding the database in DigitalOcean 1. First ensure you are on the correct project in the top right of the DigitalOcean dashboard. 2. Click *Databases* in the left hand sidebar. 3. Choose the database you want to connect to from the list. If the database has follower nodes, choose the specific node you want to connect to from the list. # Finding connection details 1. Find the database in DigitalOcean (instructions in first section above). 2. On the database details page, find *Connection details* on the right. 3. Ensure you have *Public network* selected and then choose *Connection string* in the dropdown on the right. 4. Ensure the correct user and database is selected below, and then click *show-password* in the connection string. 5. Within Equals click *Use connection string* instead and paste the connection string from DigitalOcean. # Allowing access from our IP You likely need to allow incoming connections from Equals’ IP address. 1. Find the database in DigitalOcean (instructions in first section above). 2. Select *Settings* in the tab bar at the top of the page. 3. Under *Trusted sources* click *Edit*. 4. Paste Equals' IP address in the text field: `54.68.61.53`. 5. Select ‘Add 54.68.61.53 as an address’ from the dropdown. 6. Click *Save*. Equals should now have access to your database. *** [BigQuery](/docs/bigquery-connection-guide) [PlanetScale](/docs/planetscale) # Drilldowns Source: https://docs.equals.com/docs/drilldowns Drilldowns let you trace any summarized value back to its source. When a cell, chart, or dashboard tile is built on data pulled in from a query, Equals knows exactly which underlying rows produced that value. With a single click, you can open those rows in a drilldown view - without writing a new query or leaving your workbook. ## Using drilldowns You'll find drilldowns in several places throughout a workbook and its dashboards: * **Cells**: Right-click a cell built on query data and select *Drill down*. * **Charts**: Right-click a data point on the chart and select *Drill down*. * **Dashboard tiles**: Hover a table cell and select *Drill down*. # Embed dashboards in Notion and more Source: https://docs.equals.com/docs/embed-dashboards Share your Equals dashboards in the places where your team works If your dashboard is shared with `Anyone with the link` (see [Manage dashboard access and permissions](https://docs.equals.com/docs/manage-dashboard-access-and-permissions)), you can embed it in other tools that support iframes like Notion and Coda. # Copy the embed link To embed your dashboard in Notion, first copy the link from the `Publish` panel. # Paste the embed link Then, in Notion, use the `/` command to search for `Embed link` and paste the link to your dashboard from your clipboard. # Resize the embedded dashboard Once embedded, you will be able to resize the iframe in Notion. If possible, we recommend that the destination page be set to `Full-width`, like you can do with Notion pages. *** [Send dashboards to email and Slack](/docs/send-dashboards-to-email-and-slack) [Dashboard settings](/docs/dashboard-settings) # Equals MCP Source: https://docs.equals.com/docs/equals-mcp The Equals MCP server gives AI assistants direct access to your Equals workspace. You can search workbooks and ask the Equals agent questions about your data. Please note that MCP/Slack AI calls cost normal Equals AI credits. *** ## Claude #### Team, Enterprise Adding the Equals MCP server to your Claude team will allow anyone on your team to connect Equals to their Claude sessions. You must be an Owner in your Claude team to add a custom connector. Visit the the [Connectors page](https://claude.ai/customize/connectors), then click the + button and select **Add custom connector**: Screenshot 2026 04 29 At 11 07 57
AM Then enter "Equals" as the Name, and `https://go.equals.com/api/mcp` as the Remote MCP Server URL, and then click **Add**. Screenshot 2026 04 29 At 11 31 20
AM Users can then enable the Equals connector in their Claude sessions. This will open a browser tab to authenticate in Equals to establish the connection. Screenshot 2026 04 29 At 11 33 23
AM #### Free, Pro Go to **Settings → Developer** and click **Edit config**: Screenshot 2026 04 29 At 11 15 34
AM This will open the location of the `claude_desktop_config.json` file. Open this file with a text editor and add the following: ```json theme={null} { "mcpServers": { "equals": { "command": "npx", "args": ["-y", "mcp-remote", "https://go.equals.com/api/mcp"] } } } ``` This should live alongside any existing preferences, like so: Screenshot 2026 04 29 At 11 23 58
AM Save this file, then restart Claude Desktop. On first use, a browser window will open to authorize the connection. *** ## Claude Code Run the following in your terminal: ```bash theme={null} claude mcp add --transport http equals https://go.equals.com/api/mcp ``` Then run `/mcp` inside a Claude Code session to authenticate. *** ## ChatGPT ### Web Visit [https://chatgpt.com/plugins](https://chatgpt.com/plugins) and click the plus on the top right. Screenshot-2026-07-23-at-11.30.25-AM Then enter "Equals" as the Name, `https://go.equals.com/api/mcp` as the Connection, check **I understand and want to continue**, and then click **Create**. Screenshot-2026-07-23-at-11.57.37-AM Finally, click **Sign in with Equals** to authenticate. ### Desktop Go to **Settings → Plugins → MCPs** and click **Add server**. Screenshot-2026-07-23-at-12.20.12-PM Enter "Equals" as the Name, select **Streamable HTTP** as the type, and `https://go.equals.com/api/mcp` as the URL. Leave the Bearer token env var and all of the headers fields blank. Then click **Save**. Screenshot-2026-07-23-at-12.22.16-PM Finally, click **Authenticate** next to the newly added server. *** ## Codex Add the server to `~/.codex/config.toml` (or `.codex/config.toml` in a project for a project-scoped setup): ```toml theme={null} [mcp_servers.equals] url = "https://go.equals.com/api/mcp" ``` Then authenticate from your terminal: ```bash theme={null} codex mcp login equals ``` This opens a browser window to authorize the connection. If you use the Codex IDE extension instead, open the gear menu → **MCP servers** → **Add server**, choose **Streamable HTTP**, enter `https://go.equals.com/api/mcp`, then click **Authenticate**. *** ## Cursor Open **Cursor Settings → MCP**, then add a custom server: ```json theme={null} { "mcpServers": { "equals": { "command": "npx", "args": ["-y", "mcp-remote", "https://go.equals.com/api/mcp"] } } } ``` *** ## VS Code (GitHub Copilot) 1. Open the Command Palette (`Ctrl/Cmd + Shift + P`) and run **MCP: Add Server** 2. Select **Command (stdio)** 3. Enter: ```bash theme={null} npx mcp-remote https://go.equals.com/api/mcp ``` 4. Name it `equals` 5. Activate it via **MCP: List Servers** Or add directly to your `settings.json`: ```json theme={null} { "mcp": { "servers": { "equals": { "command": "npx", "args": ["-y", "mcp-remote", "https://go.equals.com/api/mcp"] } } } } ``` *** ## Windsurf 1. Open Settings (`Ctrl/Cmd + ,`) 2. Scroll to **Cascade → MCP Servers** 3. Add a custom server: ```json theme={null} { "mcpServers": { "equals": { "command": "npx", "args": ["-y", "mcp-remote", "https://go.equals.com/api/mcp"] } } } ``` *** ## Zed Open your settings (`Cmd + ,`) and add: ```json theme={null} { "context_servers": { "equals": { "source": "custom", "command": "npx", "args": ["-y", "mcp-remote", "https://go.equals.com/api/mcp"], "env": {} } } } ``` *** ## Other Tools If your tool isn't listed above, it can still connect — the setup follows one of the same two patterns: * If it supports **remote MCP servers**, add `https://go.equals.com/api/mcp` wherever it accepts a server URL, as in the Claude, ChatGPT, and Codex setups above. * If it only supports **local MCP servers**, configure it to run the command `npx -y mcp-remote https://go.equals.com/api/mcp`, which bridges to the remote server — the same pattern as the Cursor, Windsurf, and Zed configs above. Either way, a browser window will open on first use to authorize the connection with your Equals account. *** ## What You Can Do Once connected, your AI assistant can: ### Find Workbooks Search workbooks in your Equals workspace by name or content, and list your team's trusted workbooks — curated, vetted analyses that are surfaced first as the most reliable sources to reference. ### Query Datasources List connected datasources, explore their schema, and directly run SQL queries. ### Ask Equals Ask questions about your data in natural language. The Equals agent can query all your connected datasources and read any workbook you have access to, and runs its own analysis to find answers. You can ask follow-up questions in the same conversation, and answers can include a full workbook you can open in Equals. Ask Equals consumes Equals AI credits. *** ## Troubleshooting ### Authentication Errors Make sure you have an active Equals account and that your workspace has MCP enabled. Try disconnecting and reconnecting to go through the authorization flow again. ### `npx mcp-remote` Not Found Make sure Node.js is installed: ```bash theme={null} node --version ``` If you don't have it, download it from [here](https://nodejs.org'). #### Windows If you are on Windows, you may need to replace `"command": "npx",` with `"command": "C:\\Program Files\\nodejs\\npx.cmd",`. ### Tool Calls Time Out The Equals agent can take 1–5 minutes to answer complex questions. Your AI tool should poll for results automatically; if it gives up early, try asking it to wait and check again. # Datasources FAQ Source: https://docs.equals.com/docs/faq Learn how we keep your connection details secure and manage data access # Data security ## How do you keep my credentials secure? All sensitive credentials (password, SSH private key, connection strings, OAuth tokens, etc.) are stored encrypted in the database. The credentials are encrypted with a key only accessible to the necessary production servers. ## Do you connect from a static IP? We will always connect from this static IP address: `54.68.61.53`. ## What access do you have to my data? **SQL databases** To pull data from your databases our servers necessarily have the ability to run queries against your database, and to show you the results of those queries, any data you pull is stored in our databases. However, we never access any of your data without advance permission from you on a case-by-case basis. e.g. to debug an issue you’re having. **Other datasources** Our other datasources are powered by Fivetran. Fivetran syncs connected datasources to a data warehouse we maintain. Access to this store is restricted on an as needed basis to the appropriate production servers. Customer data is segregated with unique credentials per datasource, per customer. ## What security certifications do you have? Equals is SOC 2 Type II certified. We also complete regular pen tests. # Fivetran Equals uses Fivetran's extensive library of data connectors to power our non-SQL connectors like Stripe, Salesforce, Hubspot, etc. Fivetran sit between the connected service (e.g. Stripe) and our database. They are the leading provider of this software (called "ETL") working with everyone from small companies to Fortune 500s. ## Why do you work with Fivetran? By working with Fivetran we get access to hundreds of prebuilt connectors. This lets us focus on building the best spreadsheet. ## What does Fivetran get access to? Fivetran stores credentials to connected datasources on our behalf. They use best-in-class security to keep these safe. Some of your data may be temporarily stored on Fivetran's servers in transit but is purged as soon as no longer needed, typically within 8 hours. You can learn more in Fivetran's docs. ## What does Equals get access to? Fivetran syncs connected datasources to a data warehouse we maintain. Access to this store is restricted on an as needed basis to the appropriate production servers. Customer data is segregated with unique credentials per datasource, per customer. ## Why are these integrations paid? There is a meaningful cost to us to both processing the data, as well as storing it. ## What is the fair use policy? We reserve the right to pause syncing of any Fivetran powered datasources. We may do this in cases where the amount of data being synced is significantly above average. In this case we will reach out to you to discuss custom pricing for your connection. *** [Concepts](/docs/getting-started) [Resources & tutorials](/docs/resources) # Filters and sorts Source: https://docs.equals.com/docs/filters-and-sorts Filter and sort data in your worksheet. Filters and sorts in Equals work the same as any traditional spreadsheet. To add a filter or sort: 1. Select the filter and sort icon from the toolbar. 2. Add the criteria for the filter or sort to the header of your data. # FAQ ### Do filters apply to everyone in the workbook? Filters applied over data are per user, which means that they will not be visible to others viewing a workbook. Sorts will be visible for everyone in a workbook. ### Can I apply multiple filters at once? Yes, you can apply multiple filters simultaneously to refine your data. Simply repeat the process of adding filters for different criteria. ### Do filters and sorts affect the underlying data? No, filters and sorts are applied for viewing purposes only and do not modify the underlying data in any way. Filters and sorts applied to the query from the query builder will not change the datasource but will limit or modify the data displayed in the spreadsheet for everyone. ### Do filters and sorts affect formulas in the workbook? Filters and sorts do not directly affect formulas. Formulas will still calculate based on the entire dataset, regardless of any filters or sorts applied. *** [Charts](/docs/charts) [Working with dates](/docs/working-with-dates) # Folders Source: https://docs.equals.com/docs/folders-filters Organize workbooks and saved queries with folders Folders allow you to organize your workbooks and saved queries, and share them with your workspace or with specific teammates. # Creating folders Folders you have access to, whether they were created by you or shared with you or your workspace, will automatically appear in your workspace sidebar. To create a folder, select the *New* button in the top right corner of your Home and select *Folder*. Then, give your new folder a name. You can move workbooks, saved queries, or subfolders into folders. To move any object into a folder, simply drag and drop it into the destination folder in your sidebar. Or, you can select *Move* from the `…` menu next to any object in your workspace, and then select the destination folder.) # Folder permissions and sharing There are 3 levels of access for folders: 1. **`Must be invited`:** Only you (or teammates that you individually invite to the folder) can view, modify, delete, or set access levels on the folder or its contents. By default, your folder is set to `Must be invited`. 2. **`Read Only`**: Users in your workspace can view the folder and its contents, but cannot modify them. For queries that are stored in folders, users can run the query but cannot modify it. 3. **`Edit`**: Users in your workspace can view, modify, delete, or set access levels on the folder and its contents. They can also move objects in and out of folders. To share access to a folder and its contents, select the `…` menu to the right of the folder, then click *Share*. Or, click in to the folder and hit the *Share* button in the top right corner of the page. Here, you can set permissions for your entire workspace, or invite specific teammates to the folder and set their permissions individually. Viewers of your workspace cannot be invited to edit a folder, although they can be granted read only access. By default, the permissions on workbooks, queries, or subfolders that are stored inside a folder (the “root” folder) will match the permissions of that root folder. **By inviting users to a folder, you are granting them access to that folder's contents.** Moving an object into a root folder updates its existing permissions to match those of your root folder. This means that teammates who were invited to the object but not to the root folder will lose access to that object. To invite a teammate to an object stored inside a root folder, you’ll need to invite them to the root folder itself. To do this, click on ‘Update’ to open the permissions for the root folder, then invite your teammate via email and set their access level. # FAQ ### What happens if I delete a folder? If you delete a folder, all of the contents inside the folder will be deleted. To restore folders and contents that were mistakenly deleted, contact us at [\[email protected\]](mailto:help@equals.com). ### Can I individually share access to an object that is stored in a folder? Currently, access levels on objects stored inside folders cannot be individually adjusted. To invite a teammate to an object stored in a folder, you'll need to invite them to the folder itself. ### Can I share edit access to folder for someone who is a Guest or Viewer of my workspace? Viewers of your workspace cannot be invited to edit a folder. Guests can be invited to edit specific folders, but they will remain a Guest of your workspace more generally. *** [Sharing and permissions](/docs/sharing-permissions) [How to Spreadsheet](/docs/how-to-spreadsheet) # Format text and reference cells Source: https://docs.equals.com/docs/format-text-and-reference-cells-in-paragraphs Reference cells, format text, and create hyperlinks using Markdown on dashboards Reference cells inline, **bold**, *italicize*, list, and hyperlink text on dashboards using Markdown. ## Supported Markdown ### Styling and linking text | Markdown | Formatted text | | - | - | | `**bold**` or `__bold__` | **bold** | | `*italics*` or `_italics_` | *italics* | | `[hyperlink to a great blog](https://wrap-text.equals.com)` | [hyperlink to a great blog](https://wrap-text.equals.com) | ### Lists The Markdown to create bulleted and numbered lists is as follows: ```bash bash theme={null} - Bullet one - Bullet two - Bullet three ``` ```bash bash theme={null} 1. First list item 2. Second list item 3. Third list item ``` These would appear like so when viewing a dashboard: **Bulleted List** * Bullet one * Bullet two * Bullet three **Numbered List** 1. First list item 2. Second list item 3. Third list item ## Referencing Cells You can display the contents of a cell inline within a paragraph or heading on a dashboard by wrapping the cell reference in double curly brackets. | Sheet name | Cell | Cell referenced in paragraph | | - | - | - | | Sheet 1 | C3 | `{{Sheet 1!C3}}` | | Monthly Visitors | D22 | `{{Monthly Visitors!D22}}` | Referencing cells inline is useful when you want to construct sentences like: > Last month's Net New ARR was \$868,000. It grew up 10% compared to the previous month (05-2024). In this example, `$12,500`, `10%`, and `05-2024` are all referenced cells dynamically calculated using formulas in a sheet called `ARR Build` . | Cell | Cell contents | Calculated output | Cell referenced in paragraph | | - | - | - | - | | B6 | `Net New ARR` | New New ARR | `{{ARR Build!B6}}` | | F6 | `=SUM(F2:F5)` | \$868,000 | `{{ARR Build!F6}}` | | F7 | `=(F6-E6)/E6` | 10% | `{{ARR Build!F7}}` | | F2 | `=EOMONTH(TODAY(),-1)` | 05-2024 | `{{ARR Build!F2}}` | If you put these all together when writing a sentence in your paragraph, it would appear like this in edit mode: > Last month's `{{ARR Build!B6}}` was `{{ARR Build!F6}}`. It grew `{{ARR Build!F7}}` compared to the previous month `{{ARR Build!F2}}`. *** [Create and edit dashboards](/docs/create-and-edit-dashboards) [Dashboard filters](/docs/dashboard-filters) # Advanced formula editor Source: https://docs.equals.com/docs/formula-editor Use a code editor to easily debug formulas The Formula Editor provides a roomy, code-like canvas to edit your spreadsheet formulas easily. It can be used to diagnose and debug formula errors with a line-by-line breakdown of each subexpression. # Getting started There are multiple ways to activate Formula Editor from a cell in a workbook: 1. Hit `Cmd + Shift + Enter` to open the Formula Editor directly. 2. Hit `Cmd + K` (or `Ctrl + K` on Windows) to open up the [command bar](https://docs.equals.com/docs/command-bar). Then, search for `Explain Formula` or `Edit cell (expanded)`. 3. Hit the ↖️ icon on the right side of the formula bar. On opening, the Formula Editor will automatically break down the formula in your cell and evaluate each subexpression. You can type directly in to your Formula Editor to modify the formula, and then save or discard your changes. # FAQ ### Can I modify formulas directly in the Formula Editor? Yes, you can type directly into the Formula Editor to modify the formula as needed. ### Can I undo changes made in the Formula Editor? Yes, if you select `Command` + `Z` or `Undo` from the toolbar, you can revert changes made in the Formula Editor. ### Is there a limit to the complexity of formulas that the Formula Editor can handle? No, the Formula Editor is designed to handle a wide range of formulas, including those with significant length and complexity. *** [AI Assist](/docs/ai-assist) [Dashboards](/docs/dashboards) # Overview Source: https://docs.equals.com/docs/getting-started Get a basic understanding of Equals' core concepts and features. With Equals, you can query, analyze, and report live data with the flexibility of a spreadsheet and the power of BI. This guide will walk you through Equals' core concepts and features to help you hit the ground running. For a quick walkthrough of Equals, check out our demo. [Watch on YouTube](https://www.youtube.com/watch?v=-c5XRtc6PYA) # Fundamentals ## Workspaces Your Equals workspace is home to all the workbooks, datasources, queries, and views created by its members. By enabling *Auto-join workspace* under *[Settings > Workspace](https://go.equals.com/settings?tab=workspace)*, you can ensure that users with email addresses from the same domain are automatically added to your workspace upon account creation. For more on workspace settings and configuration, visit our [workspace setup guide](https://docs.equals.com/docs/workspaces). ## Datasources Equals connects directly to your databases, data warehouses, and frequently used apps. [Datasource](https://docs.equals.com/docs/data-syncing-overview#/) connections are configured at the workspace level. View all available datasources by going to *[Datasources](https://go.equals.com/datasources)* from your workspace home screen. To add a new datasource, click the *New datasource* button on the top right corner of the page and follow the provided instructions. Datasource connections can be shared with everyone in your workspace or with individual members. ## Equals Warehouse When you connect more than one [supported datasource](https://docs.equals.com/docs/data-syncing-overview) to your Equals workspace, we automatically sync that data to your Equals Warehouse. Powered by Snowflake, Equals Warehouse makes it possible to [join](https://docs.equals.com/docs/joins) and query connected datasources in any Equals workbook. You can also transform the raw data in your Equals Warehouse into clean, analysis-ready tables called [views](https://docs.equals.com/docs/create-views). Views are synced to your data schema in your Equals Warehouse, so your team can easily and safely query them from any Equals workbook. You can manage connected datasources in your workspace under [Datasources](https://go.equals.com/datasources). To add a new datasource, click `New datasource` in the top right corner of the page and follow the instructions (or check out our [configuration guides](https://docs.equals.com/docs/data-syncing-overview#/)). ## Workbooks Equals workbooks are working files for your analyses and reports. They contain sheets that have all the spreadsheet fundamentals, including [functions](https://docs.equals.com/docs/supported-functions), [shortcuts](https://docs.equals.com/docs/keyboard-shortcuts), [pivot tables](https://docs.equals.com/docs/pivot-tables), and [charts](https://docs.equals.com/docs/charts). You can also ask [AI Assist](https://docs.equals.com/docs/ai-assist) for help building and refining your analysis. When you create a new workbook, you can choose to create either a *regular* or *connected* sheet. Connected sheets allow you to [query](https://docs.equals.com/docs/queries) data in [supported datasources](https://docs.equals.com/docs/data-syncing-overview#/) that you've connected to your Workspace using the built-in query builder or SQL editor. Queries can be run manually or on a [fixed schedule](https://docs.equals.com/docs/query-scheduling). You can create as many connected sheets in your workbook as you like. Use regular sheets to build analyses with the live data pulled into your workbook. [Auto-expand](https://docs.equals.com/docs/auto-expand) any tables to refresh them and any charts built of them with each query run. Equals ensures that your analysis is always up-to-date without the need to copy and paste data or adjust data ranges manually. ## Dashboards Every Equals workbook includes a [dashboard](https://docs.equals.com/docs/dashboards), which allows you to transform your analysis into a live, board-ready report. Equals dashboards can be [auto-distributed](https://docs.equals.com/docs/send-dashboards-to-email-and-slack) to Slack or email on a custom schedule. To [create a dashboard](https://docs.equals.com/docs/create-and-edit-dashboards), open any workbook and go to the pre-existing *Dashboard* tab. Then, add individual cells, tables and charts from your analysis to your dashboard. You can also add AI-generated executive summaries. These objects refresh based on any scheduled queries in the workbook, ensuring your dashboard always reflects the most recent data. # Transform data ## Views With [views](https://docs.equals.com/docs/create-views#/), you can use SQL to transform and join raw data from connected datasources into clean and analysis-ready tables. Once saved, Views sync to your data schema in your Equals Warehouse and can be directly queried from any workbook for analysis and reporting. Views are a great way to ensure consistency in how metrics and datasets are defined across your team. Views also support dependencies, meaning they can build on top of each other in the right order, enabling your team to create more complex transformations that are typically only possible with DBT pipelines or the help of a data engineer. # Explore data ## SQL editor Equals' full-featured [SQL editor](https://docs.equals.com/docs/building-queries-copy#using-the-sql-editor) allows you to write and run a traditional SQL query directly from any Equals workbook. To get started, first [configure a datasource](https://dash.readme.com/project/equals/v1.0/docs/overview) for your workspace. Then, click the *Connect to datas* in the top right corner of any workbook, select the datasource you'd like to query, and then select the SQL editor. ## Query builder If you don't know SQL, you can still query any supported datasource using the drag-and-drop query builder. The query builder supports common SQL statements such as joins and sorts. Queries built using the query builder can be converted to a traditional SQL query at any time by switching from the query builder to the SQL editor. To get started, first [configure a datasource](https://docs.equals.com/docs/overview) for your workspace. Then, click *Connect to data* in the top right corner of any workbook, select the datasource you'd like to query, and then select the query builder. ## Scheduling queries With [query scheduling](https://docs.equals.com/docs/query-scheduling) you can automatically pull new data into your workbook either once an hour, day or week. When the scheduled query runs it will update all formulas that depend on the updated data. To schedule a query, click *Settings* next to the *Run query* button at the top right of a connected sheet. ## Import scripts Beyond supported datasources, [import scripts](https://docs.equals.com/docs/write-an-import-script-connection) can be used to build custom integrations by pulling in data from third-party APIs. Import scripts can be written using either Javascript (Node 16) or Python (3.9). As a starting point, check out example import scripts for datasources like [Airtable](https://docs.equals.com/docs/airtable), [Typeform](https://docs.equals.com/docs/typeform), [Github ](https://docs.equals.com/docs/github)and more. ## Views With [views](https://docs.equals.com/docs/create-views), you can transform raw data from any datasource into a simpler, analysis-ready table. Once saved, views sync to your underlying data schema and can be directly queried from any workbook for further analysis. Views are great for ensuring consistency in how metrics are defined and tracked - define them once, then use them anywhere. ## Restoring queries With [query version history](https://docs.equals.com/docs/query-version-history), Equals keeps a copy of every query and the resulting data returned from the query to facilitate tracking and restoring changes. To restore any query run *and* its associated data, click *History* at the top right of the SQL editor or query builder, navigate to the version of your query you'd like to restore, and then hit *Restore*. To restore the query without changing the associated output data, select *Restore query only*. ## Saved queries [Saved queries](https://docs.equals.com/docs/saved-queries-1) enable workspace members to share commonly-used queries. Changes to a saved query will automatically update across all workbooks in which that saved query is used, ensuring that data is pulled consistently across multiple analyses. Saved queries can only be accessed by workspace members who have access to the underlying datasource. Saved queries can also be shared with the entire workspace or individual users on a `View only` or `Can edit` basis. # Analyze data ## Auto-expand With [auto-expand](https://docs.equals.com/docs/auto-expand), you can configure analyses (tables, charts, and pivot tables) to automatically refresh and expand (or contract) with each query run. This is useful for ensuring that analyses are up-to-date without the need to manually copy & paste data or expand ranges on your charts and tables. ## Calculated columns With [calculated columns](https://docs.equals.com/docs/calculated-columns), you can attach columns to data in a connected sheet that expand and contract with each query run. This is useful for automating transformations you must apply to queried data before using it in analysis, such as extracting dates or summing the value of multiple columns. To create a calculated column, enter a formula in a column directly adjacent to your queried data. The formula will auto-fill to the length of the column and stay up-to-date with each query run, eliminating the need to copy and paste formulas manually. ## Keyboard shortcuts Your keyboard is the fastest way to edit your Equals workbook. Equals supports the full range of [spreadsheet shortcuts](https://docs.equals.com/docs/keyboard-shortcuts) you would expect coming from Excel or Google Sheets. These are a few of the most helpful: `Cmd/Ctrl` + `Z` to Undo `Cmd/Ctrl` + `Y` to Redo `F4` to toggle cell locks `Ctrl` + `Space` to select column `Shift` + `Space` to select row `option` (Mac) or `Shift `+ `Alt` (Windows) to enter alt mode ## Command bar Equals has a built-in [command bar](https://docs.equals.com/docs/command-bar) that allows you to easily discover and access any workbook command (and AI Assist) with a single keyboard shortcut. These include all commands related to workbook formatting, navigation, editing, and sorting/filtering. x Press`Cmd/Ctrl`+`K` to open the command bar. From there, start typing in any command to get auto-complete suggestions. You can also enter a custom prompt for [AI Assist](https://docs.equals.com/docs/ai-assist) or select a suggested prompt. ## AI Assist Powered by Open AI's GPT-4 Turbo, [AI Assist](https://docs.equals.com/docs/ai-assist) can help you write, edit, and fix SQL queries, formulas, charts, and more directly from your Equals workbook. You can ask AI Assist for help with anything in your workbook — AI Assist will also automatically detect and surface fixes for errors in your queries and formulas. Just hit `Cmd/Ctrl` + `J` to chat with AI Assist, or `Cmd/Ctrl`+`K` to open AI Assist from the command bar. # Report on data ## Distributed reports You can [send dashboards to Slack and email](https://docs.equals.com/docs/send-dashboards-to-email-and-slack#send-dashboards-to-email-and-slack) on a custom schedule. Dashboards are sent as snapshots, showing the most recent view of tables, charts, and cells. [Scheduling query runs](https://docs.equals.com/docs/query-scheduling) and dashboard sends will ensure your dashboard is refreshed and distributed to stakeholders on a cadence that works for your team. *** What’s Next * [Datasources FAQ](/docs/faq) # Github Source: https://docs.equals.com/docs/github Example Javascript code for importing issues from Github You can use Import Scripts to import issues from your Github account directly into an Equals workbook. # Create a Github personal access token Follow the instructions here to create a Github personal access token. Your token needs the repo scope. # Add the key to a secret group Copy the access token from the prior step. Then [create a new secret group](https://docs.equals.com/docs/secret-groups) and paste the key into a new secret named github\_pk. Create a second secret in the same group called github\_username with the username that created the key. # Example code Once you've completed the prior steps, create a new workbook, add a new import script to a sheet and copy + paste the script below. Once pasted select your secret group in the toolbar (make sure the key in the secret group is called github\_pk). Update the REPO constant to the Github repo you want to pull issues from – it should include the name of the organization or user that owns the repo, followed by a slash, and the name of the repo. ``` const equals = require("equals"); const axios = require("axios"); const REPO = "ExampleOrg/example_app"; const FIRST_PAGE = `https://api.github.com/repos/${REPO}/issues?state=all&per_page=100`; const MAX_PAGES = 10; const LINK_REGEX = /<(.*)>; rel="(\w+)"/; const parseLinkHeader = (linkHeader) => { const parsed = {}; const links = linkHeader.split(","); links.forEach((link) => { const [,url,name] = link.match(LINK_REGEX); parsed[name] = url; }) return parsed; } const getIssues = async () => { let issues = []; let nextPage = FIRST_PAGE; let i = 0; while(nextPage && i < MAX_PAGES) { const resp = await axios({ method: "get", url: FIRST_PAGE, auth: { username: equals.getSecret("github_username"), password: equals.getSecret("github_pk") } }); nextPage = parseLinkHeader(resp.headers.link).next; issues = issues.concat(resp.data); i += 1; } return issues; } const issues = await getIssues(); equals.addHeaders(["number", "title", "user", "state", "closed at", "created at"]); for(const issue of issues) { if(issue.pull_request) { continue; } equals.addRow([ issue.number, issue.title, issue.user.login, issue.state, issue.closed_at, issue.created_at ]) } ``` *** [Deputy](/docs/deputy) [Google Analytics](/docs/import-from-google-analytics) # Google Sheets Source: https://docs.equals.com/docs/google-sheets Connect your Google Sheets to Equals # Formatting your Google Sheets To connect to your Google Sheets in Equals, first ensure that you have permission to view the Google Sheets workbook you would like to connect, and check that it is properly formatted: * There should be a single row of headers at the top * Only raw values will be carried over into Equals, not formulas or formats. You can re-apply your formats from Equals. # Connecting to Google Sheets Once your Google Sheet is properly formatted, you’ll just need your Google Sheets URL to connect to it as a datasource in Equals. 1. From your Google Sheets workbook, select *Share* from the top right corner, and then *Copy link*. 2. Head to the *Datasource* page from the Equals home screen. 3. If you're yet to add a datasource, you will see a list of available datasources. Otherwise, click *New Datasource* in the top right corner. 4. Select *Google Sheets*. Follow the prompt to connect your Google account. 5. Paste your Google Sheets URL into the *Workbook URL* field 6. Select *Test & Create*. *** [CSV files](/docs/csv-files) [Netsuite](/docs/netsuite) # Overview Source: https://docs.equals.com/docs/how-to-spreadsheet Best practices for building an analysis in a spreadsheet – for novices and pros. Starting from a blank spreadsheet can be daunting. Especially if you're not an analyst by background. Not to worry. This guide is built for people looking to learn how to build powerful spreadsheet analyses, no matter their level of experience. It covers: 1. [Organizing workbooks for analysis](https://docs.equals.com/docs/organizing-workbooks-for-analysis) 2. [Preparing data for analysis](https://docs.equals.com/docs/preparing-data-for-analysis) 3. [Building and sharing analyses](https://docs.equals.com/docs/building-and-sharing-analyses) ### Build as you go If you'd like to apply the practices in this guide as they are covered, you can copy and paste the contents of this [example Equals workbook](https://go.equals.com/workbooks/01df3972-972b-453a-b2b4-6a472900bd2d) into a spreadsheet of your choice. Note, to copy formulas you'll need to copy the contents directly from the formula bar as copying cells will only copy their values and not any underlying formulas producing them. *** What’s Next * [Organizing workbooks for analysis](/docs/organizing-workbooks-for-analysis) # Google Analytics Source: https://docs.equals.com/docs/import-from-google-analytics Example Javascript code for importing data from Google Analytics You can use Import Scripts to import data from your Google Analytics account directly into an Equals workbook. # Create a service account Start by going to [this page](https://console.cloud.google.com/projectselector2/apis/enableflow?apiid=analytics\&credential=client_key\&pli=1\&supportedpurview=project) and select the project you'd like to connect to. Once you select the project, enable the Google Analytics API by clicking *Next* and then *Enable*. Then you’ll need to create a service account. To do so, you’ll need to click on the menu in the left hand corner and navigate to *APIs and Services* > *Credentials*. On this screen, select *Manage Service Accounts* in the bottom left hand corner. Then select *Create Service Account*. Here you can give your account a name and click *Create and Continue*. You can continue through the two optional fields. Now your service account has been created. Clicking into the listed account, you’ll want to select “Keys” from the toolbar at the top. Click “Add Key” and “Create New Key” on the "Keys" page. You’ll want to make sure that the key you select is JSON. This will download a file on your computer. # Add the key to a secret group Open the JSON file from the step above in any text editor and copy the entire key to your clipboard. Then [create a new secret group](https://docs.equals.com/docs/secret-groups) and paste the entire JSON object in a key named `GA_KEY`. # Example code Once you've completed the prior steps, create a new workbook, add a new import script to a sheet and copy + paste the script below. Once pasted select your secret group in the toolbar (make sure the key in the secret group is called `GA_KEY`) and update your `PROPERTY_ID`. ## Google Analytics V4 Your Property ID can be found in Google Analytics: *Settings > Select your property > Property settings*. You will see the Property ID in the top right. ``` const equals = require("equals"); const axios = require("axios"); const crypto = require("crypto"); const gaKey = JSON.parse(equals.getSecret("GA_KEY")); PROPERTY_ID = "123456789"; const formatDate = (gaDate) => { const year = gaDate.slice(0,4); const month = gaDate.slice(4,6); const day = gaDate.slice(6); return `${year}-${month}-${day}` } const unixTime = () => Math.floor(Date.now() / 1000); const base64url = (obj, from64 = false) => { const as64 = from64 ? obj : Buffer.from(JSON.stringify(obj)).toString('base64'); return as64 .replace(/=/g, '') .replace(/\+/g, '-') .replace(/\//g, '_'); } const sign = (encodedHeader, encodedClaims) => { const signer = crypto.createSign("RSA-SHA256"); signer.update(`${encodedHeader}.${encodedClaims}`); const signature = signer.sign(gaKey.private_key, 'base64'); return base64url(signature, true); } const jwt = () => { const now = unixTime(); const header = { alg: "RS256", typ: "JWT" }; const claims = { iss: gaKey.client_email, scope: "https://www.googleapis.com/auth/analytics.readonly", aud: gaKey.token_uri, exp: now + 3600, iat: now, }; const encodedHeader = base64url(header); const encodedClaims = base64url(claims); const signature = sign(encodedHeader, encodedClaims); return `${encodedHeader}.${encodedClaims}.${signature}`; } const getAccessToken = async () => { var bodyData = new URLSearchParams(); bodyData.append("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"); bodyData.append("assertion", jwt()); const resp = await axios({ method: "post", url: gaKey.token_uri, data: bodyData.toString() }); return resp.data.access_token; } const getUniqueVisitors = async () => { const accessToken = await getAccessToken(); const resp = await axios({ method: "post", url: `https://analyticsdata.googleapis.com/v1beta/properties/${PROPERTY_ID}:runReport`, data: { dateRanges: [{ startDate: "2022-01-01", endDate: "2022-06-01" }], metrics: [{ name: "Users", expression: "totalUsers" }], dimensions:[{ name: "date" }], orderBys: [{ dimension: { dimensionName: "date" } }] }, headers: { Authorization: `Bearer ${accessToken}` } }) return resp.data; } equals.addHeaders(["Date", "Unique visitors"]) const visitorData = await getUniqueVisitors(); for(const row of visitorData.rows) { const date = formatDate(row.dimensionValues[0].value); const value = row.metricValues[0].value; equals.addRow([date, value]) } ``` *** [Github](/docs/github) [Intercom](/docs/intercom) # Intercom Source: https://docs.equals.com/docs/intercom You can use Import Scripts to import lead or user data from your Intercom account directly into an Equals workbook. # Create an Intercom Access Token Follow [the instructions here](https://developers.intercom.com/building-apps/docs/authentication-types#section-access-tokens) to create an Intercom access token. # Add the key to a secret group Copy the access token from the prior step. Then [create a new secret group](https://docs.equals.com/docs/secret-groups) and paste the key into a new secret named `intercom_api_key`. # Example code Once you've completed the prior steps, create a new workbook, add a new import script to a sheet and copy + paste the script below. Once pasted select your secret group in the toolbar (make sure the key in the secret group is called `intercom_api_key`). If you'd like to fetch users instead of leads, change `role` to `user`. ``` const equals = require("equals"); const axios = require("axios"); const luxon = require("luxon"); const apiKey = equals.getSecret("intercom_api_key"); const role = "lead"; const unixToDateTime = (unixTimestamp) => luxon.DateTime.fromSeconds(unixTimestamp).toFormat('yyyy-LL-dd HH:mm:ss'); const getLeadsPage = async (starting_after = undefined) => { const response = await axios({ method: "post", url: "https://api.intercom.io/contacts/search", data: { query: { field: "role", operator: "=", value: role }, pagination: { per_page: 150, starting_after }, sort: { field: "created_at", order: "descending" }, }, headers: { Authorization: `Bearer ${apiKey}`, Accept: "application/json" } }); return response.data; } const getAllLeads = async () => { let leads = []; let response; let startingAfter; do { response = await getLeadsPage(startingAfter); leads = leads.concat(response.data); startingAfter = response.pages.next && response.pages.next.starting_after; } while(startingAfter); return leads; } const leads = await getAllLeads(); equals.addHeaders(["email", "created_at"]) leads.forEach((lead) => { lead["created_at"] = unixToDateTime(lead["created_at"]); equals.addRow(lead); }) ``` *** [Google Analytics](/docs/import-from-google-analytics) [Typeform](/docs/typeform) # Joins Source: https://docs.equals.com/docs/joins Join across tables or datasources with or without SQL With Equals, it's easy to combine data across [Equals Warehouse supported datasources](https://dash.readme.com/project/equals/v1.0/docs/data-syncing-overview). For example, you could combine data from Stripe and Salesforce in the same spreadsheet to perform deeper analyses. There are two ways to join data in Equals: 1. Using the query builder (no code) 2. Using the SQL editor # Query builder joins The Query builder allows you to combine data from different tables in your connected databases (e.g. Postgres, Redshift) or across connected cloud apps (e.g. Stripe, Segment) without using SQL. Once your [datasources are connected](https://docs.equals.com/docs/datasources-overview), you can create a new query in a workbook [using the query builder](https://docs.equals.com/docs/building-queries-copy#using-the-query-builder). Select `Join column` and specify the connection you'd like to set up. An example could be joining between one Postgres table and another Postgres table, or it could be joining a Stripe table with a HubSpot table. Next, select the columns from the new datasource to join with your existing dataset. You'll also want to specify a join key: the column with matching values in both datasources to join on. For example, the `ID` in Stripe should match the `DEAL_ID` in HubSpot. Note that the query from each datasource will need to have the column shared by both sources selected. # SQL editor joins Combine data across datasources by writing traditional SQL against supported datasources. To get started, connect a datasource to a sheet in your workbook and select the SQL Editor. Then, to view the fields you want to join, open the table browser and select the additional datasource you want to join. # Supported datasources The query builder can join across any datasource, including saved queries (if the saved queries were generated using the query builder). The SQL editor can join across the supported datasources below: * Stripe * Xero * Quickbooks * Intercom * HubSpot * Zendesk Support * Salesforce * Twitter Ads * Facebook Ads * Google Ads * Shopify # Types of joins Currently, the query builder supports LEFT joins. Any type of join is supported from the SQL editor. * **Left Join** A left join returns all the records from the left table and matching records from the right table. If there are no matching records in the right table, then null values are returned for those columns. ​ * **Right Join:** A right join is similar to a left join but returns all the records from the right table and matching records from the left table. If there are no matching records in the left table, then null values are returned for those columns. ​ * **Inner Join:** An inner join returns only the matching records from both tables. Records that do not have a match in the other table are not included in the result set. ​ * **Outer Join:** An outer join returns all the records from both tables and includes null values for columns where there is no match. *** [Query version history](/docs/query-version-history) [Cell references](/docs/cell-references) # Keyboard shortcuts Source: https://docs.equals.com/docs/keyboard-shortcuts Common keyboard shortcuts supported by Equals In this document we describe all keyboard shortcuts supported by Equals, including standard shortcuts and alt mode shortcuts. Equals also has a built-in [command bar](https://docs.equals.com/docs/command-bar) enabling you to access any command with a single shortcut. # Standard shortcuts ## Common actions | Action | Mac | PC | | - | - | - | | Select all | ⌘ + a ctrl + a | ctrl + a | | Undo | ⌘ + z ctrl + z | ctrl + z | | Redo | ctrl + y ⌘ + shift + z ctrl + shift + z | ctrl + y | | Clear selection | Backspace Delete | Backspace Delete | | Open cell editor | F2 | F2 | | Toggle \$ cell locks | F4 | F4 | | Fill down | ctrl + d | ctrl + d | | Fill right | ctrl + r | ctrl + r | | Copy | ⌘ + c | ctrl + c | | Cut | ⌘ + x | ctrl + x | | Paste | ⌘ + v | ctrl + v | | Paste special | ⌘ + ctrl + v | ctrl+alt+V | | Paste values | ⌘ + shift + v | ctrl + shift + v | ## Rows and columns | Action | Mac | PC | | - | - | - | | Select column | ctrl + space | ctrl + space | | Select row | shift + space | shift + space | | Insert cells | ctrl + shift + = | | | Remove cells | ctrl + shift + - | | | Hide row | ctrl + 9 | ctrl + 9 | | Hide column | ctrl + 0 | ctrl + 0 | ## Navigate spreadsheet | Action | Mac | PC | | - | - | - | | Cell navigation | arrow keys | arrow keys | | Move up cell | shift + enter | shift + enter | | Move down cell | enter | enter | | Move right cell | tab | tab | | Jump through selections | ⌘ + arrow keys | ctrl + arrow keys | | Select cells | shift + arrow keys | shift + arrow keys | | Move left one cell | shift + tab | shift + tab | | Move to cell A1 | ⌘ + home fn + ⌘ + ← | ctrl + home | | Previous sheet | ctrl + shift + pageup | ctrl + shift + pageup | | Next sheet | ctrl + shift + pagedown | ctrl + shift + pagedown | ## Formatting cells | Action | Mac | PC | | - | - | - | | Bold | ⌘ + b ctrl + b | ctrl + b | | Italics | ⌘ + i ctrl + i | ctrl + i | | Underline | ⌘ + u ctrl + u | ctrl + u | | Strikethrough | ⌘ + shift + x | ctrl + shift + x | | Increase decimal | ctrl + shift + , | | | Decrease decimal | ctrl + shift + . | | # Alt mode shortcuts Equals supports the full set of Excel alt mode shortcuts. On a Mac, use *option* to enter alt mode. On a PC, use *shift-alt* to enter alt mode. Once you enter alt mode you will see the toolbar light up. You can then follow the hints to systematically trigger any action in the spreadsheet. For example, press *H* to access any of the associated actions in the blue area above. From here, hitting *1* will toggle bold on the selected cell. *** [Supported functions](/docs/supported-functions) [Spreadsheet formatting](/docs/spreadsheet-formatting) # Manage dashboard access and permissions Source: https://docs.equals.com/docs/manage-dashboard-access-and-permissions Select who can create, edit, and view a dashboard Equals give you complete control over who can view and edit your dashboards and their underlying data. ### Workbook Permission Inheritance Dashboards inherit the permissions of the workbook they are contained in. The folder's permissions are inherited if the workbook is contained in a folder. See [Sharing workbooks](https://docs.equals.com/docs/sharing-permissions#sharing-workbooks) for full details on how permissions work in Equals. # View and edit access Click the `Share` in the top-right of the workbook to see and manage access settings for named and anonymous users. Note that only those with `Can edit` access can change these settings. ## Can edit This will allow people to view and edit the dashboard and sheets in the workbook. ## Read only People with this level of access will be able to view, but not edit, the dashboard and sheets in the workbook. ## Dashboard only Use this setting to allow people to view, but not edit, the dashboard. Sheets in the workbook will not be accessible. # Anonymous access If you'd like to make your dashboard viewable by anyone without requiring an Equals account, simply change the access setting for`Anyone with the link` to `Can edit`, `Read only` or `Dashboard only`. This is how a dashboard will appear to people without an account when `Anyone with the link` is set to anything other than `Must be invited`. *** What’s Next * [Send dashboards to email and Slack](/docs/send-dashboards-to-email-and-slack) # Manage access to views Source: https://docs.equals.com/docs/managing-access-to-views Determine who can create, edit, and query a view. Access to a view is determined by permissions to the underlying datasource. To give people access to a view, you'll need to [grant them access](https://docs.equals.com/docs/sharing-permissions#sharing-datasources) to the corresponding datasource. Users who have access to a given datasource can: * See any corresponding views in the views list. * Create, modify, or delete those views. * Query those views from any workbook. ### Dependency visibility Currently, all users in your workspace can see the downstream dependencies of a given view from the **`Used by...`** list, even if they don't have access to those dependent views. This ensures visibility into the impact of any changes made. However, users cannot see or modify any dependent views they don’t have access to. Users that do not have access to a given datasource will see a **`Request access`** screen when attempting to open a corresponding view. Selecting **`Request access`** sends a request to the creator of that datasource (as listed on the [Datasources page](https://go.equals.com/datasources) in your workspace). *** [Create and edit views](/docs/create-views) [Query views from a workbook](/docs/querying-views-from-a-workbook) # Managing your ARR Build Source: https://docs.equals.com/docs/managing-your-arr-build Configure and maintain your custom ARR Build You can customize your ARR reports in Equals by adjusting the configuration settings of your ARR Build to match your business's specific revenue logic. Any changes you make will automatically trigger a rebuild of your ARR Build views, updating any analyses and reports built off them in workbooks. You can also make corrections to Stripe invoices and define exclusions (specific customers and domains). Doing so will override the underlying Stripe data and be reflected in your ARR Build views, so you can rest assured that any reports or analyses built off views accurately reflect your business's true ARR. # Configuring your ARR Build logic By default, your ARR Build is configured to reflect how most SaaS businesses recognize different ARR events based on your Stripe invoices. You can edit the default configuration settings as needed for your business from your ARR Build configuration settings (`Views` > `ARR Build` > `Configuration`). From here, you'll be able to determine how your business will recognize revenue across five dimensions: 1. **New ARR Event** **Options:** Count ARR at the time of contract signing or upon the first payment. **Recommendation:** Self-serve B2C companies may prefer counting ARR after the first successful payment. This lowers your overall ARR but will also prevent inflation in churn due to customers that never activate. B2B businesses may prefer to count ARR immediately. 2. **Churned ARR Event** **Options:** Stop tracking ARR upon a customer's cancellation request or at end of the billing period. **Recommendation:** Ending ARR at billing end often aligns with revenue recognition. Ending ARR on a cancellation request would enable a more accurate view of customer retention and future ARR. 3. **Restarted ARR Cut-off Window** **Options:** Count returning customers as “Restart ARR” always or only if they return within a set time. **Recommendation:** Most businesses choose to count all returning customers as Restart ARR. 4. **Paid Trials** **Options:** Include paid trials in ARR or exclude them. Free trials are excluded by default. **Recommendation:** Including paid trials could impact the start date for counting ARR. Depending on your trial conversion rates, it may also impact churn and retention metrics. 5. **Discounts** **Options:** Ignore or subtract discounts from your ARR. **Recommendation:** Subtract discounts to better reflect actual revenue collected. If your business requires more advanced customization than what's available, or if you need help determining the configuration settings for your business, our team of [Equals Experts](https://equals.com/experts/) is ready to help. Just reach out to us via the messenger in the bottom-right corner of your workspace Home. # Managing Stripe invoice corrections While your ARR Build configuration settings will cover most cases of recognizing revenue, you can also make one-off corrections to Stripe invoices as needed. For example, you could adjust revenue recognition dates for a specific invoice to reflect when a deal was signed versus when the customer was invoiced. You can view and edit all corrections made to date from the `Data corrections` tab of your ARR Build. Corrections override the underlying Stripe data, which will be reflected in the ARR Build views. To make a correction: 1. Go to the `Data corrections` tab, and then navigate to `Review data`. 2. Select a customer to see a list of Stripe invoices associated with that customer. 3. Choose the invoice you want to correct. 4. Click `Make a correction`, then adjust the invoice start date, end date, and/or ARR amount as needed: 1. **Start Date**: Adjust start dates to be based on contract signing, first invoice, or other custom deal requirements. 2. **End Date:** Modify end dates for invoices, useful for cases when invoices are mistakenly marked as non-recurring revenue. You can adjust the end date for a specific invoice to help your ARR smoothly transition to the next billing cycle. 3. **ARR Amount:** Customize amounts to reflect updated ARR values or zero out as needed for non-recurring revenue items. 5. Add a note to describe the correction if needed. 6. Click `Save changes`. Corrections will be marked with a purple label in the invoice list from the `Review data` screen. You can return to a corrected invoice at any time to edit the correction. # Managing customer and domain exclusions You can exclude ARR events from specific customers or domains from showing up in your ARR Build views and reports. To see a list of all exclusions made to date, go to `Data corrections` > `Exclusions`. To exclude a customer: 1. Go to `Data corrections` > `Review data`. 2. Select the customer you want to exclude. 3. Click `Exclude customer` to remove them from your ARR Build. To reinclude a customer, simply select Reinclude in ARR. Doing so will automatically trigger a rebuild of your ARR Build views. To exclude a domain: 1. Go to `Data corrections` > `Exclusions`. 2. Type the domain name you want to exclude. 3. Click `Exclude domain`. To re-include a domain, click the "X" next to the excluded domain in the list. Doing so will automatically trigger a rebuild of your ARR Build views. # Next steps With your ARR Build configured, your ARR reports will be tailored to your business's specific revenue logic. From here, you're ready to[ edit](https://docs.equals.com/docs/create-and-edit-dashboards) (if needed) and start [distributing](https://docs.equals.com/docs/send-dashboards-to-email-and-slack) your pre-built reports to your team, investors, or board. Then, you can build out [custom analyses and reports](https://docs.equals.com/docs/understanding-and-using-your-arr-build) using ARR data that's fresh, accurate, and trustworthy. *** [Get started with your ARR Build](/docs/arr-build-get-started) [Using your ARR Build views](/docs/using-your-arr-build-views) # Memories API Source: https://docs.equals.com/docs/memories-api Memories are facts the Equals AI analyst remembers about your workspace — context it has learned from conversations, or that you've added yourself on the [Memories page](https://go.equals.com/memories). The Memories API lets you manage them programmatically: sync context from other systems, audit what the analyst knows, or build your own tooling on top. All endpoints live under: ``` https://go.equals.com/api/v1 ``` *** ## Authentication Requests are authenticated with an API token, passed as a bearer token: ```bash theme={null} curl https://go.equals.com/api/v1/memories \ -H "Authorization: Bearer eq_your_token_here" ``` To create a token, go to **Settings → API tokens** in Equals and click **Create token**. The token is shown only once, at creation — store it somewhere safe. Tokens act as you, scoped to the workspace they were created in, and can be revoked from the same page at any time. Screenshot-2026-07-23-at-11.05.08-AM *** ## The memory object ```json theme={null} { "id": "2f1b6a9c-8f4e-4c1a-9b2d-7e5f3a1c8d4b", "content": "Fiscal year starts in February. Q1 = Feb–Apr.", "created_at": "2026-07-21T18:30:00Z", "updated_at": "2026-07-21T18:30:00Z" } ``` | Field | Type | Description | | - | - | - | | `id` | string | Unique identifier for the memory | | `content` | string | The memory itself, as plain text | | `created_at` | string | When the memory was created (ISO 8601) | | `updated_at` | string | When the memory was last updated (ISO 8601) | *** ## List memories ``` GET /api/v1/memories ``` Returns all memories in the workspace, newest first. ```bash theme={null} curl https://go.equals.com/api/v1/memories \ -H "Authorization: Bearer $EQUALS_API_TOKEN" ``` ```json theme={null} { "memories": [ { "id": "2f1b6a9c-8f4e-4c1a-9b2d-7e5f3a1c8d4b", "content": "Fiscal year starts in February. Q1 = Feb–Apr.", "created_at": "2026-07-21T18:30:00Z", "updated_at": "2026-07-21T18:30:00Z" } ] } ``` *** ## Get a memory ``` GET /api/v1/memories/:id ``` ```bash theme={null} curl https://go.equals.com/api/v1/memories/2f1b6a9c-8f4e-4c1a-9b2d-7e5f3a1c8d4b \ -H "Authorization: Bearer $EQUALS_API_TOKEN" ``` Returns the memory object. *** ## Create a memory ``` POST /api/v1/memories ``` | Parameter | Type | Description | | - | - | - | | `content` | string | Required. The memory to remember. | ```bash theme={null} curl -X POST https://go.equals.com/api/v1/memories \ -H "Authorization: Bearer $EQUALS_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"content": "ARR excludes one-time services revenue."}' ``` Returns the created memory object with status `201`. *** ## Update a memory ``` PATCH /api/v1/memories/:id ``` | Parameter | Type | Description | | - | - | - | | `content` | string | Required. The new content. | ```bash theme={null} curl -X PATCH https://go.equals.com/api/v1/memories/2f1b6a9c-8f4e-4c1a-9b2d-7e5f3a1c8d4b \ -H "Authorization: Bearer $EQUALS_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"content": "ARR excludes one-time services and setup fees."}' ``` Returns the updated memory object. *** ## Delete a memory ``` DELETE /api/v1/memories/:id ``` ```bash theme={null} curl -X DELETE https://go.equals.com/api/v1/memories/2f1b6a9c-8f4e-4c1a-9b2d-7e5f3a1c8d4b \ -H "Authorization: Bearer $EQUALS_API_TOKEN" ``` Returns an empty response with status `204`. *** ## Errors Errors are returned as JSON with an `error` message: ```json theme={null} { "error": "Unauthorized" } ``` | Status | Meaning | | - | - | | `401` | Missing, invalid, revoked, or expired API token | | `403` | The token's user is no longer a member of the workspace | | `404` | No memory with that id in the workspace | | `422` | Invalid request — for example, creating a memory with empty `content` | # Netsuite Source: https://docs.equals.com/docs/netsuite Connect your NetSuite instance to Equals To connect NetSuite to Equals you will need to take several sequential steps which include: * Enabling API connections in NetSuite * Identifying your Account ID * Creating a Client ID and Client Secret, and * Creating a Role and User to obtain your Token ID and Token Secret. Once you've connected successfully using this information, you'll be able to query all data from NetSuite. You can also create Reports to bring your custom NetSuite reports into Equals. Note: NetSuite is an enterprise connection so you'll be prompted to schedule a setup call with our team before getting connected. *** # Enabling API connections in NetSuite To begin, log in to NetSuite and select *Setup* from the toolbar, then *Company* > *Enabled Features*. Here, you'll click on the *SuiteCloud* tab. Under *SuiteTalk (Web Services)*, enable *SOAP Web Services* and *REST Web Services*. Under *Manage Authentication*, enable *Token-based authentication*. Your setup should look like the image below: Once you've done this, scroll to the bottom of the page and select Save. *** # Finding your Account ID Your Account ID can be found in your NetSuite URL, which should look something like this: [https://1234567.app.netsuite.com/app](https://1234567.app.netsuite.com/app). In this example, your Account ID is the first string (`1234567`). You can also find your Account ID by navigating to *Setup > Company > Company Information*. Here, you'll see your Account ID listed along with other company details. *** # Obtaining your NetSuite Client ID and Client Secret key Once you have logged into your NetSuite account, navigate to *Setup > Integration > Manage Integrations > New.* This will bring you to a new screen where you can name your integration. Under the *Authentication* header, check *Token-based authentication* and uncheck *TBA: Authorization Flow*. Under the OAuth 2.0 header, uncheck *Authorization Code Grant.* Your final configuration should look like this: Click *Save.* A Client ID key and Client Secret key will populate below (note: this will only be visible once, so be sure to copy this to enter into the Equals datasource setup page). *** # Creating a Role Navigate to *Setup -> Users/Roles -> Manage Roles*. Next to your user's role listed, click *Customize.* This will create a copy of your role, and you'll want to give this role a name (ex: `Equals Datasource`). Ensure that you add the following permissions necessary for API access: * Log in using Access Tokens * REST Web Services * SOAP Web Services. *** # Creating a User Navigate to *Lists > Employees > Employees > New*. For the employee name, you'll want to use `Equals Datasource` or something similarly recognizable. Finally, under the *Access* section, select *Give access*. Still under *Access*, in the *Roles* section, add the role created above. Your setup should look like this: Then select *Save.* *** # Creating a Token ID and Token Secret Navigate to *Setup > Users/Roles > Access Tokens > New*. For *Application Name* select the Integration that was created above. For *User*, select the User that was created above. For *Role*, select the Role above that was assigned to the user. Give the token a name (ie. `Equals Datasource Access Token`). Once you click *Save*, you'll see the tokens revealed below. Record the **`Token ID`** and **`Token Secret`** (they won’t be shown again and these are the last details you'll need to enter into Equals). Now you have all the data you need to enter into Equals and can click *Save and Test* on the Equals datasource page. This will reveal a new section titled *Synced reports*. Clicking on *New* here will allow you to set up reports such as your Balance Sheet, General Ledger, etc. # Setting up Reports After you've successfully connected to NetSuite, click on *New* next to the *Reports* listing. This will walk you through the creation of a *Saved Search* in NetSuite that will set up a process by which Equals ingests CSV files sent on a scheduled cadence by NetSuite, so that you receive this data in your spreadsheet seamlessly. *** [Google Sheets](/docs/google-sheets) [Plaid](/docs/plaid) # Organizing workbooks for analysis Source: https://docs.equals.com/docs/organizing-workbooks-for-analysis Structure your spreadsheet tabs to create analyses that are easy to follow and understand. Here, we'll break down the best practices for organizing your workbook to ensure you can build a robust and scalable analysis that is easy for others to understand and collaborate on. Here's Bobby, Equals' Co-founder and CEO, with a quick walkthrough of the key takeaways. [Watch on YouTube](https://www.youtube.com/watch?v=_pHPyyRRoBU) # Understanding workbooks Analyses are built in `workbooks`. Creating a workbook is like creating a document in a Word processor (e.g. Microsoft Word, Google Docs). If you've used Excel, it's the equivalent of creating a new file. Workbooks are comprised of multiple spreadsheet `tabs` (also known as sheets) that all can reference one another. The best practice is to keep workbooks as compact as possible so that as you add data and invite teammates to work with them, they’re easily understood and less likely to break. We recommend keeping workbooks limited to one topic. For example, you might have a workbook that houses your revenue forecast. Another workbook that houses your product engagement statistics. And another workbook where you track your sales pipeline and forecast. You can link workbooks if you need to pull those things together. # Structuring your workbook with tabs Knowing how you set up your workbook is important as you dive into an analysis. You want to organize your workbook so teammates can easily understand it and re-use it with minimal upkeep and chance of breaking. The best practice here is to organize the tabs in your workbook into four categories: 1. **Data tabs.** These tabs house the raw data returned from querying a data source, and are the foundation upon which your analyses are built. In Equals, [you can build, run, and refresh queries](https://docs.equals.com/docs/queries) directly from this tab to update your analysis. Keeping these tabs focused solely on your queried data outputs makes your workbook easy to understand, maintain, and scale over time. Don’t build your analysis in these tabs. 2. **Input tabs.** These tabs house reference information you might use to build an analysis. They support the `Data` and `Analysis` tabs and are typically manually maintained and updated. As with `Data tabs`, don’t build analyses in your `Input tabs`. 3. **Analysis tabs.** This is where you summarize or extract insights from your data using formulas to pull and aggregate data from your `Data tabs`. This is also where you’ll do any further analysis – whether it’s simple metrics inferred from your aggregations, extrapolations, or visualizations, it should all happen in analysis tabs. 4. **Dashboard tabs.** This is where you can transform your analysis into a consumable format that highlights the most important insights in a logical order. [With Equals' dashboard builder](https://docs.equals.com/docs/building-and-sharing-dashboards), you can add charts, tables, cells, and more directly from your workbook. You can also [schedule dashboards](https://docs.equals.com/docs/dashboard-scheduling#dashboard-destinations) to automatically send to Slack or email - hourly, daily, weekly, or monthly - so stakeholders always have access to the latest data. # Grouping and color-coding tabs We recommend grouping tab types together, i.e. all `Data tabs` should live next to one another in a workbook. We also recommend color-coding tabs in the same category for clearer organization, e.g., make all your `Input tabs` gray and all your `Analysis tabs` purple. This will make it easier for other stakeholders to understand how your analysis comes together. Next, we’ll explain best practices for setting up each tab type. *** What’s Next * [Preparing data for analysis](/docs/preparing-data-for-analysis) # Pivot tables Source: https://docs.equals.com/docs/pivot-tables Aggregate data using pivot tables With Pivot Tables you can analyze any data in your Equals workbooks without writing formulas. Pivot Tables are particularly powerful in Equals as you can pivot directly off data from your SQL database, data warehouse, Salesforce, or Quickbooks instance. To create a Pivot Table: 1. Select the data you'd like to analyze, click *Insert* > *Pivot Table*. You'll see the Pivot Table configuration sidebar where you can set up your analysis. 2. Select the + button to add fields from your data as rows, columns, or values to be displayed in the pivot. 3. Click on the field to customize the data displayed. There are multiple ways to summarize your data: * By adding fields as *Rows*, you'll generate a unique list of all the values in that field as separate rows. * By adding fields as *Values*, you'll be able to choose how to aggregate the data in that field (e.g., sum, count, average, min, max). * By adding fields as *Columns*, you can break down pivots by one or more dimensions across separate columns. # Advanced features Pivot Tables support a number of advanced features: * **Sort by** can be used to organize your pivot table based on a specific value. Clicking into a field will allow you to use the sort by functionality. * **Totals** toggle to show or hide grand totals, can also be handled at the field level. Clicking into a field will allow you adjust this at the field level. * **Calculated Fields** can be used to add a field based off the source data. For example, if you had a "Total Spend" field and a "Number of Purchases" field, you could create an "Average Spend" calculated field that divided the first by the second. Use the "Calculated Column" text visible in the drop-down for Rows, Values, or Columns (after clicking on the + button) to create and insert a Calculated Field. * **Summary Functions** can be used to summarize your values in different ways. e.g. Sum, Count, Min, Max, etc. To change the Summary Function used, click on a displayed field and choose the function you would like to summarize by. * **Filters** can be used to filter an existing analysis. To filter your analysis, click on the + icon next to the Filter section to add a field you’d like to apply a filter over. Note: date filters will not include future dates (ex: if you select “January 2022” on the 4th of January, the 5th of January will not be displayed as the filter will be identical to the selection on the date of pivot creation). *** [Spreadsheet formatting](/docs/spreadsheet-formatting) [Charts](/docs/charts) # Plaid Source: https://docs.equals.com/docs/plaid Connect your company's bank account to Equals via Plaid Equals can connect to any bank account via Plaid. With a connected bank account Equals becomes the fastest way to do cash burn and reconciliation analyses. # Getting connected To connect a bank account via Plaid: 1. Head to *Datasources* from the Equals home screen 2. If you're yet to add a datasource, you will see a list of available datasources. Otherwise, click *New Datasource* in the top right corner. 3. Choose *Bank Account (Plaid)* from the list. 4. Give your datasource a name – this is how it'll appear through out Equals – and then click *Connect to your bank* and follow the steps in the Plaid modal. Once connected, you'll be able to query your Plaid data directly from any Equals workbook, using either the SQL editor or Query Builder. # Security FAQ ## What access does Equals get to our bank? Equals only requests read-only access to your bank. We have no ability to modify any data or make any transactions. ## What is stored when I connect a bank account to Equals? Equals never has access to your bank account's username and password – that is handled by Plaid, an industry leader used by apps like Venmo. When you connect a bank account to Equals, we store credentials given to us by Plaid that allow us limited access to your bank account. These credentials are stored encrypted in our database, with keys only accessible to production servers. *** [Netsuite](/docs/netsuite) [Quickbooks](/docs/quickbooks) # PlanetScale Source: https://docs.equals.com/docs/planetscale Connect a PlanetScale database with our MySQL connector To connect to PlanetScale from Equals, choose MySQL as the datasource type and follow the instructions below. # Finding connection details 1. Find the database you want to connect to in the PlanetScale dashboard. 2. Click *Connect* in the top right. 3. In the modal that opens select *General* in the *Connect with* dropdown. 4. You will now see the **`database [name]`**, **`user`** and **`host`** for your database. The **`password`** was set when setting up the database. If you don’t know the password you can click *New password* above the connection details. Note: this will also update the username. 5. The **`port`** for PlanetScale is always `3306`. # Allowing access from our IP PlanetScale does not support limiting inbound connections by IP address and so no further action is required beyond the steps above. *** [DigitalOcean](/docs/digitalocean) [Railway](/docs/railway) # Plausible.io Source: https://docs.equals.com/docs/plausibleio Example Javascript code for importing data from Plausible.io You can use Import Scripts to import data from your Plausible.io account directly into an Equals workbook. # Create a Plausible personal access token You can obtain a Plausible API Key from your account by going to your user settings page [plausible.io/settings](https://plausible.io/settings). # Add the key to a secret group Copy the access token from the prior step. Then [create a new secret group](https://docs.equals.com/docs/secret-groups) and paste the key into a new secret named `plausible_io_api_key`. # Example code Once you've completed the prior steps, create a new workbook, add a new import script to a sheet and copy + paste the script below. Once pasted select your secret group in the toolbar (make sure the key in the secret group is called `plausible_io_api_key`). ``` const equals = require('equals');const axios = require('axios');const luxon = require('luxon'); const baseUrl = 'https://plausible.io/api/v1/stats/';const siteId = 'interval.com';const apiKey = equals.getSecret('plausible_io_api_key'); function formatJSDate(jsDate) {return luxon.DateTime.fromJSDate(jsDate).toFormat('yyyy-LL-dd');} const response = await axios.get(baseUrl + 'timeseries', {params: {site_id: siteId,period: 'custom',date: '2022-06-01,' + formatJSDate(new Date()),interval: 'date',metrics: 'visitors,bounce_rate',},headers: {Authorization: `Bearer ${apiKey}`,}}); equals.addRows(response.data['results']); ``` *** [Typeform](/docs/typeform) [Writeback to CRM](/docs/write-back-to-hubspot) # Preparing data for analysis Source: https://docs.equals.com/docs/preparing-data-for-analysis Correctly pull and structure raw data to build robust analyses that scale. `Data tabs` are the foundation of your analysis. They’re where you house and prepare your data. Here, we'll walk through how to structure your queried data in a tabular format to ensure you can build a scalable analysis. Here's Bobby with a quick walkthrough of what you can expect to learn. [Watch on YouTube](https://www.youtube.com/watch?v=82zzEYygV1U) # Setting up a Data tab When setting up a query (i.e., a data pull), the best practice is to condense like attributes into a singular column. For instance, a single column denotes the location and another transaction amount. Also, be sure to aggregate data at its minimum level of granularity. For example, group by day, month, or year. Let’s walk through an example: Imagine we want to set up a `Data tab` to power a revenue-by-country analysis. The ***WRONG*** way would be to set one up like the example below, where revenue for each country is broken out into multiple columns. Why is this wrong? It makes maintaining and updating your analysis much more difficult. When you go to build your `Analysis tab`, you'll have to change reference columns for *every* country. You won't be able to reuse formulas (we’ll walk you through this later), creating redundancy and more work for you. Similarly, if we wanted to add a new country, say Australia or Japan, we’d have to insert a new column and move our `Total Revenue` (column G above) over. Consequently, we must update the `Data tab` and rework any `Analysis tabs` to reference the new columns correctly. So, what’s a better approach? Collapse all countries into one single column. Here’s the ***CORRECT*** way to set up this `Data tab`. In this case, all countries are now contained in a single column. There are many more rows, but that’s OK because, as we learned earlier, expanding by adding rows is more scaleable. Additionally, spreadsheets are designed to perform well doing columnar calculations (we’ll show you how later in this guide). More importantly, on the `Analysis tab`, we only have to reference column C (`Revenue`) vs. every individual country column for any revenue calculations. And if we want to add other countries down the line, the structure of the `Data tab` doesn’t need to change. ### Query datasources in your spreadsheet In Equals, connected sheets allow you to [query datasources](https://equals.com/explorer/) directly from your workbook, making it easy to build analyses with live data. # Infinity Sheets Infinity sheets are only supported when connected to datasources stored in the **Equals data warehouse.** ### Converting to Equals Infinity By default, Equals workbooks have a 5 million cell limit. If exceeded, workbook performance may begin to slow down. If you need to work with data beyond the above limits, you can use Equals Infinity. Equals Infinity allows you to query and analyze significantly larger datasets without row or cell limits. However, it does come with some limitations compared to standard sheets, including *no support for calculated or notes columns, and the inability to build pivot tables or charts directly on Infinity data*. To switch to an infinity sheet, open your Query Builder / SQL Editor window, then select the down arrow next to "Run Query." A pop-up window will appear saying "Convert to infinity and run." Clicking that button will swap your sheet to an Infinity sheet. # Enriching and expanding your Data tab The other benefit of this tabular format is that the data is now structured, so expanding our analysis is simple and scalable. For example, we know that we need to analyze revenue by `Country`, but we might also need to be prepared to ask questions about revenue based on who owns it (i.e., a specific `VP of Sales`) and perhaps also based on the `Region` a given country rolls up to. This is where `Input tabs` become useful. Below is an example of one that summarizes `Country Details`. While it may seem overly simple, it’s worth maintaining separately–you’ll see why later. We’ll use this as a reference in our `Data tab` to return the `VP Sales Owner` for each `Country` returned by our query. We'll do this by adding a new column, `Owner`, to our tabular data set and use the `VLOOKUP` formula to return the specific value in a data set that matches an input value. ### Auto-expand formulas as your data set grows In Equals, columns that contain functions/formulas alongside a dataset returned from a query are called [Calculated columns](https://docs.equals.com/docs/calculated-columns). They're great because they auto-expand as your data set expands, so you don't have to do so manually. So, how does this make our analysis simpler and more robust to support scale? You’ll see many benefits when we learn how to build the `Analysis tab`. First, let’s see how scalable this is by adding more countries from a new region, e.g., Australia and Japan from APAC. Because we've set up our `Data tab` correctly, all we have to do is add two rows to our `Input tab`. Now, the `Owner` and `Region` columns in the `Data tab` will automatically update whenever the query returns data for Australia and Japan. Now think back to the original, ***WRONG*** way we’d structured our `Data tab`, and imagine trying to add things like`Region` and `Owners` or new countries. It'd be a bunch of extra work and time wasted. ### In summary: * Structure your query results in `Data tabs` in a tabular format * Expand `Data tabs` downwards by adding new rows * Avoid queries that add new data by adding additional columns * Append calculations and additional metadata alongside your query results using `Input tabs` Now we'll discover more benefits of structuring our `Data tab` in tabular format as we explore building out an analysis. *** What’s Next * [Building and sharing analyses](/docs/building-and-sharing-analyses) # Scheduling queries Source: https://docs.equals.com/docs/query-scheduling Schedule queries to refresh on a schedule that works for your team With query scheduling, you can set queries to refresh on an hourly, daily, or weekly basis. When the scheduled query runs, it will refresh the associated data and update all formulas in your workbook that depend on that data. To schedule a query: 1. Open the *Connections* panel from the top right corner of your workbook. 2. Navigate to the specific query you'd like to schedule. 3. Click *Schedule* above the *Run Query* button. 4. Select whether to run your query on an hourly, daily, or weekly basis. For daily or weekly query runs, select a specific time or day on which to refresh your query. You can also schedule all queries in a given workbook to update simultaneously. To do so: 1. Go to the *All Connections* tab of the connections panel. 2. Select the *Schedule* button beneath your connected datasources. 3. Schedule your queries to run on an hourly, daily, or weekly basis. *** [Data notes & edits](/docs/data-notes-edits) [Saved queries](/docs/saved-queries-1) # Query version history Source: https://docs.equals.com/docs/query-version-history Restore past versions of queries and their output data With query version history, your workbook will automatically keep a copy of every query and the resulting data that was returned from that query. From the version history panel, you can easily restore past versions of a query and the associated data. Currently, query version history is not supported for [views](https://docs.equals.com/docs/views-1). To restore a previous query run: 1. Navigate your connected sheet. 2. Click on the `History` button on the top-left side of the editor. 3. Select a previous version of the query to restore. 4. Select a restore option from the drop-down menu on the `Restore` button. If you click *Restore query and data*, that version of the query and the associated output data will be returned. If you click *Restore query only*, a query run will not complete and only the query syntax will be restored. *** [Building queries](/docs/building-queries) [Joins](/docs/joins) # Query views from a workbook Source: https://docs.equals.com/docs/querying-views-from-a-workbook Query a synced view from any Equals workbook for further analysis Once a view has been synced, any user with [access](https://docs.equals.com/docs/managing-access-to-views) to its underlying datasource will be able to [query](https://docs.equals.com/docs/building-queries) that view from any Equals workbook for further analysis. To do so, first open an Equals workbook. Then select **`Connect data`** in the top right corner. From here: 1. Select the datasource your view has been synced to. 2. Select either the query builder or SQL editor. 3. Query the view as you would any other table in the data schema. You'll need to select the table name that corresponds with the view as it is reflected in view settings. *** [Manage access to views](/docs/managing-access-to-views) [Import scripts](/docs/write-an-import-script-connection) # Quickbooks Source: https://docs.equals.com/docs/quickbooks Connect your QuickBooks instance to Equals To create a new Quickbooks connection: 1. Go to the *Datasources* page from the Equals home screen. 2. If you're yet to add a datasource, you will see a list of available datasources. Otherwise, click *New Datasource* in the top right. 3. Select *QuickBooks*, then give your datasource a name that will be used throughout Equals 4. Click *Connect to QuickBooks* and follow the steps. You’ll be asked to connect via OAuth and then follow secondary steps to connect to your Quickbooks instance. # Querying from Quickbooks Once you've connected your QuickBooks instance, you will be able to query your Quickbooks data using either the Query Builder or SQL Editor. In addition, you will see a *Report Sync* option from the connections panel. *Report Sync* will allow you to pull prebuilt reports from QuickBooks into your spreadsheet, so that you don’t need to write many lines of SQL to get your traditional P+L or General Ledger in a usable format. By default, reports will populate the spreadsheet in the same format as they can be downloaded from QuickBooks. If you would like to reconfigure this data into a tabular format, you can select the *flatten file* toggle and your data will be displayed in a formula-friendly (tabular) manner. *** [Plaid](/docs/plaid) [Salesforce](/docs/salesforce) # Railway Source: https://docs.equals.com/docs/railway Connect a Postgres or MySQL databased hosted on Railway Railway supports both Postgres and MySQL databases. The instructions are the same for both. To get started sign in to Railway and select the project that contains your database. # Finding connection details 1. Select your database from the project home screen. 2. Once viewing the database, click *Connect* in the tab bar. 3. Click *Show* to the right of *Postgres Connection URL*. 4. Within Equals click *Use connection string instead* and paste the connection string, with the password shown, from Railway. You should now be able to connect to your database from Equals. # Enabling access from our IP Railway does not support limiting inbound connections by IP address and so no further action is required beyond the steps above. *** [PlanetScale](/docs/planetscale) [Snowflake](/docs/snowflake) # Resources & tutorials Source: https://docs.equals.com/docs/resources Resources for self-learning and ways to get in touch for further support # Product demos * [Equals in 2 minutes](https://www.youtube.com/watch?v=fdYRixIOTBA) * [Command Bar and AI Assist](https://www.youtube.com/watch?v=9oX1y2JwR84) * [Query joins](https://www.youtube.com/watch?v=7mzw-r11ZDg) * [Dashboards]() * [Stripe integration](https://www.youtube.com/watch?v=w-X4YvixiC8) * [Salesforce integration](https://www.youtube.com/watch?v=4ct3urW-_ts) * [Quickbooks integration](https://www.youtube.com/watch?v=c0__Ssx-aXQ) # Get in touch ## Contact support Reach out to Equals support by opening the messenger widget in the bottom right corner of your screen. You can also email us at [\[email protected\].](mailto:help@equals.com) ## Contact sales [Speak with our sales team](https://go.equals.com/access/new) for more information on pricing, choosing a plan, or to request a demo. # Get updates ## Subscribe to our changelog The [changelog](https://updates.equals.com/changelog) is the best place to keep tabs on product updates and changes (you can also subscribe to get update notifications). You can access the changelog from within Equals by clicking on *Product updates* in the bottom left corner of your screen. ## Subscribe to our blog (WrapText) Discover our latest insights on company building, business strategy, finance & analytics, marketing, and more on our [blog](https://wrap-text.equals.com/). We're committed to building in public and transparently sharing the successes (and failures) we encounter along the way. *** [Datasources FAQ](/docs/faq) [Workspace setup](/docs/workspaces) # Salesforce Source: https://docs.equals.com/docs/salesforce Connect your SFDC instance to Equals To create a new Salesforce connection: 1. Head to the *Datasource* page from the Equals home screen 2. If you're yet to add a datasource, you will see a list of available datasources. Otherwise, click *New Datasource* in the top right corner. 3. Select *Salesforce*, then give your datasource a name that will be used throughout Equals. 4. Click *Connect to Salesforce* and follow the steps. Once you've connected to your Salesforce instance, you'll be able to build analyses and dashboards powered by live Salesforce data, straight from your Equals workbook. For a quick demo, watch the video below. You'll also be able to work with the Equals team to configure an [ARR Build Blueprint](https://dash.readme.com/project/equals/v1.0/docs/create-and-configure-the-arr-build-blueprint). This provides clean, analysis-ready [views](https://dash.readme.com/project/equals/v1.0/docs/create-views) based on your raw Stripe data (including Daily ARR and Daily ARR by Customer) that can be used to build accurate ARR analyses and reporting. [Watch on YouTube](https://www.youtube.com/watch?v=4ct3urW-_ts) *** [Quickbooks](/docs/quickbooks) [Segment](/docs/segment) # Saved queries Source: https://docs.equals.com/docs/saved-queries-1 Use saved queries to ensure that data is pulled consistently across workbooks Saved queries enable workspace members to create, share, and manage queries and import scripts. Changes to a saved query will automatically update across all workbooks in which that saved query is used, ensuring that data is pulled consistently across multiple analyses. # Creating and updating saved queries To create a saved query: 1. Select the *Saved Queries* listing on the left hand side of the Equals home screen, then click *Create a Saved Query.* Note that you can also create a saved query from an existing query within a workbook, by clicking on the`...` dropdown. 2. Connect to a datasource and write your query using the query builder or SQL editor. You can select *Preview Query* to review the output as you build the query, and can even create calculated columns in the preview area. 3. When ready, give your query a name at the top of the editor. If you select the icon adjacent to the title, you can also add a description. Then click *Create*. You can update this query at any time by making changes to the saved query and then selecting *Publish Changes* in the top right corner of the editor. The published changes will be applied automatically across any workbook that uses that saved query. # Sharing saved queries To share a saved query, select the *Share* button in the upper right corner of your screen. You have two choices here, **`Read only`** and **`Can edit`** sharing. * **`Read only`** allows a user to execute the saved query but does not give the user any editing access to the saved query, nor visibility into the written command. * **`Can edit`** allows a user to make changes to the underlying query and allows them to view the saved query edit and preview console. To use a saved query, open a new workbook or sheet and click on the *Connections* button. Scrolling down, you’ll see saved queries listed. Clicking on the query and selecting *Connect* will pull the data into your workbook. # FAQ ### What if I share a query with someone who doesn't have access to the datasource? If you share a query with a user in run mode, they will be able to view the output of the query regardless of whether or not they have access to the datasource. They will not be able to modify the query in any way or view any additional information stored in the database. If you share a query with a user in edit mode, they will be granted access to the underlying database. ### What if I want to remove a user from a saved query? You can revoke access to a saved query, which will remove datasource access if the user previously had edit access to the saved query. Revoking access to a saved query will also remove any query runs from this database from all sheets they have access to. ### Will users be able to modify calculated columns in the saved query? No - the calculated columns created in the saved query previewer will appear as results only fields (in purple) when pulled into a workbook. *** [Scheduling queries](/docs/query-scheduling) [Spreadsheet fundamentals](/docs/supported-functions) # Schema refreshes Source: https://docs.equals.com/docs/schema-refreshes Datasource schemas will refresh automatically, or can be triggered manually Datasources will refresh automatically every six hours, but you can also trigger a refresh manually. To do so: * Navigate to a connected sheet. * Open the table browser from the editor. * Click on the 🔄 icon to manually refresh the schema. *** [Cell references](/docs/cell-references) [Data notes & edits](/docs/data-notes-edits) # Secret groups Source: https://docs.equals.com/docs/secret-groups Store Import Script secrets in an encrypted, shareable store With Import Scripts, you can write your own custom Javascript or Python code to import data from any API or internal tool directly into an Equals workbook. Secret Groups allow you to securely store secrets (API keys, passwords, etc.) outside your code, in an encrypted and shareable store. To create a new secret group, go to the Import Script settings (*Datasources > Import Script*) and click *Create Secret Group*: You can add any number of secrets and any number of users to a secret group. To use a secret group, you select it on a per-script basis in the Import Script toolbar. You can select as many as you want: Other users with access to the workbook can only run the script if they have access to all secret groups used. # Security FAQ ## How do you store my secrets securely? All secrets are stored encrypted in our database, with keys only accessible to the necessary production servers. Access to these servers is extremely restricted within the engineering organization. ## How do you keep my secrets safe within my organization? Secrets are only accessible to users with whom they are explicitly shared. Only users with access to all secret groups used in a script are able to run the script. *** [Writing import scripts](/docs/write-an-import-script-connection) [Examples](/docs/airtable) # Segment Source: https://docs.equals.com/docs/segment Connect your Segment instance to Equals Note: Segment is an enterprise connection so you'll be prompted to schedule a setup call with our team before getting connected. You'll want to start by copying the webhook URL listed on the first screen from the pop-up modal. Then, you can select "Save & Test" and you can select "Save changes" in Equals. This will enable access to Segment. In order to begin the transfer of data, you'll want to [log into your Segment account](https://app.segment.com/login/?ref=nav) and take the following steps: 1. From the Segment web app, navigate to Connections > Catalog. 2. Search for Equals in the Destinations Catalog, and select the destination. 3. Click **Add destination**. 4. Select the data source that will send data to Equals and give this destination a name. 5. Add your webhook URL copied from Equals into the URL field on this next step. 6. Select Enable destination. 7. If you want to be more granular about the data pushed from Segment into Equals, you can click on the "Mappings" header in the connection setting page (shown above) and can follow the steps in the Destinations Actions documentation on [Customizing mappings](https://segment.com/docs/connections/destinations/actions/#customize-mappings). You can create up to 5 mappings, each of which can send to a different webhook URL. After doing that, you can enable the destination and configured mappings. *** [Salesforce](/docs/salesforce) [Stripe](/docs/stripe) # Send dashboards to email and Slack Source: https://docs.equals.com/docs/send-dashboards-to-email-and-slack Put your reporting on autopilot by automatically distributing dashboards to stakeholders on custom schedules What's better than dashboards that auto-update? Dashboards that automatically distribute. ### Who can add and edit a destinations Only workspace members with `Can edit` permission for to the workbook can add and edit destinations. See [Manage dashboard access and permissions](https://docs.equals.com/docs/manage-dashboard-access-and-permissions) for more information. # Adding a destination Click on `Publish`in the top-right of a dashboard. From here, you can configure custom schedules (hourly, daily, weekly, or monthly) to automatically send a dashboard snapshot to selected destinations, including email and Slack. # Configuring a destination For both email and Slack, you'll see a preview of how your dashboard will appear and be able to choose: 1. How frequently you want to send a snapshot of your dashboard to that destination: 1. Hourly 2. Daily 3. Weekly 4. Monthly 2. The time you want it to send. Note that times are based on the workbook's defined timezone, which can be changed under `File` > `Settings`. 3. The email addresses or Slack channels you want to send it to. You can perform a test send before saving the destination. # Auto-refresh data before sending Your dashboard's charts, tables and cells will auto-update whenever the underlying data is updated. We recommend scheduling your dashboard to send to destinations *after* any [scheduled queries](https://docs.equals.com/docs/query-scheduling) are set to run to ensure recipients receive the most up-to-date version of the data on your dashboard. # Connecting Slack To send dashboards to Slack, you must first connect your Equals Workspace to your Slack Workspace. If a connection has not already been established, you will be prompted to do this when adding Slack as a dashboard destination for the first time. You can configure this connection anytime in your [Equals workspace settings](https://go.equals.com/settings?tab=workspace). Once your Equals Workspace is connected to your Slack Workspace, **you must invite the`Equals` Slack app to any *private* channels** you want to send dashboards to. This app is automatically installed when you perform step one. You do not need to do this for public channels. (Steps in Slack: open the invite page, select "Integrations" from the pop up, click on "Add an app" and search for "Equals".) ### A quick note on permissions Equals respects permissions in Slack. This means that Equals users can only see the Slack channels they can access in Slack when creating, editing, or viewing a scheduled destination. # FAQs ## Can I change a scheduled destination after saving it? Yes, you can modify and delete a scheduled destination at any time. ## Do I need to be a Slack administrator to set up a connection to Slack? Yes, you need to be an administrator of your Slack workspace to set up a connection to Equals. *** [Manage dashboard access and permissions](/docs/manage-dashboard-access-and-permissions) [Embed dashboards in Notion and more](/docs/embed-dashboards) # Sharing and permissions Source: https://docs.equals.com/docs/sharing-permissions Share and control access to your work in Equals This article will cover how collaboration works in Equals with an overview of permissions and sharing for datasources and workbooks. # Sharing datasources You can share access to real time data with anyone in Equals. This will allow users to write any query from the datasource. **Once you share a datasource with a user, they will be able to query that datasource as if they were the user who set it up.** To share a datasource, go to *Datasources* from the Equals home screen, then hit *Share* from the ... menu to the right of that datasource you'd like to share. You can then share the datasource with individual users by entering their email address and setting a permission level. You can also share edit access to the datasource with everyone in your workspace. If you select `Must be invited`, users in your workspace will not be able to view or query that datasource unless you share it with them individually. # Sharing views Access to views is determined by access to its underlying datasource(s). To give someone access to query a view in a workbook, you'll need to grant them access to the corresponding datasource under [Datasources](https://go.equals.com/datasources). Similarly, access to the [ARR Build Blueprint for Stripe](https://docs.equals.com/docs/create-and-configure-the-arr-build-blueprint) is determined by access to the Stripe datasource. Users who have access to the corresponding datasource can: * See any corresponding views or the ARR Build Blueprint in the [Views](https://go.equals.com/views) list * Create, modify or delete those views or the ARR Build Blueprint * Query those views or the ARR Build Blueprint in any workbook # Sharing workbooks To share a workbook, open that workbook and click *Share* in the top right corner. From the share modal, you can set the following permissions to determine workspace users' level of access to your workbook: * **`Read only`** - All users in your workspace, including Editors, will only be able to view your workbook and will not be able to make changes to it. * **`Can edit`** - All Editors in your workspace will be able to edit your workbook. Viewers will not be able to edit your workbook. * **`Dashboard only`** - All users in your workspace, including Editors, will only be able to view the dashboard included in your workbook. When sharing a workbook with an individual user, you can choose a permission level to give that user either `Read only` or `Can edit` access. ​ Workbooks can also be shared with your entire workspace, so that everyone at the workspace can view or edit the workbook. There are also a number of workspace-specific sharing options: * **`Must be invited`** - Users in your workspace will not be able to view that workbook unless you share the workbook with them individually. * **`Anyone with link`** - Allow anyone with the link to view your workbook, regardless of whether they have an Equals account. Users without an Equals account will only be able to view your workbook as an `Anonymous user`. Users with an Equals account will have `Read only` or `Can edit` access to your workbook, depending on the permission level you set. You can also share multiple workbooks at the same time by storing them in a folder, and then sharing access to the folder ([learn more](https://docs.equals.com/docs/folders-filters) about folders). You can also disable the ability to utilize the "anyone with link" sharing across your workspace from the [Settings](https://go.equals.com/settings?tab=workspace) page. Just toggle the "enable public link sharing" button under "Access control". This will allow anyone signed in and part of your workspace to be able to open the link, but will prevent any random access. ## Exporting workbooks To download data from an Equals workbook, we currently allow for CSV and Excel exports. You can open up the workbook you want to download and navigate to *File > Download as CSV* for each sheet you'd like to save. *Download as Excel* exports your entire workbook as a single `.xlsx` file that opens cleanly in Microsoft Excel, Google Sheets, Numbers, or any other spreadsheet app. Every sheet in your workbook becomes a worksheet in the downloaded file, named to match, and the file itself takes the name of your workbook. ## Exporting dashboards as PDF You can export a dashboard as a PDF to share it outside Equals. Open the dashboard in edit mode, click the *Publish & Export* button in the toolbar, then click *Export to PDF* under *Export*. Equals builds the PDF and your browser downloads it, named after the dashboard. Only users with `Can edit` access to the workbook can export a dashboard as a PDF. Users with `Read only` or `Dashboard only` access, and anonymous viewers of a public link, can't export it. ## Sharing a workbook with queried data If you share a workbook with connected sheets, all users will be able to see the query for the connected sheets. However only users to whom the datasource is also shared (regardless of whether they have workbook edit access) will be able to run queries. This prevents unauthorized access to your datasources. # Sharing saved queries With saved queries, you can save and share queries to be used across multiple workbooks, ensuring that data is pulled consistently across analyses. To share a saved query, select the *Share* button in the upper right corner of your screen. You have two choices here, **`Read only`** and **`Can edit`** sharing. * **`Read only`** allows a user to execute the saved query but does not give the user any editing access to the saved query, nor visibility into the written command. * **`Can edit`** allows a user to make changes to the underlying query and allows them to view the saved query edit and preview console. To use a saved query, open a new workbook or sheet and click on the *Connections* button. Scrolling down, you’ll see saved queries listed. Clicking on the query and selecting *Connect* will pull the data into your workbook. *** [Workspaces](/docs/workspaces) [Folders](/docs/folders-filters) # Snowflake Source: https://docs.equals.com/docs/snowflake Connect to a Snowflake warehouse from Equals To connect to Snowflake you need four pieces of information: **`Account URL`**, **`Database name`**, **`Username`**, **`Password`**. The Default schema field is optional. 1. To find your **`Account URL`**, open your Snowflake dashboard and go to *Admin* > *Accounts*. 2. Find the account you want to connect to (you may have one or multiple), hover over the name, and click the link button to copy the URL. Paste this value (it should be of the form `XXX.snowflakecomputing.com`) into Equals. 3. To find your Database name, click *Data* in the dashboard sidebar, make sure *Databases* is selected under *Data*. 4. You will now see a list of your databases, copy the **`Database name`** of the database you want into Equals. 5. Finally, you need to enter the **`Username`** and **`Password`** with access to the database. If you’re unsure of what to enter here ask for help from whoever set up Snowflake for your company. Please use a user account with a `LEGACY_SERVICE` type. # Allowing access from our IP You may need to allow connections from Equals IP address. To do so: 1. In the Snowflake dashboard go to *Admin* > *Security*, ensure *Network policies* is selected in the tab bar at the top. 2. If you have no active policies, Equals should be able to access your database. If you have an active policy, continue following these steps. 3. Click the “…” menu beside your active policy, then “*Edit Policy.* 4. Paste Equals’ IP address `54.68.61.53` in the text field under *X allowed IP addresses* and press enter. 5. Click *Save changes*. Equals should now be able to access your database. *** [Railway](/docs/railway) [Supabase](/docs/supabase) # Spreadsheet formatting Source: https://docs.equals.com/docs/spreadsheet-formatting Customize the way data is displayed in your workbook This document captures all the ways to format your workbook, including borders, conditional formatting rules, and custom number formats. # Borders You can add borders to emphasize a range of cells or a single cell in your workbooks. To get started, click on a cell or a selection of cells. Then, click on the borders icon from the toolbar. This will open a dropdown that will allow you to customize how you'd like your borders applied. Borders example # Conditional formatting Conditional formatting makes it easy to highlight trends or patterns in your data by making cells or values easy to identify. You can use conditional formatting to color-code cells that meet a specific set of criteria. Conditional formatting example To get started: 1. Select a cell or a range of cells and click on *Format > Conditional Formatting > New Rule* from the toolbar. 2. Set rules for your formatting. You can toggle between the *Highlight cell* option, which allows you to granularly set the conditions for your formatting, or you can use the *Color scale* option which will apply shading based on the median value in your data range. Selecting *Manage Rules* (*Format > Conditional Formatting > Manage Rules*) will allow you to view all of the formatting criteria applied in your sheet and make changes. # Custom number formatting With custom number formatting, you can change how your data is displayed. For example, you can set all negative numbers in parentheses or add your currency symbol to spend data. Custom number format example To apply a custom number format to a selection on your sheet: 1. Click on *Format* in your workbook's toolbar. This will open a console where you can configure how your data should be presented. 2. Write a set of rules in the console that will be applied to the data on your sheet. You can specify as many rules as you need. Clicking on "Templates" will allow you to browse common formatting options to use as a starting point. ## Syntax for setting formats To use colors in your format, write a color name in brackets (for example, `[Blue]`) anywhere in the desired part of the format. You must use English color names. Supported colors include: `white`, `red`, `blue`, `green`, `magenta`, `yellow`, and `cyan`. You can also use `Color#`, where `#` is a number between 1 and 56 corresponding to the [56 Excel ColorIndex colors.](http://dmcritchie.mvps.org/excel/colors.htm) If you specify a color in the custom format, that color will take precedence over colors selected in the text color picker. The following symbols can be used to format numbers: | Symbol | Result | Example | | - | - | - | | 0 | Digit or Zero | `2` formatted with `00` will show `02` | | # | Digit if needed | `2` formatted with `##` will show `2` | | ? | Digit or Space | `2` formatted with `??` will show `2` | | . | Decimal point | `1.345` formatted with `#.#` will show `1.3` | | , | Thousands separator | `1345` formatted with `#,##0` will show `1,345` | | % | Percentage | `0.3` formatted with `0%` will show `30%` | | e-, e+ | Exponential format | `12200000` formatted with `0.00E+00` will emit `1.22E+07` | | "text" | Pass-through | `2` formatted with `0 "USD"` will show `2 USD` | | \\ | Escape | Pass the next character through as-is | | \$, -, +, /, (, ), | Pass-through | Printed as-is without quotes | | @ | Text value | Non-numeric value as-is: `two` formatted with `"one"@"three"` will show `onetwothree` | Let me know if you need further help! *** [Keyboard shortcuts](/docs/keyboard-shortcuts) [Pivot tables](/docs/pivot-tables) # Stripe Source: https://docs.equals.com/docs/stripe Connect your company's Stripe account to Equals To connect your Stripe account to Equals you need to create an API key within the Stripe admin dashboard. 1. To get started head to [the Stripe API Keys](https://dashboard.stripe.com/apikeys) page. 2. Click "*Create Restricted Key*" in the "*Restricted Keys*" section. 3. Name your key `Equals` and grant *Read* access to *All core resources*, *All Billing resources*, and *All Connect resources*. Note: even if you don't use all of these Stripe features, set up will fail without access. 4. Click *Create Key*. You may need to enter your password at this step. 5. Once created, Stripe will show you the key in a modal. Copy this value and paste it into Equals. Once you've connected to your Stripe instance, you'll be able to build analyses and dashboards powered by live Stripe data, straight from your Equals workbook. We also offer support for custom-built Stripe ARR reporting with [Equals Experts](https://equals.com/experts/) — for more information, reach out to us via the Intercom messenger or at [\[email protected\].](mailto:experts@equals.com) *** [Segment](/docs/segment) [Xero](/docs/xero) # Supabase Source: https://docs.equals.com/docs/supabase Connect a Postgres database hosted on Supabase Supabase only supports Postgres databases. To get started sign in to Supabase and ensure the correct project is selected in the header. # Finding connection details 1. Once you’re on the correct project, select the cog icon for *Settings* in the sidebar. 2. Click *Database* in the sidebar and scroll to the bottom of the page. 3. Copy the connection string at the bottom, substituting `[YOUR-PASSWORD]` for the password you created when setting up the database. If you don’t know the password ask the person on your team that created the database. 4. In Equals, select *Use connection string instead* and paste the string with the substituted password. 5. Equals should now be able to connect to your database. # Allowing access from our IP Supabase does not support limiting inbound connections by IP address and so no further action is required beyond the steps above. *** [Snowflake](/docs/snowflake) [Other datasources](/docs/data-syncing-overview) # Supported Functions Source: https://docs.equals.com/docs/supported-functions The complete list of functions supported in Equals formulas # Array Array formulas can operate on ranges of cells, making them useful for performing complex calculations with a single operation that would otherwise require multiple steps or the use of "helper" cells and columns. Simply type your formula and, if it generates multiple values, they will automatically spill over into adjacent cells marked by a purple outline (the *spill range*). To edit an array formula, select the master cell at the top or top-left of the spill range. Note that currently, you cannot nest an array formula within other formulas. If you encounter a `#SPILL!`error, ensure that no cells in the spill range are blocked. * UNIQUE * FILTER * RANDARRAY * XLOOKUP * XMATCH * SORT * TEXTSPLIT # Date and time * DATE * DATEDIF * DATEVALUE * DAY * DAYS * EDATE * EOMONTH * HOUR * MINUTE * MONTH * MONTHSTO * MONTHSFROM * NETWORKDAYS * NOW * SOWEEK * SOMONTH * TIME * TIMEVALUE * TODAY * WEEKDAY * WEEKNUM * WORKDAY * WEEKSTO * WEEKSFROM * YEAR * YEARFRAC # Financial * IRR * NPV * PMT # Information * CELL * TYPE # Logical * AND * FALSE * IF * IFERROR * IFNA * IFS * NOT * OR * TRUE * ISBLANK * ISERROR * ISNUMBER # Lookup * ADDRESS * CHOOSE * COLUMN * COLUMNS * HLOOKUP * INDEX * JSONLOOKUP * LOOKUP * MATCH * ROW * ROWS * SORT * SORTBY * SWITCH * VLOOKUP # Math * ABS * EVEN * FLOOR * INT * LOG * MOD * ODD * PRODUCT * QUOTIENT * RAND * RANDBETWEEN * ROUND * ROUNDDOWN * ROUNDUP * SQRT * SUM * SUMIF * SUMIFS * SUMPRODUCT * TRUNC # Statistical * AVERAGE * AVERAGEIF * AVERAGEIFS * CHISQ.TEST * COUNT * COUNTA * COUNTBLANK * COUNTIF * COUNTIFS * COUNTUNIQUEIFS * FORECAST * MAX * MAXIFS * MEAN * MEDIAN * MEDIANIFS * MIN * MINIFS * NORM.DIST * PERCENTILE * PERCENTILE.EXC * PERCENTILE.INC * QUARTILE * QUARTILE.EXC * QUARTILE.INC * RANK * STDEV * T.TEST # Text * CHAR * CLEAN * CONCAT * CONCATENATE * EXACT * FIND * HYPERLINK * LEFT * LEN * LOWER * REGEXMATCH * REGEXEXTRACT * RIGHT * MID * SEARCH * SUBSTITUTE * TEXT * TEXTAFTER * TRIM * UPPER * VALUE *** [Saved queries](/docs/saved-queries-1) [Keyboard shortcuts](/docs/keyboard-shortcuts) # Typeform Source: https://docs.equals.com/docs/typeform Example Javascript code for importing response data from Typeform You can use Import Scripts to bring response data from your Typeform surveys directly into an Equals workbook. # Create a Typeform API Key and locate your Form Id To find your API key, navigate to your personal settings and select `Generate a new token`. To find your form ID, click into your form and copy the Id from the URL. For example, in the URL "[https://mysite.typeform.com/to/u6nXL7"](https://mysite.typeform.com/to/u6nXL7%22) the form ID is `u6nXL7`. # Add the key to a secret group Copy the the API key and form ID from the prior step. Then create a new secret group and paste the key into a new secret named `typeform_api_key` and `typeform_form_id`. # Example code Once you've completed the prior steps, create a new workbook, add a new import script to a sheet and copy + paste the script below. Once pasted select your secret group in the toolbar (make sure the key in the secret group is called `typeform_api_key` and `typeform_form_id`). You'll want to modify the code below to reflect type of results you're importing. ``` const equals = require("equals"); const axios = require("axios"); const API_URL = "https://api.typeform.com/forms"; const API_KEY = equals.getSecret("typeform_api_key"); const FORM_ID = equals.getSecret("typeform_form_id"); const getFormData = async () => { const resp = await axios({ method: "get", url: `${API_URL}/${FORM_ID}/responses`, headers: { Authorization: `Bearer ${API_KEY}`, }, params: { page_size: 96, }, }); return resp.data; } const formData = await getFormData(); // Create an array of column headers based on the keys of the first response if (formData.items && formData.items.length > 0) { const headers = Object.keys(formData.items[0].answers); equals.addHeaders(headers); // Add a row for each response, extracting the text value from each field object for (const response of formData.items) { const rowData = Object.values(response.answers).map((field) => { if (field.type && (field.type === "text" || field.type === "email" || field.type === "choice" || field.type === "number" || field.type === "date")) { if (field.type === "text" || field.type === "number" || field.type === "date") { return field.text ? field.text : ""; } else if (field.type === "email") { return field.email; } else if (field.type === "choice" && field.choices && field.choices.length > 0) { // The selected choice is stored in the first item of the choices array return field.choices[0].text; } else { return ""; } } }); equals.addRow(rowData); } } ``` *** [Intercom](/docs/intercom) [Plausible.io](/docs/plausibleio) # Overview Source: https://docs.equals.com/docs/using-your-arr-build-views Learn how to use your ARR Build for analysis in any Equals workbook Your ARR Build includes clean, analysis-ready views of your Stripe data, which can be used to build accurate ARR analyses and reporting. These views include: 1. **ARR Build Daily by Customer:** Aggregates ARR movements for each active customer by day 2. **ARR Build Invoice Items:** Displays each line item or discount from invoices in your Stripe instance, along with any associated ARR contributions. # How are they generated? While views are generally configured using custom SQL, your ARR Build views are automatically generated based on how your business recognizes ARR. Upon signup, your views are auto-generated based on the default configuration, which you can modify at any time. View [this article](https://docs.equals.com/docs/managing-your-arr-build) for full details on configuration settings. # Where are they stored? The `Daily by Customer` and `Invoice Items` views are automatically kept in sync with Stripe and stored in your [Equals Warehouse](https://docs.equals.com/docs/getting-started#equals-warehouse). This means any members in your workspace can safely query these views from any workbook (or from another view) for further analysis without impacting the underlying data. # Who can access them? Access to your ARR Build is based on permissions for the underlying Stripe datasource. To give users access to your ARR Build, you'll need to [grant them access](https://docs.equals.com/docs/sharing-permissions#sharing-datasources) to the Stripe datasource. Users with access to the corresponding Stripe datasource can: 1. View, create, modify, or delete your ARR Build. 2. Query your ARR Build views from any workbook. # How do you query them? You'll need to connect a sheet in a workbook to your Stripe datasource. Here's how: 1. Create a new sheet. 2. Click `Connect data` in the top-right of the sheet. 3. Find and select your Stripe datasource. 4. Choose how you would like to create your query — using the Query builder or SQL editor. 1. If you select the Query builder, find and select the `ARR Build Daily by Customer view` from the `Select tables` and columns dropdown, and build your query. 2. If you select the SQL editor, you can write your own query or copy and paste one of the examples below and adjust as needed. 5. Run your query. *** [Managing your ARR Build](/docs/managing-your-arr-build) [ARR Build Daily by Customer](/docs/arr-build-daily-by-customer) # Views in your warehouse Source: https://docs.equals.com/docs/views-in-your-warehouse Equals now has the ability to write "views" into your own BigQuery or Snowflake warehouse. This works by creating a new schema/dataset within your warehouse named "equals\_views", and then writing view tables there on a schedule (every 6 hours), or when you manually refresh the view table. You can configure these on the datasource connection page within Equals. #### BigQuery For BigQuery, you will need to set up a couple of things: 1. A service account set up for Equals to use to write data. This should be in *addition* to the scopes needed to query (per [https://docs.equals.com/docs/bigquery-connection-guide#using-predefined-roles](https://docs.equals.com/docs/bigquery-connection-guide#using-predefined-roles)). 2. Create a dataset in BigQuery called "equals\_views". Go into that, click "share" and assign the "BigQuery Data Owner" role to just this dataset. OR if you want some more specific permissions: Grant the service account "BigQuery User" role for the project. This allows Equals to create the dataset and grants extra permissions to tables created that way (but not existing tables). 3. Once that is done, you will need to create the Private Key per[ https://docs.equals.com/docs/bigquery-connection-guide#create-private-key](https://docs.equals.com/docs/bigquery-connection-guide#create-private-key) and upload to the new section in the datasource configuration in Equals (for a service account). 4. Ensure your existing read connection user has the appropriate permissions to query this dataset/tables. #### Snowflake You will need a separate user role for a service account within Equals. This role should have permissions like so: 1. Create a role in Snowflake with the permissions Equals needs to write data ```sql theme={null} GRANT USAGE ON DATABASE my\_db TO ROLE my\_role; -- creating the schema; you can leave this off if you create the schema yourself: GRANT CREATE SCHEMA ON DATABASE my\_db TO ROLE my\_role; -- creating tables: GRANT USAGE ON SCHEMA my\_db.equals\_views TO ROLE my\_role; GRANT CREATE TABLE ON SCHEMA my\_db.my\_schema TO ROLE my\_role; -- For writing data to the table views we create: GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA my\_db.equals\_views TO ROLE my\_role; GRANT INSERT, UPDATE, DELETE ON FUTURE TABLES IN SCHEMA my\_db.equals\_views TO ROLE my\_role; ``` 2. Assign that role to a user you will use in Equals. 3. Create a private key for that user, and upload into your datasource configuration within Equals (under service account). 4. Ensure your existing read connection user has the appropriate permissions to query this schema/tables. # Working with dates Source: https://docs.equals.com/docs/working-with-dates Tips and tricks on how to analyze dates Spreadsheet formulas may return different data depending on the format of the cells being analyzed. Here are a few tips and tricks to keep in mind when working with dates in spreadsheets. ### Identifying cell formatting The first thing you'll want to do when writing a formula based on a date value is to ensure that the cell is storing the data as a date. We have two cells with the same data below, each stored differently: While at face value both cells appear to display the date April 1st, 2024, only one is storing the date as a date while the other stores it as a text string. A good rule of thumb for identifying this quickly is to see if the cell's content is left-aligned. If so, it is likely a text string. If the cell's content is right-aligned, it's likely stored as a date. ### How formatting will change formula results Let's say you want to take a sum of the amount paid by your customers for the month of April. If you write a SUMIFS formula that attempts to SUM values that are stored as text (column D) and your criteria (cell I6) is stored as a date, your output will be 0. Notice how this will not happen if you are using the date field as your lookup column (column B). When writing SUMIFS or COUNTIFS statements, we recommend leveraging date values instead of string values. ### Common mistakes Oftentimes it's tempting to write a TRIM(LEFT...) formula to extract a date value from a timestamp (which is a string value). Instead of leveraging a formula that will return another string value, we'd recommend using =DATE(YEAR(),MONTH(),DAY()) for these cases, or =DATEVALUE(). This will ensure that the output is stored as a serialized date number (ex: April 1, 2024 = 45383) under the hood and will make sure that all formulas evaluate as expected. *** [Filters and sorts](/docs/filters-and-sorts) [Date matching formulas](/docs/date-matching-formulas) # Overview Source: https://docs.equals.com/docs/workspaces Create and configure your Equals workspace Your Equals workspace is your company account, and contains all workbooks, [datasources](https://docs.equals.com/docs/datasources-overview), [queries](https://docs.equals.com/docs/saved-queries-1), and [views](https://docs.equals.com/docs/views) relating to your company. Generally, the first Equals user from a specific company will be asked to create a workspace as part of their account creation. Subsequent users coming from that domain can be automatically added to the workspace by enabling *auto-join*. Users coming from a different domain will need to be manually invited in order to join the workspace as an Editor or Viewer. There are several pages in your workspace: * Your **Home** shows all of the [folders](https://docs.equals.com/docs/folders-filters) you have access to, and all queries and workbooks you have access to that are not stored within a folder. * The **Workbooks** page shows all of the workbooks you created or have access to, whether they are stored in a folder or not. * The **Templates** page shows all of the templates you can use to jumpstart your Equals workbook. * The **Saved Queries** page shows the [saved queries](https://docs.equals.com/docs/saved-queries-1) you created or have access to. * From the **Datasources** page you can select and configure new datasources for use by your workspace. * From the **Views** page you can create and save [views](https://docs.equals.com/docs/views) of your raw data for easier analysis. To find anything in your workspace, apply filters by Content Type, Creator, and Last Updated date range from your Home, or the Workbooks and Saved Queries pages. # Workspace settings Click on your workspace logo in the upper left corner and go to *Settings > Workspace* . From here, you can: * Set a workspace name * Enable or disable Google Authentication for Gmail accounts * Set a default timezone for your workspace (this will impact the timing of scheduled queries) * Set a default location for your workspace (this will impact default date formats and currencies) * Enable or disable auto-join to automatically add new members to your workspace * Upload your company logo * Connect to your company Slack account as a dashboard destination for your entire workspace * Enable or disable Equals branding on all dashboard distribution emails coming from your workspace * Enable or disable [AI Assist](https://docs.equals.com/docs/ai-assist) for your entire workspace # Managing workspace members Enabling *auto-join* from *Settings > Workspace* will ensure that all users coming from your domain address will be automatically added to your company's workspace upon account creation. To invite new users to your workspace manually, go to *Settings > Members* and add individual workspace members via email. Here you can set different roles and permissions for members of your Equals workspace: * **Editor** - Has full permissions to modify workbooks shared with them, query from all datasources shared with them, invite others, and change permissions for workspace members. * **Viewer** - Can only view but not make changes to specific workbooks shared with them. * **Guest** - Not a member of a workspace, but someone invited to view specific workbooks. These users will typically have an email domain different from your company domain and can include investors, advisors, or other external stakeholders. Editors and viewers count towards your overall seat count for your workspace, and will affect your pricing (see [pricing plans](https://equals.com/pricing/)). *** [Resources & tutorials](/docs/resources) [Sharing and permissions](/docs/sharing-permissions) # Overview Source: https://docs.equals.com/docs/write-an-import-script-connection You can write import scripts using either Javascript or Python to build custom integrations with Equals, pulling in data from outside sources such as third party APIs. # Creating import scripts To create an import script, first open a new workbook and click on the *Connections* button in the upper right corner. Then, select *Import Script* as the datasource. By default, Equals will load an example import script that will bring dummy data into your workbook. You can toggle between Javascript and Python on this screen. You can replace the demo data with your custom code. If you have an API key that you don't want to expose in your workbook's script, you can use [secret groups](https://docs.equals.com/docs/secret-groups) to hide these sensitive fields. # Writing import scripts We currently have two different languages that can be used to build Import Scripts: Javascript (Node 16) and Python (3.9) - you can swap between these for each connected sheet from the upper corner of the editor. # Javascript ## Usage First, import the equals library via a require statement `const equals = require("equals");`. Then add data and set headings with the below methods. `equals.addRows(data)` *Add rows of data to the sheet. Data must be an array of arrays, or an array of objects. Can be called repeatedly to add more data. If you set headers (below) and call addRows with an array of objects, we will use the header values to pluck corresponding values from the objects.* `equals.addRow(data)` *Add a single row of data (a list or an object).* `equals.addHeaders(headers)` *Add headings to the data being imported into the sheet. Should be an array of string objects. If not called, then either the keys of the first object, or the values of the first array will be used as headings.* `equals.getSecret(secretKeyName)` *Retrieve a secret passed to your script from your defined secret groups.* # Python ## Usage First, import the equals library with `import equals`. And then use the following methods to add data to your sheet. `equals.add_rows(data)` *Add rows of data to the sheet. Data must be a list of lists, or a list of dicts; such as from JSON. Can be called repeatedly to add more data. If you set headers (below) and call addRows with a list of dicts, we will use the header values to pluck corresponding values from the dicts.* `equals.add_row(data)` *Convenience method for a single row of data (a list or a dict).* `equals.add_headers(headers)` *Add headings to the data being imported into the sheet. Should be a list of string objects. If not called, then either the keys of the first dict, or the values of the first list will be used as headings.* `equals.get_secret(secret_key_name)` *Retrieve a secret passed to your script from your defined secret groups.* # Example - retrieving lead data from Intercom with Javascript We'd like to get a list of all our leads in [Intercom](https://www.intercom.com/). We can do this with some custom Javascript. After adding a secret group with the API key we need, we can use the secret in the script: ``` const equals = require("equals"); const axios = require("axios"); const luxon = require("luxon"); const apiKey = equals.getSecret("intercom\_api\_key"); const role = "lead"; function unixToDateTime(unixTimestamp) { return luxon.DateTime.fromSeconds(unixTimestamp).toFormat('yyyy-LL-dd HH:mm:ss'); } let response = await axios.post(", { query: { field: "role", operator: "=", value: role }, pagination: { per\_page: 150 }, sort: { field: "created\_at", order: "descending" } }, { headers: { Authorization: \`Bearer ${apiKey}\`, Accept: "application/json" } }); equals.addHeaders(\["name", "email", "created\_at"\]); response.data\["data"\].forEach((row) => { row\["created\_at"\] = unixToDateTime(row\["created\_at"\]); equals.addRow(row); }); ``` # Example - fetching stock price with Python We'd like to be able to pull in stock price information for AAPL on a monthly basis. To do this we can fetch the information from a remote API, and then get it automatically inserted into the spreadsheet. ``` import equals import requests import os api\_key = equals.get\_secret("alphavantage\_api\_key") query = f" r = requests.get(query) data = r.json() equals.add\_headers(\["End of month", "Open", "Close"\]) for eom, datapoint in data\["Monthly Time Series"\].items(): equals.add\_row(\[eom, datapoint\["1. open"\], datapoint\["4. close"\]\]) ``` This is enough to get us up and running with Python. # Dependencies We provide some common dependencies for usage in Import Scripts. **Javascript Version** Node 16. **Javascript Dependencies** The following dependencies are available for usage in Javascript: | Package | Version | | - | - | | axios | 0.27.2 | | lodash | 4.17.21 | | luxon | 3.0.1 | | mongodb | 4.8.1 | **Python Version** Python 3.9. **Python Dependencies** The following dependencies are available for usage in Python: | Package | Version | | - | - | | python-dateutil | 2.8.2 | | mixpanel | 4.10.0 | | requests | 2.26.0 | | flatdict | 4.0.1 | | pymongo | 4.2.0 | | stripe | 4.0.2 | *** [Query views from a workbook](/docs/querying-views-from-a-workbook) [Secret groups](/docs/secret-groups) # Writeback to CRM Source: https://docs.equals.com/docs/write-back-to-hubspot Push data from your Equals workbooks to HubSpot or Salesforce objects. **What is Writeback?** Writeback lets you update properties directly from a single column in an Equals sheet. Common use cases: * Push a calculation from Equals, e.g. push forecasted values to “Forecast” field * Fix incorrect CRM values, e.g. Amount, Stage, or Owner * Transfer data from one datasource to another, e.g. push Stripe ARR values to Salesforce Please note that this action cannot be undone. ### Getting started **Setting up a Writeback Destination** Regardless of the datasource (i.e., Salesforce or HubSpot), you’ll need to connect it again as a Writeback destination. Here’s how to do that: 1. Reach out to your Equals CSM to get this functionality enabled 2. Once done, navigate to the [Datasources](https://go.equals.com/datasources/writeback) page and click on the Writeback tab 3. Click “Create Writeback” → “Connect to \[CRM source]” 4. Sign in to your CRM account 5. You should now see “Connected” **Setting up the sync** Open or create a data sheet in the Equals workbook. Writeback is available in either the SQL Editor or Query Builder window. Click “Show Settings” to access in the SQL Editor, or if accessing through the Query Builder, then scroll down until you see “Writeback”. You can configure Equals to either create & update records, or to only update existing records. *More details on how to set this up is found below.* Confirm the sheet includes a primary key column: this is the unique ID that matches each row in Equals to a single record in your CRM. *More information on this below.* **Primary Keys** A Primary Key is a column in your sheet with no duplicates, and that maps to a property that is set to *Require Unique Values* (found in property settings). Example *(based on HubSpot)*: * For Contacts → the “Email” property is already unique by default in HubSpot, so the email column in your sheet can be your Primary Key. * For Companies → the HubSpot > Company > ID field in Equals will be the same as Record\_ID in HubSpot. You cannot use HubSpot’s default “Domain” property because it is not unique. If you would like to match on Domain, most teams create a new property called “unique\_domain” (with Require Unique Values *ON*), and then populate it via a HubSpot workflow. To writeback, you must have a column with unique IDs in Equals that map back to the corresponding primary key values in the CRM. **Set up write back configuration** Once your data sheet with the values to be written back is ready, make sure it includes a column with an ID (primary key) so the data can be properly mapped back to the corresponding records in your CRM. More on matching fields below. Here’s how to set up a writeback: 1. Click on the Writeback section in the Query Builder or Settings in SQL Editor. 2. Select the Destination (datasource) and the Object within that Destination to be written back to. You can only choose one Object per sheet to write back to. 3. In Record Matching, select the column name within the Equals datasheet containing the primary key / ID values. 4. Then, select the relevant field in the writeback destination with the matching ID values. There is more information on record matching in the section below. 5. Select Update & Create (available if the match key is not platform’s internal ID, e.g. it’s not Hubspot Object Id) or Update 6. Click on Done to confirm the configuration **(Note: Hitting 'Done' won't kickoff anything -- this is just configuration step.)**. 7. To define the field(s) to be written back, this will be completed in the Value Mapping section in which Source = column within the Equals data sheet ; Target Field = destination field to be written back to. **(Note: Hitting Done will immediately trigger writeback)** 8. If there are more values you'd like to write back, click the '+' next to Writeback and you'll see the Value mapping popup reappear to plug in those new values. *Tip: To test writeback with a smaller subset of values, you can first apply a filter or limit and set up writeback on that filtered set of rows. Keep in mind that if you later remove the filter or limit, writeback will begin syncing across all rows automatically.* **Matching Records** Configuring how records are matched is a key step in setting up a writeback. The available matching options vary by destination, but most support matching on either an internal ID (such as a HubSpot or Salesforce Object ID) or a specific property. The field you want to use for matching records must be available in the data sheet. HubSpot * HubSpot Object ID (like Record ID) – supports updates only * A custom unique field – supports both creating new entries and updates, but the field must have "require unique values for this property" enabled Salesforce * Salesforce Object ID – supports updates only * A custom unique field – supports both creating new entries and updates ### FAQ **Can I push data to custom objects?** Yes, this is possible. If you want to writeback to a custom object, you must first create a custom property under that object. **When does the syncing happen?** Anytime there is a new row in the table, or when the value in the writeback column changes it will automatically trigger the writeback and push new data to your CRM. **Can I manually trigger sync?** No, you currently can’t manually trigger the sync. **I created a new property but I’m not seeing it as an option in Equals** If you just created a new property in HubSpot/Salesforce, click on the Sync (refresh icon) in the Writeback popover to refresh the schema. **Can I undo Writeback?** You cannot undo any Writeback you have sent, so you should set this up once you’re confident in the information you want to push. **Are blank / empty values synced?** No, blank values are not written to the destination. ### Have more questions? [Reach out](mailto:help@equals.com). We're always happy to lend a hand! *** [Plausible.io](/docs/plausibleio) [Querying data](/docs/building-queries) # Xero Source: https://docs.equals.com/docs/xero Connect your Xero instance to Equals To create a new Xero connection: 1. Go to the *Datasources* page from the Equals home screen. 2. If you're yet to add a datasource, you will see a list of available datasources. Otherwise, click *New Datasource* in the top right. 3. Select *Xero*, then give your datasource a name that will be used throughout Equals. 4. Click *Connect to Xero* and follow the steps. You’ll be asked to connect via OAuth and then follow secondary steps to connect your Xero instance. # Querying from Xero Once you've connected your Xero instance, you will be able to query your Xero data from any workbook using either the Query Builder or SQL Editor. In addition, you will see a *Report Sync* option from the connections panel. *Report Sync* will allow you to pull prebuilt reports from Xero into your spreadsheet, so that you don’t need to write many lines of SQL to get your traditional P+L or General Ledger. By default, reports will populate the spreadsheet in the same format as they can be downloaded from Xero. If you would like to reconfigure this data into a tabular format, you can select the *flatten file* toggle and your data will be displayed in a formula-friendly (tabular) manner. *** [Stripe](/docs/stripe) [Views](/docs/create-views) # Dropdowns and data validation Source: https://docs.equals.com/dropdowns-and-data-validation Data validation controls what can be entered into a cell. Dropdowns are the most common use: instead of typing a value and hoping it matches, you pick from a fixed list of options rendered as coloured pills. Equals also supports checkboxes and a full set of text, number, date, and custom formula rules, so a range of cells can only ever hold the values you expect. ## Adding a dropdown * **Insert menu**: Select the cells you want to cover, then choose *Insert* > *Dropdown*. Equals creates a rule on that range with two starter options and opens the sidebar so you can edit them. * **Checkbox**: *Insert* > *Checkbox* does the same thing for a simple true/false cell, rendered as a tickbox you can click directly in the grid. * **Data menu**: *Data* > *Data validation* opens the sidebar directly, where you can add a rule of any criteria type. In the sidebar you can rename each option, drag options to reorder them, and pick a colour for each from the light and dark swatch palettes. Under *Data range* you can add or adjust the ranges the rule applies to — a single rule can cover several ranges, on the same sheet or across sheets. ## Using dropdowns * **Pick a value**: Click the pill in a cell to open the list, then select an option. The cell takes the option's colour. * **Edit in place**: The bottom of the option list has *Edit dropdown*, which reopens the sidebar for that rule. * **Invalid values**: Typing or pasting a value that isn't in the list still writes the value, but the cell is marked with a red triangle. Hovering it explains why the value is invalid. ## Other validation rules Beyond dropdowns and checkboxes, a rule can require a cell to satisfy: * **Text**: contains, does not contain, starts with, ends with, is exactly, is a valid email, is a valid URL. * **Number**: greater than, less than, equal to, not equal to, between, not between — with or without equality. * **Date**: is, is before, is after, is between, is not between. * **Custom formula**: any formula that returns TRUE for a valid cell, so you can validate against a lookup range, another column, or query results. These rules don't block entry; they flag cells that fail, so you can spot bad data in a model without it disappearing on you. ## Managing rules *Data* > *Data validation* lists every rule in the workbook, split into rules on the current sheet and rules on other sheets. Each entry shows the criteria and the ranges it covers. Click a rule to edit it, or use the cross to remove it — removing a rule leaves the cell values in place and only stops validating them. Rules move with your data. Inserting, deleting, or moving rows and columns shifts the ranges a rule covers, and copying cells carries their validation to the destination. # Equals Documentation Source: https://docs.equals.com/index Query, analyze, and report live data with the flexibility of a spreadsheet and the power of BI.
# Welcome to
Equals Documentation

Query, analyze, and report live data with the flexibility of a spreadsheet and the power of BI. Get started quickly with guides, tutorials, and reference documentation.

Analyst

Forecast how much of our open pipeline we're going to close this month.

2 of 3 steps completed
Pull all deals with a close date in January
Add an expected amount column using stage data
Summarize end of month pipeline forecast

Fetching this month's open opportunities from Salesforce.

Queried Salesforce data in January Deals
Added "Expected Amount" to January Deals

I also added an "expected amount" calculated column to the open deals sheet, which weights how much pipeline each deal will actually close based on historical win rates for each deal's stage.

Now I'll summarize what we're tracking towards by the end of the month.

Working…
Waiting… Stop
## Get Up and Running

Follow these steps to start analyzing your data in minutes.

Your Equals [workspace](/docs/getting-started) is home to all your workbooks, datasources, queries, and views. Enable auto-join under [Settings > Workspace](https://go.equals.com/settings?tab=workspace) to automatically add team members with matching email domains. Connect to [databases and warehouses](/docs/connecting-sql-databases-to-equals) like PostgreSQL, Snowflake, and BigQuery, or SaaS tools like [Stripe](/docs/arr-build-get-started), Salesforce, and HubSpot. Data syncs automatically to your [Equals Warehouse](/docs/data-syncing-overview) powered by Snowflake. Use the [SQL editor](/docs/getting-started#explore-data) or drag-and-drop [query builder](/docs/getting-started#explore-data) to explore your data. [Schedule queries](/docs/getting-started#explore-data) to run automatically on a fixed cadence. ```sql theme={null} -- Example: Query your synced Stripe data SELECT customer_id, SUM(amount) as total_revenue FROM stripe.charges WHERE status = 'succeeded' GROUP BY customer_id ORDER BY total_revenue DESC ``` Create powerful analyses with [spreadsheet functions](/docs/how-to-spreadsheet), [pivot tables](/docs/getting-started#analyze-data), and [charts](/docs/getting-started#analyze-data). Press `Cmd/Ctrl + J` to open [AI Assist](/docs/getting-started#analyze-data) for help writing formulas and SQL. For SaaS companies, check out the [ARR Build](/docs/arr-build-get-started) for automated revenue reporting. Transform your analysis into live, board-ready [dashboards](/docs/getting-started#report-on-data). [Distribute to Slack or email](/docs/getting-started#report-on-data) on a custom schedule, or export as PDF.
## Explore the Documentation

Discover how to connect, transform, explore, and analyze your data.

Connect to databases, data warehouses, and SaaS tools. Sync data to your Equals Warehouse powered by Snowflake. Use Views to transform raw data into clean, analysis-ready tables with SQL. Build dependencies like DBT pipelines. Query data with the SQL editor or drag-and-drop query builder. Schedule queries and create saved queries. Use spreadsheet fundamentals, pivot tables, charts, and AI Assist to build powerful analyses.
## Connect Your Data

Equals connects directly to your databases, data warehouses, and frequently used apps.

## Learn to Build Analyses

Whether you're new to spreadsheets or a seasoned pro, learn best practices for building powerful analyses.

Structure workbooks for clarity. Clean and transform your data. Create and share with your team.
## Frequently Asked Questions

Common questions about security, datasources, and the Equals platform.

All sensitive credentials (passwords, SSH keys, OAuth tokens) are stored encrypted in our database with keys only accessible to necessary production servers. Equals is SOC 2 Type II certified. Yes, we always connect from the static IP address `54.68.61.53`. You may need to allowlist this IP in your database firewall. Equals supports SQL databases (PostgreSQL, MySQL, Redshift, BigQuery, Snowflake), and SaaS tools including Stripe, Salesforce, HubSpot, Intercom, Zendesk, Shopify, and more. When you connect multiple supported datasources, they automatically sync to your own Equals Warehouse powered by Snowflake. This allows you to join, transform, and query data across sources.
## Need help?

Reach out to us via Intercom, watch tutorials, or contact support directly.