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 digital product is sold at a creator-set price (in USD), ready for you to attach downloadable files and images. Create one with the Create a product endpoint (POST /open-api/v1.0/products) by setting type: "digital". Selling printed merch from your own artwork instead? See Create design products.
OAuth scope: offer_write for creating the product and managing its digital files. Attaching product images also needs media_write, since the image bytes are uploaded through the media library first.API keys have full access to these endpoints. See Authentication for API keys or OAuth for multi-shop apps.

Create the product

Send type: "digital" with a creator-set price (a USD amount). Products default to hidden. Set publishOnCreate: true to make the product visible on the storefront as soon as it’s created; otherwise it stays hidden and can only be published from the Fourthwall admin.
curl -u "your_username:your_password" \
  -X POST https://api.fourthwall.com/open-api/v1.0/products \
  -H "Content-Type: application/json" \
  -d '{
    "type": "digital",
    "name": "My Digital Product",
    "description": "A detailed description of my digital product",
    "price": 25.00
  }'
Response
{
  "productId": "<uuid>",
  "customizationId": null,
  "images": []
}

Attach downloadable files

These are the files your buyers download after purchase. Unlike media-library images — which are shop-wide and reusable across products by imageIda digital file belongs to the one product you upload it against. The upload URL is scoped to a productId, the bytes are stored under that product, and confirming links the file to it. The flow mirrors the media upload used for design artwork — request a pre-signed URL, PUT the bytes to Google Cloud Storage, then confirm — but it’s a product-scoped endpoint and the confirm step links the file to the product instead of registering a reusable image.
Digital files are size-limited per shop: 25 MB on free plans, up to 1 GB otherwise. The size you send is enforced both when the URL is issued and by the signed URL itself — sending more bytes than declared fails the upload.
1

Request a pre-signed upload URL

Call POST /open-api/v1.0/products/{productId}/digital-files/upload-url with the file’s metadata. The response is the same { uploadUrl, fileUrl } shape as the media flow: a short-lived uploadUrl to PUT the bytes to, and the fileUrl you’ll confirm in the last step.
curl -u "your_username:your_password" \
  -X POST https://api.fourthwall.com/open-api/v1.0/products/<uuid>/digital-files/upload-url \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "my-ebook.pdf",
    "contentType": "application/pdf",
    "size": 1048576
  }'
Response
{
  "uploadUrl": "https://storage.googleapis.com/...&X-Goog-Signature=...",
  "fileUrl": "<file>",
  "expiresAt": "2026-05-28T12:34:56Z"
}
expiresAt is when the pre-signed uploadUrl stops accepting PUTs; request a new one if it lapses.
2

Upload the file bytes

PUT the raw bytes to the uploadUrl. This goes directly to Google Cloud Storage, not to Fourthwall — do not send your Fourthwall credentials with it.The URL is signed with the same two conditions as the media upload, and missing either fails with 403 SignatureDoesNotMatch:
  • Content-Type — must equal the contentType you sent in step 1 (here, application/pdf).
  • x-goog-content-length-range: 0,<size> — must use the same size you sent in step 1 (here, 1048576).
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; if it expires, request a new one.
curl -X PUT "<uploadUrl from previous step>" \
  -H "Content-Type: application/pdf" \
  -H "x-goog-content-length-range: 0,1048576" \
  --data-binary @my-ebook.pdf
3

Confirm the upload

Link the uploaded file to the product with POST /open-api/v1.0/products/{productId}/digital-files. Pass the fileUrl from step 1 and the fileName buyers will see. The response is the full, updated product.
curl -u "your_username:your_password" \
  -X POST https://api.fourthwall.com/open-api/v1.0/products/<uuid>/digital-files \
  -H "Content-Type: application/json" \
  -d '{
    "fileUrl": "<file>",
    "fileName": "my-ebook.pdf"
  }'
Buyers receive digital files as downloads (they’re served with Content-Disposition: attachment). Repeat this flow once per file to attach several downloads to the same product. To remove one, call DELETE /open-api/v1.0/products/{productId}/digital-files with its fileUrl.

Attach product images

Product images are the showcase thumbnails shown on the storefront — separate from the downloadable files above. They are not uploaded through the digital-files endpoint. Instead, upload the image through the shop-wide media library (POST /open-api/v1.0/media/upload-url, then PUT the bytes — exactly as in Create design products), then attach the resulting URL to the product by its pixel dimensions:
cURL
curl -u "your_username:your_password" \
  -X POST https://api.fourthwall.com/open-api/v1.0/products/<uuid>/images \
  -H "Content-Type: application/json" \
  -d '{
    "images": [
      { "url": "<file>", "width": 800, "height": 600 }
    ]
  }'
Pass the fileUrl you uploaded as url; width and height are the image’s pixel dimensions.

Next steps

Create a product reference

Full request and response schema for POST /products.

Digital files

Upload and confirm the downloadable files customers receive.

Attach product images

Add showcase images to a digital product.

Create design products

Render your artwork onto tees, mugs, and more.