---
title: Embeds
description: "Live data from records you publish, on a site SalexHub does not host: a script tag, or JSON and HTML from one address. Read-only, keyless, no personal data."
url: https://salexhub.com/docs/developers/embeds
type: reference
area: developers
section: Developers
last_updated: 2026-10-09
prerequisites:
  - https://salexhub.com/docs/developers
related:
  - https://salexhub.com/docs/developers/forms
  - https://salexhub.com/product/web
tools:
  - embed.save
checked_against: salexhub/platform 3a1bd7144
---

# Embeds

Live data from records you publish, on a site SalexHub does not host: a script tag, or JSON and HTML from one address. Read-only, keyless, no personal data.

An embed puts live data from your records on a site SalexHub does not host: a price list read when the visitor arrives, so the page never drifts from the records it quotes. It is read-only and needs no key. Embeds work in every organization.

## Make an embed

Owners and Admins build embeds under **Marketing > Embeds**. Everyone else can view them.

### Choose New embed

Give it a **Name**, and choose the **Site** it may appear on: **Any site**, or one of your tracked sites. Bound to a site, it answers only that domain; left unbound, anyone may embed it anywhere. Tracked sites come with the Marketing hub.

### Add blocks

**Add block** offers **Hero**, **Text**, **Records** and **Form**. A Records block names the object, a heading, the **Properties to show** and **How many** (up to 48).

### Open the object for embeds

A Records block shows nothing until an admin switches on **This object may appear in embeds** for that object. It is off by default.

### Save

**Save** updates the fragment on the live site at once. There is no separate publish. When a block will show nothing, the save says which and why.

## What an embed can show

These rules are checked on every request, not only when you save:

- only objects an admin opened for embeds;
- only the fields the block names, at most 12 per Records block;
- never a field marked as personal or sensitive data, such as a contact's name, email or phone, and never a formula that reads one. The editor marks such a field "Personal data: never shown in an embed";
- every record of the object that matches the block's filters. An embed has no viewer, so the organization's sharing rules do not narrow it: the filters are the only narrowing.

An uploaded picture, such as a company's logo, is a file a visitor cannot open, so it shows as a gap.

A Form block renders **Your name**, **Phone number**, **Email** and **Anything we should know?** with a **Send** button, and posts to the [form endpoint](https://salexhub.com/docs/developers/forms). Without an email or a phone, it asks the visitor for one.

## Put it on your page

The screen prints the snippet for each embed. Paste it where the embed should appear:

```html title="Your page"
<script defer src="https://app.salexhub.com/e.js"></script>
<div data-slx-embed="slxe_0a1b2c3d4e5f6a7b8c"></div>
```

The loader fills each placeholder with the embed's HTML inside a shadow root, so its styles and your page's do not touch. It looks for placeholders once, when the page loads: a placeholder your script adds later stays empty. A paused or removed embed leaves the placeholder as it is.

## Fetch it from your server

Search engines index what your server rendered, and a script fills the page after it loads. For that, fetch the embed yourself:

| Request | Answer |
| --- | --- |
| `GET https://app.salexhub.com/api/e/<key>` | JSON: `{ "ok": true, "blocks": [...], "formKeys": {...} }` |
| `GET https://app.salexhub.com/api/e/<key>?format=html` | An inert HTML fragment with inline styles, no scripts, ending with a "Powered by SalexHub" link |

```json title="JSON answer"
{
  "ok": true,
  "blocks": [
    {
      "type": "records",
      "heading": "Northwind price list",
      "columns": [
        { "slug": "name", "label": "Name" },
        { "slug": "unit_price", "label": "Unit price" }
      ],
      "rows": [
        { "name": "Annual support plan", "unit_price": 4800, "unit_price_currency": "AED" },
        { "name": "Onboarding workshop", "unit_price": 1500, "unit_price_currency": "AED" }
      ],
      "text": [
        { "name": "Annual support plan", "unit_price": "AED 4,800" },
        { "name": "Onboarding workshop", "unit_price": "AED 1,500" }
      ]
    },
    { "type": "form", "formId": "cmg0r2k8p0004t6y3u9i1o5pa", "heading": "Ask for a quote" }
  ],
  "formKeys": { "cmg0r2k8p0004t6y3u9i1o5pa": "slxf_9c8b7a6f5e4d3c2b1a" }
}
```

- Block shapes: `hero` has `title`, and may have `subtitle`, `image`, `ctaLabel` and `ctaHref`; `text` has `body` and may have `heading`; `records` has `columns`, `rows` and `text`, and `refused` when it can show nothing (`not_publishable`, `no_fields` or `error`); `form` has `formId`, whose public key is in `formKeys`.
- Rows carry only the allowed columns, never record ids. An amount stays a number, with its currency code beside it as `<field>_currency`. An uploaded picture is `null`.
- `text` holds what each cell reads, and is what the HTML fragment prints: an amount formatted with its currency in your organization's format.

## Freshness, limits and access

- Each answer may be cached for 60 seconds, and served stale for up to 5 more minutes while it refreshes: a changed record shows within about a minute.
- A bound embed answers a browser only on its own domain and its subdomains, with `www.` ignored; another site gets `403`. A request with no `Origin`, from a server, is answered.
- An unknown key and a paused or removed embed both answer `404` with `{"ok":false}`.
- An embed made on the screen holds up to 20 blocks; one saved by the Agent or through the API, up to 30.

---

The same page for people: https://salexhub.com/docs/developers/embeds. Index of this site for agents: https://salexhub.com/llms.txt
