{
  "openapi": "3.0.1",
  "info": {
    "title": "Print on Demand T-Shirt Design & Listing Generator",
    "description": "Score print-on-demand niches, screen every brand and slogan against the US trademark registry, write copy validated against your platform’s own character limits, and generate print-ready transparent artwork. Supports Amazon Merch on Demand, Etsy, Redbubble and Zazzle.",
    "version": "1.0",
    "x-build-id": "DNUwaOGhdNEZxz8QZ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/sian.agency~t-shirt-design-and-listing-generator/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-sian.agency-t-shirt-design-and-listing-generator",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/sian.agency~t-shirt-design-and-listing-generator/runs": {
      "post": {
        "operationId": "runs-sync-sian.agency-t-shirt-design-and-listing-generator",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/sian.agency~t-shirt-design-and-listing-generator/run-sync": {
      "post": {
        "operationId": "run-sync-sian.agency-t-shirt-design-and-listing-generator",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "🎛️ Mode",
            "enum": [
              "full",
              "discover",
              "research",
              "ideate",
              "clearance",
              "listing",
              "design"
            ],
            "type": "string",
            "description": "Which stages to run. `research` (the default) scores niches only — one charge per niche. `discover` finds brand-new niches from what print-on-demand sellers are saying on YouTube. `full` chains niche scoring, slogans, trademark clearance, listing copy and artwork.\n\nEvery mode that generates a name or slogan screens it for trademarks automatically.\n\n💳 Discover, Slogans and all artwork need a paid plan. Research, Clearance and Listings are free.",
            "default": "research"
          },
          "platform": {
            "title": "🏪 Platform",
            "enum": [
              "amazon-merch",
              "etsy",
              "redbubble",
              "zazzle"
            ],
            "type": "string",
            "description": "Which storefront the listing copy is written and validated for. Every limit comes from that platform's own documentation — where a platform publishes no limit for a field, none is enforced and the row says so. `amazon-merch` has the strictest rules, so copy validated for it usually fits elsewhere too. Etsy and Zazzle publish listing rules but no artwork spec, so they cannot be used for `design` runs.",
            "default": "amazon-merch"
          },
          "niches": {
            "title": "🎯 Niches",
            "type": "array",
            "description": "The niches you want to work, e.g. `cat mom t-shirt`. One row and one charge per niche. Required for every mode except `clearance` and `discover` — `discover` goes and finds niches for you instead.\n\nStill accepts the old `keywords` field name.",
            "default": [
              "cat mom t-shirt"
            ],
            "items": {
              "type": "string"
            }
          },
          "phrases": {
            "title": "⚖️ Phrases to screen",
            "type": "array",
            "description": "Brand names, titles or slogans to check against the trademark registry. Required for `clearance` mode. In every other mode these are generated for you and screened automatically.",
            "items": {
              "type": "string"
            }
          },
          "nichesFile": {
            "title": "📄 Bulk niche file",
            "type": "string",
            "description": "Optional CSV or TXT with one niche per line, for bulk runs. A `niche` / `keyword` / `phrase` header row is ignored.\n\nStill accepts the old `keywordsFile` field name."
          },
          "sources": {
            "title": "📡 Source Channels (Discovery)",
            "uniqueItems": true,
            "type": "array",
            "description": "Which creator channels to mine in **Discover** mode. Leave empty to use our curated list of twelve print-on-demand sellers and educators. Use handles without the @ — e.g. `DetourShirts`.\n\nMarketplace data shows what *already* sells, so the competition has arrived. These channels talk about what is working now.\n\n💳 Requires a paid Apify plan.",
            "items": {
              "type": "string"
            }
          },
          "marketplace": {
            "title": "🌍 Marketplace",
            "enum": [
              "US",
              "UK",
              "DE",
              "FR",
              "IT",
              "ES",
              "JP"
            ],
            "type": "string",
            "description": "Which storefront to analyse competitors on. Trademark screening covers the US registry only — other marketplaces still get a screen, plus a warning row telling you it does not reflect local rights.",
            "default": "US"
          },
          "productType": {
            "title": "👕 Product type",
            "enum": [
              "standard-tshirt",
              "premium-tshirt",
              "apparel",
              "mens-graphic-tshirt",
              "womens-sleeveless-top",
              "baseball-cap",
              "bucket-hat",
              "socks",
              "scarf",
              "pin"
            ],
            "type": "string",
            "description": "Sets the print canvas size and safe zone for generated artwork, using the selected platform's own published dimensions. Options that do not exist on your platform fall back to its default product. Amazon Merch: standard or premium t-shirt, both 4500x5400 — the only Merch canvas we could corroborate, since Amazon publishes its specs behind a seller login. Redbubble: apparel, premium tee, graphic tee, sleeveless top, caps, socks, scarf, pin.",
            "default": "standard-tshirt"
          },
          "maxResultsPerKeyword": {
            "title": "📊 Competitor listings per niche",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "How many live competitor listings to analyse when scoring each niche.",
            "default": 20
          },
          "includeBestsellerContext": {
            "title": "🏆 Add bestseller context",
            "type": "boolean",
            "description": "Also look at what is already winning the category, not just what matches the term. Uses one extra marketplace lookup per niche.",
            "default": false
          },
          "includeConflictingMarks": {
            "title": "📋 Return the conflicting marks",
            "type": "boolean",
            "description": "Return the actual blocking trademarks — owner, serial number, status and classes — not just a yes/no. This is what makes the output a clearance report you can act on. Strongly recommended.",
            "default": true
          },
          "trademarkRiskThreshold": {
            "title": "🚦 Risk threshold",
            "enum": [
              "strict",
              "balanced",
              "permissive"
            ],
            "type": "string",
            "description": "How to treat a live mark in a non-apparel class. A live mark that covers apparel always blocks, at every setting.",
            "default": "balanced"
          },
          "artOutput": {
            "title": "🎨 Artwork output",
            "enum": [
              "none",
              "printReady",
              "textOnly"
            ],
            "type": "string",
            "description": "`none` runs no artwork at all. `printReady` produces a full-resolution 300-DPI transparent print file and requires a paid Apify plan.\n\n**Text only** renders your wording from an actual font file instead of asking an image model to draw letters. It costs a fraction of the AI artwork, and the spelling is exact by construction — no model can misspell it.",
            "default": "none"
          },
          "transparency": {
            "title": "🫧 Transparency mode",
            "enum": [
              "keyed",
              "native"
            ],
            "type": "string",
            "description": "How the artwork gets its transparent background. `keyed` (default) generates the design and then cuts the background out — excellent, and on every plan. `native` asks the model for real transparency from the start, so nothing can be cut away wrongly: on our test renders roughly ten times less semi-transparent edge, which is what shows as a faint halo on a coloured garment. It is billed as its own, higher-rate event and needs a paid plan plus `artOutput: printReady`.",
            "default": "keyed"
          },
          "designText": {
            "title": "✍️ Design Text",
            "type": "string",
            "description": "The exact wording to render, used when **artOutput** is *Text only*.\n\nLeave it empty to use the first cleared slogan from the ideation stage, or the niche itself.\n\n💳 **Requires a paid Apify plan.**"
          },
          "fontFamily": {
            "title": "🔤 Font",
            "enum": [
              "anton",
              "bebas",
              "archivo",
              "montserrat",
              "alfaslab",
              "ultra",
              "titan",
              "staatliches",
              "righteous",
              "lobster",
              "pacifico",
              "shrikhand",
              "bungee",
              "rubikmono",
              "permanent",
              "creepster",
              "chewy"
            ],
            "type": "string",
            "description": "Which display face to render the text in. All of these were loaded and measured against the live Google Fonts API — none is offered that cannot actually be parsed.\n\n💳 **Requires a paid Apify plan.**",
            "default": "anton"
          },
          "fontUrl": {
            "title": "📎 Custom Font URL",
            "type": "string",
            "description": "An https link to your own **.ttf** or **.otf** file, which overrides the font picker above.\n\nThe file is validated by parsing it, not by trusting the file extension — a link that returns anything other than a real font fails the run with a clear message rather than producing blank artwork.\n\nWOFF and WOFF2 are not supported.\n\n💳 **Requires a paid Apify plan.**"
          },
          "textColor": {
            "title": "🎨 Text Colour",
            "type": "string",
            "description": "Hex colour for the rendered text, e.g. `#ffffff`. White is the default because most print-on-demand garments are dark.\n\n💳 **Requires a paid Apify plan.**",
            "default": "#ffffff"
          },
          "designFinish": {
            "title": "🩹 Design Finish",
            "enum": [
              "clean",
              "subtle-wear",
              "heavy-erosion",
              "vintage-stain",
              "worn-gray",
              "textured"
            ],
            "type": "string",
            "description": "Optional distressed finish, using the same grunge textures as our in-house production designs.\n\n**Clean** leaves the art untouched. The others erode and age it so it reads as screen-printed rather than computer-generated. The same design always distresses identically, so a re-run reproduces the file exactly.\n\n💳 Applies to artwork, which needs a paid plan.",
            "default": "clean"
          },
          "designStyle": {
            "title": "🖌️ Design style",
            "enum": [
              "typographic",
              "vintage-distressed",
              "line-art",
              "mascot",
              "minimal-graphic"
            ],
            "type": "string",
            "description": "Visual language for generated artwork.\n\n- **Typographic** — expressive lettering as the hero. Best seller on most platforms.\n- **Vintage distressed** — retro badge, halftone texture, washed palette.\n- **Line art** — clean single-weight monoline, no fills.\n- **Mascot** — bold outlines, flat cel shading, sticker-style.\n- **Minimal graphic** — geometric, lots of negative space, two or three flat colours.\n\nEvery style is constrained to what survives printing: no gradients, no hairlines.",
            "default": "typographic"
          },
          "designAngle": {
            "title": "🎯 Commercial Angle",
            "enum": [
              "group-event",
              "niche-interest",
              "occupation-hobby",
              "family-role",
              "emotional-hook",
              "wordplay"
            ],
            "type": "string",
            "description": "Who the design is aimed at, which changes what gets drawn.\n\n**Group event** is the one worth knowing about: a reunion or a bachelorette party buys a dozen shirts rather than one, and a design built to look deliberate on twelve people at once is a different brief.\n\nAll angles are evergreen — no seasonal or trend-tied artwork.",
            "default": "niche-interest"
          },
          "garmentColor": {
            "title": "👕 Garment Colour",
            "enum": [
              "any",
              "dark",
              "light"
            ],
            "type": "string",
            "description": "The colour of the garment this art will be printed on, which decides the contrast rules.\n\nLeave it on **Any** unless you know — the art is then drawn to survive on both light and dark fabric. Telling us the garment produces stronger art, because the palette can commit.",
            "default": "any"
          },
          "designsPerConcept": {
            "title": "🔢 Designs per concept",
            "minimum": 1,
            "maximum": 4,
            "type": "integer",
            "description": "How many variations to generate per niche. Each one is charged separately. Free plans are capped at 1.",
            "default": 1
          },
          "referenceImage": {
            "title": "🖼️ Reference image (advanced)",
            "type": "string",
            "description": "⚠️ WARNING: uploading artwork you do not own is the single most common cause of permanent print-on-demand account termination. Only upload work you created yourself and hold full rights to. Third-party art, fan art, logos, characters and stock images will get your account closed with no appeal."
          },
          "copyTone": {
            "title": "🗣️ Copy tone",
            "enum": [
              "direct",
              "funny",
              "heartfelt",
              "professional"
            ],
            "type": "string",
            "description": "Voice for listing copy and slogans.\n\n- **Direct** — plain and benefit-first, no jokes. Safest default.\n- **Funny** — witty and punchy, never crude.\n- **Heartfelt** — warm and sincere, gift-giving framing.\n- **Professional** — polished and restrained, for a workplace audience.\n\nTone never overrides a platform's rules — character limits and banned vocabulary are enforced in code regardless of what you pick here.",
            "default": "direct"
          },
          "sloganCount": {
            "title": "💡 Slogans per Niche",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many slogan candidates to keep per niche.\n\n**This controls spend.** Every slogan that is kept is screened against the trademark register, which is one clearance charge each — so 10 slogans across 3 niches is 30 screenings. The model is always asked for a wide set and the surplus is discarded before anything is charged.\n\nDefault 5. Maximum 10.\n\n💳 **Requires a paid Apify plan.** Slogan ideation is a paid feature — every slogan it writes is screened against the trademark register.",
            "default": 5
          },
          "platformLimits": {
            "title": "📏 Character limits (advanced)",
            "type": "object",
            "description": "Override the character limits your copy is validated against. Leave this EMPTY unless you have a reason: by default each field is checked against the selected platform's own published limit, and a value here replaces it. `null` in the output means the platform publishes no limit for that field, so none was enforced. Keys: `brand`, `title`, `bullet`, `bulletCount`, `description`."
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}