Docs
DashboardSite Management

API Blocks

Connect external APIs to your site and render live data using configurable block templates.

Overview

API Blocks (also known as Dynamic Blocks) allow you to fetch data from any external HTTP endpoint and display it dynamically on your site using an editor template. This enables you to integrate live data feeds, e.g., product lists, news feeds, weather widgets, or payment checkout systems, directly on your site without writing server-side code.

API Blocks are an advanced feature. Familiarity with REST APIs, JSON, and basic templating will help, but every step below walks through it with no code required.


Step 1: Create an API Block

To begin, you must define the connection to your external data provider:

Open your site dashboard and select API Blocks from the sidebar.

Click the New API Block button in the top right.

Give your API block a clear, descriptive name (e.g., Product Feed) and click Create & Configure.

Every block you create appears in a searchable, paginated list showing its Name, Endpoint URL, HTTP Method, and Cache strategy/TTL. Use the Manage button (or the three-dot menu) to reopen the Builder, or Delete to permanently remove a block.

Deleting an API block cannot be undone. Any page still referencing it will stop rendering that block's data.


Step 2: Configure the API Request

Once created, you will be taken to the API Block Builder, where you can customize the outbound HTTP request:

  • Request URL: Enter the endpoint address. You can use placeholder variables using curly braces, e.g., https://api.example.com/items?page={page}.
  • HTTP Method: Choose from GET, POST, PUT, PATCH, or DELETE.
  • Params tab: Add query-string parameters as key/value rows.
  • Headers tab: Add static request headers (e.g., a custom user agent) as key/value rows.
  • Request Body tab: For write methods (POST, PUT, PATCH), provide a JSON body template that interpolates your variables. This tab is disabled for GET/DELETE requests, which cannot carry a body.

Every row in the Params and Headers tabs has a checkbox — uncheck it to temporarily disable that row without deleting it.

Click Send to test the request. This automatically saves your current configuration first, then executes the live call and shows the response in a panel below with Body, Headers, Cookies, and Results (the parsed data after your Root Path is applied) sub-tabs, plus the status code, response time, and payload size.


Step 3: Secure Authenticated Endpoints

If your external API requires authentication, do not hardcode your secrets or keys directly in the request headers:

Navigate to the Auth tab in the Builder. By default the request uses None (public API) — no credential is attached.

Click + Add credential.

Give the credential a name (e.g. Stripe API) and choose an auth type:

  • Bearer token: Appends Authorization: Bearer <token> to requests.
  • API key header: Appends a custom header matching your key (e.g. X-API-Key: <secret>).
  • Basic auth: Generates a standard base64 username and password header (secret is stored as user:pass).
  • None: Saves a named, domain-restricted credential with no secret or auth header — useful when you only need the allowlist below without sending credentials.

Allowed domains: As an essential security measure, list the exact, comma-separated domain names (e.g., api.stripe.com, dummyjson.com) that this credential is allowed to communicate with. The builder automatically blocks calls to unlisted domains to prevent credential leaks.

Click Save credential, then select it from the credential dropdown for your request.

Once saved, a secret is never shown again — the field only ever displays a placeholder. You can replace a credential's secret but not reveal it.

All credential secrets are encrypted at rest.


Step 4: Caching Policies

To maintain fast page load times and prevent hitting third-party API rate limits, configure the caching behaviors on the Cache tab:

  • TTL (seconds): The number of seconds a fetched response remains valid before it needs to be updated.
  • Strategy:
    • Cache-first: Serves the cached data immediately. The network is only queried if the cache is completely empty.
    • Network-first: Always tries to query the live API first. If the request fails or times out, the site falls back to the last cached copy.
    • Stale-while-revalidate: Serves the cached content instantly to site visitors, and concurrently triggers a background request to fetch fresh data for the next visitor.

Step 5: Design Templates (LiquidJS)

