Storefronts
The Storefronts API lets you create a draft Creator page, read the pages in your store and their traffic analytics, update the saved draft styles, header, and settings, manage the widgets on a page, host images, videos, and files for those drafts, publish a draft so it goes live, and take the live page down.
Overview
The Storefronts API provides endpoints to:
- List storefronts
- Retrieve storefront details
- Create a storefront
- Get storefront analytics
- Update storefront styles
- Update storefront header
- Update storefront settings
- List storefront blocks
- Retrieve a storefront block
- Create a storefront block
- Update a storefront block
- Reorder storefront blocks
- Publish a storefront
- Unpublish a storefront
In the dashboard these pages are labeled Creator page. The API resource is
storefronts — paths, identifiers, and JSON fields use that name.
A storefront is a single scrollable page. This is a different resource from Pages (landing pages).
Identifiers
Create Storefront is collection-level
(POST /storefronts) and mints the UUID. Later paths take that UUID as {id},
except Get Storefront Block and
Update Storefront Block, which take it as
{storefrontId} so the widget can be {id}.
Each storefront has two identifiers, and they are not interchangeable:
idis the storefront's stable identifier — a UUID. It never changes, and it is the key you pass to Get Storefront, Get Storefront Analytics, Update Storefront Styles, Update Storefront Header, Update Storefront Settings, Get Storefront Blocks, Get Storefront Block, Create Storefront Block, Update Storefront Block, Reorder Storefront Blocks, Publish Storefront, and Unpublish Storefront.slugis the current URL slug (for examplemy-studio). It is mutable in the dashboard, so use it for display only, never as a stable reference. The live visitor URL keeps the slug from the last publish until the storefront is published again.
Each widget has its own id — a UUID. Pass it as {id} on
Get Storefront Block and
Update Storefront Block
(/storefronts/{storefrontId}/blocks/{id}), and in the
reorder items list.
name is set on Create Storefront and cannot be
patched. name and slug cannot be changed through the API — use the
dashboard.
Status
A storefront is either draft or published. Filter the list by either
value, or omit the filter to return storefronts in any state.
draft— not live.public_urlisnull. Create Storefront always creates this status. Unpublish Storefront sets this status.published— live atpublic_url. Publish Storefront sets this status. The saved draft can still contain unpublished edits; those show up onpreview_url, not on the live page.
Creating a storefront
Create Storefront accepts name only. The slug is
generated from that name. The page is always a draft. Styles and header are
a snapshot of this store's profile and branding at create time; later
dashboard branding edits do not rewrite this draft. Widgets start empty.
Open preview_url to see the page. Go live with
Publish Storefront.
Going live
Publish Storefront and
Unpublish Storefront are empty POSTs — there is no
request body.
Publish copies the saved draft to the live page. Re-publish refreshes that
live page from the current draft and refreshes published_at. Unpublish takes
the live page down and leaves the draft.
There is no content gate: a page with empty widgets still publishes. Visitors keep seeing the previous live page until Publish Storefront.
Active plan required
Only Publish Storefront requires an active Easytools
plan. Re-publish is gated too. Without a plan the call returns 422 and the
live page stays as it was — including when {id} does not exist.
Create Storefront, Unpublish Storefront, every draft styles / header / settings PATCH, every create / update / reorder, and every read keep working.
The body carries a message and no errors key, as with
Publish Product:
{
"message": "Storefront cannot be published without an active Easytools plan"
}
Analytics breakdowns
Get Storefront Analytics returns one breakdown
per call, selected with the type parameter:
| Type | Returns |
|---|---|
summary | Period totals — visitors, pageviews, bounce rate, and revenue. |
daily | Per-day visitor and revenue trend. |
sources | Traffic sources (Google, Direct, ...) with a referrer-URL drill-down. |
countries | Visitors and revenue by country. |
devices | Device-type split, keyed by pageviews and their share. |
partners | Affiliate (?ref=) partner performance. |
realtime | Visitors on the storefront in the last 5 minutes (live snapshot). |
Revenue is reported per currency, with amounts in minor units (e.g. cents)
(for example 45000 is 450.00 USD). bounce_rate_percent is an integer 0-100
(13 means 13%). This is a different shape from Pages analytics —
UUID id, those units, and no paths type.
See Get Storefront Analytics for the full shape of each breakdown.
Draft preview
Get Storefront always returns preview_url — a temporary
signed link to the saved draft. Create Storefront
returns a fresh one. The three section PATCH endpoints,
Create Storefront Block,
Update Storefront Block, and
Reorder Storefront Blocks return a fresh one
as well, including when a PATCH body is {}. Follow it in a browser; it needs
no Authorization header. The link expires about an hour after the call, so
request again for a fresh one instead of storing it.
preview_url is present even when status is published. It is the draft,
which may differ from what visitors see at public_url.
Get Storefronts,
Get Storefront Blocks, and
Get Storefront Block omit preview_url. Create and
update put it on the block object. Reorder puts it next to items, not on
each widget.
Publish Storefront and
Unpublish Storefront each return a fresh
preview_url. On publish, public_url is the shareable live link;
preview_url is the saved draft.
Draft updates
A new page starts with this store's profile and default branding on styles and header, and no widgets. Add widgets with Create Storefront Block. Later branding edits in the dashboard do not rewrite this draft.
Each PATCH writes one section of the saved draft —
styles, header, or
settings. Visitors still see the last
published page at public_url (null while the storefront is a draft). Open
preview_url to see the edit. Published storefronts accept these calls: the
draft changes; the live page does not until
Publish Storefront.
Omitted keys stay. Nested objects (header.photo,
settings.privacy_easylegal) sparse-merge. header.links replaces the
whole array ([] clears). Unknown keys at any nesting level return 422
(The {key} field is not allowed.). An empty body {} returns 200;
nothing changes, including updated_at.
Colors are #RRGGBB (six hex digits). #fff returns 422.
These strings clear with "". The stored value is "", not null:
- URLs:
logo_url,background_image_url,photo.src_url/video_src_url/iframe_src_url,og_image_url,favicon_url,webclip_url,privacy_url. Absolutehttp://orhttps://only; relative paths return422. - Free text:
title,bio,photo.alt,page_title,page_description.
Enum tokens (layout, image_style, page_language, checkout_open_mode,
and the rest) cannot be cleared with "".
theme_id is an integer or null. Sending it does not copy a palette; send
color and font keys for a visual change.
Analytics pixel configuration is not readable and not writable. Sending
external_analytics returns 422. Stored pixels are left as they are.
Media
Upload Media hosts the bytes and
returns a file_url. It does not change the saved draft. PATCH that file_url into
header, settings,
or a widget. Skip this call when the URL is
already a public http:// or https:// link — storefront PATCHes store the
URL as given, unlike product image_url.
type=image is a photo or a video. Raster stills come back with a .webp
file_url — use the returned value. Video bytes return type=video; PATCH
header.photo.video_src_url (or a widget video_src_url), not src_url.
type=file is a private locator for config.file. PATCH
config.file = { name, url, external: false }. Do not GET url.
There is no download_url (unlike
product files).
Widgets / blocks
A new page has no widgets.
Get Storefront with include=blocks returns blocks: [].
Add widgets with Create Storefront Block.
Widgets live under the storefront UUID.
List and get read the
saved draft layout. Create appends one widget.
Update sparse-patches one. There is no delete:
set is_hidden to true to take a widget off the public page (it stays on
GET so it can be unhidden). Reorder rewrites
display order with a full items list — every current block exactly once,
including hidden ones.
These writes change the saved draft. Visitors still see the last published
page at public_url until Publish Storefront.
Open preview_url to see the edit.
Allowed type, layout, and config keys are on
Create Storefront Block.
Easylegal footer
privacy_easylegal.footer_id is the legal footer on this storefront. There is
no top-level footer_id.
Update Storefront Settings accepts a UUID, or
null to clear. An integer is 422. The storefront keeps an integer for that
footer. Get Storefront resolves that integer to a UUID when
footer_id is included. The response never returns the integer.
include=settings still omits privacy_easylegal.footer_id. Settings stays
the appearance block — title, description, language, checkout open mode,
images, the privacy link, and privacy_easylegal.enabled.
include=footer_id returns settings as only
{ "privacy_easylegal": { "footer_id": ... } }. Other settings keys, including
privacy_easylegal.enabled, are omitted. styles, header, and blocks
stay null.
include=settings,footer_id returns the full settings object plus that footer
id.
When footer_id is included, the value is a UUID string, null when nothing
is attached, or
{ "message": "The Easytools attachment could not be resolved." } when that
footer cannot be resolved. The storefront response stays HTTP 200. Other
requested fields still return. null means nothing is attached. A missing
footer_id key means the token was not included.
Update Storefront Settings returns 200
without footer_id. Get Storefronts does not include it.
Unknown include tokens are ignored.
Custom domains
Each storefront includes its attached custom domains, including ones that are
still pending or have failed. When a domain is configured for the storefront,
public_url is that domain; otherwise it is the platform URL. A pending or
failed domain still appears in domains but does not change public_url.
Storefront Object
Returned by Get Storefront and by the section PATCH
endpoints. The list returns a leaner projection — no
preview_url and no draft sections. A styles, header, or settings PATCH
returns this object with only the patched section populated; the other three
section keys are null.
| Field | Type | Nullable | Description |
|---|---|---|---|
id | string | No | Stable storefront identifier (UUID). |
slug | string | No | Current URL slug. Mutable, so use it for display only — never as a stable id. |
name | string | No | Display name (the Creator page name in the dashboard). |
status | string | No | Publication status: draft or published. |
public_url | string | Yes | Live visitor URL. null when the storefront is a draft. A configured custom domain is used when one is attached. |
preview_url | string | No | Temporary signed URL of the saved draft. Expires after about one hour. See Draft preview. |
domains | array | No | Custom domains attached to this storefront. Empty when none are attached. See Domain. |
created_at | string | No | When the storefront was created (ISO 8601). |
updated_at | string | No | When the storefront was last updated (ISO 8601). |
published_at | string | Yes | When the storefront was last published. null while it is a draft or after it has been unpublished. |
styles | object | Yes | Draft styles. null unless styles is included. |
header | object | Yes | Draft header. null unless header is included. |
settings | object | Yes | Draft settings. On Get Storefront, null unless settings or footer_id is included. Analytics pixel configuration is never included. privacy_easylegal.footer_id is included only with include=footer_id. See Easylegal footer. A settings PATCH returns this object without that id. |
blocks | array | Yes | Draft widgets in display order. null unless blocks is included. An empty page returns []. See Block. |
Domain
| Field | Type | Nullable | Description |
|---|---|---|---|
domain | string | No | The custom domain. |
status | string | No | Configuration status: pending, configured, or failed. |
include_www | boolean | No | Whether the www. subdomain is included. |
Block
Returned by Get Storefront when include=blocks, and by
the nested block endpoints. Hidden widgets stay. Product references in
config (product_id, and collection items[].product_id) are product
UUIDs. Allowed type, layout, and config keys for writes are on
Create Storefront Block.
| Field | Type | Nullable | Description |
|---|---|---|---|
id | string | No | Stable block identifier (UUID). |
type | string | No | Widget type. One of the 14 writable types on Create Storefront Block, or secret_code — a read-only type that is returned but cannot be created or updated. |
layout | string | Yes | Layout token for the widget, when the type uses one. |
order | integer | No | Display order, starting at 1. |
is_hidden | boolean | No | Whether the widget is hidden from visitors. |
is_hidden_on_mobile | boolean | No | Whether the widget is hidden on mobile viewports. |
config | object | No | Per-type widget config. |