Fourthwall
Make custom merch & products
- Category
- Commerce
- Primary Subcategory
- Custom Print & Personalized Keepsakes
Integration details
Description
Make custom apparel, merch, and streetwear with Fourthwall, using ChatGPT. Turn a logo or image into real products: t-shirts, hoodies, hats, mugs, stickers, plushies, or whatever swag / apparel you can dream up. We also support more premium and bespoke products. Type your ideas and get live previews for different colors and design placements. Once you're happy, you can place an order. No minimums required. You can also sell your products online or run a campaign with Fourthwall: manage promotions, track orders, and see what's selling without leaving the chat. Fourthwall handles the hard parts: manufacturing, fulfillment, shipping, customer support, and sales tax. No upfront costs, no inventory, no monthly fees.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Custom Print & Personalized Keepsakes
- Secondary Subcategories
- None listed
- Brand
- Fourthwall
- Access
- Account optional
- First tracked
- 2026-07-02
- Tool count
- 145
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for Fourthwall
Get updates when Fourthwall’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT Custom Print & Personalized Keepsakes
View Category145 tools agents can invoke
Reactivate a promotion (set status to LIVE). Only works for ENDED promotions. Cannot activate ARCHIVED or ALL_USED promotions. Use when a shop owner wants to re-enable a previously deactivated discount code.
ecommerce_activate-promotion
Adds a new print region to an existing customization's design state with an initial image. Use this when the user wants to place artwork on a region that the catalog product supports (`availableRegions` from inspect-design) but the current customization doesn't yet contain. edit-design cannot add new regions — it only mutates regions already present in the state. BEFORE calling: - inspect-design to confirm the regionId is in `availableRegions` and not already in the state's `sizes[*].regions[*].regionId` list (i.e. not already added). - The image must already be saved (use ecommerce_save-media-library-image first); pass its CDN href plus natural width/height in pixels. AFTER calling: use rerender-design-previews with customizationId to regenerate preview images. Returns the updated inspect summary plus the same availableRegions list inspect-design exposes. Errors: - DESIGN_PIPELINE_INVALID_REGIONS — regionId is not on the catalog product. Surface validRegions to the user. - DESIGN_PIPELINE_COLLIDING_REGIONS — the region conflicts with one already in the design (e.g. "front" alongside "front_large"); the manufacturer rejects that combination. Surface the pair and ask the user which placement to keep — use remove-design-region on the other before retrying. - DESIGN_PIPELINE_BAD_REQUEST with "already part of this design" — the region is already in the state; use edit-design instead.
ecommerce_add-design-region
Adds colors to the draft's color selection. Does NOT affect the live product. Each color must appear in the product's availableColors (case-sensitive). Read availableColors from get-draft-attributes before calling. Passing an unknown color throws CUSTOMIZATION_INVALID_COLORS with the valid set — surface the valid options to the user and stop; do not retry with guessed spellings (e.g. "heather grey" vs "Heather Gray"). Errors: - FEATURE_NOT_SUPPORTED_FOR_DESIGNER: the design was made in Printful's embedded designer, not the Fourthwall designer. Its colors and sizes are chosen inside the Printful designer (Edit design on the product page); nothing was changed. Tell the creator that and stop, do not retry. Use rerender-design-previews after to see updated previews. Use apply-draft-to-product when the creator confirms changes.
ecommerce_add-draft-colors
Adds sizes to the draft's size selection. Does NOT affect the live product. Each size must appear in the product's availableSizes (case-sensitive). Read availableSizes from get-draft-attributes before calling. Passing an unknown size throws CUSTOMIZATION_INVALID_SIZES with the valid set — surface the valid options to the user and stop; do not retry with guessed sizes (e.g. requesting "3XL" when the product caps at "2XL"). Errors: - FEATURE_NOT_SUPPORTED_FOR_DESIGNER: the design was made in Printful's embedded designer, not the Fourthwall designer. Its colors and sizes are chosen inside the Printful designer (Edit design on the product page); nothing was changed. Tell the creator that and stop, do not retry. Use rerender-design-previews after to see updated previews. Use apply-draft-to-product when the creator confirms changes.
ecommerce_add-draft-sizes
Internal helper for the media-library widget. Run a vision analysis on an image that already has a URL (a selected media-library image) and return its description plus the analyzed URL. Not a user-facing action — the widget calls it when the user confirms a selected image. Safe to re-call: results are cached by image identity. Parameters: - imageUrl: The image to analyze — a media-library CDN URL or a GCS object URL in Omni's bucket.
analyze-image
Syncs the current draft state to the live product. Call this ONLY when the creator explicitly confirms the changes. This atomically: 1. Reads the draft's current attributes and design state 2. Rebuilds the product's variants from the draft 3. Recalculates pricing Use rerender-design-previews after to see final product previews. Throws FEATURE_NOT_SUPPORTED_FOR_DESIGNER for Printful-designer designs, see add-draft-colors.
ecommerce_apply-draft-to-product
Stage 1 of brand extraction: analyze a brand sheet and stash a checkpoint. Runs the vision analyzer on the image. Does NOT extract a logo or run any image generation — that happens in `brand_extract_assets`. Returns a `checkpoint_uri` that the follow-up call uses to pull only the artworks/logo it actually needs. Parameters: - image_path: Source brand sheet (PNG/JPEG) or brand deck (PDF). For PDF input a cheap text-only selector picks the most informative pages (at most 6), rasterizes them, and sends them to the vision model in one call — useful for multi-page merch decks or brand guidelines. When pages were dropped, `checkpoint_md` carries a NOTE saying so. Accepts an `http(s)://` URL (fetched anonymously) or a `gs://bucket/key` URI for an object in this shop's own storage (e.g. a media-library image). The `https://storage.googleapis.com/<bucket>/<key>` form (and its `storage.cloud.google.com` / virtual-hosted variants) is accepted the same way. Returns a dict with: - checkpoint_uri: opaque URI (gs:// in prod, file:// in local dev) that pins this analysis run; pass back as the first argument to `brand_extract_assets`. - brand_name: confirm with the user before spending image-gen calls. - checkpoint_md: a markdown summary of the brand (mood, palette, typography, logo description, products, and the artwork "menu" with ids and descriptions). Use this to decide which `want_artwork_ids` to request next. - artwork_candidates: structured list of `{id, kind, name, description}` for the same menu — the `id` values are what `brand_extract_assets` accepts in `want_artwork_ids`. - logo_description: verbal description of the primary logo, helpful for confirming "yes this is the right brand" before extraction. Typical flow: r1 = brand_analyze(image_path="...") # confirm r1["brand_name"] with the user, pick artwork ids from # r1["artwork_candidates"], then: r2 = brand_extract_assets( checkpoint_uri=r1["checkpoint_uri"], want_logo=True, want_artwork_ids=["main_logo", "side_heart"], ) For long brand decks where the synchronous round-trip risks an MCP proxy timeout, use `brand_analyze_start` + `brand_analyze_status` instead — they expose the same pipeline behind a job_id poll loop.
brand_analyze
Async variant of `brand_analyze`. Enqueues the analysis and returns immediately, or returns the inline result if the job finishes inside the ~50s budget. Parameters: - image_path: same shape as `brand_analyze` (http(s) URL, or a gs:// / storage.googleapis.com URI in this shop's own storage). Returns either: - `{"status": "done", "result": {...}}` — the analysis finished inside the inline wait window; treat `result` exactly like `brand_analyze` would have returned. - `{"job_id": "ba_...", "status": "pending" | "running", "progress": {...}}` — the job is still in flight. Poll `brand_analyze_status(job_id)` every 5–10 seconds. Typical brand-deck jobs take 120–180s; very short single-image inputs may return inline. On failure surfaces `{"job_id": "ba_...", "status": "failed", "error": "..."}` rather than raising, so the model can decide whether to retry.
brand_analyze_start
Poll the status of a `brand_analyze_start` job. Parameters: - job_id: the id returned by `brand_analyze_start`. Returns: - `{"job_id", "status": "pending" | "running" | "done" | "failed", ...}` - `progress` (optional): `{stage, pct}` while running. - `result` present when status=="done" — same shape as `brand_analyze`. - `error` present when status=="failed". Returns within ~1s. Raises if `job_id` is unknown or has aged out of the 24h TTL.
brand_analyze_status
Stage 2 of brand extraction: produce just the assets you actually need. Reads the checkpoint produced by `brand_analyze`, then runs the logo stage and/or a focused per-artwork extraction for only the requested ids. Outputs are uploaded back into the same checkpoint, so calling this again with a different `want_artwork_ids` set extracts more without re-running analysis. Parameters: - checkpoint_uri: the URI returned by `brand_analyze`. - want_logo: extract the pixel-faithful 2048x2048 transparent logo PNG. Default True — flip to False on follow-up calls when you only want additional artworks. - want_artwork_ids: list of artwork ids (from `brand_analyze`'s `artwork_candidates`) to extract as transparent PNGs. Each id costs one medium-quality parallel gpt-image-2 call. Pass an empty list (or omit) to skip artwork extraction. Unknown ids raise — the message lists what's available so you can correct. At least one of `want_logo=True` or a non-empty `want_artwork_ids` must be set; otherwise the call has nothing to do and raises. Returns a dict with: - checkpoint_uri: echoed back so the model can chain another call. - brand_name - logo_compact: gs:// URI of a downsized, <512 KB transparent logo PNG. Pass it as `data` to `storefront_update-draft-theme-logo` (and to any downstream tool that wants the brand logo — there is no high-res variant; this is the canonical logo asset). Also None when the cut left no visible pixels — then use the original logo (e.g. `recommended_logo_url` from `brand_from_url`) for the storefront instead. None if want_logo=False or the checkpoint bucket is unset. - favicon: gs:// URI of a square <512 KB favicon PNG derived from the same logo. Pass it as `data` to `storefront_update-draft-theme-favicon`. None if want_logo=False or the checkpoint bucket is unset. - artworks: list of {id, kind, name, upload, media} for every successfully extracted id. `upload` is the gs:// URI; `media` is the media-library entry — pass `media[].media_url` to ecommerce tools like `ecommerce_generate-product-design-previews` so they can resolve the asset without a separate upload step. - failed_artworks: list of {id, kind, name, error_kind, message} for ids the model service refused. `error_kind` is one of `moderation_blocked`, `rate_limited`, `bad_request`, `api_error`, `other` — `moderation_blocked` means OpenAI's safety system rejected that specific artwork prompt; the caller should drop or rephrase that id and retry without it. - cost: usage summary for the artwork stage — `{input_text_tokens, input_image_tokens, output_image_tokens, total_tokens, estimated_usd, calls}`. Estimate uses published gpt-image rates; the OpenAI invoice is authoritative. For long extractions where the synchronous round-trip risks an MCP proxy timeout, use `brand_extract_assets_start` + `brand_extract_assets_status` — same pipeline behind a job_id poll.
brand_extract_assets
Async variant of `brand_extract_assets`. Enqueues the extraction and returns immediately, or returns the inline result if the job finishes inside the ~50s budget. Parameters: same as `brand_extract_assets`. Returns either: - `{"status": "done", "result": {...}}` — the extraction finished inline; treat `result` exactly like `brand_extract_assets` would have returned. - `{"job_id": "bx_...", "status": "pending" | "running", "progress": {...}}` — the job is still in flight. Poll `brand_extract_assets_status(job_id)` every 5–10 seconds. Typical extractions take 60–180s depending on how many artwork ids you requested. On failure surfaces `{"job_id": "bx_...", "status": "failed", "error": "..."}`.
brand_extract_assets_start
Poll the status of a `brand_extract_assets_start` job. Parameters: - job_id: the id returned by `brand_extract_assets_start`. Returns: - `{"job_id", "status": "pending" | "running" | "done" | "failed", ...}` - `progress` (optional): `{stage, pct}` while running. - `result` present when status=="done" — same shape as `brand_extract_assets`. - `error` present when status=="failed". Returns within ~1s. Raises if `job_id` is unknown or has aged out of the 24h TTL.
brand_extract_assets_status
Browse available catalog blanks; never generates artwork or previews.
checkout_session_blanks
Bulk-update prices across an offer's variants. Call get-offers-by-ids first to see current variants and prices. Pick ONE mode: - UNIFORM — omit groupBy. Set `price` (and optional `compareAtPrice`) on every active variant. - BY ATTRIBUTE — set groupBy to SIZE/COLOR/CUSTOM and pass `priceUpdates` as an array of {attributeValue, price, compareAtPrice?} entries. Variants whose attribute value is not in the array are left unchanged. Example priceUpdates: [{"attributeValue":"S","price":10.00},{"attributeValue":"L","price":20.00,"compareAtPrice":30.00}] Rules: - `price` and `priceUpdates` are mutually exclusive — pass exactly one. - All prices are set in USD dollars, NOT cents (9.99 = $9.99). Shops price in USD; checkout handles currency conversion automatically. - `priceUpdates` is a plain JSON array, NOT a stringified JSON string.
ecommerce_bulk-update-offer-variant-prices
Cancel giveaway links. IRREVERSIBLE. Always confirm with the user first. Provide EITHER giftId (cancel one link) OR packageId (cancel all available links in package). Only AVAILABLE links are cancelled. Already redeemed links are unaffected.
ecommerce_cancel-giveaway-links
Cancel a full or partial order. IRREVERSIBLE. ALWAYS confirm with the user before calling. Before calling, use `get-order-cancellation-by-ids` to check eligibility: - For a full cancellation: `fullyCancellable` must be true. - For a partial cancellation: `partiallyCancellable` must be true; pass an `itemsToCancel` subset of `cancellableItems` (variantId + quantity). Omit `itemsToCancel` (or pass empty) to cancel the whole order. Payment handling — done automatically, no separate confirmation step: - If the shop's balance covers the refund, the refund is issued immediately (status = CANCELLED). - If the balance is insufficient, the shortfall is charged to the shop's card and the cancellation is queued (status = CHARGE_INITIATED). A background job finalizes the cancellation once the charge settles. If the charge fails, the cancellation is abandoned and the order stays open. The response fields `fromBalance`, `chargeAmount`, and `status` make this explicit. Always surface these to the user — especially `chargeAmount` when > 0. Permission: requires ORDER_WRITE role on the shop. Typical rejection reasons (returned as errors from the endpoint): - STATUS: order already cancelled, failed, etc. - IN_PRODUCTION_OR_DELIVERING: items in fulfillment - OLDER_THAN_ALLOWED_CANCELLATION_TIMEFRAME - CONTAINS_DIGITAL_ITEMS / GIFT_CARD_ALREADY_USED - REFUND_IN_PROGRESS: an existing refund is pending; wait or resolve first - ExpectedChargeAmountChanged: a rare race where the required charge changed between our estimate and submission; just retry.
ecommerce_cancel-order
Update the shipping address on an order. Only allowed before items enter production or shipping. The use case verifies: - Order status permits address changes (not in production/shipped/delivered/cancelled) - All items have `canUpdateAddress == true` for this issuer - Third-party fulfillment systems accept the update If the address is identical to the current one, the call is a no-op and returns the order unchanged. Emits `OrderAddressChangedEvent` on change. Permission: requires ORDER_WRITE role on the shop. Required fields: firstName, lastName, address1, city, country. Optional fields: address2, state, zip, phone. Returns the updated order summary (same shape as get-order-details-by-ids).
ecommerce_change-order-shipping-address
Read how the checkout this widget opened for this exact cart ended.
checkout_session_payment_status
Start product generation from the current generated-image payload.
checkout_session
Render the next view deferred until a shopper opens product details.
checkout_session_detail_previews
Open Product Designer with an optional color and active size, retaining all saved sizes.
checkout_session_editor_init
Version-check and save one card's Product Designer document, then refresh its preview.
checkout_session_editor_save
Read session progress, waiting briefly when `after_revision` is still current.
checkout_session_status
Internal helper for the show-upload widget. Confirm that an image finished uploading and return a vision analysis of it. Not a user-facing action — the widget calls it after PUTting the file. Safe to re-call: an already-confirmed upload returns the cached analysis. Returns two URLs for the same image, used for different purposes: - url: the stable internal GCS URL — use this for any further processing (handing the image to the model, chaining into other tools). Never expires, but the browser can't fetch it. - publicUrl: a time-limited signed read URL — use this only to show the image to the user (e.g. the widget's preview). Don't pass it on for further processing; it expires after ~60 minutes. Parameters: - uploadId: The id returned by request-upload-url.
confirm-image-upload
Create a new bundle offer — a group of existing offers sold together at a combined price. The bundle starts in HIDDEN state. Use update-bundle to change status to PUBLIC when ready.
ecommerce_create-bundle
Create a new collection for the shop. Collections group products (offers) together for display on the storefront. Required fields: - name: Collection display name (max 200 chars) - description: Collection description (HTML allowed) - available: Whether the collection is available - offerIds: List of Offer IDs to include in the collection Optional fields: - availableFrom/availableTo: Schedule when the collection becomes visible (ISO 8601 datetime) The collection is created in HIDDEN state. Use update-collection-state to make it PUBLIC. Returns the created collection with: - Identity: id (CollectionId), shopId (ShopId), name, slug, description - Visibility: available (boolean), state (PUBLIC/HIDDEN/ARCHIVED) - Time-based availability: availableFrom (nullable ISO 8601), availableTo (nullable ISO 8601) - Products: offerIds (list of OfferIds) - Sorting: sortingStrategy (MANUAL/BEST_SELLING/NEWEST/OLDEST/NAME_ASC/NAME_DESC)
ecommerce_create-collection
Create a combined listing — merges color variants from multiple offers (same product library) into one storefront product. Unlike bundles, combined listings share the same product library. All offers must have compatible colors (no duplicates). The listing starts in HIDDEN state. Use update-combined-listing to change status to PUBLIC when ready. Use validate-combined-listing first to check if offers are compatible.
ecommerce_create-combined-listing
Create gift cards (store credit) with an amount, optionally with custom codes. Skip the `codes` parameter unless the user explicitly asks for specific codes — random 12-character friendly codes (e.g., "L3WQNU1MV4W9") will be generated automatically. Use `numberOfCards` to control how many cards to create with auto-generated codes (defaults to 1, max 50). When `codes` IS provided: single code = single card, multiple codes = bulk group (1-50). All cards share the same amount and expiration. Codes are auto-uppercased, 8-36 chars, alphanumeric. Returns created card details (single) or group ID (bulk). Use get-gift-cards to browse. All amounts are set in USD dollars (NOT cents) — gift cards are priced in the shop's USD, and checkout handles currency conversion for non-USD customers. Examples: • Auto-generated single: amount=50 • Auto-generated bulk: numberOfCards=10, amount=25 • Single with custom code: codes=["GIFT50"], amount=50 • Bulk with custom codes: codes=["VIP1","VIP2","VIP3"], amount=25, expiresAt="2026-12-31T23:59:59Z"
ecommerce_create-gift-cards
Create a package of giveaway links (free product URLs) for a product. Each link is a unique URL someone can use to claim a free product. Links are grouped into a package. REQUIRED: • offerId: product ID (UUID). Use get-offers to find IDs. • numberOfGifts: how many links to generate (1-50) Returns: packageId + list of created gift IDs. Use get-giveaway-links to see URLs.
ecommerce_create-giveaway-links
Create a membership discount code (percentage off membership subscription). ⚠ NOT SUPPORTED — do NOT promise these to the user: expiration / end date / start date / scheduled activation. There is no time-based field. `durationCharges` is the number of BILLING CYCLES the discount applies for (not a calendar date). To stop a code, use deactivate-promotion. DELIVERY MODE — provide exactly one: • code: single promo code (e.g. "MEMBER20") — most common • codes: list of bulk codes for multi-code promotions REQUIRED: • percentage (1-100): discount percentage • subscriptionType: ALL_MEMBERS | MONTHLY_ONLY | ANNUAL_ONLY OPTIONAL: • tierIds: restrict to specific membership tier IDs (null = all tiers). • durationCharges: how many billing cycles the discount lasts (1-1000). Null = lifetime (discount applies to every cycle, never auto-stops). • newMembersOnly: only new members can use this code (default false) • limitToSingleUse: limit code to one total redemption (default false) Examples: • 20% off all members for life: code="MEMBER20", percentage=20, subscriptionType="ALL_MEMBERS" • 50% off first 3 cycles, annual only: code="ANNUAL50", percentage=50, subscriptionType="ANNUAL_ONLY", durationCharges=3 • Bulk codes for new monthly members: codes=["NEW1","NEW2"], percentage=30, subscriptionType="MONTHLY_ONLY", newMembersOnly=true
ecommerce_create-membership-promotion
Creates offers from previously generated design previews — processes multiple designs concurrently. Each design is processed independently — failures for one do not affect others. IMPORTANT: You must call generate-product-design-previews first to get customizationIds. Waits up to 1 minute per design for completion, then returns results. Each result contains: - customizationId: the input customization ID - pipelineId, status, type, offerId?, images[], priceSuggestions?, error? — present on success - bulkError?: string — present on failure Use this tool to: - Create offers after the user approves the preview images Offer names default to the product name when omitted. Offer descriptions default to empty when omitted. Offers are created in HIDDEN state — use update-offer-status to publish. WORKFLOW after creation: tell the user the default price that was applied (read it from priceSuggestions in the result) and that it can be changed any time, then offer to order a physical sample (create-sample-checkout — charged at manufacturing cost only).
ecommerce_create-offers-from-designs
One-shot: creates offers directly from product designs in a single call. Skips the preview→approve step — use this when the user pre-approved (e.g. "create offers for all of these") or already saw mockups and just wants offers made. Products are processed concurrently — no polling needed, results returned directly. Each product is processed independently — failures for one product do not affect others. For the preview-first flow (review mockups, then create offers from approved ones), use generate-product-design-previews followed by create-offers-from-designs. regionUrls MUST be URLs from the shop's media library (use get-media-library-images, or upload via request-media-upload-link → PUT file → save-media-library-image). BEFORE calling this tool, use get-catalog-product-details to check: 1. supportsBackendRendering must be true for the product 2. Only use regions from printAreas where supportsBackendRendering=true 3. placementsOnly=true (see get-catalog-product-details): every placement prints, so placementIds are optional — name them only to choose which artwork goes where. Otherwise name the one you want. 4. Do not combine conflicting placements in one design — a full-front print and a small chest print occupy the same area, so "front" and "front_large" cannot both be used (same for "back"/"back_large"). Pick one per area, or the request is rejected with DESIGN_PIPELINE_COLLIDING_REGIONS. Each result contains: - productId: the input product ID - pipelineId, status, type, customizationId, offerId, images[], priceSuggestions?, error? — present on success - bulkError?: string — present on failure WORKFLOW after creation: tell the user the default price that was applied (read it from priceSuggestions in the result) and that it can be changed any time, then offer to order a physical sample (create-sample-checkout — charged at manufacturing cost only).
ecommerce_create-offers-from-products
Creates a checkout session to order product samples at cost. Use get-offers or get-offers-by-ids to find variant IDs for the items to order. Returns: - checkoutPath: Relative path to the checkout page (e.g., "/checkout/ch_abc123") Sample credits are applied automatically at checkout when available; if the balance is zero or insufficient, the buyer pays the remaining amount on the checkout page. You do NOT need to check the balance beforehand — never gate this call on get-sample-credit-balance. Examples: - Order 2 units of a variant: items="8d79c46d-9a56-4266-885b-4b02a21aacd2:2" - Order multiple variants: items="aaa-uuid:1,bbb-uuid:3"
ecommerce_create-sample-checkout
Create a shop discount promotion. ⚠ Use ONLY the parameter names declared on this tool — do not invent or paraphrase. For an entire-order discount, OMIT `productIds` (there is no `appliesTo` parameter). ⚠ NOT SUPPORTED — do NOT promise these to the user, even if help articles imply otherwise: • Expiration / end date / start date / scheduled activation — there is no time-based field. To stop a promotion, use deactivate-promotion. To cap total usage, set `maxUses`. • Stacking rules, per-product discount tiers, BOGO without using FREE_PRODUCTS. All monetary amounts are set in USD dollars (NOT cents) — shops price in USD; checkout handles per-customer currency conversion automatically. RECIPES (each line shows the required fields per discountType): • 10% off all orders: { discountType: "PERCENTAGE", code: "SAVE10", percentage: 10 } • $10 off + free shipping: { discountType: "FIXED_AMOUNT", code: "TAKE10", amount: 10, freeShipping: true } • Free shipping: { discountType: "FREE_SHIPPING", code: "SHIPFREE" } • Free product: { discountType: "FREE_PRODUCTS", code: "FREEGIFT", freeVariantId: "<variant-uuid>" } • Bulk codes: replace `code` with `codes: ["VIP1","VIP2"]`. Auto-apply: replace `code` with `autoApplyTitle: "Summer Sale"`. COMMON OPTIONS (all types): • productIds: restrict to specific offer IDs. OMIT for entire-order (default). • freeShipping: bundle free shipping (PERCENTAGE, FIXED_AMOUNT, FREE_PRODUCTS) • minimumOrderAmount: USD dollars (e.g. 50 = $50) • allowedCountries: ISO 3166-1 alpha-2 codes (e.g. ["US","CA"]). Omit = all. • maxUses (1-1000, omit = unlimited), onePerCustomer (default false) • shippingOption (PERCENTAGE only): EXCLUDED | FREE | FREE_LOWEST_ONLY • lowestShippingOnly (FREE_SHIPPING only); freeProductQuantity (FREE_PRODUCTS only, default 1)
ecommerce_create-shop-promotion
Deactivate a promotion (set status to ENDED). Customers can no longer use this code. To reactivate later, use activate-promotion. To permanently remove, use delete-promotion.
ecommerce_deactivate-promotion
Create a copy of an existing offer (product). The duplicated offer will have a new ID and a modified slug (with a suffix). The duplicate starts in HIDDEN state so it won't be visible on the storefront until published.
ecommerce_duplicate-offer
Edits an existing customization's design state and returns the updated layout. BEFORE calling: use inspect-design to understand the current layout (imageIds, indices, region dimensions) and to read availableRegions — the legal values for `target.regionId`. Passing a regionId not in availableRegions returns DESIGN_PIPELINE_INVALID_REGIONS with the valid set; surface that to the user and stop — do not retry with another guessed regionId. Adding artwork to a region that conflicts with one already in the design returns DESIGN_PIPELINE_COLLIDING_REGIONS naming the forbidden pair; the product cannot be manufactured with both, so ask the user which placement to keep and remove-design-region the other. AFTER calling: use rerender-design-previews with customizationId to regenerate preview images. Operations: - scale-absolute: set size as fraction of the REGION's contain-fit (regionFraction: 1 = largest size that fits unrotated, above 1 extends past the region), also when the image sits in a smaller placement - scale-relative: multiply current size (factor: e.g. 1.5 = 150%) - move-absolute: snap to named position (anchor: top-left/top-center/top-right/center-left/center/center-right/bottom-left/bottom-center/bottom-right) - move-relative: offset by fraction of region (dx: -1.0 to 1.0, dy: -1.0 to 1.0) - rotate: set rotation (degrees) - replace-image: swap image URL (href, naturalWidth, naturalHeight) - remove: delete image from region - add-image: add new image (href, width, height, optional regionFraction — region-relative, omit it to fill the placement — anchor) Every replace-image / add-image href must be the exact CDN url returned by ecommerce_save-media-library-image (copy it verbatim, never retype it); an href that is not in this shop's media library is rejected with a BadRequest and nothing is saved. - reorder: change z-order (position: numeric z-index) Target filtering: sizes (e.g. ["S","M"]), regionId (e.g. "front"), imageId (dataId from inspect), imageIndex (0-based). Omit target fields to apply to all. Returns updated inspect summary with all image positions.
ecommerce_edit-design
Edits tracking information on existing self-fulfilled (creator-fulfilled) order fulfillments. Supports batch updates (up to 10). WHEN TO USE: A creator has shipped one or more existing self-fulfilled orders and you need to update the carrier and tracking number on the existing fulfillment. This tool cannot create new fulfillments — it only edits existing ones. INPUT FORMAT: Each entry is a pipe-delimited string with exactly 3 parts: fulfillmentId|trackingCompany|trackingNumber All 3 parts are required: - fulfillmentId: starts with "ful_" prefix (get it from "get-fulfillment-details") - trackingCompany: carrier name — one of: USPS, UPS, FedEx, DHL, Canada Post, Royal Mail, or other carrier - trackingNumber: the tracking number provided by the carrier EXAMPLES: - ["ful_abc123|USPS|9400111899223100001234"] - ["ful_abc123|USPS|9400111899223100001234", "ful_def456|FedEx|794644790138"] WHAT HAPPENS: The fulfillment transitions to PACKAGED status. A shipment tracker with a customer-visible tracking page URL is created in the background (not in this response). RETURNS: List of updated fulfillments with id, orderId, status, items, and shippingLabels. RELATED: Use "get-fulfillment-details" first to look up fulfillment IDs for an order.
ecommerce_edit-self-fulfilled-tracking
Creates design preview pipelines for multiple products and generates mockup images. Use this when the user wants to review mockups BEFORE offers are created — then call create-offers-from-designs on approved customizationIds. If the user has already pre-approved (e.g. "create offers for all of these"), prefer create-offers-from-products instead — it goes straight to offer creation in one call and avoids re-rendering the previews. Products are processed concurrently — no polling needed, results returned directly. Each product is processed independently — failures for one product do not affect others. regionUrls MUST be URLs from the shop's media library (use get-media-library-images, or upload via request-media-upload-link → PUT file → save-media-library-image). BEFORE calling this tool, use get-catalog-product-details to check: 1. supportsBackendRendering must be true for the product 2. Only use regions from printAreas where supportsBackendRendering=true 3. placementsOnly=true (see get-catalog-product-details): every placement is a separate printed item, such as a mug's two sides or a sticker sheet's slots. Set fillAllPlacements to put one artwork on all of them, or name a placementId per artwork to choose what goes where. Otherwise name the one you want. 4. Do not combine conflicting placements in one design — a full-front print and a small chest print occupy the same area, so "front" and "front_large" cannot both be used (same for "back"/"back_large"). Pick one per area, or the request is rejected with DESIGN_PIPELINE_COLLIDING_REGIONS. IMPORTANT: Each product has its own design settings (regions, placements) because different products have different print areas (e.g., 'front_large' vs 'front'). Use get-catalog-product-details for each product to determine the correct region names and placements. Each result contains: - productId: the input product ID - pipelineId, status, type, customizationId, images[], priceSuggestions?, error? — present on success - bulkError?: string — present on failure WORKFLOW: Show images to the user — do NOT quote priceSuggestions at this stage; pricing is applied at offer creation, not on previews. If approved, call create-offers-from-designs with customizationIds. To re-render an existing customization after edit-design, use rerender-design-previews instead.
ecommerce_generate-product-design-previews
Get the Affiliate Earnings analytics report for the shop within a date range: confirmed affiliate referral bonus earnings. This report shows affiliate earnings over time with the following columns per row: - date: The time period - earnings: Total confirmed affiliate referral bonus earnings for this period (USD) - payout_count: Number of individual affiliate payout events in this period IMPORTANT - Aggregation precision selection: Each row represents one time unit. Choose the finest granularity that produces at most 31 rows: - HOUR: use only for ranges up to 31 hours (up to ~1 day) - DAY: use only for ranges up to 31 days (up to ~1 month) - WEEK: use only for ranges up to 31 weeks (up to ~7 months) - MONTH: use only for ranges up to 31 months (up to ~2.5 years) - QUARTER: use only for ranges up to 31 quarters (up to ~7 years) - YEAR: use for ranges longer than 31 quarters For example: "last 2 years" → MONTH (24 rows), "last week" → DAY (7 rows), "last 6 months" → WEEK (~26 rows), "today" → HOUR (24 rows), "last 5 years" → QUARTER (20 rows). Examples: - Monthly affiliate earnings for 2024: from="2024-01-01T00:00:00Z", to="2024-12-31T23:59:59Z", aggregationPrecision="MONTH" - Weekly affiliate earnings: from="2024-10-01T00:00:00Z", to="2024-12-31T23:59:59Z", aggregationPrecision="WEEK"
ecommerce_get-affiliate-earnings-report
Retrieves all connected integrations for the shop. This is a high-level overview — for TikTok or YouTube details, use get-tiktok-configuration or get-youtube-integrations. Returns a list of integrations, each with: - app: Integration identifier (TWITCH_GIFTING, TWITCH_DISCOUNTS_FOR_SUBS, YOUTUBE_PRODUCT_SHELF, TIKTOK_SHOP, INSTAGRAM_SHOP, INSTAGRAM_CHECKOUT, TWITTER_SHOP, STREAMELEMENTS, STREAMLABS, TIKTOK_FEED, INSTAGRAM_FEED, SHIPSTATION, LAYLO, KLAVIYO, MAILCHIMP, KIT, BEEHIIV, FWDISCORD, PLEDGE, BOOKFUNNEL) - status: CONNECTED, NOT_CONNECTED, NOT_CONFIGURED, IN_PROGRESS, COMING_SOON, EXTERNAL, BROKEN - categories: list of SOCIAL_COMMERCE, ALERTS, SOCIAL_FEED, EMAIL_MARKETING, SHIPPING, OTHER - recommendations: list of sales recommendations (e.g. "SALES (priority: 1)"), empty if none - channelName: Twitch channel name (nullable, only for Twitch integrations) - missingScopes: OAuth scopes that need to be granted (nullable, only for Twitch/StreamElements) Status values: - CONNECTED: Fully set up and active - NOT_CONNECTED: Not configured at all - NOT_CONFIGURED: Partial setup (e.g., OAuth connected but configuration incomplete) - IN_PROGRESS: Setup is being processed - COMING_SOON: Feature not yet available - EXTERNAL: Configured outside Fourthwall (e.g., TikTok Feed, Instagram Feed) - BROKEN: Needs attention (e.g., missing scopes, expired auth) Use this tool to: - See all available and connected integrations for a shop - Check which sales channels are set up (TikTok Shop, YouTube Merch Shelf) - Verify email marketing tool connections (Klaviyo, Mailchimp, Kit, Beehiiv, Laylo) - Identify integrations that need attention (BROKEN status) - Get sales recommendations based on connected integrations
ecommerce_get-all-integrations
Retrieves all subscription plans available for the shop. To check the shop's current plan and usage, use get-current-subscription instead. Returns a list of plans, each with: - Identity: id, name, custom (boolean — true if specially configured for this shop), pro (boolean) - Pricing: priceAmount (BigDecimal), priceCurrency (String, e.g. "USD"), recurringPeriod (MONTHLY/YEARLY, nullable — null means one-time) - Limits: - offersLimit (Int): maximum number of products (-1 = unlimited) - membersLimit (Int): maximum team members (-1 = unlimited) - domainsLimit (Int): maximum custom domains (-1 = unlimited) - productDesignerArtworkStorageLimitBytes (Long): artwork storage for product designer - digitalProductsStorageLimitBytes (Long): storage for digital product files - Features: - digitalProductsFeePercent (Double): transaction fee percentage for digital products - creditForSamplesAmount (BigDecimal): monthly credit for ordering product samples - creditForSamplesCurrency (String): currency of sample credit - upgradable (boolean): whether the plan can be upgraded to a higher tier - tag (nullable): PRO, PRO_UNLIMITED, DEFAULT, DEFAULT_LEGACY, DEFAULT_UNLIMITED, CUSTOM
ecommerce_get-available-plans
Get the Average Order Value analytics report for the shop within a date range: average transaction metrics over time. This report shows average order metrics over time with the following columns per row: - date: The time period - total_orders: Total number of orders - unique_customers: Number of customers who placed orders - avg_tx_value: Average amount paid by customer per order - avg_gross_revenue: Average profit value per order - avg_product_revenue: Average product sales price per order - avg_product_cost: Average declared cost of self-produced products per order - avg_shipping_revenue: Average shipping cost per order - avg_donation_revenue: Average donation value per order - avg_discount_amount: Average discount value per order - avg_taxes_amount: Average taxes amount per order - avg_fourthwall_product_costs: Average cost of manufacturing of Fourthwall products per order - avg_payment_processing_fees: Average payment processing fees per order Precision: choose finest granularity producing <=31 rows (HOUR for ~1d, DAY for ~1mo, WEEK for ~7mo, MONTH for ~2.5y, QUARTER for ~7y, YEAR beyond).
ecommerce_get-average-order-value-report
Get comprehensive product details for one or more catalog products BY PRODUCT SLUG(S). Required param: `slugs` (a list of product slug strings, e.g. ['cotton-heritage-unisex-premium-hoodie-dtg']). Fetches all products concurrently. Returns enriched data including material, weight, fabric weight, print area pricing, size guide, colors, sizes, reviews, and more. This is the go-to tool for answering detailed product FAQ questions. CHOOSING THE RIGHT TOOL: this tool takes SLUGS, not IDs. If you only have a product ID (e.g. 'pro_abc123'), use get-catalog-product-details-by-id instead. IMPORTANT: Only use slugs returned by `get-catalog-products` or `search`. Do NOT construct or guess slugs from product names — they will not match real catalog entries. Returns a list of products (one per slug, in the same order), each containing: - Identity: id, brand, brandModel, name, slug, fulfillmentType - Category: categoryPath (list of category names) - Pricing: priceFrom, priceTo (BigDecimal) - Production: productionMethod, otherProductionMethods (alternative methods for same product), minimumOrdersNumber - Print areas: printAreas — list of available print areas, each containing: - type: region identifier (e.g. "front", "back", "neck_label") - name: display name (e.g. "Front", "Back", "Neck Label") - required: boolean — when true this area MUST carry artwork or the product cannot be manufactured (the manufacturer rejects the sync). Always design every required area, even when the product name highlights a different (optional) one — e.g. a "Custom Background" sticker sheet has a required "Stickers" area plus an optional "Background". - salePrice: formatted price string (e.g. "$8.50") - supportsBackendRendering: boolean — whether this specific region can be used with generate-product-design-previews - placements: list of placements within the region, each an object with id and name (e.g. [{"id": "leftChest", "name": "Left chest"}, {"id": "centerChest", "name": "Center chest"}]). Empty list when no placements. - placementsOnly: boolean — when true the placements are separate printed items (a sticker sheet's slots, a mug's two sides) and every one gets artwork. Name placements to choose which design goes where, or omit them and they are assigned for you. When false they are alternative spots on one surface, so name the one you want. - Backend rendering: supportsBackendRendering (boolean) — whether this product supports design preview generation via generate-product-design-previews. When true, check each print area's supportsBackendRendering to determine which regions can be designed. - Background: supportsBackground (boolean) — whether this product takes a `backgroundColor` in generate-product-design-previews, filling the canvas behind the artwork (a poster matte, a desk mat). Do not send a colour when false. - Colors: list of available color names - Sizes: list of available sizes — canonical strings; pass them back to the design tools verbatim, without re-casing or reformatting - Size guide: sizeGuide — formatted string like "Chest: S=34-36, M=38-40 (inches)" - Fit summary: fitSummary — one-sentence plain-language fit note like "Fits as expected." or "Oversized fit. Size down one size for a closer fit." Null when the product has no fit type set; lead with it before the measurement table. - Fabric: fabricWeightGsm (GSM), material (primary), distinctMaterials (all unique materials across variants, e.g. heather vs solid differ) - Weight: weightRange — formatted string like "5.00-6.20 oz" - Origin: countryOfProduction - Description: description, moreDetails, sizeAndFitNotes - Returns: guaranteeAndReturns — guarantee and returns policy text - Legal: legalWarningSubstance — legal/safety warnings (e.g. Prop 65) - Reviews: reviewSummary — formatted string like "4.63/5 (119 reviews) - Creators love the softness..." - Stock issues: colorsWithStockIssues — only colors that have problems, each with the discontinuedSizes and outOfStockSizes for that color. Colors absent from this list are fully available across every size in `sizes`. - Shipping: shipsFrom — regions where the product is fulfilled from (e.g. ["US", "EU", "CA"]) - Badges: badges (e.g. ["OUR_PICK", "BESTSELLER"]) - favourite: boolean
ecommerce_get-catalog-product-details
Browse source products from the product catalog with filtering and pagination. These are products available for customization — NOT the shop's own offers. To view products already added to the shop, use get-offers instead. Returns: - Pagination: pageNumber, pageSize, totalElements, totalPages - Per product: - Identity: id, brand, brandModel, name, slug - Category: categoryPath (list of category names) - Pricing: priceFrom (BigDecimal), priceTo (BigDecimal) - Production: productionMethod, minimumOrdersNumber (nullable Int) - Reviews: reviewsSummary with count and rating (nullable) - Metadata: customizationType (REQUESTABLE/INSTANT/DESIGNER_V3_READY/PRINTFUL_DESIGNER_READY), favourite (boolean), badges (OUR_PICK/BESTSELLER/NEW/SIGNATURE) - Print details (only when includePrintDetails=true): printDetails — { supportsBackendRendering (boolean), supportsBackground (boolean), printAreas: [{ type, name, required, salePrice, supportsBackendRendering, placements: [{ id, name }], placementsOnly }] }. required=true means the area MUST carry artwork or the product cannot be manufactured. IMPORTANT: To find a specific catalog product by name, brand, or keyword, you MUST use the `search` tool. NEVER paginate through results to find a specific entity.
ecommerce_get-catalog-products
Get details of one or more catalog products by their slugs. Fetches all products concurrently. This returns catalog source products — NOT shop offers. Use get-offers-by-ids for shop product details. IMPORTANT: Only use slugs returned by `get-catalog-products` or `search`. Do NOT construct or guess slugs from product names — they will not match real catalog entries. Returns a list of products, each containing: - Identity: id, brand, brandModel, name, slug - Category: categoryPath (list of category names from breadcrumbs) - Pricing: priceFrom (BigDecimal), priceTo (BigDecimal) - Production: productionMethod (SUBLIMATION/DTG/EMBROIDERY/SCREEN_PRINTING/PRINTED/STICKER/DTFX/UV/ALL_OVER_PRINT/KNITTING/DRINKWARE/GARMENT_PRINTED/ACRYLIC_CUTOUT/DIE_CUT_MAGNET/HOLO_STICKER/LASER_ETCHED/OTHER), minimumOrdersNumber (nullable Int) - Metadata: customizationType (REQUESTABLE/INSTANT/DESIGNER_V3_READY/PRINTFUL_DESIGNER_READY), favourite (boolean), badges (OUR_PICK/BESTSELLER/NEW/SIGNATURE) - Note: reviewsSummary is not available for single product lookups
ecommerce_get-catalog-products-by-slugs
Retrieves all non-archived collections for the shop. NOTE: The system-level "All Products" collection (used internally to display all products on the Products page) is excluded from results. Only user-created collections are returned. Returns a list of collections, each with: - Identity: id (CollectionId), shopId (ShopId), name, slug, description - Visibility: available (boolean), state (PUBLIC/HIDDEN/ARCHIVED) - Time-based availability: availableFrom (nullable ISO 8601), availableTo (nullable ISO 8601) - Products: offerIds (list of OfferIds — use get-offers-by-ids to look up each product) - Sorting: sortingStrategy (MANUAL/BEST_SELLING/NEWEST/OLDEST/NAME_ASC/NAME_DESC) IMPORTANT: To find a specific collection by name or keyword, you MUST use the `search` tool. NEVER iterate through results to find a specific entity.
ecommerce_get-collections
Get details of one or more collections by their IDs. Fetches all collections concurrently. Use get-collections to discover collection IDs if you don't have any. Returns a list of collections, each containing: - Identity: id (CollectionId), shopId (ShopId), name, slug, description - Visibility: available (boolean), state (PUBLIC/HIDDEN/ARCHIVED) - Time-based availability: availableFrom (nullable ISO 8601), availableTo (nullable ISO 8601) - Products: offerIds (list of OfferIds — use get-offers-by-ids to look up each product) - Sorting: sortingStrategy (MANUAL/BEST_SELLING/NEWEST/OLDEST/NAME_ASC/NAME_DESC)
ecommerce_get-collections-by-ids
Get the Contributions Per Type analytics report for the shop within a date range: transaction count breakdown by contribution type. This report shows contribution counts over time with the following columns per row: - date: The time period - shop_orders: Number of shop orders - sample_orders: Number of sample orders - orders_twitch_gifts_purchases: Number of Twitch gifts purchases - orders_twitch_gifts_redeems: Number of Twitch gifts redeems - donations: Number of donations - giveaway_links: Number of giveaway links - memberships_subscriptions: Subscriptions = New subscriptions + Renewals + Upgrades - memberships_message_tips: Number of message tips - memberships_locked_messages: Number of locked messages - memberships_paid_posts: Number of paid posts - memberships_subscription_gifts: Number of subscription gifts - memberships_twitch_gifts: Number of Twitch gifts - total: Total contributions across all types Precision: choose finest granularity producing <=31 rows (HOUR for ~1d, DAY for ~1mo, WEEK for ~7mo, MONTH for ~2.5y, QUARTER for ~7y, YEAR beyond). Filter groups (pass comma-separated keys to include only specific metrics): - shop_metrics: shop_orders, sample_orders, orders_twitch_gifts_purchases, orders_twitch_gifts_redeems, donations, giveaway_links - memberships_metrics: memberships_subscriptions, memberships_message_tips, memberships_locked_messages, memberships_paid_posts, memberships_subscription_gifts, memberships_twitch_gifts
ecommerce_get-contributions-per-type-report
Get the Conversion Rates analytics report for the shop within a date range: checkout funnel conversion metrics. This report shows conversion funnel data over time with the following columns per row: - date: The time period - total_sessions: Total number of user sessions adjusted to be at least as large as the number of carts created (baseline for conversion percentages, always 100%) - cart_created_count: Number of shopping carts created by users, including carts from gift and giveaway checkouts - cart_created_percentage: Percentage of sessions that resulted in cart creation - checkout_created_count: Number of initiated checkouts - checkout_created_percentage: Percentage of sessions that resulted in checkout initiation - checkout_paid_count: Number of completed payments - checkout_paid_percentage: Percentage of sessions that resulted in completed payment Precision: HOUR for ranges <=1 day, DAY for longer.
ecommerce_get-conversion-rates-report
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Fourthwall alternatives on ChatGPT?
As of 2026-09-28, Fourthwall competes with Bonfire, Create Prints, decoradesign, Maple & Marker, Photo9, Pixum, Print.com, PrintA, Printify, PrintTiler, Promotion Pros Catalog, Scribble, Send Postcard, Skylit Studio Custom Gifts, SoMerch, Stars In Hands Gift Studio, 굿새김 Goodsaegim in ChatGPT Custom Print & Personalized Keepsakes, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.