Unify Applications
Logo
Data Sources Overview

Data Sources Overview

Logo

7 mins READ

A data source is a named, reusable request for data that lives on a page or on the whole app. Configure it once — which API to call, which records to query, with what inputs — and every block on that page can bind to its results. The data source owns the fetching: when it runs, when it re-runs, how its response is shaped, and what loading and error states it exposes while doing so.

data_sources_overview.png
data_sources_overview.png

Note: Open the Data panel in the Application Builder. It has two lists: App (data shared across all pages) and a list named after the current page, such as Homepage (data specific to this page). Variables and functions live alongside data sources but are separate concepts.

What a Data Source Can Call

Every data source calls an app action. You pick the app and its action when you create the data source, from the Select an app picker (Most popular or All apps).

App

What it does

Typical use

Storage by UnifyApps

Creates, fetches, updates, and deletes records in your data objects.

Reading and writing records the platform already stores.

Analytics by UnifyApps

Queries reports or runs an analytics query.

Feeding charts and metrics.

Callable

Calls a callable automation and returns its output.

Running your own logic and returning the result to the page.

Custom HTTP Endpoint

Sends an HTTP request.

Reaching your own or a third-party REST API.

Connectors

Runs an action of any connector in All apps.

Reading data from an external system.

Page Scope vs App Scope

When you create a data source you choose where it lives:

ScopeLives inAccessible fromUse when
Page DataThis page onlyBlocks on this pageThe query is specific to this page's concern
App DataThe app's global scopeEvery page in the appThe same data is needed across multiple pages — create once, use everywhere

Warning: A single page caps at 100 data sources. Hitting that limit shows a "Data source limit reached" dialog. The recommended fix is to split heavy pages, share data via App Data, or combine related queries where possible.

The Lifecycle: Configure → Run → Bind → Refresh

Every data source moves through the same four stages regardless of what it calls or its scope.

  1. Configure: Define what to fetch: the endpoint or query, its inputs, and its run behavior. Inputs can be static values or expressions bound to page state, other data sources, or user input. Inputs configured as expressions make the data source reactive — it re-runs automatically when the referenced value changes.

  2. Run: The data source executes. An automatic data source runs on its own — on page load and again whenever an input it depends on changes. A manual one runs only when something explicitly triggers it, such as a button action.

  3. Bind Results: Blocks read the response through the data source's name in a {{ }} expression. Alongside the response, each data source exposes its live request state: data (the response), isLoading (true until the first result arrives), isFetching (true while any run is in progress, including later refetches) and error (the request error, or empty when the request succeeded). Data sources that use infinite loading also expose isFetchingNextPage and hasNextPage.

  4. Refresh: Data stays current through three mechanisms: polling (re-run on an interval), focus refetch (re-run when the user returns to the tab), or an explicit trigger from an action. See Caching & Refetch.

Optional Lifecycle Capabilities

Two optional features extend the standard lifecycle:

Capability

What it does

See

Response Transform

A JavaScript snippet that reshapes the raw response before blocks read it — flatten nesting, rename fields, compute derived values.

Response Transforms

Infinite Loading

Turns the response from a fixed window into an append-only list; consuming blocks pull additional pages on demand.

Infinite Loading

How to Add a Data Source

  1. Open the Data panel: In the Application Builder left rail, select the Data panel.

  2. Click + → Data Source: Click + on the App list or the page's list and choose Data Source. The Select an app picker opens, with Most popular and All apps — for example Storage by UnifyApps, Analytics by UnifyApps, Callable, Custom HTTP Endpoint and your connectors.

  3. Pick the app and action: Select the app, then choose its action. The data source is created and opens with the tabs App & Action, Input and Advanced. A Connection tab also appears for apps that need a connection, such as connectors.

  4. Configure inputs, run behavior, and advanced options: On the Input tab set run behavior (Automatic / Manual), configure the action's inputs, and optionally add a response transform or event handlers. The Advanced tab controls timing, caching, retries, and disable conditions.

  5. Save and run: Click Save & Run (shown as Save for a manual data source, or Run when there are no unsaved changes) to test the data source, then check the Output and Schema tabs at the bottom of the panel.

