The Channel API requires special access — it is invite only and
currently in beta. Your channel must be granted access by Fourthwall, which
provisions a dedicated
channel.* client for it;
reach out to request access. See
Authentication.The defining idea: the shop appears on publish
Browsing templates, uploading artwork, and rendering a preview are all shop-less — they go straight through the Channel API on the credential alone. Only on publish does a shop come into play: your backend provisions one (once) and creates the live product against it.Preview is shop-less; create is shop-bound.
Two credential faces, one channel
The same channel credential authenticates two API surfaces:- channel-api (
/channel-api/v1.0/…) — authorized by the channel bearer alone. Everything shop-less: template browsing, upload, preview, shop lookup, and shop provisioning. - open-api (
/open-api/v1.0/…) — the product-templates list is shop-less, but product create / list / state / delete are shop-bound: the same bearer plus anX-ShopIdheader selects the shop you provisioned.
Architecture: a thin backend-for-frontend
Keep the credential on your server. Each/api/* route is a small proxy that
attaches the channel credential and forwards to one (or, for publish, a few)
Fourthwall endpoints. The browser only ever talks to your own routes.
The flow, step by step
1
Connect the channel
Install your channel app and exchange the OAuth code for the channel
credential, holding it server-side. Confirm the connection by reading the
current channel:
cURL
2
Pick a blank product
List blank product templates and let the creator choose one. This is
shop-less:
cURL
3
Upload and register the artwork
Request a presigned upload URL,
PUT the bytes, then register the image to
get an imageId. Both calls are on the channel face — no shop yet:cURL
4
Render a live preview
Render preview mockups synchronously from the chosen template +
imageId.
Still shop-less:cURL
5
Publish — the shop boundary
Publish is the only step that needs a shop, and it owns the whole shop
lifecycle so your client makes a single call:
GET /channel-api/v1.0/shops— does the channel have a shop yet?POST /channel-api/v1.0/shops— only on first publish (idempotent: a second publish reuses the same shop, never a duplicate).POST /open-api/v1.0/productswith theX-ShopIdheader — create the live product from the sameproductId+imageIdthe preview was rendered from.
cURL
Managing published products
Once a shop exists, manage the catalog on the open-api face withX-ShopId:
- Show / hide →
PUT /open-api/v1.0/products/{id}/state(PUBLIC/HIDDEN) - Archive →
DELETE /open-api/v1.0/products/{id} - List →
GET /open-api/v1.0/products
Full example
Read Linkstand end to end — a Next.js app-router project where the BFF inlib/fourthwall.ts
is the only module that holds the credential and talks to Fourthwall.