# Get Collection Source: https://docs.fourthwall.com/api-reference/platform/collections/get-collection GET /open-api/v1.0/collections/{slug} Returns collection by slug # List Collections Source: https://docs.fourthwall.com/api-reference/platform/collections/list-collections GET /open-api/v1.0/collections Returns all collections with pagination # Get Donation Source: https://docs.fourthwall.com/api-reference/platform/donations/get-donation GET /open-api/v1.0/donations/{donationId} Returns donation by id # List Donations Source: https://docs.fourthwall.com/api-reference/platform/donations/list-donations GET /open-api/v1.0/donations Returns all donations with pagination # Create Fulfillment Source: https://docs.fourthwall.com/api-reference/platform/fulfillment/create-fulfillment POST /open-api/v1.0/fulfillments Creates a fulfillment with a shipment tracker for provided order items. When trackers change their state, order.status will change to IN_PRODUCTION, PARTIALLY_IN_PRODUCTION, PARTIALLY_SHIPPED, SHIPPED depending on the shipping tracker info. Order updated webhooks will be triggered. # Get Gift Purchase Source: https://docs.fourthwall.com/api-reference/platform/gift-purchases/get-gift-purchase GET /open-api/v1.0/gift-purchase/{giftPurchaseId} Returns gift purchase details by id # Finish Draw Source: https://docs.fourthwall.com/api-reference/platform/gifting/finish-draw PUT /open-api/v1.0/gifting/draw/{id}/finish Finish draw and select winners # Get Draw Source: https://docs.fourthwall.com/api-reference/platform/gifting/get-draw GET /open-api/v1.0/gifting/draw/{id} Get draw details # Create Giveaway Links Source: https://docs.fourthwall.com/api-reference/platform/giveaway-links/create-giveaway-links POST /open-api/v1.0/giveaway-links Creates a new package with specified number of giveaway links # Get Giveaway Package Source: https://docs.fourthwall.com/api-reference/platform/giveaway-links/get-package GET /open-api/v1.0/giveaway-links/packages/{packageId} Returns all giveaway links for packageId # List Giveaway Packages Source: https://docs.fourthwall.com/api-reference/platform/giveaway-links/list-packages GET /open-api/v1.0/giveaway-links/packages Returns all packages with giveaway links # List Mailing List Entries Source: https://docs.fourthwall.com/api-reference/platform/mailing-lists/list-entries GET /open-api/v1.0/mailing-list-entries Returns all mailing list entries # Get Member Source: https://docs.fourthwall.com/api-reference/platform/memberships/get-member GET /open-api/v1.0/memberships/members/{id} Gets a member by id # List Members Source: https://docs.fourthwall.com/api-reference/platform/memberships/list-members GET /open-api/v1.0/memberships/members Lists all members for the current shop # List Membership Tiers Source: https://docs.fourthwall.com/api-reference/platform/memberships/list-tiers GET /open-api/v1.0/memberships/tiers Lists all tiers for the current shop # Get Order Source: https://docs.fourthwall.com/api-reference/platform/orders/get-order GET /open-api/v1.0/order/{orderId} Returns order by id # Get Order by Friendly ID Source: https://docs.fourthwall.com/api-reference/platform/orders/get-order-by-friendly-id GET /open-api/v1.0/order/by-friendly-id/{friendlyId} Returns order by friendly id # List Orders Source: https://docs.fourthwall.com/api-reference/platform/orders/list-orders GET /open-api/v1.0/order Returns all orders with pagination # Mark Digital Download Complete Source: https://docs.fourthwall.com/api-reference/platform/orders/mark-download-complete PUT /open-api/v1.0/order/{orderId}/downloaded Marks digital download as downloaded. If no downloads exist and defaultFileUrl is provided in the request body, creates a download with that URL and marks it as downloaded. # Exchange Token Source: https://docs.fourthwall.com/api-reference/platform/platform-token/exchange-token POST /open-api/v1.0/platform/token OAuth 2.0 token endpoint. Supports 'authorization_code' grant type for exchanging authorization codes for tokens, and 'refresh_token' grant type for refreshing access tokens. # Get Product Source: https://docs.fourthwall.com/api-reference/platform/products/get-product GET /open-api/v1.0/products/{productId} Returns product by id # Get Product Inventory Source: https://docs.fourthwall.com/api-reference/platform/products/get-product-inventory GET /open-api/v1.0/products/{productId}/inventory Returns product (offer) inventory by id # List Products Source: https://docs.fourthwall.com/api-reference/platform/products/list-products GET /open-api/v1.0/products Returns all products with pagination # Update Product Availability Source: https://docs.fourthwall.com/api-reference/platform/products/update-product-availability PUT /open-api/v1.0/products/{productId}/availability Toggle whether a product is visible and available for purchase on your storefront **This endpoint does not update inventory quantities.** It only toggles product visibility on your storefront. * Setting `available: true` makes the product visible and purchasable * Setting `available: false` hides the product from your storefront To manage actual inventory quantities (e.g., setting stock to 50 units), use the [Fourthwall dashboard](https://my.fourthwall.com). The API currently does not support programmatic inventory quantity updates. ## What this endpoint does This endpoint controls whether a product appears on your storefront. It accepts a simple boolean toggle: ```json theme={null} { "available": true } ``` This is useful for: * Temporarily hiding products without deleting them * Launching products at a specific time by toggling availability * Removing discontinued items from your storefront ## Common misconception Many developers expect this endpoint to accept inventory quantity updates like: ```json theme={null} { "variantId": "...", "quantity": 50 } ``` **This is not supported.** To view current inventory levels, use the [Get Product Inventory](/api-reference/platform/products/get-product-inventory) endpoint. # Create Promotion Source: https://docs.fourthwall.com/api-reference/platform/promotions/create-promotion POST /open-api/v1.0/promotions Creates a promotion # Get Promotion Source: https://docs.fourthwall.com/api-reference/platform/promotions/get-promotion GET /open-api/v1.0/promotions/{promotionId} Returns a promotion by id # List Promotions Source: https://docs.fourthwall.com/api-reference/platform/promotions/list-promotions GET /open-api/v1.0/promotions Returns all promotions # Get Current Shop Source: https://docs.fourthwall.com/api-reference/platform/shop/get-current-shop GET /open-api/v1.0/shops/current Returns the current shop # Get or Create Public Token Source: https://docs.fourthwall.com/api-reference/platform/shop/get-public-token PUT /open-api/v1.0/public-token Returns an existing public token for the shop, or creates a new one if none exists # Get Shop Contact Info Source: https://docs.fourthwall.com/api-reference/platform/shop/get-shop-contact-info GET /open-api/v1.0/shops/current/contact-info Returns the current shop contact info # End Streaming Source: https://docs.fourthwall.com/api-reference/platform/streaming/end-streaming PUT /open-api/v1.0/streaming/end Sets streaming status to ended for specified services # Get Streaming Status Source: https://docs.fourthwall.com/api-reference/platform/streaming/get-streaming-status GET /open-api/v1.0/streaming Returns streaming status for all services # Start Streaming Source: https://docs.fourthwall.com/api-reference/platform/streaming/start-streaming PUT /open-api/v1.0/streaming/start Sets streaming status to started for specified services # Create Webhook Source: https://docs.fourthwall.com/api-reference/platform/webhooks/create-webhook POST /open-api/v1.0/webhooks Create a webhook # Delete Webhook Source: https://docs.fourthwall.com/api-reference/platform/webhooks/delete-webhook DELETE /open-api/v1.0/webhooks/{webhookConfigurationId} Delete a webhook # Get Webhook Source: https://docs.fourthwall.com/api-reference/platform/webhooks/get-webhook GET /open-api/v1.0/webhooks/{webhookConfigurationId} Get a webhook # Get Webhook Event Source: https://docs.fourthwall.com/api-reference/platform/webhooks/get-webhook-event GET /open-api/v1.0/webhook-events/{webhookEventId} Get a single webhook event by ID # List Webhook Events Source: https://docs.fourthwall.com/api-reference/platform/webhooks/list-webhook-events GET /open-api/v1.0/webhook-events Get webhook events with pagination and optional filtering by webhook type # List Webhooks Source: https://docs.fourthwall.com/api-reference/platform/webhooks/list-webhooks GET /open-api/v1.0/webhooks Get webhooks # Update Webhook Source: https://docs.fourthwall.com/api-reference/platform/webhooks/update-webhook PUT /open-api/v1.0/webhooks/{webhookConfigurationId} Update a webhook # Add to Cart Source: https://docs.fourthwall.com/api-reference/storefront/carts/add-to-cart openapi/storefront.json post /v1/carts/{cartId}/add # Change Cart Quantity Source: https://docs.fourthwall.com/api-reference/storefront/carts/change-cart-quantity openapi/storefront.json post /v1/carts/{cartId}/change # Create Cart Source: https://docs.fourthwall.com/api-reference/storefront/carts/create-cart openapi/storefront.json post /v1/carts # Get Cart Source: https://docs.fourthwall.com/api-reference/storefront/carts/get-cart openapi/storefront.json get /v1/carts/{cartId} # Remove from Cart Source: https://docs.fourthwall.com/api-reference/storefront/carts/remove-from-cart openapi/storefront.json post /v1/carts/{cartId}/remove # Get Collection Source: https://docs.fourthwall.com/api-reference/storefront/collections/get-collection openapi/storefront.json get /v1/collections/{slug} Returns a collection # Get Collection Products Source: https://docs.fourthwall.com/api-reference/storefront/collections/get-collection-products openapi/storefront.json get /v1/collections/{slug}/products Returns all products in the collection # List Collections Source: https://docs.fourthwall.com/api-reference/storefront/collections/list-collections openapi/storefront.json get /v1/collections Returns all collections # Get Product by Slug Source: https://docs.fourthwall.com/api-reference/storefront/products/get-product openapi/storefront.json get /v1/products/{slug} # Get Shop Information Source: https://docs.fourthwall.com/api-reference/storefront/shop/get-shop openapi/storefront.json get /v1/shop # App Sections Source: https://docs.fourthwall.com/apps/app-sections Distribute custom iframe sections with your app App Sections are similar to [embedded sections](/embedded-sections/overview), but are distributed with your app. You specify the App Section at the app level, and anyone that installs your app will be able to add it to their shop. ## Signature The signature for app sections works exactly the same as [embedded sections](/embedded-sections/signature), but instead uses your app HMAC secret (also used to verify app webhooks). You can find the app HMAC secret in your [App settings](https://my-shop.fourthwall.com/admin/dashboard/settings/platform-apps?redirect). ## Message passing The messages are different from embedded sections. ### Resize ```json theme={null} { "type": "RESIZE", "data": { "height": 100 } } ``` ### Close ```json theme={null} { "type": "CLOSE" } ``` ## Settings We have an experimental feature that allows you to configure settings for your app section. Contact support on Discord to get access. # Embedded Settings Source: https://docs.fourthwall.com/apps/embedded-settings Provide a settings page for your app users Embedded settings allows you to provide a settings page for users of your app. This will be available when clicking through the app tile on the [apps page](https://my-shop.fourthwall.com/admin/dashboard/apps). This works similarly to [embedded sections](/embedded-sections/overview). ## Getting started You will specify the URL of the iframe that will be rendered on [your app](https://my-shop.fourthwall.com/admin/dashboard/settings/platform-apps?redirect) page, under Settings URL. ## Signature Like embedded sections, this will be called with an HMAC signature. ### Parameters | Parameter | Description | | ----------- | ------------------------------------------------- | | `timestamp` | The timestamp of when the signature was generated | | `shop_id` | The shop ID of the creator using your app | | `hmac` | The HMAC signature | The signature is generated using the following data string: ``` timestamp=${timestamp}&shop_id=${id}&app_id=${app_id} ``` The HMAC here is in base64 vs. hex in the embedded sections. Your HMAC secret key is available in the basic information section of your [Platform App settings](https://my-shop.fourthwall.com/admin/dashboard/settings/platform-apps?redirect). ## JavaScript Example ```javascript theme={null} async function getHmacKey(secret) { const encoder = new TextEncoder(); const keyData = encoder.encode(secret); return await crypto.subtle.importKey( 'raw', keyData, { name: 'HMAC', hash: 'SHA-512' }, false, ['sign', 'verify'] ); } async function verifySignature(params, hmacSignature, secret) { const { shopId, appId, timestamp } = params; const encoder = new TextEncoder(); const key = await getHmacKey(secret); const data = `timestamp=${timestamp}&shop_id=${shopId}&app_id=${appId}`; const messageData = encoder.encode(data); const signature = await crypto.subtle.sign('HMAC', key, messageData); const providedSignature = base64ToUint8Array(hmacSignature); if (signature.byteLength !== providedSignature.length) { return false; } return crypto.subtle.verify('HMAC', key, providedSignature, messageData); } ``` # Getting Started Source: https://docs.fourthwall.com/apps/getting-started Create multi-shop OAuth apps with the Fourthwall Platform ## Overview If you are looking to build an app that will be used by multiple shops, you will need to use OAuth. ## Creating an app Navigate to [Platform apps settings](https://my-shop.fourthwall.com/admin/dashboard/settings/platform-apps?redirect) to create an OAuth app. Here you will set some details for your app, the redirect URLs, and the scopes (permissions) you need for the app. Once you have this information, you are ready to [authenticate as your app](/guides/oauth). # Publishing Your App Source: https://docs.fourthwall.com/apps/publishing Submit your Fourthwall app for review and publication We're still developing an app publishing process. For now, you can submit your app for review by contacting us on Discord. We'll review your app and get back to you with any feedback. ## Before Submitting To make sure your app is ready for review, please make sure to set the following in your app settings: 1. A clear description 2. A Learn More URL that links to a page with more information about your app 3. App Icon Please also be ready with: 1. A video of your app in action 2. A support email that we can reach out to if there are any issues ## Guidelines We will be looking for: * **Value** - Your app must provide value to the community * **Quality** - Your app must be well-tested, well-maintained, and well-supported. We reserve the right to remove broken apps even after they have been published. * **No generative art** - Your app must NOT use generative art. Generative AI is also frowned upon, but we will consider on a case-by-case basis. # Messages Source: https://docs.fourthwall.com/embedded-sections/messages PostMessage API for embedded sections From inside the iframe (on the page you've provided), you can pass certain messages to the parent frame to trigger actions. ## Supported Events ### Resize Dynamically resize the iframe height: ```json theme={null} { "type": "resize", "height": 100 } ``` ### Close Close or hide the embedded section: ```json theme={null} { "type": "close" } ``` # Embedded Sections Source: https://docs.fourthwall.com/embedded-sections/overview Embed secure iframe sections into your Fourthwall shop Embedded sections are a way to embed content sections into your Fourthwall shop. These sections use HMAC signatures to verify that the content is being embedded on a Fourthwall shop, and can be gated by memberships. For app sections that can be distributed with your app, see [App Sections](/apps/app-sections). Embedded sections allow you to extend your Fourthwall shop with custom content that is securely embedded and verified. This is particularly useful for: * **Live stream overlays** - Display real-time order notifications, supporter shoutouts, or donation goals during your streams * **Customer support tools** - Embed live chat widgets, FAQ sections, or ticket submission forms directly in your shop * **Social proof elements** - Show recent purchases, customer reviews, or social media feeds to build trust * **Membership gated content** - Create exclusive content sections that only appear for paying members ## How it works An embedded section is rendered as an iframe on your shop with certain query parameters added to the URL to prove that it is being embedded for: 1. A specific Fourthwall shop 2. A specific supporter (for memberships) 3. A specific tier (for memberships) First generate a secret key in [Developer settings](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers#embedded-hmac-secret?redirect). Without setting the secret key, the iframe will not be rendered. You can add it as a section like any other section in your shop. Embedded section example Once added, you will need to configure a URL for the iframe. Embedded section configuration Now whenever someone visits your shop, the iframe will be called with a signature. # Signature Verification Source: https://docs.fourthwall.com/embedded-sections/signature Verify embedded section authenticity using HMAC-SHA512 ## Overview To ensure the authenticity of embedded sections, Fourthwall uses HMAC-SHA512 signatures to prove that the content is being embedded on a Fourthwall shop, for a specific supporter and tier. ## Parameters The following parameters are passed to your iframe: | Parameter | Description | | -------------- | ------------------------------------------------- | | `hmac` | The HMAC signature | | `timestamp` | The timestamp of when the signature was generated | | `shop_id` | Your shop ID | | `supporter_id` | Supporter ID of the logged-in member | | `tier_id` | Tier ID of the supporter's subscription | ## Verification To verify the signature, recalculate the HMAC signature using the same parameters and your secret key. The data string format: ``` shop_id=${shop_id}&supporter_id=${supporter_id}&tier_id=${tier_id}×tamp=${timestamp} ``` Your secret key is available in your [Developer settings](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers#embedded-hmac-secret?redirect). **Never leak this secret in your code.** If exposed, it can be used to impersonate any supporter on your shop. ## JavaScript Example ```javascript theme={null} async function getHmacKey(secret) { const encoder = new TextEncoder(); const keyData = encoder.encode(secret); return await crypto.subtle.importKey( 'raw', keyData, { name: 'HMAC', hash: 'SHA-512' }, false, ['sign', 'verify'] ); } async function verifySignature(params, hmacSignature, secret) { const { shopId, supporterId, tierId, timestamp } = params; const encoder = new TextEncoder(); const key = await getHmacKey(secret); const data = `shop_id=${shopId}&supporter_id=${supporterId}&tier_id=${tierId}×tamp=${timestamp}`; const messageData = encoder.encode(data); const signature = await crypto.subtle.sign('HMAC', key, messageData); const generatedSignatureHex = uint8ArrayToHex(new Uint8Array(signature)); return generatedSignatureHex === hmacSignature; } ``` # Authentication Source: https://docs.fourthwall.com/guides/authentication Authenticate with shop-level API keys using Basic Access Authentication **Which authentication method should you use?** * **Basic Auth** - Use this if you are building integrations for **your own shop**. This is the most common use case and what most developers need. Simply create API credentials and include them with each request. * **OAuth** - Use this only if you are building an app that will be used by **multiple different shops** (e.g., a third-party integration that other Fourthwall creators will install). See the [OAuth guide](/guides/oauth) for details. The simplest way to authenticate is with a shop level API key. This key will give you unrestricted access to all API endpoints for your shop. ## Getting credentials The creation of API credentials is reserved for users with the **SUPER ADMIN** role. 1. Navigate to [For developers](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers?redirect) to create an API user. 2. If API credentials haven't been generated yet, you will find a "Create API User" button under the "Open API" section. Click on it, and shortly after, the Username and Password for the Open API User will be provided. Keep your API credentials confidential and do not share them with unauthorized personnel. These credentials grant access to sensitive data and actions within our system. Always use HTTPS/SSL for encrypted communication when making API requests. ## Authorizing with credentials After Open API User was created, you can authorize your request by using **Basic Access Authentication**. This can be achieved by constructing an **Authorization** header with the format **Basic base64-encoded-username-and-password**. The base64-encoded credentials should be passed with each request to gain access to the protected resources. ```bash cURL theme={null} curl -u "your_username:your_password" https://api.fourthwall.com/open-api/v1/order/{YOUR_ORDER_ID} ``` ```javascript JavaScript theme={null} const username = "your_username"; const password = "your_password"; // Combine username and password with a colon const combinedCredentials = `${username}:${password}`; // Encode the combined credentials to Base64 const base64Credentials = btoa(combinedCredentials); const apiUrl = "https://api.fourthwall.com/open-api/v1/order/{YOUR_ORDER_ID}"; const requestOptions = { method: "GET", headers: { "Authorization": `Basic ${base64Credentials}`, "Content-Type": "application/json" } }; fetch(apiUrl, requestOptions) .then(response => response.json()) .then(data => { console.log(data); }) .catch(error => { console.error("Error:", error); }); ``` # OAuth Authentication Source: https://docs.fourthwall.com/guides/oauth OAuth 2.0 authentication flow for multi-shop apps If you are looking to build an app that will be used by multiple shops, you will need to use OAuth. First, create an app by following the instructions in [Apps - Getting started](/apps/getting-started). Once completed, you will need to know: 1. Your redirect URL 2. Your client ID 3. Your client secret ## Authorize URL Link your users to this URL to start the login process for your app. Always use `my-shop.fourthwall.com` as the shop URL as this will link to the logged in user's current shop. You can copy this URL from the OAuth tab of your app. You will need to provide your Client ID in the path (you can get this from your apps settings page), your redirect URL, as well as an optional state parameter. ``` https://my-shop.fourthwall.com/admin/platform-apps//connect?redirect_uri=&state= ``` ## Getting an access token After the user has authorized your app, they will be redirected to your redirect URL with an authorization code and the state parameter if you provided one. You will need to exchange this code for an access token. ```bash theme={null} curl -XPOST https://api.fourthwall.com/open-api/v1.0/platform/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code&redirect_uri=&client_id=&client_secret=&code=" ``` The response will contain an `access_token`, `refresh_token`, and other information. ## Using the access token ```bash theme={null} curl -XGET https://api.fourthwall.com/open-api/v1/order/{YOUR_ORDER_ID} \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ## Refreshing the access token Access tokens expire rather quickly (within a few minutes). You can use the `refresh_token` to get a new access token without having to re-authorize the user. ```bash theme={null} curl -XPOST https://api.fourthwall.com/open-api/v1.0/platform/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=refresh_token&client_id=&client_secret=&refresh_token=" ``` # Platform API Overview Source: https://docs.fourthwall.com/guides/overview RESTful API for managing your Fourthwall shop programmatically The Fourthwall Platform API is a RESTful API that allows you to manage various aspects of your shop. It can be accessed either directly using your own API key (this gives you full access to your own shop) or indirectly through OAuth for multi-shop apps. ## Authentication Methods Direct shop access with Basic Auth credentials Multi-shop app authentication with access tokens # Rate Limiting Source: https://docs.fourthwall.com/guides/rate-limiting API rate limits and best practices for handling rate limit errors To ensure fair usage and maintain optimal system performance, we have implemented rate limiting for API requests. Each user is allowed a maximum of **100 requests** within a **10-second rolling window**. ## What this means for you * You can make up to 100 requests within any 10-second period * If you exceed this limit, any additional requests will be delayed until the 10-second window is reset Plan your API usage accordingly to avoid interruptions and ensure the smooth functioning of our services. # Introduction Source: https://docs.fourthwall.com/index Build integrations with the Fourthwall platform Welcome to the Fourthwall developer documentation. Build custom integrations, automate your shop, or create apps for the Fourthwall ecosystem. ## What can you build? Manage orders, products, memberships, and more with full API access. Build custom storefronts with public shop and product data. Receive real-time notifications for orders, subscriptions, and events. Create apps that integrate directly into creator dashboards. ## Ready to start? Get your API key and make your first API call in minutes. # Quickstart Source: https://docs.fourthwall.com/quickstart Make your first API call in minutes Get up and running with the Fourthwall API in three steps. ## 1. Get your API credentials Creating API credentials requires the **SUPER ADMIN** role. 1. Go to [Settings > For Developers](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers?redirect) 2. Under "Open API", click **Create API User** 3. Save the username and password that are generated ## 2. Make your first API call Test your credentials by fetching your shop details. The Fourthwall API uses **Basic Authentication** - simply pass your username and password with each request. ```bash cURL theme={null} # Basic Auth - the simplest way to authenticate curl -u "your_username:your_password" \ https://api.fourthwall.com/open-api/v1.0/shops/current ``` ```javascript JavaScript theme={null} const username = "your_username"; const password = "your_password"; // Basic Auth: base64 encode "username:password" const credentials = btoa(`${username}:${password}`); fetch("https://api.fourthwall.com/open-api/v1.0/shops/current", { headers: { "Authorization": `Basic ${credentials}` } }) .then(res => res.json()) .then(data => console.log(data)); ``` ```python Python theme={null} import requests from requests.auth import HTTPBasicAuth # Basic Auth is built into the requests library response = requests.get( "https://api.fourthwall.com/open-api/v1.0/shops/current", auth=HTTPBasicAuth("your_username", "your_password") ) print(response.json()) ``` The `-u` flag in cURL automatically handles Basic Auth encoding for you. Under the hood, it creates an `Authorization: Basic ` header. You should receive a response with your shop details: ```json theme={null} { "id": "sh_abc123", "name": "My Shop", "currency": "USD", ... } ``` ## 3. Explore the API Now that you're authenticated, explore what you can build: Fetch orders from your shop Get your product catalog Get real-time event notifications Browse all available endpoints # Community Source: https://docs.fourthwall.com/resources/community Join the Fourthwall developer community Come chat with us on [Discord](https://discord.com/invite/kc6P68z3Uz)! ## Useful Channels * **#developers-general** - General developer discussion and questions * **#creator-resources** - Resources and tools for creators # LLM Support Source: https://docs.fourthwall.com/resources/llm-support Use Fourthwall documentation with AI code editors Our documentation is optimized for use with Large Language Models (LLMs) and AI code editors. We provide specially formatted documentation files that help AI assistants generate accurate code and provide better guidance. ## Documentation Files We provide two versions of our documentation optimized for AI consumption: | File | Size | Description | | ---------------------------------------------------------- | ------- | ---------------------------------------------------- | | [llms.txt](https://docs.fourthwall.com/llms.txt) | \~45KB | Compact version with hierarchical sections and links | | [llms-full.txt](https://docs.fourthwall.com/llms-full.txt) | \~592KB | Complete documentation with full content | These files follow the [llms.txt](https://llmstxt.org/) standard. ## Quick Setup Add this to your AI editor's configuration file (`.cursorrules`, `CLAUDE.md`, `.github/copilot-instructions.md`, etc.): ```markdown theme={null} # Fourthwall Development Fourthwall is an e-commerce platform for creators to sell merchandise, memberships, and digital products. Documentation: https://docs.fourthwall.com/llms-full.txt When working with Fourthwall APIs: - Platform API: shop management (authentication, products, orders, inventory, webhooks) - Storefront API: custom storefronts (cart, checkout, collections) - Apps: OAuth apps with multi-shop support - Security: HMAC signature verification for webhooks and embedded sections ``` ## MCP Server Our documentation is available via an MCP server, enabling AI applications to query our docs directly. **MCP Server URL:** `https://docs.fourthwall.com/mcp` 1. Open Claude settings and navigate to **Connectors** 2. Select **Add custom connector** 3. Enter name: `Fourthwall Docs` 4. Enter URL: `https://docs.fourthwall.com/mcp` 5. Select **Add** 1. Open command palette (`Cmd+Shift+P` / `Ctrl+Shift+P`) 2. Search for **Open MCP settings** 3. Add to your `mcp.json`: ```json theme={null} { "mcpServers": { "fourthwall-docs": { "url": "https://docs.fourthwall.com/mcp" } } } ``` Run in your terminal: ```bash theme={null} claude mcp add fourthwall-docs https://docs.fourthwall.com/mcp ``` Once connected, AI tools can search our documentation directly instead of relying on web search results. ## Context7 Integration Our documentation is also available via the **[Context7 MCP](https://context7.com/)** server. **Project ID:** `/llmstxt/fourthwall_llms-full_txt` For setup instructions for your editor (Claude, Cursor, VSCode, Windsurf, Zed, etc.), see the [Context7 Installation Guide](https://github.com/upstash/context7). ## What's Included * **Platform API** - Authentication, products, orders, inventory, webhooks * **Apps** - OAuth apps, app sections, app webhooks * **Storefront** - Custom storefronts, cart management, checkout * **Webhooks** - Event types, signature verification, testing * **Code Examples** - Authentication, API calls, signature verification ## Additional Resources * [Fourthwall Brand Guidelines](https://fourthwall.com/brand) * [Fourthwall Brand llms.txt](https://fourthwall.com/brand/llms.txt) For questions or issues with AI integrations, join our [Discord community](https://discord.com/invite/kc6P68z3Uz) in #developers-general. # Storefront Showcase Source: https://docs.fourthwall.com/resources/showcase Example custom storefronts built with Fourthwall Check out these example storefronts built with the Fourthwall Storefront API: ## Featured Storefronts Official Next.js starter kit for building custom storefronts ## Build Your Own Ready to build your own custom storefront? Get started with our [Storefront API documentation](/storefront/overview). # Architecture Source: https://docs.fourthwall.com/storefront/architecture How the Storefront API connects your frontend to Fourthwall ## How It All Connects Here's the complete flow from browsing to purchase: ```mermaid theme={null} flowchart TB subgraph Your_Frontend["Your Frontend"] A[Browse Products] B[Manage Cart] end subgraph Storefront_API["Storefront API"] C["/collections/{slug}/products"] D["/products/{slug}"] E["/carts"] end subgraph Fourthwall["Fourthwall"] F[Checkout Page] G[Order Complete] end A -->|"Fetch"| C A -->|"Fetch"| D B -->|"Create/Update"| E B -->|"Redirect with cart_id"| F F -->|"Payment processed"| G G -->|"Return to your site"| Your_Frontend ``` **The journey:** 1. **Browse**: Your frontend fetches products and collections from the Storefront API 2. **Cart**: Customer adds items, you manage the cart via API 3. **Checkout**: Redirect to Fourthwall checkout with the cart ID 4. **Complete**: Fourthwall handles payment, then returns customer to your site ## Deployment Options If you build your storefront on the Fourthwall shop editor, your shop is served directly from our servers to your customers. ```mermaid theme={null} flowchart TB A["Fourthwall.com
shops"] B["Customer"] A -->|"<html>"| B ``` While this is a great way to get started, it does have some limitations. To build a truly custom experience, you can build your own frontend and use the Storefront API to pull in products and handle the cart process. ### With a proxy The most straight-forward way to build a custom storefront is through a proxy server. We've optimized for a setup through Vercel, though other services like Netlify would work as well. ```mermaid theme={null} flowchart TB A["Fourthwall
storefront api"] B["Your site
vercel"] C["Customer"] A -->|"API calls"| B B -->|"API calls"| A B -->|"<html>"| C ``` In this setup, your frontend application will make API calls to the Vercel backend. The Vercel backend acts as a proxy that will then make calls to the Fourthwall API. Your Vercel application can contain whatever code you want, allowing for a fully customizable storefront. ### Separate frontend It is also possible to build your custom site as a static frontend only site. In this setup, the static site will make API calls directly to the Fourthwall API. ```mermaid theme={null} graph LR A["Your site"] B["Fourthwall
storefront api"] C["Customer"] B -->|"API calls"| A A -->|"<html>"| C ``` # Building a Cart & Checkout Source: https://docs.fourthwall.com/storefront/cart-checkout-tutorial End-to-end guide for implementing shopping cart and checkout This guide walks through the complete flow from adding items to a cart through redirecting to checkout. ## Overview ```mermaid theme={null} flowchart LR A[Create Cart] --> B[Add Items] B --> C[Redirect to Checkout] C --> D[Customer Completes Purchase] ``` ## Step 1: Create a Cart First, create an empty cart. You'll get back a `cart_id` that you'll use for all subsequent operations. ```javascript theme={null} const STOREFRONT_TOKEN = "your_storefront_token"; const API_BASE = "https://storefront-api.fourthwall.com/v1"; async function createCart() { const res = await fetch(`${API_BASE}/carts?storefront_token=${STOREFRONT_TOKEN}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ currency: "USD" }) }); return res.json(); } const cart = await createCart(); console.log(cart.id); // e.g., "crt_abc123" ``` Store the `cart_id` in localStorage or a cookie so it persists across page refreshes. ## Step 2: Add Items to Cart Add products to the cart using a variant ID. You can get variant IDs from the [product endpoints](/storefront/products). ```javascript theme={null} async function addToCart(cartId, variantId, quantity = 1) { const res = await fetch( `${API_BASE}/carts/${cartId}/items?storefront_token=${STOREFRONT_TOKEN}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ variantId, quantity }) } ); return res.json(); } // Add a product to the cart await addToCart(cart.id, "var_xyz789", 2); ``` ## Step 3: View Cart Contents Fetch the current cart to display items to the user: ```javascript theme={null} async function getCart(cartId) { const res = await fetch( `${API_BASE}/carts/${cartId}?storefront_token=${STOREFRONT_TOKEN}` ); return res.json(); } const currentCart = await getCart(cart.id); console.log(currentCart.items); // Array of cart items console.log(currentCart.totals); // Price totals ``` ## Step 4: Redirect to Checkout When the customer is ready to purchase, redirect them to the Fourthwall checkout page using the cart ID: ```javascript theme={null} function redirectToCheckout(cartId, currency = "USD") { const checkoutDomain = "your-shop.fourthwall.com"; // Your checkout domain const checkoutUrl = `https://${checkoutDomain}/checkout/?cartCurrency=${currency}&cartId=${cartId}`; window.location.href = checkoutUrl; } // When user clicks "Checkout" button redirectToCheckout(cart.id, "USD"); ``` The checkout URL format is: ``` https://{checkout_domain}/checkout/?cartCurrency={currency}&cartId={cart_id} ``` Make sure to use your shop's checkout domain, not `storefront-api.fourthwall.com`. ## Complete Example Here's a complete implementation you can adapt: ```javascript theme={null} const STOREFRONT_TOKEN = "your_storefront_token"; const API_BASE = "https://storefront-api.fourthwall.com/v1"; const CHECKOUT_DOMAIN = "your-shop.fourthwall.com"; // Cart state let cartId = localStorage.getItem("cartId"); async function ensureCart() { if (cartId) { // Verify cart still exists const res = await fetch( `${API_BASE}/carts/${cartId}?storefront_token=${STOREFRONT_TOKEN}` ); if (res.ok) return cartId; } // Create new cart const res = await fetch(`${API_BASE}/carts?storefront_token=${STOREFRONT_TOKEN}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ currency: "USD" }) }); const cart = await res.json(); cartId = cart.id; localStorage.setItem("cartId", cartId); return cartId; } async function addToCart(variantId, quantity = 1) { const id = await ensureCart(); const res = await fetch( `${API_BASE}/carts/${id}/items?storefront_token=${STOREFRONT_TOKEN}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ variantId, quantity }) } ); return res.json(); } function checkout() { if (!cartId) { alert("Your cart is empty"); return; } window.location.href = `https://${CHECKOUT_DOMAIN}/checkout/?cartCurrency=USD&cartId=${cartId}`; } ``` ## Next Steps Make your checkout page match your brand See all cart operations # Checkout Setup Source: https://docs.fourthwall.com/storefront/checkout Configure Fourthwall checkout pages for custom storefronts When the user is ready to checkout, you will redirect them to the Fourthwall checkout page. This is where they can review their order and enter their shipping and payment information. Checkout page It's best to style the checkout page so that it matches the rest of your store. This will help create a seamless shopping experience for your customers. We recommend using a simple theme like Clean Frame and then setting the styling (colors + typography) so that it matches your main store. You can [style your checkout process here](https://my-shop.fourthwall.com/admin/dashboard/store-design/layout/index/?redirect). You will also want to connect a custom domain like `checkout..com` to the checkout page so that the redirect from your main store is seamless. You can connect custom domains [here](https://my-shop.fourthwall.com/admin/dashboard/settings/domain/?redirect). In the Vercel starter kit, you can add the checkout domain (custom or otherwise) to the `env.local` file under the `NEXT_PUBLIC_FW_CHECKOUT` variable. If you are building your own frontend, you will simply redirect the user to: ``` https:///checkout/?cartCurrency=&cartId= ``` ## Setting up a meta redirect (recommended) The emails sent from Fourthwall can sometimes include a link to the Fourthwall (checkout) page. When a user clicks on this link, you will want to redirect them to your domain. You can add a redirect script to your `Head` component [here](https://my-shop.fourthwall.com/admin/dashboard/store-design/general/advanced/?redirect). ```html theme={null} ``` # Collection Handles Source: https://docs.fourthwall.com/storefront/collection How to get a collection handle for the Storefront API The Storefront collection APIs use the collection handles (slugs) to identify the collection you want to display. It defaults to the "all" collection, but you can specify a different collection by providing the handle. Looking to fetch products? See [Fetching Products](/storefront/products) for the complete guide. ## The `all` Collection The `all` collection is a special built-in collection that contains **all public products** in your shop. Use it when you want to display your entire catalog: ```javascript theme={null} GET /v1/collections/all/products?storefront_token=YOUR_TOKEN ``` ## Finding Collection Handles Here's how to get the handle for a collection: 1. Go to the [Collections page](https://my-shop.fourthwall.com/admin/dashboard/products/collections/?redirect) 2. Click on the collection you want to get the handle for. Make sure this collection is public. 3. The handle is the last part of the copyable URL. # Getting Started Source: https://docs.fourthwall.com/storefront/getting-started Get started with Storefront API authentication and deployment ## Authentication You can create a Storefront token in your [developer settings](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers/?redirect). This token will be used to authenticate your requests to the Storefront API. Storefront token ## Vercel The best way to get started is with Vercel and Next.js. Vercel is a cloud platform that makes it easy to deploy websites and applications. Next.js is the React-based framework that Vercel is built on. You can fork our open source project to get started: [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FFourthwallHQ%2Fvercel-commerce) Once you have forked the repo, you can follow the instructions in the README to learn how to run the project locally and deploy. The only things you will need to configure are the default environment variables. ## Static page If you decide to build your own frontend, you can simply make fetch requests directly to the Fourthwall API to get the information you need. ```javascript theme={null} const res = await fetch("https://storefront-api.fourthwall.com/v1/collections?storefront_token="); ``` The full set of endpoints available to you can be found in the Storefront API reference. # Storefront API Overview Source: https://docs.fourthwall.com/storefront/overview Build custom storefronts on top of Fourthwall products The Storefront API lets you build custom storefronts on top of your Fourthwall product collections. Create a fully custom shopping experience while leveraging Fourthwall's product catalog, fulfillment, and checkout. ## Quick start Get your storefront token from [Settings > For Developers](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers/?redirect), then fetch your collections: ```bash theme={null} curl "https://storefront-api.fourthwall.com/v1/collections?storefront_token=YOUR_TOKEN" ``` ## What you can do * **Fetch products and collections** - Display your Fourthwall products on any website or app * **Manage shopping carts** - Create and update carts via API * **Checkout** - Redirect customers to Fourthwall's hosted checkout page ## Next steps Set up authentication and make your first API call Understand how the API connects to your frontend # Fetching Products Source: https://docs.fourthwall.com/storefront/products How to fetch products using the Storefront API The Storefront API organizes products into **collections**. There is no standalone "List Products" endpoint—instead, you fetch products through collections. ## The `all` Collection Every shop has a built-in `all` collection that contains all public products. This is the easiest way to get all products: ```javascript theme={null} // Get all products const res = await fetch( "https://storefront-api.fourthwall.com/v1/collections/all/products?storefront_token=YOUR_TOKEN" ); const { results, paging } = await res.json(); ``` ## Common Patterns ### Get all products (paginated) ```javascript theme={null} async function getAllProducts(token) { const products = []; let page = 0; let hasMore = true; while (hasMore) { const res = await fetch( `https://storefront-api.fourthwall.com/v1/collections/all/products?storefront_token=${token}&page=${page}&size=50` ); const data = await res.json(); products.push(...data.results); hasMore = data.paging.hasNextPage; page++; } return products; } ``` ### Get products from a specific collection ```javascript theme={null} const res = await fetch( "https://storefront-api.fourthwall.com/v1/collections/merch/products?storefront_token=YOUR_TOKEN" ); ``` ### Get a single product by slug Use this when you already know the product slug (e.g., from a URL like `/products/cool-t-shirt`): ```javascript theme={null} const res = await fetch( "https://storefront-api.fourthwall.com/v1/products/cool-t-shirt?storefront_token=YOUR_TOKEN" ); ``` ## Why Collections? Collections let you: * Organize products into categories (e.g., "Apparel", "Accessories") * Control which products appear on your storefront * Create featured or seasonal groupings The `all` collection is always available as a catch-all. # Shop Feeds Source: https://docs.fourthwall.com/storefront/shop-feeds RSS and JSON product feeds for shop integration ## Products RSS feed If you're just looking to read public product information, you do not need to use the Open API. All sites publish a Merchant Center Feed under an RSS address: ``` ${shop_url}/.well-known/merchant-center/rss.xml ``` **Example:** for [https://shop.fourthwall.com](https://shop.fourthwall.com) the RSS feed URL would be [https://shop.fourthwall.com/.well-known/merchant-center/rss.xml](https://shop.fourthwall.com/.well-known/merchant-center/rss.xml) ## Collections JSON feed A JSON version of the products in a collection. ``` ${shop_url}/collections/{slug}.json ``` **Example:** [https://shop.fourthwall.com/collections/all.json](https://shop.fourthwall.com/collections/all.json) **Paginated:** [https://shop.fourthwall.com/collections/all/2.json](https://shop.fourthwall.com/collections/all/2.json) # Managing Webhooks via API Source: https://docs.fourthwall.com/webhooks/api-management Programmatically create, update, and manage webhook subscriptions In addition to setting up webhooks through the [dashboard](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers?redirect), you can programmatically create and manage webhooks using the Platform API. This is useful for: * Automating webhook setup as part of your deployment process * Building integrations that dynamically configure webhooks * Managing webhooks across multiple shops programmatically ## Creating a Webhook Use the [POST /webhooks](/api-reference/platform/webhooks/create-webhook) endpoint to create a new webhook subscription: ```bash theme={null} curl -u "your_username:your_password" \ -X POST "https://api.fourthwall.com/open-api/v1.0/webhooks" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-server.com/webhooks/fourthwall", "allowedTypes": ["ORDER_PLACED", "ORDER_UPDATED", "DONATION"] }' ``` The response includes the webhook configuration with its ID and secret key: ```json theme={null} { "id": "wcon_P-VkRfmJTBaC6_Tst22cew", "url": "https://your-server.com/webhooks/fourthwall", "allowedTypes": ["ORDER_PLACED", "ORDER_UPDATED", "DONATION"], "secret": "e3f93c7c-c92b-4b8f-a9b1-5b70e0891abc" } ``` Store the `secret` value securely - you'll need it to [verify webhook signatures](/webhooks/signature-verification). ## Complete Example: Create, Receive, and Verify Here's a complete flow showing how to set up a webhook programmatically and handle incoming events: **Step 1: Create the webhook** ```python theme={null} import requests # Create webhook subscription using Basic Auth response = requests.post( "https://api.fourthwall.com/open-api/v1.0/webhooks", auth=("your_username", "your_password"), json={ "url": "https://your-server.com/webhooks/fourthwall", "allowedTypes": ["ORDER_PLACED"] } ) webhook_config = response.json() webhook_secret = webhook_config["secret"] # Store this securely! ``` **Step 2: Receive and verify webhook events** ```python theme={null} import hmac import hashlib import base64 from flask import Flask, request, jsonify app = Flask(__name__) WEBHOOK_SECRET = "your_stored_secret" def verify_signature(payload, signature_header): """Verify the webhook signature matches.""" digest = hmac.new( WEBHOOK_SECRET.encode('utf-8'), payload, digestmod=hashlib.sha256 ).digest() computed_signature = base64.b64encode(digest).decode('utf-8') return hmac.compare_digest(computed_signature, signature_header) @app.route('/webhooks/fourthwall', methods=['POST']) def handle_webhook(): # Get the signature from headers signature = request.headers.get('X-Fourthwall-Hmac-SHA256') # Verify the signature if not verify_signature(request.data, signature): return jsonify({"error": "Invalid signature"}), 401 # Parse the webhook payload event = request.json # Handle different event types if event["type"] == "ORDER_PLACED": order_data = event["data"] print(f"New order received: {order_data['friendlyId']}") # Process the order... # Always return 200 to acknowledge receipt return jsonify({"status": "received"}), 200 ``` ## API Endpoints The Platform API provides these endpoints for webhook management: | Endpoint | Description | | -------------------------------------------------------------------- | --------------------------------- | | [POST /webhooks](/api-reference/platform/webhooks/create-webhook) | Create a new webhook subscription | | [GET /webhooks](/api-reference/platform/webhooks/list-webhooks) | List all webhooks | | [GET /webhooks/](/api-reference/platform/webhooks/get-webhook) | Get a specific webhook | | [PUT /webhooks/](/api-reference/platform/webhooks/update-webhook) | Update a webhook | | [DELETE /webhooks/](/api-reference/platform/webhooks/delete-webhook) | Delete a webhook | # Webhook Event Types Source: https://docs.fourthwall.com/webhooks/event-types Complete reference of webhook event types with JSON payload examples Below you will find all the webhook event types that are currently supported by Fourthwall. To distinguish between different event types you can use the `type` field in the Webhook JSON payload. ## Order placed **Webhook type** = `ORDER_PLACED` ```json theme={null} { "id": "00aa4abd-5778-4199-8161-0b49b2f212e5", "shopId": "sh_c689d374-22ca-43d3-8d29-9ef0805cc4cb", "friendlyId": "D3XZFWPP", "checkoutId": "ch_BV44UYrXQA2T_Xcf1288tw", "promotionId": "prm_a1bc23", "status": "CONFIRMED", "email": "supporter@fourthwall.com", "emailMarketingOptIn": false, "username": "Supporter username", "message": "Sample message", "amounts": { "subtotal": { "value": 5.5, "currency": "USD" }, "shipping": { "value": 5.5, "currency": "USD" }, "tax": { "value": 5.5, "currency": "USD" }, "donation": { "value": 5.5, "currency": "USD" }, "discount": { "value": 5.5, "currency": "USD" }, "total": { "value": 5.5, "currency": "USD" } }, "billing": { "address": { "name": "Joe Doe", "address1": "Main Street 1", "city": "San Francisco", "state": "CA", "country": "US", "zip": "12345" } }, "shipping": { "address": { "name": "Joe Doe", "address1": "Main Street 1", "city": "San Francisco", "state": "CA", "country": "US", "zip": "12345" } }, "offers": [ { "id": "00aa4abd-5778-4199-8161-0b49b2f212e5", "name": "My TShirt", "slug": "my-tshirt", "variant": { "id": "00aa4abd-5778-4199-8161-0b49b2f212e5", "name": "My TShirt", "sku": "WDEK-DRE200L", "unitPrice": { "amount": 5.5, "currency": "USD" }, "quantity": 1 } } ], "source": { "type": "ORDER" }, "createdAt": "2020-08-13T09:05:36.939Z", "updatedAt": "2020-08-13T09:05:36.939Z" } ``` `source.type` values: * `ORDER` - Standard order * `SAMPLES_ORDER` - Order placed with sample budget * `TWITCH_GIFT_REDEMPTION` - Gift redemption event * `GIVEAWAY_LINKS` - Purchase from giveaway link ## Order updated **Webhook type** = `ORDER_UPDATED` Sent when an order's status changes. The `update.type` field indicates what changed (e.g., `STATUS`). ## Gift purchase **Webhook type** = `GIFT_PURCHASE` Sent when someone purchases gifts for others. ## Donation **Webhook type** = `DONATION` ```json theme={null} { "id": "don_Kpcjx4HIQ1e4bTIOjX9CsA", "shopId": "sh_c689d374-22ca-43d3-8d29-9ef0805cc4cb", "status": "COMPLETED", "email": "supporter@fourthwall.com", "username": "supporter username", "message": "message from supporter", "amounts": { "total": { "value": 17.00, "currency": "USD" } }, "createdAt": "2021-07-01T12:00:00Z", "updatedAt": "2021-07-01T12:00:00Z" } ``` ## Product created **Webhook type** = `PRODUCT_CREATED` Sent when a new product is created in the shop. ## Product updated **Webhook type** = `PRODUCT_UPDATED` Sent when a product is modified. ## Membership subscription purchased **Webhook type** = `SUBSCRIPTION_PURCHASED` Sent when supporter purchases a subscription for the first time or re-subscribes after cancellation. ```json theme={null} { "id": "251430", "email": "supporter@fourthwall.com", "nickname": "username", "subscription": { "type": "ACTIVE", "variant": { "id": "mtv_3331", "tierId": "mt_123", "interval": "MONTHLY", "amount": { "value": 5.00, "currency": "USD" } } } } ``` ## Membership subscription changed **Webhook type** = `SUBSCRIPTION_CHANGED` Sent when supporter changes subscription tier. ## Membership subscription expired **Webhook type** = `SUBSCRIPTION_EXPIRED` Sent after the subscription period ends without renewal. ## Thank you sent **Webhook type** = `THANK_YOU_SENT` ```json theme={null} { "id": "ty_3k8rV3C8SNWSj0pS9fDilA", "mediaUrl": "https://fourthwall.com/1", "contribution": { "type": "ORDER", "id": "0bd66320-e0f4-4697-86f8-0ff0a51a0d95", "shopId": "sh_demo", "supporter": { "email": "fw@email.com", "username": "John Doe", "message": "test message" } } } ``` `contribution.type` can be: `ORDER`, `DONATION`, or `GIFT_PURCHASE`. ## Newsletter subscribed **Webhook type** = `NEWSLETTER_SUBSCRIBED` ```json theme={null} { "email": "test@example.com" } ``` ## Platform App disconnected **Webhook type** = `PLATFORM_APP_DISCONNECTED` ```json theme={null} { "appId": "app_123", "shopId": "sh_123" } ``` ## Gift draw started **Webhook type** = `GIFT_DRAW_STARTED` ```json theme={null} { "id": "gdr_EdJvIXu3SEiXe_QkPavHSA", "type": "INITIAL", "giveawayId": "giv_EdJvIXu3SEiXe_QkPavHSA", "giveawayFriendlyId": "D3XZFWPP", "shopId": "sh_c689d374-22ca-43d3-8d29-9ef0805cc4cb", "durationSeconds": 60, "offer": { "id": "063c74ae-7290-4a75-bd8b-e9a1c4afe65c", "name": "My T-shirt", "slug": "my-shirt", "description": "super-tshirt", "primaryImage": { "id": "67e870a5-e002-4e5f-80aa-bb9134fe9a4b", "url": "https://cdn.fourthwall.com/image.jpeg", "width": 1536, "height": 2048 } }, "amounts": { "subtotal": { "value": 2.00, "currency": "USD" }, "total": { "value": 4.00, "currency": "USD" } }, "email": "test@fourthwall.com", "username": "test-username", "message": "test-message", "gifts": [ { "status": "AVAILABLE", "id": "gft_EdJvIXu3SEiXe_QkPavHSB", "winner": null } ], "createdAt": "2021-01-01T00:00:00Z" } ``` ## Gift draw ended **Webhook type** = `GIFT_DRAW_ENDED` Same structure as `GIFT_DRAW_STARTED`, but with winner information populated: ```json theme={null} { "gifts": [ { "status": "AVAILABLE", "id": "gft_EdJvIXu3SEiXe_QkPavHSA", "winner": { "email": null, "username": "test-winner-1", "selectedAt": "2021-01-01T00:00:00Z", "redeemUri": "https://shop.fourthwall.com/redeem" } } ] } ``` # Getting Started with Webhooks Source: https://docs.fourthwall.com/webhooks/getting-started Real-time webhook notifications for shop events Ready to boost your applications, Twitch, or YouTube live stream with Fourthwall's webhooks? This powerful tool helps your apps stay in sync with your shop in real-time, responding to key events as they happen. Picture this: the moment a supporter purchases a product from your shop, a webhook sends a notification your way. Now it's your turn to act, using the data received through your webhook to drive the next steps. ## Example Use Cases Webhooks offer a world of possibilities for real-time application integration: * **Interactive IoT integrations:** Sync your webhooks with smart devices. For instance, set your lights to flash whenever an order is placed. * **Data harvesting for internal usage**: Use webhooks to gather and process data, keeping your internal systems up-to-date. * **External software linkage:** Connect your store with external software, such as accounting tools, to automate and streamline operations. * **Immediate alerts for shipping partners:** Keep your shipping companies in the loop about new orders in real time. * **Automated data clean-up:** Safeguard customer privacy by using webhooks to remove customer data from databases once it's no longer necessary. ## Example Flow ```mermaid theme={null} sequenceDiagram participant Client participant Fourthwall Client->>Fourthwall: ① Create a webhook
subscription for
events Note over Fourthwall: ② Event happened, e.g.
order placed Fourthwall->>Client: ③ Send JSON with
data Client->>Fourthwall: ④ 200 HTTP OK
response ``` 1. A webhook subscription is set up on the 'ORDER\_PLACED' topic for a shop, using a specified HTTPS endpoint (via the [dashboard](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers?redirect) or the [API](/api-reference/platform/webhooks/create-webhook)). 2. Someone places an order in the shop. 3. Fourthwall takes this order event and sends it, along with the order details (payload), to the subscription endpoint. 4. The client app receives this event, sends back an 'OK 200' HTTP status code, and then can perform any needed actions. ## Next Steps Create and manage webhooks programmatically See all available webhook events and payloads Secure your webhook endpoint Test webhooks during development # Gifting Guide Source: https://docs.fourthwall.com/webhooks/gifting-guide Handle gift purchase webhooks for Twitch gift redemptions This is a beta feature. Below you will find all the information you need to know about gifting with Fourthwall. ## 1. How to enable Streamelements gifting 1. Go to [Twitch Gifting App](https://my-shop.fourthwall.com/admin/dashboard/apps/twitch?redirect) in your Fourthwall admin dashboard 2. Select Streamelements gifting radio button and ensure your shop is connected with Streamelements 3. Click on the `Enable` checkbox to enable the Twitch Gifting App ## 2. Webhook configuration Go to [Webhook Settings](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers?redirect) and create webhooks for: * `GIFT_DRAW_STARTED` * `GIFT_DRAW_ENDED` ## 3. How to start Gift Draw First, ensure your stream is live: ```bash theme={null} PUT https://api.fourthwall.com/open-api/v1.0/streaming/start Authorization: Basic {credentials} Content-Type: application/json { "services": [ { "type": "TWITCH", "broadcasterId": "test-broadcaster-id", "broadcasterLogin": "raziosx", "thumbnailUrl": "test-thumbnail-url" } ] } ``` Then go to your shop main page and purchase any product as a gift. This will trigger the `Gift draw started` webhook event. ## 4. How to finish Gift Draw Send a request to finish the draw: ```bash theme={null} PUT https://api.fourthwall.com/open-api/v1.0/gifting/draw/{drawId}/finish Authorization: Basic {credentials} Content-Type: application/json { "participants": [ { "service": "TWITCH", "userId": "{twitchWinnerUserId}", "userName": "{twitchWinnerUserName}" } ] } ``` The response will include the winner details along with the redeem URL. The `Gift draw ended` webhook will also be triggered. Gift draws not finished within the configured time (+ 1 minute) will be automatically finished without winners to allow redoing the draw. # Limitations Source: https://docs.fourthwall.com/webhooks/limitations Webhook ordering guarantees, delivery constraints, and best practices ## Key limitations **Ordering is not guaranteed** between different topics for the same resource. For example, an `ORDER_UPDATED` webhook might be delivered before an `ORDER_CREATED` webhook. Your system should handle such cases. * **At-least-once delivery**: Webhook events should be delivered at least once. This means your endpoint might receive the same event more than once. You can detect duplicate events by comparing the `id` value of received events. * **Delivery not guaranteed**: Webhook delivery is not always guaranteed. If you require your data to be always consistent, you should implement reconciliation jobs to fetch data from Fourthwall periodically. # Retry Policies Source: https://docs.fourthwall.com/webhooks/retry-policies Webhook delivery guarantees, retry logic, and timeout handling ## Response policy Your client should respond as quickly as possible with an `OK 200 HTTP` status code. Any other response will result in our system marking the event as failed delivery. Response times longer than **2000ms** may result in a failed delivery. ## Retry policy In case of no response or a response different than OK 200 HTTP status code from your client, our platform will make additional attempts to redeliver the event: * **Initial attempt**: The platform will try to deliver the message 5 times with a timeout set to 5 seconds for each attempt # Signature Verification Source: https://docs.fourthwall.com/webhooks/signature-verification Verify webhook authenticity with HMAC-SHA256 signatures If you want to verify whether the request was in fact sent from Fourthwall you can do that by calculating the webhook digital signature. ## Getting your secret key First head to the [webhook configuration panel](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers?redirect) in your site settings and find the secret key value assigned to your shop, e.g.: ``` e3f93c7c-c92b-4b8f-a9b1-5b70e0891abc ``` ## Verifying the signature Each webhook request comes with an `X-Fourthwall-Hmac-SHA256` base64 encoded header. To verify the request: 1. Compute the HMAC-SHA256 using your secret key and the entire webhook body 2. Base64 encode the result 3. Compare with the header value ```python theme={null} import hmac import hashlib import base64 SECRET = 'secret_value_from_your_shop_webhook_settings' def verify_signature(data, hmac_header): digest = hmac.new(SECRET.encode('utf-8'), data, digestmod=hashlib.sha256).digest() computed_hmac = base64.b64encode(digest) return hmac.compare_digest(computed_hmac, hmac_header.encode('utf-8')) ``` You can use any programming language as long as the algorithm follows the same principles. ## Signature verification for Platform Apps The verification process for Platform Apps is the same, but uses a different header: `X-Fourthwall-Hmac-Apps-SHA256`. You can get your HMAC key in your app's [settings](https://my-shop.fourthwall.com/admin/dashboard/settings/platform-apps?redirect). # Testing Webhooks Source: https://docs.fourthwall.com/webhooks/testing Test your webhook integration You can test your webhook configuration in the following ways: 1. **Manual testing**: Click the `Send test notification` button on the [webhook list](https://my-shop.fourthwall.com/admin/dashboard/settings/for-developers?redirect). You'll receive an event with test data. You can differentiate test events from normal events by checking if the `testMode` field is set to `true`. 2. **Real events**: Perform the action in your store that you've subscribed to. For example, create an order when you have configured a webhook with `ORDER_PLACED` events. # Webhook Model Source: https://docs.fourthwall.com/webhooks/webhook-model Webhook event structure and fields All webhook events share the same structure. Following is an example JSON event: ```json theme={null} { "testMode": false, "id": "weve_geAva6c1RAuyb9HQxbSlmA", "webhookId": "wcon_P-VkRfmJTBaC6_Tst22cew", "shopId": "sh_7ad0c438-beda-4779-a885-0dc325a755c1", "type": "ORDER_PLACED", "apiVersion": "V1_BETA", "createdAt": "2023-07-12T15:05:11.078089+00:00", "data": { // Event-specific data } } ``` ## Fields Description | Field | Description | | ------------ | ---------------------------------------------------------------------------------------------------------- | | `testMode` | If `true`, indicates the event contains only test data. See [Testing](/webhooks/testing) for more info. | | `id` | Unique identifier of the event. If you receive multiple events with the same id, treat them as duplicates. | | `webhookId` | Indicates which webhook configuration was used. | | `shopId` | Your shop ID, useful if you manage multiple shops under the same webhook endpoint. | | `type` | Indicates which data type you should expect within the event. | | `apiVersion` | Version of the data type that was chosen. | | `createdAt` | Date at which the event was created. | | `data` | Contains all the actual data specific to the type of the event. |