Binding to a Data Source

Example — Binding a table to a data source result

Assuming a data source named orders_query that returns a list of orders:

// Bind the Table's data property to all records {{ orders_query.data.objects }} // Show a loading spinner conditionally {{ orders_query.isLoading }} // Show the error message when the query fails {{ orders_query.error.message }} // Count results {{ (orders_query.data.objects || []).length }}

Success & Failure Events

After a run finishes, the data source fires its On Success or On Failure event. These are ordinary action lists where you chain toasts, navigation, or further actions off the fetch outcome. Attach them on the Input tab under Event Handlers.

Tip: Put "what happens after a save" logic (show a success toast, navigate back) in the data source's On Success event — not chained inline after a trigger action — so it only runs when the fetch actually succeeded.

Common Gotchas

GotchaExplanation
Automatic is not "always fresh"An automatic data source re-runs when its bound inputs change — not when the server's data changes. Use polling or an explicit refresh to pick up server-side changes.
Manual data shows nothing until triggeredA block bound to a manual data source shows nothing until something fires it. Bindings resolve to empty values before the first run.
Legacy mode is automatic-like but differentData sources created before run behavior existed have no mode set. The platform treats them like automatic sources, but triggering them from an action differs slightly. Set an explicit mode to remove ambiguity.
Automatic can mean many runsEvery distinct change to a bound input triggers a re-run. An input bound to rapidly changing values (unthrottled typing) re-fetches on each keystroke. Prefer binding to settled values or use manual run behavior.
  • Data Source Types — The apps and actions a data source can call.

  • Query Builder — Configuring a Storage Fetch records query: object, fields, filters, sorting, and paging.

  • Run Behavior & Triggering — Automatic vs manual, page-load behavior, dependency ordering, triggering from actions.

  • Caching & Refetch — Polling, background and focus refetch, retries, and action-driven refreshes.

  • Response Transforms — Reshaping a response with JavaScript before blocks read it.

  • Infinite Loading — "Load more" pagination — the has-more flag, the cursor, and how blocks consume pages.

  • Data Binding — The {{ }} expression syntax that connects data source results to UI blocks.

  • Managing Data Sources — Creating, copying, organizing and deleting data sources in the Data panel.

FAQs

What is the difference between App Data and Page Data?

App Data sources are created once and available across every page in the app — useful for things like the current user's profile or global configuration that many pages need. In the Data panel they sit in the App list. Page Data sources belong to a single page and sit in the list named after that page; they are not accessible from other pages. If you find yourself duplicating the same data source on multiple pages, move it to App Data instead.

Why does my data source show nothing on the initial page load?

The most common cause is that the data source is set to Manual run behavior. Manual sources only run when explicitly triggered — they show empty values until something fires them. Check the data source's Input tab: if Run Behaviour is Manual and you want data to appear on load, either switch it to Automatic or enable Run query on page load in the Advanced tab.

Can I use the same data source on multiple blocks on the same page?

Yes — any block on the page can bind to any data source by name. The data source runs once and all consuming blocks share the same result. You do not need to create separate data sources for each block.

What happens to the page if a data source fails?

The data source transitions to an error state — error becomes non-null and isLoading / isFetching become false. Blocks bound to data continue showing whatever they had before (or nothing, on first load). The failure events fire, which is where you can show an error message or take corrective action. The page itself does not crash.

How do I refresh a list after saving or deleting a record?

Use the Trigger Data Source action in the save/delete operation's On Success event handler. Point it at the list's data source — this invalidates the cached result and re-fetches, updating the list to reflect the change. Place the trigger in the save data source's On Success event so it only fires after a confirmed successful save.