Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.fourthwall.com/llms.txt

Use this file to discover all available pages before exploring further.

A design product runs your artwork through the design pipeline: it renders each region’s image onto a product template (a tee, mug, hoodie, …) and creates a purchasable product. Create one with the Create a product endpoint (POST /open-api/v1.0/products) by setting type: "design". Looking to sell downloadable files instead? See Create digital products.
OAuth scope: offer_write for creating products, plus media_write for the image upload steps below.API keys have full access to these endpoints. See Authentication for API keys or OAuth for multi-shop apps.
A design product is built from one or more regions (for example front and back), each rendered from an image you supply. You don’t pass an image URL directly — instead you upload the image, register it in your media library to obtain an imageId, and reference that id per region when you create the product.
1

Pick a product template

Each design product renders onto a product template (the blank tee, mug, etc.). List the available templates with GET /open-api/v1.0/product-templates and note the id you want — you’ll pass it as productTemplateId.
2

Request a pre-signed upload URL

Call POST /open-api/v1.0/media/upload-url with the file’s metadata. The response contains a short-lived uploadUrl to PUT the bytes to, and the fileUrl you’ll register in the next step.
curl -u "your_username:your_password" \
  -X POST https://api.fourthwall.com/open-api/v1.0/media/upload-url \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "my-design.png",
    "contentType": "image/png",
    "size": 482190
  }'
Response
{
  "uploadUrl": "https://storage.googleapis.com/...&X-Goog-Signature=...",
  "fileUrl": "https://cdn.fourthwall.com/media/.../my-design.png"
}
3

Upload the image bytes

PUT the raw image bytes to the uploadUrl. This request goes directly to Google Cloud Storage, not to Fourthwall — do not send your Fourthwall credentials with it.The URL is signed with two conditions you must match exactly, or GCS rejects the upload with 403 SignatureDoesNotMatch:
  • Content-Type — must equal the contentType you sent in step 2 (here, image/png).
  • x-goog-content-length-range: 0,<size> — must use the same size you sent in step 2 (here, 482190).
The x-goog-content-length-range header is required and easy to miss — it’s baked into the URL’s signature. Omitting it (or sending a different size) fails with 403 SignatureDoesNotMatch even when everything else looks right. The uploadUrl is short-lived (~6 hours); if it expires, request a new one.
curl -X PUT "<uploadUrl from previous step>" \
  -H "Content-Type: image/png" \
  -H "x-goog-content-length-range: 0,482190" \
  --data-binary @my-design.png
4

Register the image to get an imageId

Now persist the uploaded image in your media library with POST /open-api/v1.0/media/images. Pass the fileUrl from step 2 along with the image’s pixel dimensions. The response’s id is the imageId you’ll reference per region.
curl -u "your_username:your_password" \
  -X POST https://api.fourthwall.com/open-api/v1.0/media/images \
  -H "Content-Type: application/json" \
  -d '{
    "fileUrl": "https://cdn.fourthwall.com/media/.../my-design.png",
    "width": 2400,
    "height": 2400
  }'
Response
{
  "id": "img_k66ZW4fsRm6c2def3itltA",
  "uri": "https://cdn.fourthwall.com/media/.../my-design.png",
  "width": 2400,
  "height": 2400,
  "thumbnail": "https://cdn.fourthwall.com/...",
  "preview": "https://cdn.fourthwall.com/..."
}
Register an image once and reuse its imageId across multiple regions or multiple products — there’s no need to re-upload the same artwork.
5

Create the design product

Finally, call POST /open-api/v1.0/products with type: "design". Each entry in regions pairs a product region with the imageId you just registered.
curl -u "your_username:your_password" \
  -X POST https://api.fourthwall.com/open-api/v1.0/products \
  -H "Content-Type: application/json" \
  -d '{
    "type": "design",
    "productTemplateId": "pro_k66ZW4fsRm6c2def3itltA",
    "name": "My Awesome Design Tee",
    "description": "Limited edition design",
    "regions": [
      { "region": "front", "imageId": "img_k66ZW4fsRm6c2def3itltA", "placementStrategy": "AUTO" }
    ],
    "publishOnCreate": false
  }'
Response
{
  "productId": "off_a1b2c3d4e5f6",
  "customizationId": "cus_a1b2c3d4e5f6",
  "images": [
    {
      "url": "https://cdn.fourthwall.com/.../front-black.png",
      "width": 1200,
      "height": 1200,
      "style": "Unisex Tee",
      "color": "Black",
      "size": null,
      "region": "front"
    }
  ]
}
Pass the registered image’s id (the imageId) in regions[].imageId — not the uploadUrl or fileUrl. An imageId that isn’t a registered media-library image is rejected with a validation error; register it via POST /open-api/v1.0/media/images first.

Placement strategies

By default each region uses placementStrategy: "AUTO", which lets the renderer apply the product’s automation defaults. Set it explicitly to control how the image is placed:
StrategyBehavior
AUTOLet the renderer decide using the product’s defaults (preferred placement, or fill-all for items like mugs and stickers).
FILL_ALLApply the image to every placement in the region.
FULL_REGIONRender the image across the full region, skipping the preferred placement.
PLACEMENT_IDTarget a single placement named by placementId (required for this strategy).
You can also limit which colors and sizes are rendered, and set a profitMargin (a USD amount, e.g. 10.00) on top of the base cost. Products are created hidden unless you set publishOnCreate: true.

Next steps

Create a product reference

Full request and response schema for POST /products.

Media library

Upload and register images to reference by imageId.

Product templates

Browse templates to find a productTemplateId.

Create digital products

Sell downloadable files with a creator-set price.