Below the request tabs, design how your fetched data is rendered on the site using the sandboxed LiquidJS template engine:

  1. Root Path: Specify a dot-path inline next to the tabs to target a nested list or object in the response. For example, if the API returns { "data": { "items": [...] } }, set the Root Path to data.items to bind your template directly to the array.
  2. Variables panel: Click Send in the request bar above. The builder inspects the API response and populates the Variables panel (below the editor) with a badge count and a collapsible, hierarchical list of every field found. Click a scalar field to insert {{ path }} at your cursor; click an array field to insert a ready-made loop — {% for item in path %} ... {% endfor %} — and its child fields become available as item.field chips.
  3. Liquid Markup: Author your HTML layouts using loops and condition statements:
    {% for product in data.products %}
      <div class="product-card">
        <h3>{{ product.title }}</h3>
        <p>Price: {{ product.price | currency }}</p>
      </div>
    {% endfor %}
    Use the format button in the editor toolbar to auto-format your markup, and Render to preview the output in the panel on the right.
  4. Formatting Filters: Standard Liquid formatting (including truncate) is supported alongside two custom filters:
    • | currency: Formats a number as a currency string, e.g. {{ price | currency }} → $19.99. Pass a symbol to override the default $, e.g. {{ price | currency: '€' }}.
    • | dateFormat: Formats a date/timestamp using Intl.DateTimeFormat, e.g. {{ date | dateFormat }} (defaults to en-US). Pass a locale to override it, e.g. {{ date | dateFormat: 'en-GB' }}.

All template output is HTML-escaped by default for security. If a field genuinely contains safe HTML you want rendered as-is (not visible as text), pipe it through the built-in | raw filter, e.g. {{ product.descriptionHtml | raw }}.

Templates run in a sandbox with no filesystem, network, or {% include %}/{% render %} access, and are capped at a 2-second render timeout — this keeps a slow or malformed template from affecting your published page.


Step 6: User Interactions & Behaviors

Define what happens when the block renders or when visitors interact with it on the Behavior tab:

  • Trigger ("When does it run?"):
    • On page load: Fetch and render the data immediately when the page mounts.
    • On button click: Render an action button first. The request is only sent when the button is clicked.
  • Action (what the response does):
    • Render template: The standard mode. Renders the template output inline.
    • Load more (append): Appends additional pages of data incrementally when the visitor clicks the button, instead of replacing what's already shown.
    • Redirect (e.g. checkout): Navigates the browser to a URL returned by the API response (e.g., redirecting to a Stripe Checkout URL returned by a payment initialization endpoint).

Depending on the trigger/action combination you choose, additional fields appear:

  • Button label: Shown whenever a button is rendered (button-click trigger, or Load More). Customize the text, e.g. Buy Now, Subscribe, Load More. Leave it blank to fall back to a sensible default (Load data, Continue, or Load more).
  • Redirect field (dot-path in response): Only for Redirect — the dot-path to the URL in the API response, e.g. url or data.checkoutUrl.
  • Page size (exposed as {limit} / {skip}): Only for Load More — how many items to request per page.

Pagination exposes {limit}, {skip}, {offset}, and {page} placeholders you can use in your Request URL or Body, e.g. ?limit={limit}&skip={skip}.


Step 7: Adding API Blocks to Your Pages

To add your configured API block to a page:

Open your site's visual page editor.

Add the Dynamic API Block element from the block library onto the canvas.

Select the block, and open the right sidebar settings.

Pick your API Block definition from the selection list.

Customize the wrapper's presentation: Width and Min Height, a Hover Effect (None, Lift Up, Soft Glow, Zoom), Margin/Padding, and per-device Visibility toggles (Desktop, Tablet, Mobile).

Until you pick an API Block definition, the element shows a placeholder ("Dynamic API Block — open the settings panel to pick an API block") only while editing — it renders nothing on the published page.

An unconfigured or deleted API Block reference is simply skipped on the live site, so it never breaks the surrounding layout.


  • Forms — The other way to collect and display dynamic data on your pages.
  • Blocks — Every block type available in the editor, including Dynamic API Block.
  • Site Overview & Page Manager — See the API Blocks tab in context with the rest of the sidebar.