{"openapi":"3.1.0","info":{"title":"Slop City API","version":"0.1.0","summary":"Run a merch or dropship store as a city of AI agents","description":"REST API for your Slop City city. Create a key in Settings. Requires a plan that includes API access; writes need the read_write_api scope. Writes never publish, order or spend. The free tools under /api/v1/tools need no key and are rate limited."},"servers":[{"url":"https://app.slopship.com"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"city"},{"name":"observatory"},{"name":"studio"},{"name":"customs"},{"name":"factory"},{"name":"harbor"},{"name":"postoffice"},{"name":"bank"},{"name":"townhall"},{"name":"billboard"},{"name":"free-tools"}],"paths":{"/api/v1/buildings":{"get":{"operationId":"buildings_list","summary":"Status of every building","description":"Status, queue length and autonomy of every building.","tags":["city"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/ideas":{"get":{"operationId":"ideas_list","summary":"Ideas from the Observatory","description":"Ideas found by the Observatory.","tags":["observatory"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Max rows (default 50)"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/designs":{"get":{"operationId":"designs_list","summary":"Designs from the Studio","description":"Designs from the Studio and their state.","tags":["studio"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Max rows (default 50)"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/ip-checks":{"get":{"operationId":"ip_check_get","summary":"IP check results","description":"Customs House IP check results, optionally for one crate.","tags":["customs"],"parameters":[{"name":"item_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Max rows (default 50)"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/products":{"get":{"operationId":"products_list","summary":"Products from the Factory","description":"Products made by the Factory.","tags":["factory"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Max rows (default 50)"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/listings":{"get":{"operationId":"listings_list","summary":"Store listings","description":"Store listings (drafts and live) from the Harbor.","tags":["harbor"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Max rows (default 50)"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/orders":{"get":{"operationId":"orders_list","summary":"Orders","description":"Orders received at the Post Office (no buyer details).","tags":["postoffice"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Max rows (default 50)"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/bank":{"get":{"operationId":"bank_summary","summary":"Profit and loss","description":"Profit and loss per product and per city, AI spend shown separately.","tags":["bank"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/stuck":{"get":{"operationId":"stuck_list","summary":"Stuck or failed crates","description":"Stuck or failed crates with the reason.","tags":["city"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/approvals":{"get":{"operationId":"approvals_list","summary":"Crates waiting for approval","description":"Crates waiting in the Town Hall approval queue.","tags":["townhall"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/approvals/{item_id}/approve":{"post":{"operationId":"approvals_approve","summary":"Approve a waiting crate","description":"Approve a crate waiting at the Town Hall. Moves it on in the dry-run pipeline; publishes, orders and spends nothing.","tags":["townhall"],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","description":"Crate id, itm_xxx"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/approvals/{item_id}/reject":{"post":{"operationId":"approvals_reject","summary":"Reject a waiting crate","description":"Reject a crate waiting at the Town Hall.","tags":["townhall"],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","description":"Crate id, itm_xxx"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/rooms":{"get":{"operationId":"room_get","summary":"Setup settings of every building room","description":"Setup settings of one building's room (niches, style, policy, products, channels, shipping, budgets). Omit room_id to list every room's settings.","tags":["city"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/rooms/{room_id}":{"get":{"operationId":"room_get","summary":"Setup settings of one room","description":"Setup settings of one building's room (niches, style, policy, products, channels, shipping, budgets). Omit room_id to list every room's settings.","tags":["city"],"parameters":[{"name":"room_id","in":"path","required":true,"schema":{"type":"string","enum":["observatory","studio","customs","factory","harbor","postoffice","bank","billboard"]}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}},"put":{"operationId":"room_set","summary":"Change setup settings of one room","description":"Change setup settings of one building's room. Send only the settings to change. Saves preferences; publishes, orders and spends nothing. It can tighten the order review limit, the AI cap and the routing, but cannot loosen them (only you can, in the room).","tags":["city"],"parameters":[{"name":"room_id","in":"path","required":true,"schema":{"type":"string","enum":["observatory","studio","customs","factory","harbor","postoffice","bank","billboard"]}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["settings"],"properties":{"settings":{"type":"object","description":"Setting keys and new values, as returned by room_get"}},"additionalProperties":false}}}}}},"/api/v1/niche":{"get":{"operationId":"niche_validate","summary":"Free niche check","description":"Free niche check: how specific the niche is, brand risk and overlap with rising themes.","tags":["observatory"],"parameters":[{"name":"niche","in":"query","required":false,"schema":{"type":"string","description":"The niche, for example sourdough bakers"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/autonomy":{"get":{"operationId":"autonomy_get","summary":"Autonomy of every building","description":"Autonomy mode (suggest, ask, auto) of every building.","tags":["city"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/autonomy/{building_id}":{"put":{"operationId":"autonomy_set","summary":"Set a building's autonomy","description":"Set a building's autonomy to suggest, ask or auto (auto needs a plan that includes it).","tags":["city"],"parameters":[{"name":"building_id","in":"path","required":true,"schema":{"type":"string","enum":["observatory","studio","customs","factory","townhall","harbor","postoffice","bank","billboard"]}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","enum":["suggest","ask","auto"]}},"additionalProperties":false}}}}}},"/api/v1/integrations":{"get":{"operationId":"integrations_list","summary":"Connected providers and stores","description":"Connected providers and stores (POD, dropship, shops, social) with status and what each can do. Never returns credentials.","tags":["harbor"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/integrations/{provider_id}/test":{"post":{"operationId":"integrations_test","summary":"Run the read-only connection test","description":"Run the read-only connection test for one connected provider and record its health.","tags":["harbor"],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","description":"printful, printify, gelato, feed, shopify, etsy, woocommerce, tiktokshop or timetopost"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/integrations/{provider_id}/disconnect":{"post":{"operationId":"integrations_disconnect","summary":"Disconnect a provider","description":"Disconnect a provider or store and delete its stored credentials. Reconnecting needs the credentials again.","tags":["harbor"],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","description":"printful, printify, gelato, feed, shopify, etsy, woocommerce, tiktokshop or timetopost"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/autopilot":{"get":{"operationId":"autopilot_overview","summary":"What the autopilot is waiting on","description":"What the autopilot is waiting on: orders held for approval, ideas in Customs, draft listings, parked items and the AI and ad budgets.","tags":["townhall"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/parks":{"get":{"operationId":"parks_list","summary":"Parked work and why","description":"Work that stopped on purpose, with the reason (over budget, not connected, waiting for a decision).","tags":["townhall"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/budget":{"get":{"operationId":"budget_get","summary":"AI and ad budgets","description":"Monthly AI budget and ad budget, spent and remaining.","tags":["bank"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/orders/{order_id}/propose-approve":{"post":{"operationId":"order_propose_approve","summary":"Suggest approving a held order (you approve in the city)","description":"Suggest approving a held order. The order is only sent to the fulfilment provider when you approve it in the city; this spends nothing.","tags":["postoffice"],"parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["store_provider","note"],"properties":{"store_provider":{"type":"string","description":"Store the order came from, e.g. shopify"},"note":{"type":"string"}},"additionalProperties":false}}}}}},"/api/v1/orders/{order_id}/propose-claim":{"post":{"operationId":"order_propose_claim","summary":"Suggest a claim on an order","description":"Suggest a claim (misprint, damaged, remorse) on an order. A reprint costs money, so you confirm it in the city.","tags":["postoffice"],"parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["store_provider","reason","note"],"properties":{"store_provider":{"type":"string","description":"Store the order came from, e.g. shopify"},"reason":{"type":"string","enum":["misprint","damaged","remorse"]},"note":{"type":"string"}},"additionalProperties":false}}}}}},"/api/v1/listings/{idea_key}/propose-publish":{"post":{"operationId":"listing_propose_publish","summary":"Suggest publishing a draft listing","description":"Suggest publishing a draft listing. It goes live only when you publish it in the city.","tags":["harbor"],"parameters":[{"name":"idea_key","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/ideas/{idea_key}/reject":{"post":{"operationId":"idea_reject","summary":"Reject an idea waiting in the Customs House","description":"Reject an idea waiting in the Customs House. Approving an idea (clearing it for paint and sale) is your decision in the city.","tags":["customs"],"parameters":[{"name":"idea_key","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/ads":{"get":{"operationId":"ads_status","summary":"Ad connections, budget cap and return on ad spend","description":"Ad platform connections, monthly budget cap, approval mode, spend and return on ad spend.","tags":["billboard"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/ads/settings":{"put":{"operationId":"ads_settings_set","summary":"Set the ad budget cap and approval mode","description":"Set the monthly ad budget cap (hard stop, in cents of the account currency) and/or the approval mode (approve = you approve every action, auto needs a plan that includes it).","tags":["billboard"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["budget_cap_minor","approval_mode"],"properties":{"budget_cap_minor":{"type":"integer","minimum":0,"description":"Monthly cap in cents. 0 = nothing may be spent."},"approval_mode":{"type":"string","enum":["approve","auto"]}},"additionalProperties":false}}}}}},"/api/v1/ads/roas":{"get":{"operationId":"ads_roas","summary":"Ad spend against revenue","description":"Ad spend against the revenue those ads brought in, per platform and per day (last 30 days).","tags":["billboard"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/ads/proposals":{"get":{"operationId":"ads_proposals_list","summary":"Ad actions waiting for approval","description":"Ad actions the agent proposed and their state (pending, approved, rejected, blocked).","tags":["billboard"],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","approved","rejected","blocked"]}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}},"post":{"operationId":"ads_propose_spend","summary":"Propose an ad spend (needs approval)","description":"Propose an ad spend for a connected platform. It waits for your approval (or is auto-approved in auto mode) and is blocked if it would pass the monthly cap. Nothing is sent to the platform.","tags":["billboard"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["platform","title","amount_minor","detail"],"properties":{"platform":{"type":"string","enum":["meta","tiktok","google","pinterest"]},"title":{"type":"string"},"amount_minor":{"type":"integer","minimum":1},"detail":{"type":"string"}},"additionalProperties":false}}}}}},"/api/v1/ads/proposals/{proposal_id}/decide":{"post":{"operationId":"ads_proposal_decide","summary":"Approve or reject an ad proposal","description":"Reject a pending ad proposal. Approving is done by you in the Billboard Tower, never by the agent.","tags":["billboard"],"parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["decision"],"properties":{"decision":{"type":"string","enum":["approve","reject"]}},"additionalProperties":false}}}}}},"/api/v1/ab-tests":{"get":{"operationId":"ab_tests_list","summary":"A/B tests","description":"A/B tests with their versions, results, chance of being best and status.","tags":["billboard"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}},"post":{"operationId":"ab_test_create","summary":"Create an A/B test","description":"Create an A/B test of 2 to 4 versions (creative, headline, price, listing_title or thumbnail) on an ad platform or an Etsy/Shopify listing (rotation). Metric: ctr, cvr or roas.","tags":["billboard"],"parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","kind","channel","metric","variants","min_sample","max_days"],"properties":{"name":{"type":"string"},"kind":{"type":"string","enum":["creative","headline","price","listing_title","thumbnail"]},"channel":{"type":"string","enum":["meta","tiktok","google","pinterest","etsy","shopify"]},"metric":{"type":"string","enum":["ctr","cvr","roas"]},"variants":{"type":"array","minItems":2,"maxItems":4,"items":{"type":"object","properties":{"label":{"type":"string"},"content":{"type":"string"},"weight":{"type":"integer","minimum":5,"maximum":95}},"required":[],"additionalProperties":false}},"min_sample":{"type":"integer"},"max_days":{"type":"integer"}},"additionalProperties":false}}}}}},"/api/v1/ab-tests/{test_id}":{"get":{"operationId":"ab_test_get","summary":"One A/B test with results","description":"One A/B test with results in plain words.","tags":["billboard"],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/ab-tests/{test_id}/record":{"post":{"operationId":"ab_test_record","summary":"Record daily numbers","description":"Record daily numbers per version (impressions, clicks, conversions, spend_minor, revenue_minor). The test auto-stops when a winner is clear.","tags":["billboard"],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rows"],"properties":{"rows":{"type":"array","maxItems":400,"items":{"type":"object","properties":{"variant_id":{"type":"string"},"day":{"type":"string"},"impressions":{"type":"integer"},"clicks":{"type":"integer"},"conversions":{"type":"integer"},"spend_minor":{"type":"integer"},"revenue_minor":{"type":"integer"}},"required":["variant_id"],"additionalProperties":false}}},"additionalProperties":false}}}}}},"/api/v1/ab-tests/{test_id}/stop":{"post":{"operationId":"ab_test_stop","summary":"Stop a test","description":"Stop a running A/B test now.","tags":["billboard"],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/ab-tests/{test_id}/promote":{"post":{"operationId":"ab_test_promote","summary":"Propose making the winner live","description":"Propose making the winning version live. Needs your approval; nothing changes until you approve.","tags":["billboard"],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/ab-sample-size":{"get":{"operationId":"ab_sample_size","summary":"How many views a test needs","description":"How many views each version needs: baseline rate (like 0.02) and the lift worth detecting (like 0.2 for +20%).","tags":["billboard"],"parameters":[{"name":"baseline","in":"query","required":false,"schema":{"type":"number"}},{"name":"lift","in":"query","required":false,"schema":{"type":"number"}},{"name":"daily_traffic","in":"query","required":false,"schema":{"type":"number"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanRequired"},"403":{"$ref":"#/components/responses/PlanRequired"}}}},"/api/v1/tools/print_size_check":{"get":{"operationId":"print_size_check_get","summary":"Print size checker","description":"Check whether your artwork is sharp enough to print on a t-shirt. Give the image width and height in pixels and get the print size at 300 and 150 dpi, the effective dpi when scaled to fill the print area, and the pixel size you need. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"parameters":[{"name":"width","in":"query","required":false,"schema":{"type":"number","description":"Width (pixels)"}},{"name":"height","in":"query","required":false,"schema":{"type":"number","description":"Height (pixels)"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}},"post":{"operationId":"print_size_check","summary":"Print size checker","description":"Check whether your artwork is sharp enough to print on a t-shirt. Give the image width and height in pixels and get the print size at 300 and 150 dpi, the effective dpi when scaled to fill the print area, and the pixel size you need. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"width":{"type":"number","description":"Width (pixels)"},"height":{"type":"number","description":"Height (pixels)"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}}},"/api/v1/tools/pod_profit_calc":{"get":{"operationId":"pod_profit_calc_get","summary":"Profit calculator","description":"Work out your real profit per print-on-demand order after marketplace fees. Includes Etsy listing, transaction and payment fees for US and Spanish sellers, Offsite Ads, and TikTok Shop referral fees, with break-even price and the price for your target margin. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"parameters":[{"name":"channel","in":"query","required":false,"schema":{"type":"string","enum":["etsy","tiktok_us","tiktok_eu"],"description":"Sales channel"}},{"name":"country","in":"query","required":false,"schema":{"type":"string","enum":["US","ES"],"description":"Etsy seller country (Etsy only)"}},{"name":"currency","in":"query","required":false,"schema":{"type":"string","enum":["USD","EUR"],"description":"Currency"}},{"name":"price","in":"query","required":false,"schema":{"type":"number","description":"Selling price"}},{"name":"shipCharged","in":"query","required":false,"schema":{"type":"number","description":"Shipping charged to the buyer"}},{"name":"cost","in":"query","required":false,"schema":{"type":"number","description":"Printful product cost"}},{"name":"shipCost","in":"query","required":false,"schema":{"type":"number","description":"Printful shipping cost"}},{"name":"other","in":"query","required":false,"schema":{"type":"number","description":"Other costs per order (optional)"}},{"name":"targetMargin","in":"query","required":false,"schema":{"type":"number","description":"Target margin % (optional)"}},{"name":"offsiteAds","in":"query","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}},"post":{"operationId":"pod_profit_calc","summary":"Profit calculator","description":"Work out your real profit per print-on-demand order after marketplace fees. Includes Etsy listing, transaction and payment fees for US and Spanish sellers, Offsite Ads, and TikTok Shop referral fees, with break-even price and the price for your target margin. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"channel":{"type":"string","enum":["etsy","tiktok_us","tiktok_eu"],"description":"Sales channel"},"country":{"type":"string","enum":["US","ES"],"description":"Etsy seller country (Etsy only)"},"currency":{"type":"string","enum":["USD","EUR"],"description":"Currency"},"price":{"type":"number","description":"Selling price"},"shipCharged":{"type":"number","description":"Shipping charged to the buyer"},"cost":{"type":"number","description":"Printful product cost"},"shipCost":{"type":"number","description":"Printful shipping cost"},"other":{"type":"number","description":"Other costs per order (optional)"},"targetMargin":{"type":"number","description":"Target margin % (optional)"},"offsiteAds":{"type":"boolean","description":"Order came from an Etsy Offsite Ad (15%)"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}}},"/api/v1/tools/trademark_risk_check":{"get":{"operationId":"trademark_risk_check_get","summary":"Trademark risk checker","description":"Screen a t-shirt slogan for trademark risk before you print it. Checks a local list of protected brands and known slogans, catches leetspeak and one-letter misspellings, flags licensed-product wording, and links to the USPTO, EUIPO and WIPO searches. A screening aid, not legal advice. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"parameters":[{"name":"slogan","in":"query","required":false,"schema":{"type":"string","maxLength":300,"description":"Shirt slogan"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}},"post":{"operationId":"trademark_risk_check","summary":"Trademark risk checker","description":"Screen a t-shirt slogan for trademark risk before you print it. Checks a local list of protected brands and known slogans, catches leetspeak and one-letter misspellings, flags licensed-product wording, and links to the USPTO, EUIPO and WIPO searches. A screening aid, not legal advice. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slogan":{"type":"string","maxLength":300,"description":"Shirt slogan"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}}},"/api/v1/tools/etsy_tags_titles":{"get":{"operationId":"etsy_tags_titles_get","summary":"Etsy tag and title generator","description":"Generate a full set of 13 Etsy tags (each 20 characters or fewer) and a title up to 140 characters from a theme and a few keywords. Rule-based, so the same input always gives the same result, with a trademark flag on risky words. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"parameters":[{"name":"theme","in":"query","required":false,"schema":{"type":"string","maxLength":60,"description":"Theme or main keyword"}},{"name":"product","in":"query","required":false,"schema":{"type":"string","maxLength":40,"description":"Product"}},{"name":"audience","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"Who is it for (comma separated)"}},{"name":"occasion","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"Occasions (comma separated)"}},{"name":"style","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"Styles (comma separated)"}},{"name":"extra","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"Other keywords (comma separated)"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}},"post":{"operationId":"etsy_tags_titles","summary":"Etsy tag and title generator","description":"Generate a full set of 13 Etsy tags (each 20 characters or fewer) and a title up to 140 characters from a theme and a few keywords. Rule-based, so the same input always gives the same result, with a trademark flag on risky words. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"theme":{"type":"string","maxLength":60,"description":"Theme or main keyword"},"product":{"type":"string","maxLength":40,"description":"Product"},"audience":{"type":"string","maxLength":200,"description":"Who is it for (comma separated)"},"occasion":{"type":"string","maxLength":200,"description":"Occasions (comma separated)"},"style":{"type":"string","maxLength":200,"description":"Styles (comma separated)"},"extra":{"type":"string","maxLength":200,"description":"Other keywords (comma separated)"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}}},"/api/v1/tools/dropship_margin_calc":{"get":{"operationId":"dropship_margin_calc_get","summary":"Dropship margin calculator","description":"Calculate dropshipping profit per order after payment fees, refunds, supplier cost and ad cost. See break-even ROAS, the most you can spend to win an order, and whether the supplier's delivery window will hurt conversion, with a single ready-to-scale score. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"parameters":[{"name":"price","in":"query","required":false,"schema":{"type":"number","description":"Selling price"}},{"name":"shipCharged","in":"query","required":false,"schema":{"type":"number","description":"Shipping charged to the buyer"}},{"name":"cost","in":"query","required":false,"schema":{"type":"number","description":"Supplier product cost"}},{"name":"shipCost","in":"query","required":false,"schema":{"type":"number","description":"Supplier shipping cost"}},{"name":"adCost","in":"query","required":false,"schema":{"type":"number","description":"Ad cost to win one order"}},{"name":"refundPct","in":"query","required":false,"schema":{"type":"number","description":"Refund and chargeback allowance %"}},{"name":"feePct","in":"query","required":false,"schema":{"type":"number","description":"Payment fee %"}},{"name":"feeFixed","in":"query","required":false,"schema":{"type":"number","description":"Payment fee per order"}},{"name":"daysMin","in":"query","required":false,"schema":{"type":"number","description":"Fastest delivery (days)"}},{"name":"daysMax","in":"query","required":false,"schema":{"type":"number","description":"Slowest delivery (days)"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}},"post":{"operationId":"dropship_margin_calc","summary":"Dropship margin calculator","description":"Calculate dropshipping profit per order after payment fees, refunds, supplier cost and ad cost. See break-even ROAS, the most you can spend to win an order, and whether the supplier's delivery window will hurt conversion, with a single ready-to-scale score. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"price":{"type":"number","description":"Selling price"},"shipCharged":{"type":"number","description":"Shipping charged to the buyer"},"cost":{"type":"number","description":"Supplier product cost"},"shipCost":{"type":"number","description":"Supplier shipping cost"},"adCost":{"type":"number","description":"Ad cost to win one order"},"refundPct":{"type":"number","description":"Refund and chargeback allowance %"},"feePct":{"type":"number","description":"Payment fee %"},"feeFixed":{"type":"number","description":"Payment fee per order"},"daysMin":{"type":"number","description":"Fastest delivery (days)"},"daysMax":{"type":"number","description":"Slowest delivery (days)"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}}},"/api/v1/tools/niche_validate":{"get":{"operationId":"niche_validate_get","summary":"Niche validator","description":"Validate a print-on-demand or merch niche before you design for it. Scores specificity, identity pull, gift appeal, staying power, marketplace room and price fit, flags trademark risk, and suggests how to sharpen the idea. A transparent heuristic, not live search volume. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"parameters":[{"name":"niche","in":"query","required":false,"schema":{"type":"string","maxLength":80,"description":"Niche or product idea"}},{"name":"audience","in":"query","required":false,"schema":{"type":"string","maxLength":80,"description":"Who buys it (optional)"}},{"name":"product","in":"query","required":false,"schema":{"type":"string","enum":["tee","hoodie","mug","poster","tote","other"],"description":"Product"}},{"name":"season","in":"query","required":false,"schema":{"type":"string","enum":["evergreen","seasonal","trend"],"description":"Demand pattern"}},{"name":"listings","in":"query","required":false,"schema":{"type":"string","enum":["unknown","low","medium","high"],"description":"Marketplace listings for the exact phrase"}},{"name":"price","in":"query","required":false,"schema":{"type":"number","description":"Target price (optional)"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}},"post":{"operationId":"niche_validate","summary":"Niche validator","description":"Validate a print-on-demand or merch niche before you design for it. Scores specificity, identity pull, gift appeal, staying power, marketplace room and price fit, flags trademark risk, and suggests how to sharpen the idea. A transparent heuristic, not live search volume. Free, no key. Rate limited.","tags":["free-tools"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"niche":{"type":"string","maxLength":80,"description":"Niche or product idea"},"audience":{"type":"string","maxLength":80,"description":"Who buys it (optional)"},"product":{"type":"string","enum":["tee","hoodie","mug","poster","tote","other"],"description":"Product"},"season":{"type":"string","enum":["evergreen","seasonal","trend"],"description":"Demand pattern"},"listings":{"type":"string","enum":["unknown","low","medium","high"],"description":"Marketplace listings for the exact phrase"},"price":{"type":"number","description":"Target price (optional)"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{}}}},"422":{"description":"Input needs fixing"},"429":{"description":"Rate limited"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from Settings"}},"responses":{"Unauthorized":{"description":"Missing, invalid or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PlanRequired":{"description":"The plan does not include this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}},"Autonomy":{"type":"string","enum":["suggest","ask","auto"]},"Building":{"type":"string","enum":["observatory","studio","customs","factory","townhall","harbor","postoffice","bank","billboard"]}}}}