{"openapi":"3.1.0","info":{"title":"Viewider Product API","version":"1.2.8.0","description":"External API for Viewider's commerce platform: products & product groups, inventory, Viewider/Yasuee marketplace listings, shipments & tracking, B2B transactions/orders, and sourcing.\n\nAUTH: preferred auth is a Bearer machine-token (see bearerAuth) — mint/rotate via POST /rotateMachineToken with client_id + client_secret (FIX-314). The legacy POST /getAccessToken username/password flow mints a long-lived token and is DEPRECATED. Some endpoints additionally rely on a server-side PHP session.\n\nENVELOPE: every operation returns HTTP 200 even on error. Success = SuccessEnvelope (status: success, response shaped per endpoint); failure = ErrorEnvelope (status: fail, err_msg / err_des). Always inspect the status field.\n\nPATH SUFFIX: some paths carry a literal .php suffix (e.g. /transaction/getOrder.php) and some do not — send each path verbatim. A few filenames embed typos (editInventroy, CreateViewdierAPIListings) preserved in the URL.\n\nSANDBOX: a read-only sandbox is available — authenticate with a sandbox key and select the Sandbox server; every read scopes to an isolated test account with no real external bindings, so reads are completely safe. Write and transaction endpoints stay marked not-yet-sandbox-testable until safe-write and mocked-transaction support roll out. Request a sandbox key from Viewider API support.","contact":{"name":"Viewider API Support","url":"https://viewider.com/developers"}},"servers":[{"url":"https://viewider.com/externalAPI","description":"Production — same-origin with these docs; use this for the in-browser Test Request (no CORS)."},{"url":"https://api.viewider.com/externalAPI","description":"Production — api host (server-to-server integrations)."},{"url":"https://viewider.com/externalAPI","description":"Sandbox — same endpoint as production; sandbox vs live is decided by your KEY, not the host. Authenticate with a sandbox key and every read scopes to an isolated test account that holds no real external bindings, so no real orders, shipments or marketplace publishes can occur. Read-only today; safe-write and mocked-transaction testing are rolling out. Request a sandbox key from Viewider API support (self-serve issuance coming to /developers/keys)."}],"security":[{"bearerAuth":[]}],"tags":[{"name":"auth","description":"Token minting and rotation (access-token / machine-token)."},{"name":"product","description":"Product groups, products, inventory, categories and reference enums."},{"name":"ViewiderListing","description":"Viewider/Yasuee marketplace listing config, packages, sites and upload."},{"name":"shipment","description":"Shipment creation, labels, status and tracking checkpoints."},{"name":"transaction","description":"B2B orders, sales records, confirm/pay and shipping services."},{"name":"sourcing","description":"Marketplace stores, cart/checkout and ViewiderAPI listing sourcing."},{"name":"listing","description":"Cross-marketplace listing search and per-listing detail."},{"name":"order","description":"Seller sales records and platform transaction search and export."},{"name":"inventory","description":"Inventory record search, item lookup and per-SKU stock history."},{"name":"marketplace"},{"name":"reference"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Bearer machine-token. Mint/rotate via POST /rotateMachineToken with client_id + client_secret. Legacy username/password and long-lived access_token are deprecated."}},"schemas":{"ErrorEnvelope":{"type":"object","required":["timestamp","status","err_msg","err_des"],"description":"Failure is ALSO returned with HTTP 200. Detect via status == fail.","properties":{"timestamp":{"type":"string"},"status":{"const":"fail"},"err_msg":{"type":"string"},"err_des":{"type":"string"}}}}},"paths":{"/getAccessToken":{"post":{"tags":["auth"],"summary":"[Deprecated] Mint a long-lived access token from a username and password. Use POST /rotateMachineToken instead.","description":"Exchanges a Viewider account username and password for a long-lived access token (scope 0, expiring in the year 2046). Send the credentials as `application/x-www-form-urlencoded` form fields `username` and `password`; no Authorization header is used. On success the token is returned as `response.access_token`. This is a legacy flow with no refresh path or client-secret auth and breaks on every OAuth key rotation — prefer the client-credentials flow at POST /rotateMachineToken instead. Every reply is a JSON envelope, so always check the `status` field (a `fail` envelope can arrive even with HTTP 200).","security":[],"deprecated":true,"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"password":{"type":"string","description":"Account password. Required."},"username":{"type":"string","description":"Viewider account username. Required."}},"required":["username","password"]},"example":{"username":"yasuee_integration","password":"s3cr3t-pa55w0rd"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"access_token":{"type":"string"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:32:07","status":"success","response":{"access_token":"a1b2c3d4e5f60718293a4b5c6d7e8f90aabbccddeeff00112233445566778899"}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"getAccessToken"}},"/rotateMachineToken":{"post":{"tags":["auth"],"summary":"Mint a fresh, finite-expiry Bearer token for server-to-server access using client credentials.","description":"Authenticates a machine client via the OAuth client-credentials grant and returns a short-lived Bearer access token. Send `client_id` and `client_secret` as `application/x-www-form-urlencoded` form fields (not an Authorization header); the client must be configured for the `client_credentials` grant. Optionally pass `token_lifetime` in seconds (clamped to 300–2592000, default 86400). On success `response` contains `access_token`, `token_type` (`Bearer`), `expires_in` (seconds), and `expires_at` (Unix epoch); because the token is signed with the current signing key, re-call this endpoint to recover from a 401 after a key rotation. Requests must be sent over HTTPS, bad credentials return a generic error (no client-existence hint), and every reply is a JSON envelope — always check the `status` field.","security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"client_secret":{"type":"string","description":"Client secret for the given client_id. Required; bad credentials return a generic error with no client-existence hint."},"token_lifetime":{"type":"integer","description":"Optional requested token lifetime in seconds. Clamped to 300–2592000; default 86400 (24h)."},"client_id":{"type":"string","description":"OAuth client id of the machine client. Required; empty value is rejected."}},"required":["client_id","client_secret"]},"example":{"client_id":"yasuee-svc","client_secret":"cs_live_9f8e7d6c5b4a39281706","token_lifetime":86400}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string"},"expires_in":{"type":"integer"},"expires_at":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:35:51","status":"success","response":{"access_token":"f0e1d2c3b4a5968778695a4b3c2d1e0fffeeddccbbaa99887766554433221100","token_type":"Bearer","expires_in":86400,"expires_at":1782484551}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"rotateMachineToken"}},"/product/getCategoryList":{"post":{"tags":["product"],"summary":"Browse the Viewider category tree one level per call (drill-down).","description":"Drills the live Viewider category tree one level per call. Send data as the top-level category id (a numeric string, 1-10; values outside that range are rejected). Without parent, the response is that top-level category plus one page of its direct children. To go deeper, send parent as the categoryID of the node to expand — it must sit under the requested top-level category or the call is rejected. Children are paged 300 per page, sorted by categoryID ascending; walk page up to totalPages for wide nodes (a few fan out to ~14k children). Drill until isLeaf is true to obtain a leaf categoryID for listing creation. Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_get_category_tree","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"data":{"type":"string","description":"Top-level Viewider category id (numeric string, 1–10). Required; values outside 1–10 or non-numeric are rejected."},"parent":{"type":"integer","description":"Optional. categoryID of the category to expand (drill one level). Must sit under the top-level category given in data; omit to expand the top-level category itself."},"page":{"type":"integer","description":"Optional. 1-based children page (default 1). Fixed 300 children per page, sorted by categoryID ascending; the response carries totalChildren / totalPages."}},"required":["data"]},"example":{"data":"5","parent":287,"page":1}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","description":"One level of the tree: the expanded category plus one page of its direct children.","properties":{"category":{"type":"object","description":"the node that was expanded","properties":{"categoryID":{"type":"integer"},"categoryName":{"type":"string","description":"English name"},"categoryNameZh":{"type":"string","description":"Chinese name"},"isLeaf":{"type":"boolean","description":"true = no children; use this categoryID for listing creation"},"level":{"type":"integer","description":"0 = top-level"},"path":{"type":"string","description":"full English path, \" > \" separated"}}},"children":{"type":"array","items":{"type":"object","properties":{"categoryID":{"type":"integer"},"categoryName":{"type":"string","description":"English name"},"categoryNameZh":{"type":"string","description":"Chinese name"},"isLeaf":{"type":"boolean","description":"true = no children; use this categoryID for listing creation"}}}},"page":{"type":"integer"},"pageSize":{"type":"integer","description":"always 300"},"totalChildren":{"type":"integer"},"totalPages":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-02 22:40:11","status":"success","response":{"category":{"categoryID":287,"categoryName":"Home & Garden - Food & Beverages","categoryNameZh":"家居與園藝 - 食物和飲料","isLeaf":false,"level":1,"path":"Home & Garden > Home & Garden - Food & Beverages"},"children":[{"categoryID":78573,"categoryName":"Non-Alcoholic Drinks","categoryNameZh":"非酒精飲料","isLeaf":false}],"page":1,"pageSize":300,"totalChildren":12,"totalPages":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_getCategoryList"}},"/product/getConditionList":{"post":{"tags":["product"],"summary":"List all item-condition options (id + name).","description":"Returns the full list of item-condition options used when creating products (condition ids mirror eBay condition codes). Takes no request parameters. The response is an array of {conditionID, conditionName} objects. Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_list_item_conditions","requestBody":{"required":false,"content":{"none":{"schema":{"type":"object","properties":[],"description":"— reads no request parameters (any method/body is ignored beyond the session check)."},"example":[]}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"array","items":{"type":"object","properties":{"conditionID":{"type":"string"},"conditionName":{"type":"string"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:32:00","status":"success","response":[{"conditionID":"1000","conditionName":"New"},{"conditionID":"1500","conditionName":"New other (see details)"},{"conditionID":"3000","conditionName":"Used"}]}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_getConditionList"}},"/product/getFulfillmentInfo":{"post":{"tags":["product"],"summary":"Get the fulfillment reference enums (party, ship-to locations, delivery-day buckets, handling time).","description":"Returns the allowed fulfillment values to use when creating or editing product groups: fulfillment party, ship-to locations (a large country/region list), delivery-day buckets, and handling time. Takes no request parameters. The response is an object with fulfillmentParty[], fulfillmentShipToLocation[], fulfillmentDeliveryDay[], and fulfillmentHandlingTime[] arrays. Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_get_fulfillment_info","requestBody":{"required":false,"content":{"none":{"schema":{"type":"object","properties":[],"description":"— reads no request parameters."},"example":[]}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"fulfillmentParty":{"type":"array","items":{"type":"string"}},"fulfillmentShipToLocation":{"type":"array","items":{"type":"string"}},"fulfillmentDeliveryDay":{"type":"array","items":{"type":"string"}},"fulfillmentHandlingTime":{"type":"array","items":{"type":"string"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:33:00","status":"success","response":{"fulfillmentParty":["viewider","supplier"],"fulfillmentShipToLocation":["APO/FPO","Afghanistan","Africa","Hong Kong","United States","World Wide"],"fulfillmentDeliveryDay":["1-3 days","4-10 days","11-20 days","21 days or above"],"fulfillmentHandlingTime":["day_1"]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_getFulfillmentInfo"}},"/product/getMeasurementInfo":{"post":{"tags":["product"],"summary":"Get the allowed weight-unit and length-unit enums.","description":"Returns the allowed weight and length units to use in product measurement fields. Takes no request parameters. The response is an object with weightUnit[] and lengthUnit[] arrays. Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_get_measurement_info","requestBody":{"required":false,"content":{"none":{"schema":{"type":"object","properties":[],"description":"— reads no request parameters."},"example":[]}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"weightUnit":{"type":"array","items":{"type":"string"}},"lengthUnit":{"type":"array","items":{"type":"string"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:34:00","status":"success","response":{"weightUnit":["kg","g","oz","lbs"],"lengthUnit":["mm","cm","m","inch"]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_getMeasurementInfo"}},"/product/editProductPrice":{"post":{"tags":["product"],"summary":"Update the selling price of one or more products in existing product groups (live write — revised prices are pushed to your connected marketplace listings).","description":"⚠️ **Production — not yet sandbox-testable.** This MUTATES live data: it changes real product prices and pushes the revised prices to the connected marketplace listings (eBay etc.) built from these products, including reseller listings sourced from your product groups. Requires a machine-token key that carries the `product:write` capability — keys on a read-only capability preset are refused with HTTP 403. From Test Request, only use it against your own account/test data.\n\nChanges sellingPrice for products that already belong to product groups you own (owner-scoped server-side; another account's productGroupID is reported as not found). Send a data[] array (form-encoded) of {productGroupID, products:[{productID, sellingPrice}]} objects. Ids must be plain ids — the internal \"~\"/\"+\" create/delete prefixes are rejected — and sellingPrice must be an absolute number greater than 0 (the internal relative syntax such as \"+5\" or \"-10%\" is rejected, and a price of 0 is rejected as missing). Note: for normal accounts a price DECREASE takes effect on Viewider sales records only after ~6 hours, and a second decrease inside that window is ignored. The response returns the updated productGroups[] plus successCount and failCount. Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_edit_product_price","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"productGroupID":{"type":"string","description":"Plain product-group id (no \"~\"/\"+\" prefix)."},"products":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string","description":"Plain product id (no \"~\"/\"+\" prefix)."},"sellingPrice":{"type":"string","description":"Absolute price greater than 0, as a plain decimal (e.g. \"34.99\"); no \"+\"/\"-\" prefix."}}}}}},"description":"Array of {productGroupID, products:[{productID, sellingPrice}]} objects. Each element requires a plain productGroupID and, per product, a plain productID (\"~\"/\"+\" create/delete prefixes are rejected) plus an absolute sellingPrice greater than 0 (relative \"+5\"/\"-10%\" syntax is rejected; a price of 0 is rejected as missing); only productID and sellingPrice are applied."}},"required":["data"]},"example":{"data":[{"productGroupID":"68590f1a2c4b9a0012ab34cf","products":[{"productID":"68590f1a2c4b9a0012ab34cd","sellingPrice":"34.99"},{"productID":"68590f1a2c4b9a0012ab34ce","sellingPrice":"34.99"}]}]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"productGroups":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string"},"sellingPrice":{"type":"number"},"inventory":{"type":"array","items":{"type":"object","properties":{"inventoryID":{"type":"string"},"remainQuantity":{"type":"integer"},"warehouseID":{"type":"string"},"safetyLine":{"type":"integer"},"additionalCost":{"type":"integer"}}}}}}},"productGroupID":{"type":"string"}}}},"failCount":{"type":"integer"},"successCount":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:35:20","status":"success","response":{"productGroups":[{"customLabel":"PG-DEMO-001","products":[{"productID":"68590f1a2c4b9a0012ab34cd","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ee","remainQuantity":100,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]},{"productID":"68590f1a2c4b9a0012ab34ce","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ef","remainQuantity":80,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]}],"productGroupID":"68590f1a2c4b9a0012ab34cf"}],"failCount":0,"successCount":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_editProductPrice","x-mcp-write":true}},"/product/editInventroy":{"post":{"tags":["product"],"summary":"Update inventory quantity for one or more of your inventory records (absolute value or +/- delta; live write — stock levels sync to your connected marketplace listings).","description":"⚠️ **Production — not yet sandbox-testable.** This MUTATES live data: quantity changes update your listings and, for Active listings with reset-stock enabled, push the new stock levels live to the connected marketplaces (eBay, Amazon etc.). Requires a machine-token key that carries the `product:write` capability — keys on a read-only capability preset are refused with HTTP 403. From Test Request, only use it against your own account/test data.\n\nAdjusts the remaining quantity of existing inventory records you own (owner-scoped server-side). Send a data[] array (form-encoded) of {inventoryID, remainQuantity} objects; remainQuantity may be an absolute integer or a delta string such as \"+5\" or \"-3\". The response groups the inventory ids into success[], fail[], and noChange[] arrays — noChange also absorbs unknown or not-owned inventoryIDs (no existence oracle) and Viewider-type inventory, so it is not distinguishable from an unchanged value. Note the path keeps the literal misspelling \"editInventroy\". Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_edit_inventory_quantity","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"inventoryID":{"type":"string"},"remainQuantity":{"type":"string"}}},"description":"Array of {inventoryID, remainQuantity} objects. Required; each element needs inventoryID and remainQuantity. remainQuantity may be an absolute integer or a delta string like \"+5\" or \"-3\". Unknown/not-owned ids and Viewider-type inventory are skipped into noChange[]; a negative resulting quantity is allowed but flagged."}},"required":["data"]},"example":{"data":[{"inventoryID":"68590f1a2c4b9a0012ab34ee","remainQuantity":"120"},{"inventoryID":"68590f1a2c4b9a0012ab34ef","remainQuantity":"-10"}]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"success":{"type":"array","items":{"type":"string"}},"fail":{"type":"array","items":[]},"noChange":{"type":"array","items":{"type":"string"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:36:40","status":"success","response":{"success":["68590f1a2c4b9a0012ab34ee"],"fail":[],"noChange":["68590f1a2c4b9a0012ab34ef"]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_editInventroy","x-mcp-write":true}},"/product/getProductGroupID":{"post":{"tags":["product"],"summary":"List your own active product-group ids and labels, paginated 100 per page.","description":"Returns a page of the calling account's own active product groups (100 per page). Send page as a 1-based integer. The response includes pageCount, the current page, and a productGroup[] array of {customLabel, productGroupID}. Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_list_my_product_groups","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"page":{"type":"integer","description":"1-based page number, 100 product groups per page. Required; must be a scalar integer."}},"required":["page"]},"example":{"page":1}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_getProductGroupID"}},"/product/getProductGroupForInventoryByID":{"post":{"tags":["product"],"summary":"Get full product, inventory, and warehouse detail for up to 50 product-group ids.","description":"Returns detailed product and inventory data for specific product groups owned by the calling account. Send productGroupID as an array of up to 50 product-group id strings. The response nests each group's products with their SKU and inventory records (country, location, zipCode, type, linked warehouse, remainQuantity, safetyLine, additionalCost). Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_get_product_groups","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"productGroupID":{"type":"array","description":"Array of product-group id strings to expand (max 50). Required; must be an array.","items":{"type":"string"}}},"required":["productGroupID"]},"example":{"productGroupID":["68590f1a2c4b9a0012ab34cf","68590f1a2c4b9a0012ab34d9"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"data":{"type":"object","properties":{"ProductGroups":{"type":"array","items":{"type":"object","properties":{"ProductGroup":{"type":"object","properties":{"ProductGroupID":{"type":"string"},"Products":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string"},"SKU":{"type":"string"},"inventory":{"type":"array","items":{"type":"object","properties":{"inventoryID":{"type":"string"},"country":{"type":"string"},"location":{"type":"string"},"zipCode":{"type":"string"},"type":{"type":"string"},"linkedViewiderWarehouse":{"type":"string"},"remainQuantity":{"type":"integer"},"safetyLine":{"type":"integer"},"additionalCost":{"type":"integer"}}}}}}}}}}}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:41:00","status":"success","response":{"pageCount":1,"page":1,"data":{"ProductGroups":[{"ProductGroup":{"ProductGroupID":"68590f1a2c4b9a0012ab34cf","Products":[{"productID":"68590f1a2c4b9a0012ab34cd","SKU":"PG-DEMO-001-BLK","inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ee","country":"China","location":"Shenzhen","zipCode":"518000","type":"virtual","linkedViewiderWarehouse":"VW-SZ-Main","remainQuantity":100,"safetyLine":0,"additionalCost":0}]}]}}]}}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_getProductGroupForInventoryByID"}},"/product/getProductGroupsForInventory":{"post":{"tags":["product"],"summary":"Export product, inventory, and warehouse detail for every active product group you own.","description":"Returns the same nested product and inventory data as /product/getProductGroupForInventoryByID, but across all active product groups owned by the calling account — no id list needed, which makes it suitable for a full inventory snapshot or export. Results are paginated at 100 product groups per page; read pageCount from the response and step page until you have every page. Each group's products carry their SKU and inventory records (country, location, zipCode, type, linked warehouse, remainQuantity, safetyLine, additionalCost). Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_export_inventory_snapshot","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"page":{"type":"integer","description":"Optional 1-based page number, 100 product groups per page. Default 1; values below 1 return a fail envelope."}}},"example":{"page":1}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"data":{"type":"object","properties":{"ProductGroups":{"type":"array","items":{"type":"object","properties":{"ProductGroup":{"type":"object","properties":{"ProductGroupID":{"type":"string"},"Products":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string"},"SKU":{"type":"string"},"inventory":{"type":"array","items":{"type":"object","properties":{"inventoryID":{"type":"string"},"country":{"type":"string"},"location":{"type":"string"},"zipCode":{"type":"string"},"type":{"type":"string"},"linkedViewiderWarehouse":{"type":"string"},"remainQuantity":{"type":"integer"},"safetyLine":{"type":"integer"},"additionalCost":{"type":"integer"}}}}}}}}}}}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:41:00","status":"success","response":{"pageCount":3,"page":1,"data":{"ProductGroups":[{"ProductGroup":{"ProductGroupID":"68590f1a2c4b9a0012ab34cf","Products":[{"productID":"68590f1a2c4b9a0012ab34cd","SKU":"PG-DEMO-001-BLK","inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ee","country":"China","location":"Shenzhen","zipCode":"518000","type":"virtual","linkedViewiderWarehouse":"VW-SZ-Main","remainQuantity":100,"safetyLine":0,"additionalCost":0}]}]}}]}}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_getProductGroupsForInventory"}},"/ViewiderListing/getAvailableSite":{"post":{"tags":["ViewiderListing"],"summary":"List the sites you can list to on Viewider.","description":"Returns the sites you can list to, each as an object with siteID, platform, country, and domain. Authenticate with your Bearer machine-token; the request body is ignored, so an empty POST is fine. The response is the standard JSON envelope — check the status field and read the site array from response.","x-mcp-tool":"viewider_get_available_sites","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[]},"example":[]}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string"},"country":{"type":"string"},"domain":{"type":"string"},"siteID":{"type":"integer"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:05:11","status":"success","response":[{"platform":"Viewider","country":"HK","domain":"yasuee.com.hk","siteID":20000000},{"platform":"eBay","country":"US","domain":"ebay.com","siteID":10000001}]}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"ViewiderListing_getAvailableSite"}},"/ViewiderListing/getPackage":{"post":{"tags":["ViewiderListing"],"summary":"List the account's active return/shipping package presets.","description":"Returns your active package presets (return and shipping config) for the Viewider site, each as an object with name and packageID. Authenticate with your Bearer machine-token; no request parameters are needed. Each packageID identifies a preset for use when updating a listing. The response is the standard JSON envelope — check the status field and read the package array from response.","x-mcp-tool":"viewider_get_my_packages","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[]},"example":[]}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"packageID":{"type":"string"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:06:02","status":"success","response":[{"name":"Standard 30-day Return","packageID":"6630a1f2e1b2c3d4e5f60001"},{"name":"No Return / Final Sale","packageID":"6630a1f2e1b2c3d4e5f60002"}]}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"ViewiderListing_getPackage"}},"/shipment/getShipmentLabelUrl":{"post":{"tags":["shipment"],"summary":"Get the shipping label (HTML) URL and PDF URL for one or more shipments.","description":"Returns the label page URL and label PDF URL for each requested shipment. Auth is mixed: send a valid session cookie AND username + password form fields. Post form-encoded with username, password, and shipmentID (a single shipment _id or an array of _ids). On the first request for a fresh shipment the PDF is generated on demand, so shipmentPdfUrl may be null if that generation fails. Every response is a JSON envelope returned with HTTP 200 — check the status field and read response.shipment[].","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"password":{"type":"string","description":"Account password. Required; a wrong or missing value returns \"Not registered Account\"."},"username":{"type":"string","description":"Account username. Required."},"shipmentID":{"type":"array","description":"A single shipment _id or an array of _ids. Required; a scalar is treated as a one-element array.","items":{"type":"string"}}},"required":["username","password","shipmentID"]},"example":{"username":"acme_seller","password":"s3cret","shipmentID":["BW58388196299860157781","BW58388196299860157782"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"shipment":{"type":"array","items":{"type":"object","properties":{"shipmentID":{"type":"string"},"shipmentLabelUrl":{"type":"string"},"shipmentPdfUrl":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:05:11","status":"success","response":{"shipment":[{"shipmentID":"BW58388196299860157781","shipmentLabelUrl":"https://viewider.com/labs/shipment/shipmentLabel?shipmentID=BW58388196299860157781","shipmentPdfUrl":"https://viewiderexport.v2.s3.amazonaws.com/shipment/BW58388196299860157781.pdf"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"shipment_getShipmentLabelUrl"}},"/shipment/getShipmentStatus":{"post":{"tags":["shipment"],"summary":"Get the current shipment status for one or more shipments.","description":"Returns the current status string (e.g. in_transit) for each requested shipment. Auth is mixed: send a valid session cookie AND username + password form fields. Post form-encoded with username, password, and shipmentID, which may be a single shipment _id or an array of _ids. The response is a JSON envelope returned with HTTP 200 — check the status field, then read response.shipment[] where each entry is {shipmentID, shipmentStatus}.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"password":{"type":"string","description":"Account password. Required; a wrong or missing value returns \"Not registered Account\"."},"username":{"type":"string","description":"Account username. Required."},"shipmentID":{"type":"string","description":"A single shipment _id or an array of _ids. Required; an empty value returns an \"Invalid Input\" error."}},"required":["username","password","shipmentID"]},"example":{"username":"acme_seller","password":"s3cret","shipmentID":"BW58388196299860157781"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"shipment":{"type":"array","items":{"type":"object","properties":{"shipmentID":{"type":"string"},"shipmentStatus":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:06:02","status":"success","response":{"shipment":[{"shipmentID":"BW58388196299860157781","shipmentStatus":"in_transit"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"shipment_getShipmentStatus"}},"/shipment/getShipmentCheckpoint":{"post":{"tags":["shipment"],"summary":"Get tracking checkpoints for one or more shipments.","description":"Returns the tracking checkpoint history (status, location, message and time) for each requested shipment. Auth is mixed: send a valid session cookie AND username + password form fields. Post form-encoded with username, password, and shipmentID (a single shipment _id or an array of _ids). Note that each checkpoint's location is polymorphic — usually a string, but an address object for externally-sourced courier checkpoints. The response is a JSON envelope returned with HTTP 200 — always check the status field.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"password":{"type":"string","description":"Account password. Required; a wrong or missing value returns \"Not registered Account\"."},"username":{"type":"string","description":"Account username. Required."},"shipmentID":{"type":"array","description":"A single shipment _id or an array of _ids. Required; an empty value returns an \"Invalid Input\" error.","items":{"type":"string"}}},"required":["username","password","shipmentID"]},"example":{"username":"acme_seller","password":"s3cret","shipmentID":["BW58388196299860157781"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":[]},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"shipment_getShipmentCheckpoint"}},"/shipment/createShipmentByPlatformTransactionID":{"post":{"tags":["shipment"],"summary":"Create B2B supplier shipments from platform order/transaction IDs.","description":"⚠️ **Production — not yet sandbox-testable.** Running this from Test Request performs a REAL transaction (real orders / payments / shipments — real money and fulfilment). Do not call it unless you intend a real action.\n\nCreates direct-line B2B (supplier) shipments for the given platform orders. Auth is mixed: send a valid session cookie AND username + password form fields. Post form-encoded with username, password, platform (e.g. eBay, Lazada, Shopee, Shopify, Gmarket, Gittigidiyor) and transactionID (a single platform transaction ID or an array); set viewiderStock=true to fulfil from Viewider-held inventory. The response is a JSON envelope (HTTP 200, check status) whose response splits results into createShipments.success/fail, validShipment[] (newly created) and invalidShipment[] (e.g. orders that already have a shipment).","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"username":{"type":"string","description":"Account username. Required."},"transactionID":{"type":"array","description":"A single platform transaction id or an array of ids. Required; a scalar is treated as a one-element array; an empty value is rejected.","items":{"type":"string"}},"platform":{"type":"string","description":"Platform name, e.g. eBay, Lazada, Shopee, Shopify, Gmarket, Gittigidiyor. Required; empty value is rejected."},"password":{"type":"string","description":"Account password. Required; a wrong or missing value returns \"Not registered Account\"."},"viewiderStock":{"type":"string","description":"Optional. Set to true (boolean or the string \"true\") to fulfil from Viewider-held inventory; any other or absent value uses the normal supplier flow."}},"required":["username","password","transactionID","platform"]},"example":{"username":"acme_seller","password":"s3cret","platform":"eBay","transactionID":["12-34567-89012","12-34567-89013"],"viewiderStock":"true"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"createShipments":{"type":"object","properties":{"success":{"type":"array","items":{"type":"string"}},"fail":{"type":"array","items":[]}}},"validShipment":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"shipmentStatus":{"type":"string"},"shipmentType":{"type":"string"},"warehousePickUp":{"type":"boolean"}}}},"invalidShipment":{"type":"array","items":{"type":"object","properties":{"error_msg":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:09:44","status":"success","response":{"createShipments":{"success":["BW58388196299860157781"],"fail":[]},"validShipment":[{"_id":"BW58388196299860157781","shipmentStatus":"pending","shipmentType":"directLineShipment","warehousePickUp":false}],"invalidShipment":[{"error_msg":"12-34567-89013: Shipment Already Exists.(shipmentID: BW58388196299860157780)"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"shipment_createShipmentByPlatformTransactionID"}},"/shipment/createCustomShipment":{"post":{"tags":["shipment"],"summary":"Create a custom direct-line shipment from a supplied data object.","description":"⚠️ **Production — not yet sandbox-testable.** Running this from Test Request performs a REAL transaction (real orders / payments / shipments — real money and fulfilment). Do not call it unless you intend a real action.\n\nCreates a single custom direct-line shipment from a caller-supplied payload (recipient, address, parcel and items). Auth is mixed: send a valid session cookie AND username + password form fields. Post form-encoded with username, password, and a data object holding the shipment fields; if data is omitted the top-level form fields are used as the shipment data instead. shipmentType is always forced to directLineShipment. The response is a JSON envelope (HTTP 200, check status) returning createShipments.success/fail plus validShipment[] for the created shipment.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"password":{"type":"string","description":"Account password. Required; a wrong or missing value returns \"Not registered Account\"."},"username":{"type":"string","description":"Account username. Required."},"data":{"type":"object","description":"Shipment payload object (recipientName, recipientAddress, recipientPhone, weight, items[] of {sku, qty, description}, etc.). If omitted, the top-level form fields are used as the shipment data instead. shipmentType is always forced to \"directLineShipment\".","properties":{"shipmentType":{"type":"string"},"recipientName":{"type":"string"},"recipientAddress":{"type":"string"},"recipientPhone":{"type":"string"},"weight":{"type":"number"},"items":{"type":"array","items":{"type":"object","properties":{"sku":{"type":"string"},"qty":{"type":"integer"},"description":{"type":"string"}}}}}}},"required":["username","password"]},"example":{"username":"acme_seller","password":"s3cret","data":{"shipmentType":"directLineShipment","recipientName":"John Doe","recipientAddress":"123 Main St, Kowloon, HK","recipientPhone":"+85291234567","weight":1.2,"items":[{"sku":"SKU-001","qty":2,"description":"T-Shirt"}]}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"createShipments":{"type":"object","properties":{"success":{"type":"array","items":{"type":"string"}},"fail":{"type":"array","items":[]}}},"validShipment":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"shipmentStatus":{"type":"string"},"shipmentType":{"type":"string"},"warehousePickUp":{"type":"boolean"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:11:09","status":"success","response":{"createShipments":{"success":["BW58388196299860157790"],"fail":[]},"validShipment":[{"_id":"BW58388196299860157790","shipmentStatus":"pending","shipmentType":"directLineShipment","warehousePickUp":false}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"shipment_createCustomShipment"}},"/transaction/getShippingService":{"post":{"tags":["transaction"],"summary":"List your available shipping services as an {id: name} map.","description":"Returns the shipping services you can use, keyed by service ID with the service name as the value. Authenticate with your Bearer machine-token; the request body is ignored, so an empty POST is fine. The response is the standard JSON envelope — check the status field and read the {id: name} map from response.","x-mcp-tool":"viewider_list_shipping_services","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[]},"example":[]}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"5f3a1c2b9e1d4a0012ab34cd":{"type":"string"},"5f3a1c2b9e1d4a0012ab34ce":{"type":"string"},"5f3a1c2b9e1d4a0012ab34cf":{"type":"string"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:05:11","status":"success","response":{"5f3a1c2b9e1d4a0012ab34cd":"Standard Air","5f3a1c2b9e1d4a0012ab34ce":"Economy Sea","5f3a1c2b9e1d4a0012ab34cf":"Express Courier"}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"transaction_getShippingService"}},"/transaction/getB2bTransaction":{"post":{"tags":["transaction"],"summary":"List B2B sales records where you are the supplier, paginated by date.","description":"Returns B2B sales records on which you are the supplier, filtered by transaction-created date and paginated 50 per page. Authenticate with your Bearer machine-token, and supply username and password (both required) plus an optional page (default 1) and startDate in 'YYYY-MM-DD HH:mm:ss' format (defaults to today). The response is the standard JSON envelope — check the status field, then read Total, Page, Count and the Transaction[] array from response.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"page":{"type":"integer","description":"Optional 1-based page number, 50 records per page; must be numeric. Default 1."},"username":{"type":"string","description":"Sub-account or main account username. Required."},"startDate":{"type":"string","description":"Optional filter on transactionCreatedDate >= startDate, format \"YYYY-MM-DD HH:mm:ss\". Defaults to today at 00:00:00."},"password":{"type":"string","description":"Account password. Required."}},"required":["username","password"]},"example":{"username":"supplier_acct","password":"s3cr3t","page":1,"startDate":"2026-06-01 00:00:00"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"Total":{"type":"integer"},"Page":{"type":"integer"},"Count":{"type":"integer"},"Transaction":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"isAcceptReturn":{"type":"boolean"},"additionReturnFee":{"type":"integer"},"packingFee":{"type":"number"},"PostalCode":{"type":"string"},"platformBuyer":{"type":"string"},"transactionPlatform":{"type":"string"},"platformTransactionID":{"type":"string"},"platformListingID":{"type":"string"},"SKUofProduct":{"type":"string"},"SKUofListing":{"type":"string"},"platformSellingPrice":{"type":"number"},"platformCurrency":{"type":"string"},"buyerAddress":{"type":"string"},"Token":{"type":"string"},"Phone":{"type":"string"},"transactionCreatedDate":{"type":"string"},"transactionPaidDate":{"type":"string"},"transactionSiteID":{"type":"integer"},"Quantity":{"type":"integer"},"productGroupID":{"type":"string"},"productID":{"type":"string"},"seller":{"type":"string"},"sellerUserID":{"type":"integer"},"supplier":{"type":"string"},"supplierUserID":{"type":"integer"},"SalesRecordStatus":{"type":"string"},"platformTitle":{"type":"string"},"variationID":{"type":"string"},"lastMileWarehouseID":{"type":"string"},"shippingCost":{"type":"number"},"shippingCompany":{"type":"string"},"shippingService":{"type":"string"},"Country":{"type":"string"},"fulfillmentMethod":{"type":"string"},"combineOrderID":{"type":"string"},"shipmentID":{"type":"string"},"barcodeUrl":{"type":"string"},"shippingLabelUrl":{"type":"string"},"confirmTransactionTime":{"type":"string"},"internalMarkShipTime":{"type":"string"},"warehouseReceivedTime":{"type":"string"},"warehouseMarkShipTime":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:07:42","status":"success","response":{"Total":1,"Page":1,"Count":1,"Transaction":[{"_id":"6650a1f29e1d4a0012ab9001","isAcceptReturn":true,"additionReturnFee":0,"packingFee":1.5,"PostalCode":"90001","platformBuyer":"buyer_john","transactionPlatform":"eBay","platformTransactionID":"11-12345-67890","platformListingID":"v1|123456789|0","SKUofProduct":"PRD-ABC","SKUofListing":"LST-ABC","platformSellingPrice":29.99,"platformCurrency":"USD","buyerAddress":"123 Main St","Token":"tok_abc","Phone":"+1-555-0100","transactionCreatedDate":"2026-06-20 08:31:00","transactionPaidDate":"2026-06-20 08:32:10","transactionSiteID":0,"Quantity":1,"productGroupID":"6650a1f29e1d4a0012ab8000","productID":"6650a1f29e1d4a0012ab8001","seller":"seller_shop","sellerUserID":3427,"supplier":"supplier_acct","supplierUserID":11691,"SalesRecordStatus":"Confirmed","platformTitle":"Widget Pro","variationID":"var-001","lastMileWarehouseID":"WH-US-1","shippingCost":4.2,"shippingCompany":"USPS","shippingService":"First Class","Country":"US","fulfillmentMethod":"FBA","combineOrderID":"CO-2026-0001","shipmentID":"SIA-0001","barcodeUrl":"https://viewiderpublicap.v2/barcode/SIA-0001.png","shippingLabelUrl":"https://viewiderpublicap.v2/label/SIA-0001.pdf","confirmTransactionTime":"2026-06-20 09:00:00","internalMarkShipTime":"2026-06-20 10:00:00","warehouseReceivedTime":"2026-06-21 02:00:00","warehouseMarkShipTime":"2026-06-21 06:00:00"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"transaction_getB2bTransaction"}},"/transaction/placeOrder.php":{"post":{"tags":["transaction"],"summary":"Place a combined B2B order against your own listings and create sales records.","description":"⚠️ **Production — not yet sandbox-testable.** Running this from Test Request performs a REAL transaction (real orders / payments / shipments — real money and fulfilment). Do not call it unless you intend a real action.\n\nPlaces a combined order against listings you own and returns the created sales records (salesRecordID, finalPrice, shipping fields, etc.). Authenticate with your Bearer machine-token and send a required data object holding the buyer address (Address, City, State, PostalCode, Phone, BuyerName), an externalTransactionID idempotency key (reusing one returns the existing order instead of re-ordering), and a ListingInfo[] array of { ListingID, variationID, Quantity, estimatePrice }; send data as nested form fields (e.g. data[ListingInfo][0][ListingID]=...). The response is the standard JSON envelope returning an array — note a line-level rejection (e.g. not the listing owner, price mismatch, insufficient stock) comes back as an array of { errReason } objects still under status success, so inspect each element's keys.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"Order payload object. Required. Holds the buyer address (Address, City, State, PostalCode, Phone, BuyerName), an externalTransactionID idempotency key (reusing one returns the existing order instead of re-ordering), and a ListingInfo[] array of {ListingID, variationID, Quantity, estimatePrice}. Send as nested form fields (e.g. data[ListingInfo][0][ListingID]=...), not a JSON string.","properties":{"Address":{"type":"string"},"City":{"type":"string"},"State":{"type":"string"},"PostalCode":{"type":"string"},"Phone":{"type":"string"},"BuyerName":{"type":"string"},"externalTransactionID":{"type":"string"},"ListingInfo":{"type":"array","items":{"type":"object","properties":{"ListingID":{"type":"string"},"variationID":{"type":"string"},"Quantity":{"type":"integer"},"estimatePrice":{"type":"number"}}}}}}},"required":["data"]},"example":{"data":{"Address":"123 Main St","City":"Los Angeles","State":"CA","PostalCode":"90001","Phone":"+1-555-0100","BuyerName":"John Buyer","externalTransactionID":"EXT-CO-2026-0001","ListingInfo":[{"ListingID":"6650a1f29e1d4a0012abc100","variationID":"var-001","Quantity":2,"estimatePrice":29.99}]}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"array","items":{"type":"object","properties":{"combineOrderID":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"PostalCode":{"type":"string"},"Phone":{"type":"string"},"title":{"type":"string"},"userRole":{"type":"string"},"externalTransactionID":{"type":"string"},"platformBuyer":{"type":"string"},"salesRecordID":{"type":"string"},"finalPrice":{"type":"number"},"quantity":{"type":"integer"},"Address":{"type":"string"},"status":{"type":"string"},"firstLegShippingCompany":{"type":"string"},"firstLegTracking":{"type":"string"},"lastMileShippingCompany":{"type":"string"},"lastMileTracking":{"type":"string"},"ListingID":{"type":"string"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:10:05","status":"success","response":[{"combineOrderID":"CO-2026-0001","city":"Los Angeles","state":"CA","PostalCode":"90001","Phone":"+1-555-0100","title":"Widget Pro","userRole":"supplier","externalTransactionID":"EXT-CO-2026-0001","platformBuyer":"John Buyer","salesRecordID":"6650a1f29e1d4a0012abd200","finalPrice":59.98,"quantity":2,"Address":"123 Main St","status":"Confirmed","firstLegShippingCompany":"Ship It Asia","firstLegTracking":"SIA-0001","lastMileShippingCompany":"","lastMileTracking":"","ListingID":"v1|123456789|0"}]}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"transaction_placeOrder"}},"/transaction/getOrder.php":{"post":{"tags":["transaction"],"summary":"List or look up your sell-side sales records, by ID or paginated.","description":"Returns the sales records on which you are the seller, either by ID or paginated 100 per page. Authenticate with your Bearer machine-token; with no IDs the call is paginated (page, default 1, optional startDate filter), or pass salesRecordID (array of record IDs) and/or combineOrderID (array matched against externalTransactionID) to fetch specific records. The response is the standard JSON envelope — check the status field, then read page, count, totalOrder (grand total) and the orders[] array from response.","x-mcp-tool":"viewider_list_my_orders","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"page":{"type":"integer","description":"Optional 1-based page number, 100 records per page; 0 becomes 1. Only applied when neither salesRecordID nor combineOrderID is supplied."},"salesRecordID":{"type":"array","items":[],"description":"Optional array of sales-record _id values to fetch specific records; a scalar also works. When both this and combineOrderID are absent, results are paginated instead."},"startDate":{"type":"string","description":"Optional filter on transactionCreatedDate >= startDate (string compare). Default: no date filter."},"combineOrderID":{"type":"array","items":[],"description":"Optional array of externalTransactionID values to fetch specific records. Note: despite the name, this filters on externalTransactionID, not the record's combineOrderID field."}}},"example":{"page":1,"startDate":"2026-06-01 00:00:00"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"page":{"type":"integer"},"count":{"type":"integer"},"totalOrder":{"type":"integer"},"orders":{"type":"array","items":{"type":"object","properties":{"combineOrderID":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"PostalCode":{"type":"string"},"Phone":{"type":"string"},"title":{"type":"string"},"userRole":{"type":"string"},"externalTransactionID":{"type":"string"},"platformBuyer":{"type":"string"},"variationID":{"type":"string"},"salesRecordID":{"type":"string"},"finalPrice":{"type":"number"},"quantity":{"type":"integer"},"Address":{"type":"string"},"status":{"type":"string"},"firstLegShippingCompany":{"type":"string"},"firstLegTracking":{"type":"string"},"lastMileShippingCompany":{"type":"string"},"lastMileTracking":{"type":"string"},"ListingID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:12:33","status":"success","response":{"page":1,"count":1,"totalOrder":1,"orders":[{"combineOrderID":"CO-2026-0001","city":"Los Angeles","state":"CA","PostalCode":"90001","Phone":"+1-555-0100","title":"Widget Pro","userRole":"seller","externalTransactionID":"EXT-CO-2026-0001","platformBuyer":"buyer_john","variationID":"var-001","salesRecordID":"6650a1f29e1d4a0012abd200","finalPrice":59.98,"quantity":2,"Address":"123 Main St","status":"Shipped","firstLegShippingCompany":"Ship It Asia","firstLegTracking":"SIA-0001","lastMileShippingCompany":"USPS","lastMileTracking":"9400111899223450000000","ListingID":"v1|123456789|0"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"transaction_getOrder"}},"/transaction/confirmAndPayOrder.php":{"post":{"tags":["transaction"],"summary":"Confirm and pay the given sales records, returning their updated rows.","description":"⚠️ **Production — not yet sandbox-testable.** Running this from Test Request performs a REAL transaction (real orders / payments / shipments — real money and fulfilment). Do not call it unless you intend a real action.\n\nConfirms (pays) the specified sales records and returns the updated rows for the ones you own. Authenticate with your Bearer machine-token and send a required salesRecordID array of record IDs. The response is the standard JSON envelope returning an array of the updated sales-record objects (salesRecordID, finalPrice, status, shipping fields, etc.) — check the status field before reading it.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"salesRecordID":{"type":"array","items":{"type":"string"},"description":"Array of sales-record _id values to confirm and pay. Required; must be an array. Only records you own are returned."}},"required":["salesRecordID"]},"example":{"salesRecordID":["6650a1f29e1d4a0012abd200","6650a1f29e1d4a0012abd201"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"array","items":{"type":"object","properties":{"combineOrderID":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"PostalCode":{"type":"string"},"Phone":{"type":"string"},"title":{"type":"string"},"userRole":{"type":"string"},"externalTransactionID":{"type":"string"},"platformBuyer":{"type":"string"},"variationID":{"type":"string"},"salesRecordID":{"type":"string"},"finalPrice":{"type":"number"},"quantity":{"type":"integer"},"Address":{"type":"string"},"status":{"type":"string"},"firstLegShippingCompany":{"type":"string"},"firstLegTracking":{"type":"string"},"lastMileShippingCompany":{"type":"string"},"lastMileTracking":{"type":"string"},"ListingID":{"type":"string"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:15:48","status":"success","response":[{"combineOrderID":"CO-2026-0001","city":"Los Angeles","state":"CA","PostalCode":"90001","Phone":"+1-555-0100","title":"Widget Pro","userRole":"seller","externalTransactionID":"EXT-CO-2026-0001","platformBuyer":"buyer_john","variationID":"var-001","salesRecordID":"6650a1f29e1d4a0012abd200","finalPrice":59.98,"quantity":2,"Address":"123 Main St","status":"Confirmed","firstLegShippingCompany":"Ship It Asia","firstLegTracking":"SIA-0001","lastMileShippingCompany":"","lastMileTracking":"","ListingID":"v1|123456789|0"}]}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"transaction_confirmAndPayOrder"}},"/sourcing/getStoreList.php":{"post":{"tags":["sourcing"],"summary":"List the authenticated user's active marketplace stores.","description":"Returns every active store on your account, each with its storeID, name, and logo URL. Authenticate with your Bearer machine-token; no request parameters are needed. The `response` field is an array of store objects. Every reply is a JSON envelope, so check the `status` field before reading `response`.","x-mcp-tool":"viewider_list_my_stores","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[]},"example":[]}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"logo":{"type":"string"},"storeID":{"type":"integer"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:05:11","status":"success","response":[{"name":"Acme Outlet","logo":"https://viewiderpublicap.v2.s3.amazonaws.com/store/logo/7.png","storeID":7},{"name":"Gadget Hub","logo":"https://viewiderpublicap.v2.s3.amazonaws.com/store/logo/12.png","storeID":12}]}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"sourcing_getStoreList"}},"/sourcing/getViewiderListingInfo.php":{"post":{"tags":["sourcing"],"summary":"List a store's active Viewider listings with category, site, and inventory detail.","description":"Returns the active Viewider-platform listings for one store, enriched with category name, supported marketplace site names, and per-variation inventory (country, location, remaining quantity). Authenticate with your Bearer machine-token and send `storeID` (required); add `page` to paginate, 50 listings per page. The `response` object holds the listings array. Every reply is a JSON envelope, so check the `status` field first.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"page":{"type":"integer","description":"Optional 1-based page number, 50 listings per page; must be numeric. Default 1."},"access_token":{"type":"string","description":"Optional in-body bearer token (legacy alternative to the Authorization header)."},"storeID":{"type":"integer","description":"Store/seller userID to list Viewider listings for. Required; must be numeric. Note: filters on the listing's userID, not Store._id, despite the name."}},"required":["storeID"]},"example":{"access_token":"eyJ2ZXJzaW9uX2lkIjoi...","storeID":7,"page":1}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"listings":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"customLabel":{"type":"string"},"categoryID":{"type":"string"},"images":{"type":"array","items":{"type":"string"}},"productSpecific":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}}}},"conditionDescription":{"type":"string"},"supportPlatform":{"type":"array","items":{"type":"string"}},"productGroupID":{"type":"string"},"platformListingID":{"type":"string"},"additionReturnFee":{"type":"integer"},"isAcceptReturn":{"type":"boolean"},"platformUrl":{"type":"string"},"country":{"type":"string"},"location":{"type":"string"},"reservePrice":{"type":"integer"},"quantity":{"type":"integer"},"variations":{"type":"array","items":{"type":"object","properties":{"currency":{"type":"string"},"depth":{"type":"integer"},"EAN":{"type":"string"},"height":{"type":"integer"},"images":{"type":"array","items":{"type":"string"}},"ISBN":{"type":"string"},"lengthUnit":{"type":"string"},"price":{"type":"number"},"productID":{"type":"string"},"status":{"type":"string"},"UPC":{"type":"string"},"variationAttribute":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}}}},"weight":{"type":"integer"},"weightUnit":{"type":"string"},"deleted":{"type":"boolean"},"width":{"type":"integer"},"inventoryInfo":{"type":"array","items":{"type":"object","properties":{"additionalCost":{"type":"integer"},"productGroupID":{"type":"string"},"productID":{"type":"string"},"warehouseID":{"type":"string"},"type":{"type":"string"},"remainQuantity":{"type":"integer"},"country":{"type":"string"},"location":{"type":"string"}}}},"sku":{"type":"string"}}}},"CategoryName":{"type":"string"},"ListingID":{"type":"string"},"storeID":{"type":"integer"},"createTime":{"type":"string"}}}},"count":{"type":"integer"},"page":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:07:02","status":"success","response":{"listings":[{"title":"Stainless Steel Water Bottle 750ml","customLabel":"WB-750-SS","categoryID":"3z9k2","images":["https://viewiderpublicap.v2.s3.amazonaws.com/img/abc1.jpg"],"productSpecific":[{"name":"Brand","value":"Acme"}],"conditionDescription":"","supportPlatform":["eBay US","eBay UK"],"productGroupID":"PG10231","platformListingID":"","additionReturnFee":0,"isAcceptReturn":true,"platformUrl":"","country":"US","location":"California","reservePrice":0,"quantity":120,"variations":[{"currency":"USD","depth":5,"EAN":"","height":25,"images":["https://viewiderpublicap.v2.s3.amazonaws.com/img/abc1.jpg"],"ISBN":"","lengthUnit":"cm","price":19.99,"productID":"P55001","status":"Active","UPC":"012345678905","variationAttribute":[{"name":"Color","value":"Silver"}],"weight":350,"weightUnit":"g","deleted":false,"width":7,"inventoryInfo":[{"additionalCost":0,"productGroupID":"PG10231","productID":"P55001","warehouseID":"WH-US-1","type":"Self","remainQuantity":120,"country":"US","location":"California"}],"sku":"WB-750-SS"}],"CategoryName":"Drinkware","ListingID":"5gkib76up6r2xt6fp","storeID":7,"createTime":"2026-06-01 09:30:00"}],"count":1,"page":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"sourcing_getViewiderListingInfo"}},"/sourcing/addCartAndCheckOut.php":{"post":{"tags":["sourcing"],"summary":"Add up to 50 Viewider listings to the cart and check them out in one call.","description":"⚠️ **Production — not yet sandbox-testable.** Running this from Test Request performs a REAL transaction (real orders / payments / shipments — real money and fulfilment). Do not call it unless you intend a real action.\n\nAdds the given listings to your marketplace cart and immediately checks them out, returning each listing sorted into CheckOutSuccessed, CheckOutFail, or CannotAddToCart. Authenticate with your Bearer machine-token and send a `data[]` array of `{ListingID, isAcceptReturn}` objects (max 50), form-encoded as nested array fields (e.g. `data[0][ListingID]`). Every reply is a JSON envelope, so check the `status` field before reading the result buckets.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Optional in-body bearer token (legacy alternative to the Authorization header)."},"data":{"type":"array","items":{"type":"object","properties":{"ListingID":{"type":"string"},"isAcceptReturn":{"type":"boolean"}}},"description":"Array of {ListingID, isAcceptReturn} objects (max 50). Required. Send form-encoded as nested array fields (e.g. data[0][ListingID]=...&data[0][isAcceptReturn]=1), not a JSON string."}},"required":["data"]},"example":{"access_token":"eyJ2ZXJzaW9uX2lkIjoi...","data":[{"ListingID":"5gkib76up6r2xt6fp","isAcceptReturn":true},{"ListingID":"9hk2mq0za1bcd","isAcceptReturn":false}]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"CheckOutSuccessed":{"type":"array","items":{"type":"object","properties":{"listingID":{"type":"string"},"isAcceptReturn":{"type":"boolean"}}}},"CheckOutFail":{"type":"array","items":{"type":"object","properties":{"listingID":{"type":"string"},"isAcceptReturn":{"type":"boolean"}}}},"CannotAddToCart":{"type":"array","items":[]}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:10:44","status":"success","response":{"CheckOutSuccessed":[{"listingID":"5gkib76up6r2xt6fp","isAcceptReturn":true}],"CheckOutFail":[{"listingID":"9hk2mq0za1bcd","isAcceptReturn":false}],"CannotAddToCart":[]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"sourcing_addCartAndCheckOut"}},"/sourcing/CreateViewdierAPIListings.php":{"post":{"tags":["sourcing"],"summary":"Bulk-create ViewiderAPI listings from product groups for a single site.","description":"⚠️ **Production — not yet sandbox-testable.** This creates or modifies real data. From Test Request, only use it against your own account/test data.\n\nCreates ViewiderAPI listings from your product groups (max 50 per call, all sharing one siteID). The call is idempotent: product groups that already have a listing are returned as-is rather than duplicated. Authenticate with your Bearer machine-token and send a `data[]` array of `{ProductGroupID, siteID}` objects, form-encoded as nested array fields. The `response` object returns `success` (created/existing listing details) and `fail` (product groups that could not be created, each with an error message); every reply is a JSON envelope, so check `status` first.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Optional in-body bearer token (legacy alternative to the Authorization header)."},"data":{"type":"array","items":{"type":"object","properties":{"ProductGroupID":{"type":"string"},"siteID":{"type":"integer"}}},"description":"Array of {ProductGroupID, siteID} objects (max 50). Required. All elements must share one siteID, which must reference a site whose platform is \"ViewiderAPI\". Send as a nested form array, not a JSON string."}},"required":["data"]},"example":{"access_token":"eyJ2ZXJzaW9uX2lkIjoi...","data":[{"ProductGroupID":"PG10231","siteID":99000001},{"ProductGroupID":"PG10232","siteID":99000001}]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"success":{"type":"array","items":{"type":"object","properties":{"productGroupID":{"type":"string"},"title":{"type":"string"},"images":{"type":"array","items":{"type":"string"}},"listingStatus":{"type":"string"},"variations":{"type":"array","items":{"type":"object","properties":{"variationID":{"type":"string"},"UPC":{"type":"string"},"EAN":{"type":"string"},"ISBN":{"type":"string"},"quantity":{"type":"integer"},"images":{"type":"array","items":{"type":"string"}},"width":{"type":"integer"},"height":{"type":"integer"},"weightUnit":{"type":"string"},"lengthUnit":{"type":"string"},"price":{"type":"number"},"domesticFulfillmentServiceID":{"type":"string"},"breakevenPrice":{"type":"object","properties":{"viewiderFee":{"type":"number"},"shippingCost":{"type":"number"},"AdditionalShippingCost":{"type":"integer"},"isAcceptReturnCost":{"type":"number"},"breakevenPrice":{"type":"number"}}}}}},"ListingID":{"type":"string"},"htmlBody":{"type":"string"}}}},"fail":{"type":"array","items":{"type":"object","properties":{"ProductGroupID":{"type":"string"},"siteID":{"type":"integer"},"errMsg":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:14:09","status":"success","response":{"success":[{"productGroupID":"PG10231","title":"Stainless Steel Water Bottle 750ml","images":["https://viewiderpublicap.v2.s3.amazonaws.com/img/abc1.jpg"],"listingStatus":"Active","variations":[{"variationID":"V1","UPC":"012345678905","EAN":"","ISBN":"","quantity":120,"images":["https://viewiderpublicap.v2.s3.amazonaws.com/img/abc1.jpg"],"width":7,"height":25,"weightUnit":"g","lengthUnit":"cm","price":19.99,"domesticFulfillmentServiceID":"FS-US-STD","breakevenPrice":{"viewiderFee":1.2,"shippingCost":3.5,"AdditionalShippingCost":0,"isAcceptReturnCost":0.4,"breakevenPrice":5.1}}],"ListingID":"5gkib76up6r2xt6fp","htmlBody":"<div>Product description...</div>"}],"fail":[{"ProductGroupID":"PG10232","siteID":99000001,"errMsg":"versionID not found"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"sourcing_CreateViewdierAPIListings"}},"/sourcing/getListingInfo.php":{"post":{"tags":["sourcing"],"summary":"Fetch full detail for a specific set of your listings by ID.","description":"Returns full listing detail (title, images, htmlBody, per-variation breakeven price) for the listing IDs you supply. Authenticate with your Bearer machine-token and send a `listingID[]` array of ID strings (max 100). Results are scoped to your own listings, so unknown or unauthorized IDs are simply omitted from `response.success` (`response.fail` is always empty). Every reply is a JSON envelope, so check the `status` field first.","x-mcp-tool":"viewider_get_listing_info","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"Optional in-body bearer token (legacy alternative to the Authorization header)."},"listingID":{"type":"array","items":{"type":"string"},"description":"Array of listing _id strings (max 100). Required. Scoped to your own listings; unknown or unauthorized ids are omitted from the result."}},"required":["listingID"]},"example":{"access_token":"eyJ2ZXJzaW9uX2lkIjoi...","listingID":["5gkib76up6r2xt6fp","9hk2mq0za1bcd"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"success":{"type":"array","items":{"type":"object","properties":{"productGroupID":{"type":"string"},"title":{"type":"string"},"images":{"type":"array","items":{"type":"string"}},"listingStatus":{"type":"string"},"variations":{"type":"array","items":{"type":"object","properties":{"variationID":{"type":"string"},"UPC":{"type":"string"},"EAN":{"type":"string"},"ISBN":{"type":"string"},"quantity":{"type":"integer"},"images":{"type":"array","items":{"type":"string"}},"width":{"type":"integer"},"height":{"type":"integer"},"weightUnit":{"type":"string"},"lengthUnit":{"type":"string"},"price":{"type":"number"},"variationAttribute":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}}}},"domesticFulfillmentServiceID":{"type":"string"},"breakevenPrice":{"type":"object","properties":{"viewiderFee":{"type":"number"},"shippingCost":{"type":"number"},"AdditionalShippingCost":{"type":"integer"},"isAcceptReturnCost":{"type":"number"},"breakevenPrice":{"type":"number"}}}}}},"ListingID":{"type":"string"},"lastUpdateTime":{"type":"string"},"htmlBody":{"type":"string"}}}},"fail":{"type":"array","items":[]}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:18:30","status":"success","response":{"success":[{"productGroupID":"PG10231","title":"Stainless Steel Water Bottle 750ml","images":["https://viewiderpublicap.v2.s3.amazonaws.com/img/abc1.jpg"],"listingStatus":"Active","variations":[{"variationID":"V1","UPC":"012345678905","EAN":"","ISBN":"","quantity":120,"images":["https://viewiderpublicap.v2.s3.amazonaws.com/img/abc1.jpg"],"width":7,"height":25,"weightUnit":"g","lengthUnit":"cm","price":19.99,"variationAttribute":[{"name":"Color","value":"Silver"}],"domesticFulfillmentServiceID":"FS-US-STD","breakevenPrice":{"viewiderFee":1.2,"shippingCost":3.5,"AdditionalShippingCost":0,"isAcceptReturnCost":0.4,"breakevenPrice":5.1}}],"ListingID":"5gkib76up6r2xt6fp","lastUpdateTime":"2026-06-20 11:02:00","htmlBody":"<div>Product description...</div>"}],"fail":[]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"sourcing_getListingInfo"}},"/sourcing/getSelfViewdierAPIListings.php":{"post":{"tags":["sourcing"],"summary":"List your own active ViewiderAPI listings for a site.","description":"Returns the authenticated user's active ViewiderAPI listings for one site, with full variation and breakeven-price detail. Authenticate with your Bearer machine-token and send `siteID` (required); add `page` to paginate, 200 listings per page. The `response` object returns `success` (the listings), an always-empty `fail`, and `Page` echoing the current page. Every reply is a JSON envelope, so check the `status` field first.","x-mcp-tool":"viewider_list_my_listings_by_site","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"page":{"type":"integer","description":"Optional 1-based page number, 200 listings per page; honored only if numeric and > 0. Default 1."},"access_token":{"type":"string","description":"Optional in-body bearer token (legacy alternative to the Authorization header)."},"siteID":{"type":"integer","description":"Site _id to filter your own listings by. Required; cast to int."}},"required":["siteID"]},"example":{"access_token":"eyJ2ZXJzaW9uX2lkIjoi...","siteID":99000001,"page":1}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"success":{"type":"array","items":{"type":"object","properties":{"productGroupID":{"type":"string"},"title":{"type":"string"},"images":{"type":"array","items":{"type":"string"}},"listingStatus":{"type":"string"},"variations":{"type":"array","items":{"type":"object","properties":{"variationID":{"type":"string"},"UPC":{"type":"string"},"EAN":{"type":"string"},"ISBN":{"type":"string"},"quantity":{"type":"integer"},"images":{"type":"array","items":{"type":"string"}},"width":{"type":"integer"},"height":{"type":"integer"},"weightUnit":{"type":"string"},"lengthUnit":{"type":"string"},"price":{"type":"number"},"variationAttribute":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}}}},"domesticFulfillmentServiceID":{"type":"string"},"breakevenPrice":{"type":"object","properties":{"viewiderFee":{"type":"number"},"shippingCost":{"type":"number"},"AdditionalShippingCost":{"type":"integer"},"isAcceptReturnCost":{"type":"number"},"breakevenPrice":{"type":"number"}}}}}},"ListingID":{"type":"string"},"lastUpdateTime":{"type":"string"},"htmlBody":{"type":"string"}}}},"fail":{"type":"array","items":[]},"Page":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:22:55","status":"success","response":{"success":[{"productGroupID":"PG10231","title":"Stainless Steel Water Bottle 750ml","images":["https://viewiderpublicap.v2.s3.amazonaws.com/img/abc1.jpg"],"listingStatus":"Active","variations":[{"variationID":"V1","UPC":"012345678905","EAN":"","ISBN":"","quantity":120,"images":["https://viewiderpublicap.v2.s3.amazonaws.com/img/abc1.jpg"],"width":7,"height":25,"weightUnit":"g","lengthUnit":"cm","price":19.99,"variationAttribute":[{"name":"Color","value":"Silver"}],"domesticFulfillmentServiceID":"FS-US-STD","breakevenPrice":{"viewiderFee":1.2,"shippingCost":3.5,"AdditionalShippingCost":0,"isAcceptReturnCost":0.4,"breakevenPrice":5.1}}],"ListingID":"5gkib76up6r2xt6fp","lastUpdateTime":"2026-06-20 11:02:00","htmlBody":"<div>Product description...</div>"}],"fail":[],"Page":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"sourcing_getSelfViewdierAPIListings"}},"/sourcing/getProductGroupsCheckedOut.php":{"post":{"tags":["sourcing"],"summary":"List the product groups you have already checked out.","description":"Returns your checked-out cart entries (the items marked Proceed by addCartAndCheckOut), each as `{productGroupID, isAcceptReturn}`. Authenticate with your Bearer machine-token; pass `page` to paginate, 200 entries per page. Here `response` is a flat array of entries (not a success/fail object). Every reply is a JSON envelope, so check the `status` field before reading `response`.","x-mcp-tool":"viewider_list_checked_out_product_groups","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"page":{"type":"integer","description":"Optional 1-based page number, 200 entries per page; honored only if numeric and > 0. Default 1."},"access_token":{"type":"string","description":"Optional in-body bearer token (legacy alternative to the Authorization header)."}}},"example":{"access_token":"eyJ2ZXJzaW9uX2lkIjoi...","page":1}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"array","items":{"type":"object","properties":{"isAcceptReturn":{"type":"boolean"},"productGroupID":{"type":"string"}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:25:10","status":"success","response":[{"isAcceptReturn":true,"productGroupID":"PG10231"},{"isAcceptReturn":false,"productGroupID":"PG10232"}]}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"sourcing_getProductGroupsCheckedOut"}},"/searchProducts":{"post":{"tags":["product"],"summary":"Search the authenticated merchant's own product catalog by keyword (SKU/customLabel substring + product title), owner-scoped, with paging.","description":"Search the authenticated merchant's own product catalog by keyword (SKU/customLabel substring + product title), owner-scoped, with paging.","x-mcp-tool":"viewider_search_products","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"keyword":{"type":"string","description":"search term matched against SKU/customLabel substring and product title n-grams"},"page":{"type":"integer","description":"1-based page number"},"showCount":{"type":"integer","description":"page size"}},"required":["keyword"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/listProductsFiltered":{"post":{"tags":["product"],"summary":"List the authenticated merchant's own products with filters and paging, owner-scoped; optionally include the facet filter set.","description":"List the authenticated merchant's own products with filters and paging, owner-scoped; optionally include the facet filter set.","x-mcp-tool":"viewider_list_products_filtered","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"filters":{"type":"object","description":"products-page filter map (category[], location[], priceRange{minPrice,maxPrice}, stock, variation, dateRange, searchText)"},"page":{"type":"integer","description":"1-based page number"},"showCount":{"type":"integer","description":"page size"},"includeFacets":{"type":"boolean","description":"also return the cached facet filter object"},"getCache":{"type":"boolean","description":"use the per-user facet cache when includeFacets=true"}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/getProductVersions":{"post":{"tags":["product"],"summary":"Get the per-site ProductGroupVersion documents for one or more of the authenticated merchant's own product groups, owner-scoped (fail-closed on non-owned IDs).","description":"Get the per-site ProductGroupVersion documents for one or more of the authenticated merchant's own product groups, owner-scoped (fail-closed on non-owned IDs).","x-mcp-tool":"viewider_get_product_versions","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"productGroupIDs":{"type":"array","description":"product group id(s) to fetch versions for","items":{"type":"string"}},"options":{"type":"object","description":"Mongo find options e.g. {projection:{...}, sort:{timestamp:-1}}"}},"required":["productGroupIDs"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/sourcing/searchListings":{"post":{"tags":["listing"],"summary":"Search and list your own listings with structured filters, pagination and sort.","description":"Search and list your own listings with structured filters, pagination and sort.","x-mcp-tool":"viewider_search_listings","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"filter":{"type":"object","description":"structured listing filter — supports platform / listingStatus / site / token keys plus inline search syntax (e.g. platform:eBay status:Active) and title n-gram keyword. The userID key is ignored: results are always scoped to your own (main) account."},"page":{"type":"integer","description":"1-based page number. Default 1."},"pageSize":{"type":"integer","description":"rows per page, 1-200 (hard-capped at 200). Default 50."},"sort":{"type":"object","description":"Mongo-style sort, e.g. {\"timestamp\": -1}."},"includeCartWishlist":{"type":"boolean","description":"include Cart/Wishlist lookup fields. Default false (lite)."},"access_token":{"type":"string","description":"in-body bearer token (legacy alternative to the Authorization header)."}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/sourcing/getListingDetail":{"post":{"tags":["listing"],"summary":"Fetch full detail for a specific set of your listings by ID.","description":"Fetch full detail for a specific set of your listings by ID.","x-mcp-tool":"viewider_get_listing_detail","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"listingID":{"type":"array","description":"listing _id strings, max 100. Results are scoped to your own (main) account; unknown or unauthorized ids are returned in response.fail, never leaked.","items":{"type":"string"}},"includeCartWishlist":{"type":"boolean","description":"include Cart/Wishlist lookup fields. Default false (lite)."},"access_token":{"type":"string","description":"in-body bearer token (legacy alternative to the Authorization header)."}},"required":["listingID"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/listSellerSalesRecords":{"post":{"tags":["order"],"summary":"List the authenticated merchant's own sell-side sales records / orders with filter, page/pageSize pagination, total count, and a clean REST envelope (rows, totalCount, page, pageSize, is_sub_account, session_user). Buyer data masked. Force owner-scoped (sellerUserID = main account).","description":"List the authenticated merchant's own sell-side sales records / orders with filter, page/pageSize pagination, total count, and a clean REST envelope (rows, totalCount, page, pageSize, is_sub_account, session_user). Buyer data masked. Force owner-scoped (sellerUserID = main account).","x-mcp-tool":"viewider_list_seller_sales_records","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"filter":{"type":"object","description":"SR filter map (status, platform, date range, etc); sellerUserID is force-set server-side regardless of input"},"page":{"type":"integer","description":"page (int, optional, default 1)"},"pageSize":{"type":"integer","description":"pageSize (int, optional, default 50, max 200)"},"sort":{"type":"object","description":"sort (object, optional)"}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/listPlatformTransactions":{"post":{"tags":["order"],"summary":"List the authenticated merchant's own marketplace order/transaction rows for one platform (order-based for order-item-base platforms), with type counts (markShipped / warehouseReceived / cancel) and skip/limit pagination. Non-B2B only, force owner-scoped.","description":"List the authenticated merchant's own marketplace order/transaction rows for one platform (order-based for order-item-base platforms), with type counts (markShipped / warehouseReceived / cancel) and skip/limit pagination. Non-B2B only, force owner-scoped.","x-mcp-tool":"viewider_list_platform_transactions","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"platform":{"type":"string","description":"eBay | Shopee | Lazada | Shopify | Qoo10 | Gittigidiyor | Gmarket | Kgroup"},"filter":{"type":"object","description":"UI filter map (timestamp range, status, etc); owner-scope keys (userID/sellerUserID/supplierUserID/token/eBayToken/shopid) are stripped server-side"},"skip":{"type":"integer","description":"skip (int, optional, default 0)"},"limit":{"type":"integer","description":"limit (int, optional, default 100, max 200)"},"sort":{"type":"object","description":"e.g. {\"timestamp\": -1}"}},"required":["platform"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/exportPlatformTransactions":{"post":{"tags":["order"],"summary":"Export the authenticated merchant's own platform order/transaction rows matching a filter to an Excel file; returns a download URL. Owner-scoped, non-B2B. Generates a download artifact (does not mutate order data).","description":"Export the authenticated merchant's own platform order/transaction rows matching a filter to an Excel file; returns a download URL. Owner-scoped, non-B2B. Generates a download artifact (does not mutate order data).","x-mcp-tool":"viewider_export_platform_transactions","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"platform":{"type":"string","description":"eBay | Shopee | Lazada | Shopify | Qoo10 | Gittigidiyor | Gmarket | Kgroup"},"filter":{"type":"object","description":"UI filter map; owner-scope keys (userID/sellerUserID/supplierUserID/token/eBayToken/shopid) are stripped server-side"}},"required":["platform"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/listInventoryRecords":{"post":{"tags":["inventory"],"summary":"List the authenticated merchant's own inventory records (owner-scoped) with remaining/ship/available quantity, cost, safetyLine, additionalCost and warehouse. Paginated, 100/page.","description":"Owner-scoped to the caller core account (Mongo Inventory). A client-supplied userID is never honoured; unresolved owner returns empty.","x-mcp-tool":"viewider_list_inventory_records","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"page":{"type":"integer","description":"1-based page, default 1, 100 per page"},"inventoryID":{"type":"string","description":"optional: restrict to specific inventory record id(s), still owner-scoped"},"productID":{"type":"integer","description":"optional: restrict to a single product inventory, still owner-scoped"}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/searchInventoryItems":{"post":{"tags":["inventory"],"summary":"Search the authenticated merchant's own inventory by SKU (default) or product title, owner-scoped; returns enriched rows (SKU/title/price/cost/remaining quantity/warehouse). Paginated, 50/page.","description":"Owner-scoped to the caller core account via the live warehouse inventory search (Mongo, indexed). A client-supplied userID is never honoured and the cross-seller 'viewider' warehouse mode is never enabled — results are always the caller's own stock (a sub-account sees the main account's inventory). An empty keyword lists the caller's own inventory (paginated). SKU/title are joined from the product (the Mongo Inventory collection itself carries no SKU/title).","x-mcp-tool":"viewider_search_inventory_items","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"keyword":{"type":"string","description":"search term (optional). Matched against the chosen searchField. Empty -> list own inventory."},"searchField":{"type":"string","enum":["sku","title","productID"],"description":"field to search, default sku. sku = indexed SKU/legacySKU match; title = product title; productID = exact product id."},"page":{"type":"integer","description":"1-based page, default 1, 50 per page"},"warehouseID":{"type":"string","description":"optional: restrict to one warehouse, still owner-scoped"}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-25 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"page":{"type":"integer"},"pageSize":{"type":"integer"},"hasMore":{"type":"boolean"},"searchField":{"type":"string"},"keyword":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"inventoryID":{"type":"string"},"ownerID":{"type":"integer"},"productID":{"type":"string"},"productGroupID":{"type":"string"},"warehouseID":{"type":"string"},"remainQuantity":{"type":"integer"},"shipQuantity":{"type":"integer"},"variationCustomLabel":{"type":"string"},"title":{"type":"string"},"price":{"type":"number"},"cost":{"type":"number"},"upc":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-25 14:39:30","status":"success","response":{"page":1,"pageSize":50,"hasMore":false,"searchField":"sku","keyword":"940267-600","data":[{"inventoryID":"56dc85126bd61224dabfa","ownerID":548,"variationCustomLabel":"940267-600_US7.5","title":"Nike Men Air Jordan Fly'89 Sport Shoe","remainQuantity":0,"warehouseID":"dc741f1e811224f1775"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/getStockHistory":{"post":{"tags":["inventory"],"summary":"Get the stock-change history (who / when / quantity-diff / cost / sourcePrice) for one of the authenticated merchant's own inventory records, owner-scoped (fail-closed on non-owned ids).","description":"Owner-scoped: the caller must own the inventory record (verified against the Mongo Inventory document's ownerID) before any history is returned; a non-owned or unknown inventoryID returns owned:false with an empty list. Backed by the InventoryRemark change log (FIX-409), which is mainly populated for viewider-warehouse inventory — a record with no remarks legitimately returns an empty history.","x-mcp-tool":"viewider_get_stock_history","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["inventoryID"],"properties":{"inventoryID":{"type":"string","description":"the inventory record id (from searchInventoryItems / listInventoryRecords). Must belong to the caller."},"limit":{"type":"integer","description":"max history rows, default 50, max 200"}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-25 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"owned":{"type":"boolean","description":"false if the inventoryID is not owned by the caller (history then empty)"},"inventoryID":{"type":"string"},"count":{"type":"integer"},"data":{"type":"array","items":{"type":"object","properties":{"userID":{"type":"integer","description":"id of the user who made the change"},"userName":{"type":"string"},"createTime":{"type":"number","description":"epoch milliseconds"},"remainQuantity":{"type":"string"},"remainQuantityDiff":{"type":"integer"},"cost":{"type":"number"},"sourcePrice":{"type":"number"},"message":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-25 14:39:30","status":"success","response":{"owned":true,"inventoryID":"6b44688ng01jxg0h","count":1,"data":[{"userID":1057,"userName":"rainie@viewider.com","createTime":1782274061790,"remainQuantity":"2","remainQuantityDiff":1,"cost":116,"sourcePrice":108.97,"message":""}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/listShipments":{"post":{"tags":["shipment"],"summary":"List or count the authenticated merchant's own shipments with an optional Mongo-style filter, capped pagination (limit ≤ 500), sort and projection, plus a countOnly mode. Force owner-scoped: every query is AND-wrapped server-side with your (main) account's userID/payUserID, so a caller-supplied filter can never widen scope.","description":"List or count the authenticated merchant's own shipments with an optional Mongo-style filter, capped pagination (limit ≤ 500), sort and projection, plus a countOnly mode. Force owner-scoped: every query is AND-wrapped server-side with your (main) account's userID/payUserID, so a caller-supplied filter can never widen scope.","x-mcp-tool":"viewider_list_shipments","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"filter":{"type":"object","description":"Mongo-style filter map over shipment fields (e.g. status, shipmentType, trackingNumber, date range). Owner scope is force-applied server-side regardless of input, so userID/payUserID keys cannot widen scope. A top-level $where key is rejected."},"options":{"type":"object","properties":{"limit":{"type":"integer","description":"Rows per page (default 100, max 500; out-of-range values reset to 100)."},"skip":{"type":"integer","description":"Rows to skip (≥ 0) for pagination."},"sort":{"type":"object","description":"Mongo sort map, e.g. {\"createTime\": -1}."},"projection":{"type":"object","description":"Mongo projection map to trim the returned shipment fields."}},"description":"Query options. Only limit, skip, sort and projection are honoured; every other key is ignored."},"countOnly":{"type":"boolean","description":"Send 1 to return only the total matching count (response becomes {count}) instead of shipment rows."}}},"example":{"filter":{"status":2},"options":{"limit":50,"skip":0,"sort":{"createTime":-1}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-03 11:20:45"},"status":{"const":"success"},"response":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","description":"Shipment document (fields vary by shipment type; use options.projection to trim)."},"description":"Shipment documents for this page. Absent in countOnly mode."},"count":{"type":"integer","description":"List mode: number of rows returned in this page. countOnly mode: total matching shipments."}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-03 11:20:45","status":"success","response":{"data":[{"_id":"68652f1a2c4b9a0012ab34aa","trackingNumber":"VW1234567890HK","status":2,"shipmentType":"directLineShipment","createTime":"2026-06-28 09:14:02"}],"count":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"listShipments"}},"/quoteShippingCost":{"post":{"tags":["shipment"],"summary":"Quote the shipping cost for a parcel against Viewider's global shipping rate card — a pure read-only calculation (no shipment is created and no tenant data is read). Provide country, shippingID and weights; optional weightUnit/dimension/productPrice/categoryID/zipcode refine the quote, and detail=1 returns the full fee breakdown instead of the scalar total. Costs are quoted in USD. List valid shippingID values via /transaction/getShippingService.","description":"Quote the shipping cost for a parcel against Viewider's global shipping rate card — a pure read-only calculation (no shipment is created and no tenant data is read). Provide country, shippingID and weights; optional weightUnit/dimension/productPrice/categoryID/zipcode refine the quote, and detail=1 returns the full fee breakdown instead of the scalar total. Costs are quoted in USD. List valid shippingID values via /transaction/getShippingService.","x-mcp-tool":"viewider_quote_shipping_cost","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"country":{"type":"string","description":"Destination country name (e.g. \"United States\") or a numeric siteID (auto-converted server-side)."},"shippingID":{"type":"string","description":"Shipping service id to quote; list the available ids via /transaction/getShippingService."},"weights":{"type":"number","description":"Parcel weight, in weightUnit units."},"weightUnit":{"type":"string","description":"Weight unit (default \"g\")."},"dimension":{"type":"object","properties":{"length":{"type":"number"},"height":{"type":"number"},"depth":{"type":"number"},"lengthUnit":{"type":"string"}},"description":"Parcel dimensions; enables dimensional/oversize surcharges."},"productPrice":{"type":"number","description":"Declared product value; enables value-based surcharges."},"categoryID":{"type":"integer","description":"Viewider category id; applies category-specific additional handling fees."},"zipcode":{"type":"string","description":"Destination postal code; needed for zoned services to quote accurately."},"detail":{"type":"boolean","description":"Send 1 to get the full fee-breakdown object instead of the scalar cost."}},"required":["country","shippingID","weights"]},"example":{"country":"United States","shippingID":"5638217ac456e076d89","weights":450,"weightUnit":"g","zipcode":"90001"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-03 11:20:45"},"status":{"const":"success"},"response":{"type":"object","properties":{"cost":{"type":["number","string"],"description":"Scalar mode (detail unset) only: total quoted cost in USD. For unknown/unsupported inputs this is a STRING error reason (e.g. \"Invalid Service ID\") instead of a number — always type-check before using it."},"serviceID":{"type":"string","description":"detail=1 only."},"shippingWeight":{"description":"detail=1 only: chargeable weight used for the quote."},"shippingCost":{"type":"number","description":"detail=1 only."},"shippingExtraFee":{"type":"number","description":"detail=1 only."},"extraPriceCharge":{"type":"number","description":"detail=1 only."},"warehouseHandlingFee":{"type":"number","description":"detail=1 only (per-unit; multiply by product quantity)."},"additionalHandlingFee":{"type":"number","description":"detail=1 only: category-specific additional handling fee."},"pondWeightExtraPrice":{"type":"number","description":"detail=1 only."},"currency":{"type":"string","description":"detail=1 only: always \"USD\"."},"totalAmount":{"type":["number","string"],"description":"detail=1 only: grand total including additionalHandlingFee. Like cost, this is a STRING error reason (e.g. \"Invalid Service Type\") for unknown/unsupported inputs."},"shippingFullTrack":{"type":"object","description":"detail=1 only: per-leg fee objects {firstLeg, lastMile} for full-track services."}},"description":"Scalar mode (default) returns {cost}; detail=1 returns the fee-breakdown fields instead. cost/totalAmount can be a string error reason for unknown/unsupported inputs — always check the type."}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-03 11:22:10","status":"success","response":{"cost":15.42}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"quoteShippingCost"}},"/platform/getEbayShippingOptions":{"post":{"tags":["listing"],"summary":"Read eBay global shipping reference catalogs for building listing shipping policies","description":"Returns eBay global shipping reference data in one call: shipping services, local/international services, handling times, shipping locations, exclusion locations, return-policy details, and buyer-requirement details. These are global (non-owner-scoped) reference catalogs used to construct listing shipping policies; no per-account data is exposed. Callable with a machine token carrying the listing read capability.","operationId":"getEbayShippingOptions","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"siteID":{"type":"integer","description":"Optional eBay numeric site id; scopes the shipping-service and international-service catalogs to that site."},"shortForm":{"type":"string","description":"Optional short-form location code to scope the exclusion-locations catalog."}},"required":[]}}}},"responses":{"200":{"description":"Combined eBay shipping reference catalogs","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_ebay_shipping_options"}},"/getProductPriceSuggestion":{"post":{"tags":["product"],"summary":"Read the stored price-suggestion result for one of your product groups","description":"Returns the stored price-suggestion finding result (comparable-market shopping items) for one of the caller's own product groups on a given site. The query is owner-scoped: the userID filter is forced to the authenticated account, so another merchant's productGroupID returns no rows. Callable with a machine token carrying the product read capability.","operationId":"getProductPriceSuggestion","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"productGroupID":{"type":"string","description":"The product group id to read the price suggestion for; must belong to your account."},"siteID":{"type":"integer","description":"The numeric site id the price suggestion was computed for."},"withItemSpec":{"type":"boolean","description":"Optional; when true, include item-specifics detail in the returned comparable items."}},"required":["productGroupID","siteID"]}}}},"responses":{"200":{"description":"The stored price-suggestion finding result","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_product_price_suggestion"}},"/utility/geocodeAddress":{"post":{"tags":["shipment"],"summary":"Resolve an address or zipcode into geo coordinates and location components","description":"Resolves a free-form address or zipcode into geo coordinates and location components (city, state, country, postal code) via Google Geocoding. This is a global reference lookup that reads no owner-scoped data and performs no mutation. Callable with a machine token carrying the product read capability. Provide at least one of address or zipcode.","operationId":"geocodeAddress","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"address":{"type":"string","description":"Free-form address to geocode; either address or zipcode is required."},"zipcode":{"type":"string","description":"Postal code to bias/filter the geocode result; either address or zipcode is required."},"country":{"type":"string","description":"Optional country component filter to narrow the geocode result."},"with_raw":{"type":"boolean","description":"Optional; when true, include the raw Google Geocoding response alongside the parsed components."}},"required":[]}}}},"responses":{"200":{"description":"Geo coordinates and parsed location components","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_geocode_address"}},"/listDownloadFiles":{"post":{"tags":["product"],"summary":"List your own downloadable export files","description":"Returns the list of the caller's own downloadable export files stored in the S3 export bucket (name, uri, LastModified, Size). Strictly owner-scoped: the S3 listing is prefixed to the caller's own /<userID>/ folder, so no other account's files are ever returned. Machine-token safe (identity derived solely from the authenticated session, no web-login shape required); takes no parameters.","operationId":"listDownloadFiles","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[],"required":[]}}}},"responses":{"200":{"description":"The caller's own downloadable export files","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_list_download_files"}},"/getListingShippingFees":{"post":{"tags":["shipment"],"summary":"Get min/max shipping cost for a marketplace listing","description":"Returns the minimum and maximum shipping cost for a publicly-browseable marketplace listing (buyer landed-cost preview), quoted over the global rate card for the given ship-to day and destination. This is a cross-seller public storefront read (any active listing can be quoted) and returns only {min,max} shipping cost, never seller PII. Machine-token compatible; requires listingID plus a filter object with day and shipto (shipfrom optional).","operationId":"getListingShippingFees","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"listingID":{"type":"string","description":"Marketplace listing id (Listings _id) to quote shipping for"},"filter":{"type":"object","description":"Shipping quote parameters","properties":{"day":{"type":"string","description":"Ship-out day/lead-time key used to select the rate window (required)"},"shipto":{"type":"string","description":"Destination the parcel ships to, e.g. country/site (required)"},"shipfrom":{"type":"string","description":"Origin the parcel ships from (optional)"}},"required":["day","shipto"]}},"required":["listingID","filter"]}}}},"responses":{"200":{"description":"Min/max shipping cost for the listing","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_listing_shipping_fees"}},"/listMyDebitNotes":{"post":{"tags":["order"],"summary":"List your own B2B supplier debit notes","description":"Returns the authenticated merchant's own B2B supplier debit notes (statements of amounts the merchant owes as a supplier), paginated, with a total count. Strictly owner-scoped: the backing service force-sets supplierUserID to the calling account and ignores any caller-supplied user id, so another supplier's statements can never be read. Machine-token compatible; accepts optional limit (default 50, max 200) and 1-based page (default 1).","operationId":"listMyDebitNotes","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"limit":{"type":"integer","description":"Page size, 1-200, defaults to 50 (values out of range are clamped)"},"page":{"type":"integer","description":"1-based page number, defaults to 1"}},"required":[]}}}},"responses":{"200":{"description":"Paginated debit notes with total count","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_list_my_debit_notes"}},"/marketplace/getMarketplaceDepartments":{"post":{"tags":["listing"],"summary":"Get the marketplace department and category tree","description":"Returns the global marketplace department-to-category tree with per-category active-listing counts, used to build storefront browse navigation. This is global reference data served from a shared Redis cache (the same tree for every caller, not owner-scoped). Machine-token compatible and takes no parameters; the expensive real-time re-aggregation path is disabled for external callers so results always come from cache.","operationId":"getMarketplaceDepartments","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[],"required":[]}}}},"responses":{"200":{"description":"Department to category tree with active-listing counts","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_marketplace_departments"}},"/getJobStatus":{"post":{"tags":["order"],"summary":"Poll the status of a background job you enqueued","description":"Returns the current status, progress, exit code and any error of a background job identified by its process id. Scoped to the calling account: you can only poll jobs that you (or your main account) enqueued, never another tenant's jobs. Works with machine-token API keys carrying the order:read capability.","operationId":"getJobStatus","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"processId":{"type":"integer","description":"The numeric background-job / process id to poll (must be a positive integer). Either processId or tid is required."},"tid":{"type":"integer","description":"Alias for processId; the numeric job id to poll. Used only when processId is not supplied."}},"required":[]}}}},"responses":{"200":{"description":"Job status envelope","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_job_status"}},"/order/countPlatformTransactions":{"post":{"tags":["order"],"summary":"Count your platform orders by status and type","description":"Returns per-status/type buckets plus a derived total count of your own orders on a given selling platform (eBay, Shopee, Lazada, Shopify, Qoo10, etc). Scoped to the calling account: only your own orders are counted, and any owner-scope keys supplied in the filter are stripped and re-applied server-side. Works with machine-token API keys carrying the order:read capability.","operationId":"countPlatformTransactions","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"platform":{"type":"string","description":"Selling platform to count orders for, e.g. eBay | Shopee | Lazada | Shopify | Qoo10 | Gittigidiyor | Gmarket | Kgroup (required)."},"filter":{"type":"object","description":"Optional order filter map (timestamp range / status etc); owner-scope keys are stripped server-side."}},"required":["platform"]}}}},"responses":{"200":{"description":"Owner-scoped platform order counts","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_count_platform_transactions"}},"/marketplace/getMySupplierStore":{"post":{"tags":["marketplace"],"summary":"Get your own B2B supplier store profile","description":"Returns the authenticated merchant's own supplier store profile (store name, logo, address and contact) used for B2B storefront discovery. Scoped to the calling account: the store is resolved from your session-derived main account id, so you can never read another supplier's store. Works with machine-token API keys carrying the product:read capability.","operationId":"getMySupplierStore","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[],"required":[]}}}},"responses":{"200":{"description":"The caller's supplier store profile","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_my_supplier_store"}},"/sourcing/getAutoSourcingConfig":{"post":{"tags":["sourcing"],"summary":"Get your auto-sourcing engine configuration","description":"Returns the calling merchant's own auto-sourcing engine configuration (sourcing suppliers, category mappings, fulfillment and shipping settings). Scoped to the calling account: the config is keyed by your session-derived main account id and fails closed to empty for any other tenant. Works with machine-token API keys carrying the product:read capability.","operationId":"getAutoSourcingConfig","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[],"required":[]}}}},"responses":{"200":{"description":"The caller's auto-sourcing configuration","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_auto_sourcing_config"}},"/catalog/suggestCategory":{"post":{"tags":["product"],"summary":"Suggest matching categories for a product title or keyword","description":"Given a product title or keyword, returns suggested leaf categories mapped to canonical Viewider categories via an eBay category-suggestion lookup. Backed by global reference data (category mapping tables) and does not read or scope any per-account rows, so results are the same for every caller. Machine-token safe: works with a readonly product:read key.","operationId":"suggestCategory","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"cate":{"type":"string","description":"Product title or keyword to look up (primary key the handler reads)."},"keyword":{"type":"string","description":"Convenience alias for cate; used only when cate is absent."},"site":{"type":"string","description":"Marketplace site for the lookup; whitelisted to 0 (US) or 100 (motors). Optional."}},"required":[]}}}},"responses":{"200":{"description":"Suggested categories with canonical Viewider category mapping.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_suggest_category"}},"/inventory/exportInventoryReport":{"post":{"tags":["inventory"],"summary":"Export your own inventory to a downloadable xlsx report","description":"Exports the calling account's own inventory (optionally scoped to one warehouse, with filter and option maps) and returns an xlsx download descriptor. Owner-scoped and fail-closed: any caller-supplied userID is stripped and the export is forced to the authenticated account, so you only ever export your own inventory. Machine-token safe with a readonly product:read key; this endpoint downloads (never emails) the report and mutates nothing.","operationId":"exportInventoryReport","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"warehouseID":{"type":"string","description":"Optional warehouse id to scope the export to a single warehouse; empty = all warehouses."},"filter":{"type":"object","description":"Optional inventory filter map applied to the export."},"options":{"type":"object","description":"Optional export option map (e.g. column/format options)."}},"required":[]}}}},"responses":{"200":{"description":"xlsx download descriptor for the caller's inventory report.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_export_inventory_report"}},"/transaction/getPlatformTransactionFilters":{"post":{"tags":["order"],"summary":"Get order-list filter reference data for your account","description":"Returns the reference data used to build the order/transaction filter UI: the global site list, the calling account's own platform transaction identifiers, and LITE-masked token details (type, identifier, display_name). Owner-scoped: platform identifiers and token details are derived from the authenticated account only, never a caller-supplied id. Machine-token safe with a readonly order:read key; takes no parameters.","operationId":"getPlatformTransactionFilters","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[],"required":[]}}}},"responses":{"200":{"description":"Filter init data: sites, platformTransactionIdentifiers, tokenDetails.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_platform_transaction_filters"}},"/sourcing/getSourcingQuota":{"post":{"tags":["sourcing"],"summary":"Get your B2B sourcing quota, usage, and remaining","description":"Returns the calling merchant's B2B sourcing quota as {quota, used, remaining}: the plan quota limit, the used count (proceeded carts), and remaining allowance. Owner-scoped fail-closed: both the limit and usage are resolved from the authenticated account's core id, never a caller-supplied userID. Machine-token safe with a readonly product:read key; takes no parameters.","operationId":"getSourcingQuota","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[],"required":[]}}}},"responses":{"200":{"description":"Sourcing quota object: quota, used, remaining.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_sourcing_quota"}},"/catalog/suggestProductTags":{"post":{"tags":["product"],"summary":"Suggest keyword tags for a product title and category","description":"Returns suggested keyword tags derived from a product title plus category id, filtered by the merchant's own tag blacklist/whitelist. Tagging is owner-scoped: the merchant identity is taken from the authenticated session, never from caller input, and only the caller's own TagBlackList/TagWhiteList entries are applied. Callable with a machine token carrying the product:read capability.","operationId":"suggestProductTags","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Product title to derive keyword tags from (required)"},"cateID":{"type":"string","description":"Category id the product belongs to (required)"}},"required":["title","cateID"]}}}},"responses":{"200":{"description":"Suggested tags result","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_suggest_product_tags"}},"/getPopularItems":{"post":{"tags":["marketplace"],"summary":"Get popular marketplace storefront items","description":"Returns a curated top item plus a chunked list of popular active marketplace listings for the public storefront. This is global storefront reference data across all stores, not tenant-scoped; the authenticated user's own id is used only to gate whether min/max price is shown, and is never taken from caller input. Callable with a machine token carrying the listing:read capability.","operationId":"getPopularMarketplaceItems","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"sortField":{"type":"string","description":"Sort field, one of timestamp/minPrice/maxPrice/quantity (optional, default timestamp)"},"sortDir":{"type":"integer","description":"Sort direction: >=0 maps to ascending (1), otherwise descending (-1) (optional, default -1)"},"getCache":{"type":"boolean","description":"Whether to serve from cache (optional, default true)"}},"required":[]}}}},"responses":{"200":{"description":"Curated top item plus chunked popular listings","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_popular_marketplace_items"}},"/research/searchCompetitorProducts":{"post":{"tags":["sourcing"],"summary":"Search competitor products on external marketplaces by keyword","description":"Searches external marketplaces (eBay Browse API) by keyword and returns competing product listings shaped like shopping-API items, for product research. Touches no owner/tenant data — it is a live external lookup only. Callable with a machine token carrying the product:read capability.","operationId":"searchCompetitorProducts","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"keywords":{"type":"string","description":"Search keywords (required; the legacy 'keyword' key is accepted as a fallback)"},"keyword":{"type":"string","description":"Legacy single-keyword fallback, used only when 'keywords' is empty (optional)"},"index":{"type":"integer","description":"Zero-based paging offset into the result set (optional, default 0)"},"userLocation":{"type":"string","description":"Buyer location hint to bias marketplace results (optional)"}},"required":["keywords"]}}}},"responses":{"200":{"description":"Competitor product listings from the external marketplace","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_search_competitor_products"}},"/suggestSellingPrice":{"post":{"tags":["product"],"summary":"Suggest a marketplace selling price from a cost/price range","description":"Computes a suggested marketplace selling price (single value or a range) for a given cost/price using the global exchange-rate and marketplace/PayPal fee tables. Returns one Viewider site quote when siteID is given, otherwise quotes across all sites. This is a pure fee/FX calculation over global reference data with no tenant rows read; TokenName only selects a fee account level from the caller's own token (owner-restricted), and the endpoint is machine-token compatible.","operationId":"suggestSellingPrice","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"priceMin":{"type":"number","description":"Required. Cost/price lower bound, must be a positive number."},"priceMax":{"type":"number","description":"Optional. Cost/price upper bound; when provided a suggested price range is produced."},"siteID":{"type":"integer","description":"Optional Viewider site id. When provided, quote a single site; when omitted, quote all sites."},"vwFeeType":{"type":"string","description":"Optional fee type selector (e.g. creditcard). Defaults to 'creditcard'."},"TokenName":{"type":"string","description":"Optional token name selecting a fee account level from the caller's own token (owner-restricted)."}},"required":["priceMin"]}}}},"responses":{"200":{"description":"Suggested selling price / range","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_suggest_selling_price"}},"/product/getCategoryAttributes":{"post":{"tags":["product"],"summary":"Get item-specific attribute definitions for platform categories","description":"Returns the attribute / item-specific field definitions for one or more platform categories on a given site, so a product form knows which specifics to collect. Category taxonomy is global reference data queried by {site, category ids}, so there is no owner scope and nothing cross-tenant is exposed. The endpoint is machine-token compatible.","operationId":"getCategoryAttributes","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"site":{"type":"integer","description":"Required numeric site id whose category taxonomy to query."},"ids":{"type":"array","items":{"type":"string"},"description":"Required. A single category id or an array of category ids to fetch definitions for."},"with_attrs":{"type":"boolean","description":"Optional. Include item-specific attribute definitions. Defaults to true."},"viewiderAttrLang":{"type":"string","description":"Optional attribute language short code (e.g. en / zh). Defaults to 'en'."}},"required":["site","ids"]}}}},"responses":{"200":{"description":"Category attribute definitions with count","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_category_attributes"}},"/marketplace/getMarketplaceCart":{"post":{"tags":["marketplace"],"summary":"List your active B2B marketplace cart items","description":"Returns the caller's own active B2B marketplace cart items with a total count, paginated. Results are owner-scoped to the authenticated account, and pageSize is hard-capped at 100 per page. The endpoint is machine-token compatible.","operationId":"getMarketplaceCart","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"page":{"type":"integer","description":"Optional 1-based page number. Defaults to 1."},"pageSize":{"type":"integer","description":"Optional page size, 1-100 (defaults to 20, hard-capped at 100)."}},"required":[]}}}},"responses":{"200":{"description":"Paginated cart items with total count","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_marketplace_cart"}},"/marketplace/listMyCreditNotes":{"post":{"tags":["order"],"summary":"List your own credit notes (seller credits/refunds owed)","description":"Returns a paginated envelope of the calling merchant's own credit notes (seller credits or refunds owed), with a total count and the credit-note rows. Owner-scoped: the backing service force-sets SellerUserID to the authenticated account, so any caller-supplied user id is ignored and you only ever see your own credit notes. Machine-token safe — no interactive web-login session shape is required.","operationId":"listMyCreditNotes","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"limit":{"type":"integer","description":"Page size; optional numeric, defaults to 50, clamped to 1-200."},"page":{"type":"integer","description":"1-based page number; optional numeric, defaults to 1 (minimum 1)."}},"required":[]}}}},"responses":{"200":{"description":"Success envelope wrapping { count, data[] } of the caller's own credit notes.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_list_my_credit_notes"}},"/marketplace/browseMarketplaceListings":{"post":{"tags":["marketplace"],"summary":"Browse the public B2B wholesale marketplace listing grid","description":"Returns a paginated, filterable envelope ({rows, totalCount, page, pageSize}) of the public cross-supplier B2B wholesale marketplace storefront — listings from other suppliers that a merchant can discover to resell. These rows are global public reference data, not owner-scoped; the session user is resolved only to personalise cart/wishlist flags. Machine-token safe — the token's session passes the public dispatch. pageSize is capped at 100 internally, and server-side JavaScript ($where) in the filter is rejected.","operationId":"browseMarketplaceListings","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"filter":{"type":"object","description":"Optional structured filter object for the marketplace grid; must be an object. $where is rejected."},"options":{"type":"object","description":"Optional query options object (e.g. page/pageSize/sort); must be an object. pageSize is capped at 100 internally."}},"required":[]}}}},"responses":{"200":{"description":"Success envelope wrapping { rows, totalCount, page, pageSize } of marketplace listings.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_browse_marketplace_listings"}},"/marketplace/getWishlist":{"post":{"tags":["marketplace"],"summary":"List your saved/bookmarked marketplace listings (Wishlist)","description":"Returns the calling merchant's own saved/bookmarked marketplace listings (Wishlist), optionally narrowed to a set of listing IDs, with offset/limit pagination. Owner-scoped: the wishlist belongs to the authenticated account, so you only ever see your own saved listings. Machine-token safe — no interactive web-login session shape is required.","operationId":"getWishlist","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"listingIDs":{"type":"array","items":{"type":"string"},"description":"Optional array of listing IDs to filter the wishlist to; must be an array. Omit to return the whole wishlist."},"offset":{"type":"integer","description":"Pagination offset; optional numeric, defaults to 0 (floored at 0)."},"limit":{"type":"integer","description":"Page size; optional numeric, defaults to 25, clamped to 1-200."}},"required":[]}}}},"responses":{"200":{"description":"Success envelope wrapping the caller's own wishlisted marketplace listings.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_list_wishlist"}},"/getResearchHistory":{"post":{"tags":["sourcing"],"summary":"List your own product-research keyword history","description":"Returns the caller's own product-research keyword search history (paginated), newest first. Owner-scoped fail-closed: the backing service derives the owner id itself from the authenticated session and every query is a prepared statement scoped WHERE UserID = ? — no caller-supplied user id is read. Machine-token safe (identity taken from the session's core user id, not access-token data).","operationId":"getResearchHistory","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"limit":{"type":"integer","description":"Page size; must be numeric. Clamped to 1-500, defaults to 50 when omitted."},"offset":{"type":"integer","description":"Pagination offset; must be numeric and >= 0. Defaults to none when omitted."},"requireCount":{"type":"boolean","description":"When truthy, also compute and return the total count of history rows."}}}}}},"responses":{"200":{"description":"Success envelope containing the caller's research-history rows and optional count","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_research_history"}},"/order/listSupplierSalesRecords":{"post":{"tags":["order"],"summary":"List or count the caller's own supplier sales records (orders to fulfil as a supplier)","description":"Returns the sales records the authenticated merchant must fulfil in the role of a supplier (the B2B supplier order queue). Owner-scoped fail-closed: supplierUserID is force-overwritten to the caller's core account server-side, so any caller-supplied supplierUserID in filter is clobbered and cannot widen scope. Requires a FIX-314 machine token carrying the order:read capability; readonly-preset keys pass, but a missing capability is refused with HTTP 403 before parsing.","operationId":"listSupplierSalesRecords","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"filter":{"type":"object","description":"Mongo-style supplier sales record filter (status/date range etc). Owner scope is server-enforced (supplierUserID is ignored/overwritten); top-level or nested $where is rejected."},"options":{"type":"object","description":"Query options; only limit/skip/sort/projection are honored, other keys are ignored.","properties":{"limit":{"type":"integer","description":"Page size, default 100, capped at 500 (out-of-range resets to 100)."},"skip":{"type":"integer","description":"Pagination skip, coerced to >= 0."},"sort":{"type":"object","description":"Mongo sort map, e.g. {timestamp:-1}."},"projection":{"type":"object","description":"Mongo projection map to trim returned fields."}}},"countOnly":{"type":"boolean","description":"When truthy, returns only {count} total instead of the record rows."}}}}}},"responses":{"200":{"description":"Success envelope wrapping either {data,count} rows or {count} total.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_list_supplier_sales_records"}},"/listLinkedAccounts":{"post":{"tags":["marketplace"],"summary":"List the caller's own linked platform accounts, grouped by platform","description":"Returns the linked marketplace/platform accounts that belong to the authenticated caller, grouped by platform type (e.g. eBay, Shopee, Lazada), emitting only per-platform identifiers / display names — never any access token, refresh token, or secret material. Owner-scoped and fail-closed: the caller's own system user id is derived server-side from the session, never accepted from the request, so an unresolvable owner returns an empty result and no cross-tenant data is exposed. Requires a machine-token key carrying the product:read capability; readonly-preset keys are accepted.","operationId":"listLinkedAccounts","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"platform":{"type":"string","description":"Optional platform type name (e.g. \"eBay\", \"Shopee\") to narrow the result to a single platform; must be a scalar string. Omit or leave empty to return all linked platforms."}}}}}},"responses":{"200":{"description":"Linked platform accounts grouped by platform","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_list_linked_accounts"}},"/marketplace/listMarketplaceStores":{"post":{"tags":["marketplace"],"summary":"List active marketplace supplier stores (public directory)","description":"Returns the global public directory of active supplier stores on the marketplace, projected to public directory fields only (storeID/name/logo/description/listing counts) with seller PII stripped. This is a global-by-design directory, NOT owner-scoped — every caller sees the same active-store listing. Callable with a read-only machine-token key carrying the listing:read capability. Supports pagination and optional Mongo-shape filter/option narrowers over the public directory.","operationId":"listMarketplaceStores","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"chunkResult":{"type":"integer","description":"Chunk the result into arrays of this size; 0 (default) = flat list."},"limit":{"type":"integer","description":"Page size (1-500; values outside range are clamped to 100). Omit for backend default."},"page":{"type":"integer","description":"1-based page number. Omit for backend default."},"filter":{"type":"object","description":"Optional Mongo-shape filter object narrowing the public directory (cannot widen scope)."},"option":{"type":"object","description":"Optional Mongo-shape query option object (e.g. sort/projection over the public directory)."}},"required":[]}}}},"responses":{"200":{"description":"Public store directory page","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_list_marketplace_stores"}},"/getExchangeRate":{"post":{"tags":["transaction"],"summary":"Get currency exchange rates for cross-border price conversion","description":"Returns global exchange-rate reference data. If both source and target site ids are supplied, returns a per-target conversion rate map; otherwise returns the latest raw exchange-rate row (optionally resolving a currency name for the given siteid). This is shared global reference data with no owner-scoping, and is accessible with a read-only machine token.","operationId":"getExchangeRate","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"source":{"type":"string","description":"Source eBay site id(s) as a comma-separated integer list (e.g. \"0\" or \"0,2,15\"). Provide together with target to get a source→target conversion rate map. Non-integer tokens are dropped."},"target":{"type":"string","description":"Target eBay site id(s) as a comma-separated integer list. Provide together with source to get the conversion rate map. Non-integer tokens are dropped."},"siteid":{"type":"string","description":"Site id(s) as a comma-separated integer list, used to resolve the currency name for the latest raw exchange-rate row when source/target are not both supplied. Non-integer tokens are dropped."}}}}}},"responses":{"200":{"description":"Exchange-rate data envelope","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_exchange_rate"}},"/marketplace/addToCart":{"post":{"tags":["marketplace"],"summary":"Add active B2B/VW-marketplace listings to the caller's own sourcing cart","description":"⚠️ WRITE — inserts one or more active B2B/VW-marketplace listings into the CALLER'S OWN sourcing cart. Owner-scoping: the cart row owner is stamped server-side from the authenticated session user (CartCommand.php:117 unconditionally overwrites Cart.userID with the session-derived main user id) — a foreign userID/ownerID in the body is inert and never persisted. Insert-only upsert on self's cart via internal CQRS; requires the listing:write (LISTING_WRITE) capability. No external marketplace push / no external side-effect.","operationId":"marketplaceAddToCart","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","minItems":1,"maxItems":50,"description":"Listings to add to the caller's own cart (max 50 per call).","items":{"type":"object","required":["listingID"],"properties":{"listingID":{"type":"string","description":"Scalar marketplace listing id (Mongo operator objects rejected)."},"isAcceptReturn":{"type":"boolean","description":"Whether the caller accepts returns for this listing. Coerced to strict bool; defaults false when omitted."}}}}}}}}},"responses":{"200":{"description":"Cart insert processed; success envelope carries any per-item business errors."}},"x-mcp-tool":"viewider_marketplace_add_to_cart","x-mcp-write":true}},"/marketplace/removeFromCart":{"post":{"tags":["marketplace"],"summary":"Remove listings from your own marketplace cart","description":"Owner-scoped WRITE. Removes one or more listings from the authenticated merchant's OWN active B2B marketplace cart. The cart owner is server-stamped from the OAuth token's user (never read from the request body); an owner-scoped CartQuery + owner-scoped MarketplaceCommand.removeFromCart guarantee a caller can only delete their own cart rows -- any listing not present in the caller's own active cart is reported under notFound and no other tenant is ever touched. Requires the LISTING_WRITE capability (a readonly-preset key is rejected 403 before any input is parsed). Reversible (the listing can be re-added) and produces NO external marketplace push -- the removal is an internal CQRS delete only.","operationId":"marketplaceRemoveFromCart","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","minItems":1,"maxItems":50,"description":"Listings to remove from your own cart. Each item is either a bare scalar listing ID or an object {\"listingID\":\"...\"}. Must be a non-empty array (max 50). Each listingID must be a scalar; Mongo operator objects are rejected. Any userID/ownerID key is ignored -- the owner is server-stamped.","items":{"type":"object","properties":{"listingID":{"type":"string","description":"The Viewider marketplace listing ID to remove from your own cart."}}}}}}}}},"responses":{"200":{"description":"Removal outcome envelope with removedCount, failCount and a notFound array of requested listingIDs that were not in the caller's own active cart."}},"x-mcp-tool":"viewider_marketplace_remove_from_cart","x-mcp-write":true}},"/marketplace/addToWishlist":{"post":{"tags":["marketplace"],"summary":"Bookmark one or more Active marketplace listings into the calling merchant's own wishlist (live write — owner-scoped).","description":"⚠️ **Production — not yet sandbox-testable.** This MUTATES live data: it inserts wishlist rows into the calling merchant's own B2B marketplace wishlist. The owner is derived server-side from the authenticated session and stamped into every newly inserted Wishlist row — you cannot bookmark into another account's wishlist, and any userID/ownerID field inside a data item is ignored (server-stamped). Requires a machine-token key that carries the `listing:write` (LISTING_WRITE) capability — keys on a read-only capability preset are refused with HTTP 403 by AuthorizationGate before any input is parsed. NO external side-effect: this writes a CQRS event only and does NOT push anything to eBay/Amazon or any external marketplace.\n\nSend a form-encoded data[] array (non-empty, max 50) of listing ids. Each element is either a plain scalar listing id or an object carrying a scalar `listingID` — Mongo operator objects / nested arrays / non-scalars are rejected as invalid parameters. Listing ids are validated server-side against the public marketplace catalog (siteID 20000000, Active); ids that are not found or not Active are simply not added. The persisted wishlist row _id is server-minted, so a caller can never overwrite another tenant's row. Every response is a JSON envelope returned with HTTP 200, so always check the status field.","operationId":"marketplace_addToWishlist","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"string","description":"Plain scalar marketplace listing id (siteID 20000000 Active catalog). May also be an object carrying a scalar listingID; any userID/ownerID in the object is ignored (owner is server-stamped)."},"description":"Non-empty array (max 50) of marketplace listing ids to bookmark into your own wishlist. Owner is derived server-side — never send userID/ownerID. Non-scalar / Mongo-operator entries are rejected."}},"required":["data"]},"example":{"data":["68590f1a2c4b9a0012ab34cd","68590f1a2c4b9a0012ab34ce"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body — always inspect the status field.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-07 14:32:07"},"status":{"const":"success"},"response":{"type":"object","description":"Map of listingID → inserted wishlist row (or false when that listing could not be added / is not in the Active public catalog).","additionalProperties":true}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-07 14:35:20","status":"success","response":{"68590f1a2c4b9a0012ab34cd":{"_id":"68590f1a2c4b9a0012ab34ee","listingID":"68590f1a2c4b9a0012ab34cd"},"68590f1a2c4b9a0012ab34ce":false}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-mcp-tool":"viewider_add_to_wishlist","x-mcp-write":true}},"/marketplace/removeFromWishlist":{"post":{"tags":["marketplace"],"summary":"Remove listings from your marketplace wishlist","description":"⚠️ WRITE — Removes one or more listings from the authenticated merchant's own B2B marketplace wishlist. Owner is derived server-side from the session/token (userID is never read from the request body); foreign listing IDs are silently no-ops (owner-scoped fetch returns zero rows). Requires the LISTING_WRITE capability — readonly-preset keys receive 403 before any input is parsed. Mutates only the caller's own Wishlist collection; no external marketplace push or side-effect.","operationId":"marketplaceRemoveFromWishlist","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","description":"Plain scalar listing IDs to remove from the wishlist. Non-empty, max 50. Each element must be a scalar ID (Mongo operator objects / nested arrays are rejected).","minItems":1,"maxItems":50,"items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Wishlist mutation result envelope. On success, data.removed echoes the submitted listing IDs.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"removed":{"type":"array","items":{"type":"string"}}}}}}}}}},"x-mcp-tool":"viewider_remove_from_wishlist","x-mcp-write":true}},"/marketplace/moveWishlistToCart":{"post":{"tags":["marketplace"],"summary":"Move the caller's own active cart listings into their marketplace wishlist","description":"⚠️ WRITE — bulk-adds the caller's OWN active B2B marketplace cart listings into the caller's OWN marketplace wishlist. Owner is derived server-side from the session user (never from the request body); operates only on the caller's cart and writes only to the caller's wishlist. Idempotent add — listings already wishlisted, non-active, or not owned by the caller are dropped. This is the fixed \"move all my active cart items\" form: no listing ids, filter, or userID are accepted from the body (mass-filter / mass-assignment injection surfaces are neutralised server-side). Requires a user-scoped token with the LISTING_WRITE capability (readonly-preset tokens are rejected 403). No marketplace / platform API is called — no external push side-effect.","operationId":"marketplaceMoveWishlistToCart","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"access_token":{"type":"string","description":"User-scoped OAuth2 access token carrying the LISTING_WRITE capability."}},"required":["access_token"]}}}},"responses":{"200":{"description":"Envelope with added / skipped listing ids and their counts.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"added":{"type":"array","items":{"type":"string"}},"skipped":{"type":"array","items":{"type":"string"}},"addedCount":{"type":"integer"},"skippedCount":{"type":"integer"}}}}}}}}},"x-mcp-tool":"viewider_move_wishlist_to_cart","x-mcp-write":true}},"/product/listMediaLibrary":{"post":{"tags":["product"],"summary":"List the authenticated merchant's own image/media library (the product-imagery album): id / fileUrl / displayName / fileType / displayFolder / flag / timestamp per image. Optional target_folder / flag / search filters and length+offset pagination; type=count returns a single {sum} total instead of rows. Owner-scoped server-side (userID = your account).","description":"List the authenticated merchant's own image/media library (the product-imagery album used to build listing imagery): returns your own album rows with id / fileUrl / displayName / fileType / displayFolder / flag / timestamp. Optional target_folder (displayFolder) / flag (default live) / search (displayName LIKE) filters and length+offset pagination. Set type=count to return only the matching total ([{sum}]) instead of rows. Owner-scoped server-side and fail-closed: the WHERE userID filter is bound to your session account, so only your own media is ever returned regardless of input.","x-mcp-tool":"viewider_list_media_library","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"Set to count to return only the matching total ([{sum}]) instead of rows; omit for the media list."},"target_folder":{"type":"string","description":"Optional: restrict to one folder (displayFolder)."},"flag":{"type":"string","description":"Optional: status filter, default live (e.g. live / delete)."},"search":{"type":"string","description":"Optional: fuzzy match on displayName (LIKE %search%)."},"length":{"type":"integer","description":"Optional: page size (LIMIT)."},"offset":{"type":"integer","description":"Optional: pagination offset (OFFSET; only applied when length is also set)."}}},"example":{"target_folder":"product-hero","flag":"live","length":50,"offset":0}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-08 11:20:45"},"status":{"const":"success"},"response":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"userID":{"type":"string"},"fileKey":{"type":"string"},"fileUrl":{"type":"string"},"displayName":{"type":"string"},"fileType":{"type":"string"},"displayFolder":{"type":"string"},"flag":{"type":"string"},"timestamp":{"type":"string"}}},"description":"Array of your own album/media rows. When type=count the array instead holds a single {sum} count row."}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-08 11:24:05","status":"success","response":[{"id":"1048576","userID":"12099","fileKey":"template_photo/12099/product-hero/hero.jpg","fileUrl":"https://viewiderpublicap.s3-ap-southeast-1.amazonaws.com/template_photo/12099/product-hero/hero.jpg","displayName":"hero.jpg","fileType":"jpg","displayFolder":"product-hero","flag":"live","timestamp":"2026-07-01 09:12:33"}]}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"listMediaLibrary"}},"/product/getComposition":{"post":{"tags":["product"],"summary":"Preview one of your own product group's composition / BOM (bundle or multipack): component rows with per-unit cost, available stock, total cost, and the bottleneck component that caps how many bundles you can build.","description":"Read-only composition/BOM preview for a single product group you own (ADR-016). Send productGroupID as a scalar 24-hex ObjectId string. Owner scope is enforced server-side — the userID is derived from the authenticated account and can never be supplied by the caller; a product group you do not own is indistinguishable from not-found. A standalone product group (no BOM) returns an empty composition with maxBundleQty 0. Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_get_composition_bom","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"productGroupID":{"type":"string","description":"The product group id to inspect (must be a scalar 24-hex ObjectId string; must be owned by the calling account)."}},"required":["productGroupID"]},"example":{"productGroupID":"68590f1a2c4b9a0012ab34cf"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"composition":{"type":"object","properties":{"type":{"type":"string","description":"composition type, e.g. standalone | bundle | multipack"},"bom":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string"},"qty":{"type":"integer"}}}}}},"components":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string"},"customLabel":{"type":"string"},"ownerID":{"type":"integer"},"unitCost":{"type":"number"},"requiredPerUnit":{"type":"integer"},"rowCost":{"type":"number"},"available":{"type":"integer"},"derivedMaxQty":{"type":"integer"}}}},"totalCost":{"type":"number"},"maxBundleQty":{"type":["integer","null"]},"bottleneck":{"type":["object","null"],"properties":{"productID":{"type":"string"},"customLabel":{"type":"string"},"ownerID":{"type":"integer"},"unitCost":{"type":"number"},"requiredPerUnit":{"type":"integer"},"rowCost":{"type":"number"},"available":{"type":"integer"},"derivedMaxQty":{"type":"integer"}}},"currency":{"type":"string","example":"USD"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"composition":{"type":"bundle","bom":[{"productID":"68590f1a2c4b9a0012ab34d9","qty":2},{"productID":"68590f1a2c4b9a0012ab34e3","qty":1}]},"components":[{"productID":"68590f1a2c4b9a0012ab34d9","customLabel":"PG-DEMO-002","ownerID":12099,"unitCost":3.5,"requiredPerUnit":2,"rowCost":7,"available":40,"derivedMaxQty":20},{"productID":"68590f1a2c4b9a0012ab34e3","customLabel":"PG-DEMO-003","ownerID":12099,"unitCost":5,"requiredPerUnit":1,"rowCost":5,"available":12,"derivedMaxQty":12}],"totalCost":12,"maxBundleQty":12,"bottleneck":{"productID":"68590f1a2c4b9a0012ab34e3","customLabel":"PG-DEMO-003","ownerID":12099,"unitCost":5,"requiredPerUnit":1,"rowCost":5,"available":12,"derivedMaxQty":12},"currency":"USD"}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_getComposition"}},"/listItemsByExposure":{"post":{"tags":["listing"],"summary":"List the authenticated merchant's own eBay listing items in one sales-exposure bucket (0=high, 1=midHigh, 2=midLow, 3=low, 4=new) with QuantitySold / StartPrice / thumbnail / price-optimizer flag, page/50 pagination, and site / category / price-range / keyword filtering. Owner-scoped: token must be one the caller owns (validated against getTokens(session user)); a foreign or absent token returns an empty result and no caller userID is honored.","description":"List the authenticated merchant's own eBay listing items in one sales-exposure bucket (0=high, 1=midHigh, 2=midLow, 3=low, 4=new) with QuantitySold / StartPrice / thumbnail / price-optimizer flag, page/50 pagination, and site / category / price-range / keyword filtering. Owner-scoped: token must be one the caller owns (validated against getTokens(session user)); a foreign or absent token returns an empty result and no caller userID is honored.","x-mcp-tool":"viewider_list_items_by_exposure","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"A platform token the caller owns (validated server-side against getTokens(session user); a token you do not own returns an empty result). e.g. \"eBay.xxxx\""},"exposure":{"type":"integer","description":"Exposure bucket: 0=high, 1=midHigh, 2=midLow, 3=low, 4=new (optional, default 0)"},"pageNum":{"type":"integer","description":"0-based page index, 50 items/page (optional, default 0)"},"sortBy":{"type":"integer","description":"0=QuantitySold desc, 1=StartPrice desc, 2=StartPrice asc, 3=QuantitySold asc (optional, default 0)"},"selectAll":{"type":"boolean","description":"true = return the flat list of all matching item ids (unpaged); default false returns the current page of item objects"},"site":{"type":"integer","description":"eBay site id filter (optional)"},"cate":{"type":"integer","description":"Category id filter, level 1 (optional)"},"cate2":{"type":"integer","description":"Category id filter, level 2 (optional)"},"cate3":{"type":"integer","description":"Category id filter, level 3 (optional)"},"priceRange_Min":{"type":"number","description":"StartPrice lower bound, inclusive (optional)"},"priceRange_Max":{"type":"number","description":"StartPrice upper bound, exclusive (optional)"},"seachText":{"type":"string","description":"Keyword, fuzzy-matched against title / SKU / ID (optional; legacy parameter spelling preserved)"}},"required":["token"]}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"item":{"type":"array","items":{"type":"object","properties":{"item":{"type":"integer"},"title":{"type":"string"},"SKU":{"type":"string"},"StartPrice":{"type":"string"},"QuantitySold":{"type":"integer"},"Currency":{"type":"string"},"thumbnail":{"type":"string"},"url":{"type":"string"},"optimizeFlag":{"type":"string"}}}},"count":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"item":[{"item":123456789012,"title":"Demo Listing Title","SKU":"SKU-DEMO-001","StartPrice":"19.99","QuantitySold":42,"Currency":"USD","thumbnail":"https://i.ebayimg.com/images/g/demo/s-l64.jpg","url":"http://www.ebay.com/itm/123456789012","optimizeFlag":"On"}],"count":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/product/validateProductCompleteness":{"post":{"tags":["product"],"summary":"Check one of your own product groups against the Full-tier completeness standard (A-J) and return a per-check pass/fail report.","description":"Read-only completeness audit for a single ProductGroup the calling account owns. Send pgId (the ProductGroup _id) as a form field. Returns found, customLabel, an overall compliant flag, pass/total counts, and a checks map keyed A_sku..J_honest (each {pass, why}) covering IP-centric SKU, bilingual PGV (WW+HK), title length, description, item specifics, barcode honesty, packaged weight/dimensions, images on the source bucket, product-type gate, and no-fabricated-placeholder honesty. ZERO spend / ZERO write. Owner-scoped server-side: a pgId not owned by the calling account returns found=false. Every response is a JSON envelope returned with HTTP 200, so always check the status field.","x-mcp-tool":"viewider_validate_product_completeness","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"pgId":{"type":"string","description":"ProductGroup _id to audit. Required; must be a scalar string owned by the calling account."}},"required":["pgId"]},"example":{"pgId":"68590f1a2c4b9a0012ab34cf"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pgId":{"type":"string"},"found":{"type":"boolean"},"customLabel":{"type":"string"},"compliant":{"type":"boolean"},"pass":{"type":"integer"},"total":{"type":"integer"},"checks":{"type":"object","description":"Map keyed A_sku..J_honest; each value is a per-check verdict.","additionalProperties":{"type":"object","properties":{"pass":{"type":"boolean"},"why":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body - see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pgId":"68590f1a2c4b9a0012ab34cf","found":true,"customLabel":"LEGO_75404","compliant":false,"pass":8,"total":10,"checks":{"A_sku":{"pass":true,"why":"customLabel='LEGO_75404'"},"H_images":{"pass":false,"why":"0 imgs, v2=0"}}}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body - always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"product_validateProductCompleteness"}},"/platform/getShopeeLogisticsChannels":{"post":{"tags":["listing"],"summary":"Read the Shopee logistics (shipping-channel) catalog for one of your own Shopee shops","description":"Returns the stored Shopee logistics-channel document for one of the caller's own Shopee shops — the enabled shipping channels (logistic_id, enabled, fee/free flags, etc.) used when building a Shopee listing. Owner-scoped and fail-closed: the supplied shopName is resolved to a shopID, then a server-side Relation ownership check (Subject = the session owner's main user id, Object = Shopee.<shopID>) rejects any shop the authenticated account does not own before logistics is read — the owner is derived from the session, never accepted from the request. A foreign or unknown shop yields an invalid-parameter envelope, not another merchant's data. Callable with a machine token carrying the listing read capability. No mutation.","operationId":"getShopeeLogisticsChannels","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"shopName":{"type":"string","description":"The Shopee shop / token name (as shown in your linked Shopee accounts) whose logistics channels you want. Required; the shop must belong to the authenticated account or the request is rejected."}},"required":["shopName"]}}}},"responses":{"200":{"description":"The Shopee logistics-channel document for the requested shop","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_shopee_logistics_channels"}},"/order/getSellerDefectDashboard":{"post":{"tags":["order"],"summary":"Return the authenticated merchant's own eBay seller-defect dashboard: a 13-month rollup (per month: transaction count, defect count, and closed-cases-without-seller-resolution), optionally filtered by eBay token and corridor. Force owner-scoped (userID = session account) — cross-tenant read is impossible.","description":"Return the authenticated merchant's own eBay seller-defect dashboard: a 13-month rollup (per month: transaction count, defect count, and closed-cases-without-seller-resolution), optionally filtered by eBay token and corridor. Force owner-scoped (userID = session account) — cross-tenant read is impossible.","x-mcp-tool":"viewider_get_seller_defect_dashboard","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"eBay account token/identifier (maps to the eBayID filter); optional, default '~' = all of your own accounts. userID is force-scoped to the session owner server-side regardless of input."},"corridor":{"type":"string","description":"corridor filter; optional, default '~' = all"}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-08 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"token":{"type":"string"},"DefectList":{"type":"array","items":{"type":"object","properties":{"Year":{"type":"string"},"Month":{"type":"string"},"transactionCount":{"type":"integer"},"defectCount":{"type":"integer"},"closeCaseWithoutResolution":{"type":"integer"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-08 14:39:30","status":"success","response":{"token":"~","DefectList":[{"Year":"2026","Month":"07","transactionCount":128,"defectCount":1,"closeCaseWithoutResolution":0},{"Year":"2026","Month":"06","transactionCount":143,"defectCount":0,"closeCaseWithoutResolution":0}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/order/getDeliveringList":{"post":{"tags":["order"],"summary":"List the caller's own \"delivering\" orders available to ship from a last-mile warehouse","description":"Returns the authenticated merchant's own sales records that are available/picked to deliver out of a given last-mile warehouse (the seller warehouse-fulfilment 'delivering' list). Owner-scoped fail-closed: userID is derived server-side from the session (never a request field), and the all-pool warehouse result is re-scoped to the caller's own sales records — non-owned rows/SR-IDs are stripped (SEC-SERVICES-LEAK-OWNERSCOPE), so any caller-supplied userID/ownerID/mainUserID cannot widen scope. filter MUST include lastMileWarehouseID; omitting it returns an invalid-parameter envelope instead of a 500. Works with machine-token API keys carrying the order:read capability.","operationId":"getDeliveringList","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["filter"],"properties":{"filter":{"type":"object","description":"Mongo-style filter; MUST include lastMileWarehouseID (the last-mile warehouse id). Extra narrowers (status/date range etc) are allowed. Owner scope is server-enforced; userID/ownerID/mainUserID are ignored.","required":["lastMileWarehouseID"],"properties":{"lastMileWarehouseID":{"type":"string","description":"Required last-mile warehouse id to list delivering orders for."}}},"options":{"type":"object","description":"Optional Mongo-style query options (sort/limit/skip etc) passed through to the delivering-list query."}}}}}},"responses":{"200":{"description":"Success envelope wrapping the owner-scoped delivering list (rows grouped by warehouse/status). An ErrorEnvelope (status: fail) with 'invalid parameter' is returned when filter omits lastMileWarehouseID.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_delivering_list"}},"/shipment/getWarehouseRequestSummary":{"post":{"tags":["shipment"],"summary":"Grouped fulfillment / warehouse-request summary for the authenticated merchant's own outbound shipment requests: rows grouped by destination country / shipping company / tracking, each with per-group SKU count, total quantity and a product breakdown, plus a warehouseRequestCount total. Optionally narrow to one request group via requestID or summaryID. Force owner-scoped: the query is AND-wrapped server-side with your (main) account's userID, so a caller-supplied requestID / summaryID can only resolve rows you own.","description":"Grouped fulfillment / warehouse-request summary for the authenticated merchant's own outbound shipment requests: rows grouped by destination country / shipping company / tracking, each with per-group SKU count, total quantity and a product breakdown, plus a warehouseRequestCount total. Optionally narrow to one request group via requestID or summaryID. Force owner-scoped: the query is AND-wrapped server-side with your (main) account's userID, so a caller-supplied requestID / summaryID can only resolve rows you own. Works with machine-token API keys carrying the shipment:read capability; a missing capability is refused with HTTP 403 before parsing.","x-mcp-tool":"viewider_get_warehouse_request_summary","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"requestID":{"type":"string","description":"Optional. A request-storage id whose stored warehouseRequestID list narrows the summary to that group. Owner scope still applies, so a foreign id resolves to nothing. Must be a string (arrays are rejected)."},"summaryID":{"type":"string","description":"Optional. A WarehouseRequest _id; the summary is expanded to every request sharing its createTime group. Owner scope still applies, so foreign ids are filtered out by the server-forced userID. Must be a string (arrays are rejected)."}}},"example":{"summaryID":"68652f1a2c4b9a0012ab34aa"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-08 11:20:45"},"status":{"const":"success"},"response":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"object","description":"Group key { Country, shippingCompany, trackingID }.","properties":{"Country":{"type":"string"},"shippingCompany":{"type":"string"},"trackingID":{"type":"string"}}},"shippingCompany":{"type":"string"},"Country":{"type":"string"},"trackingID":{"type":"string"},"totalQty":{"type":"integer","description":"Total requested quantity across the group."},"productSkuCount":{"type":"integer","description":"Distinct product SKU count in the group."},"products":{"type":"array","items":{"type":"object","properties":{"productGroupID":{"type":"string"},"productID":{"type":"string"},"qty":{"type":"integer"},"sku":{"type":"string"}}}}}},"description":"Grouped warehouse-request summary rows for your own account."},"warehouseRequestCount":{"type":"integer","description":"Total number of warehouse requests summarized."}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-08 11:21:03","status":"success","response":{"data":[{"_id":{"Country":"United States","shippingCompany":"DHL","trackingID":"VW1234567890HK"},"shippingCompany":"DHL","Country":"United States","trackingID":"VW1234567890HK","totalQty":12,"productSkuCount":3,"products":[{"productGroupID":"68590f1a2c4b9a0012ab34cf","productID":"68590f1a2c4b9a0012ab34d0","qty":5,"sku":"PG-DEMO-001-RED"}]}],"warehouseRequestCount":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"getWarehouseRequestSummary"}},"/getSellingPerformance":{"post":{"tags":["listing"],"summary":"Get the daily sell-performance series for one of your own listings by numeric itemID over a date window. Returns response.data as a per-day array of {date, price, tran_count} (eBay transactions UNION optimizer price-change reports), plus oriPrice (the listing's original / optimizer base price) and dayDiff (window span in days). Owner-scoped server-side and fail-closed: an itemID that does not belong to your account, or a window with fewer than 2 data points, returns the same success envelope with response.data = false (deliberately indistinguishable from \"no data\" — no listing-existence oracle). Works with a machine-token API key carrying the listing:read capability.","description":"Get the daily sell-performance series for one of your own listings by numeric itemID over a date window. Returns response.data as a per-day array of {date, price, tran_count} (eBay transactions UNION optimizer price-change reports), plus oriPrice (the listing's original / optimizer base price) and dayDiff (window span in days). Owner-scoped server-side and fail-closed: an itemID that does not belong to your account, or a window with fewer than 2 data points, returns the same success envelope with response.data = false (deliberately indistinguishable from \"no data\" — no listing-existence oracle). Works with a machine-token API key carrying the listing:read capability.","x-mcp-tool":"viewider_get_selling_performance","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"itemID":{"type":"integer","description":"Numeric listing (item) id owned by your account. Required."},"startDate":{"type":"string","description":"Window start date, YYYY-MM-DD. Required. Transactions with CreatedDate strictly greater than this are included."},"endDate":{"type":"string","description":"Window end date, YYYY-MM-DD. Required. Transactions with CreatedDate strictly less than this are included."}},"required":["itemID","startDate","endDate"]},"example":{"itemID":1234567,"startDate":"2026-06-01","endDate":"2026-07-01"}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-08 11:20:45"},"status":{"const":"success"},"response":{"type":"object","properties":{"data":{"type":["array","boolean"],"items":{"type":"object","properties":{"date":{"type":"string"},"price":[],"tran_count":{"type":"integer"}}},"description":"Per-day series when there are >= 2 data points; boolean false when the listing is not owned by your account OR the window has fewer than 2 points (fail-closed, deliberately indistinguishable)."},"oriPrice":{"description":"Listing original / optimizer base price. Present only when data is an array."},"dayDiff":{"type":"integer","description":"Span between startDate and endDate in days. Present only when data is an array."}},"description":"Sell-performance payload. response.data === false means no data / not-owned (fail-closed)."}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-08 11:24:05","status":"success","response":{"data":[{"date":"2026-06-02","price":"49.99","tran_count":3},{"date":"2026-06-05","price":"47.99","tran_count":1}],"oriPrice":"49.99","dayDiff":30}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"getSellingPerformance"}},"/getNotifications":{"post":{"tags":["order"],"summary":"List the authenticated merchant's own in-app notifications (the SSE toast messages shown after async jobs finish). Defaults to the last 10; pass full=true for the entire feed. Force owner-scoped: the userId is derived server-side from the access token, never from caller input.","description":"List the authenticated merchant's own in-app notifications (the SSE toast messages shown after async jobs finish). Defaults to the last 10; pass full=true for the entire feed. Force owner-scoped: the userId is derived server-side from the access token, never from caller input.","x-mcp-tool":"viewider_get_notifications","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"full":{"type":"boolean","description":"false (default) = last 10 notifications; true = the full notification feed. Optional."}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"full":{"type":"boolean"},"count":{"type":"integer"},"messages":{"type":"array","items":{"type":"object","properties":{"mid":{"type":"integer"},"timestamp":{"type":"integer"},"read":{"type":"integer"},"title":{"type":"string"},"msg":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"full":false,"count":2,"messages":[{"mid":184023,"timestamp":1751861970,"read":0,"title":"Bulk create finished","msg":"12 product groups created"},{"mid":184001,"timestamp":1751860011,"read":1,"title":"Inventory sync","msg":"eBay listings updated"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/order/getDistinctPlatformsForOrders":{"post":{"tags":["order"],"summary":"List, keyed by last-mile warehouse ID, the distinct transaction platforms present across your own orders. Each value is the sorted platform list with \"All\" prepended. Owner-scoped server-side (supplierUserID = your core account), so only your own platforms are returned; an optional Mongo-style filter can only narrow within your own supplier records.","description":"List, keyed by last-mile warehouse ID (lastMileWarehouseID), the distinct set of transactionPlatform values across your own ViewiderSalesRecord orders. Each map value is the platform list sorted ascending with the literal \"All\" prepended (the supplier-direct shipment page's platform-filter source). Owner-scoped server-side and fail-closed (SEC-SERVICES-LEAK-RESIDUAL): supplierUserID is force-set to your session core account and every caller-supplied owner key (supplierUserID/sellerUserID/userID/ownerID/mainUserID) is stripped, so another merchant's platforms are never returned. The optional filter is AND-composed under the owner scope and can only NARROW within your own records. Callable with a machine token carrying the order:read capability.","x-mcp-tool":"viewider_get_distinct_platforms_for_orders","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"filter":{"type":"object","additionalProperties":true,"description":"Optional MongoDB-style narrowing filter (e.g. {\"shipmentID\":\"\"} for not-yet-shipped). Owner scope is force-applied on top; this filter can only narrow within your own supplier records. Owner-scope keys are ignored."}}},"example":{"filter":{"shipmentID":""}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-08 14:32:07"},"status":{"const":"success"},"response":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}},"description":"Map keyed by lastMileWarehouseID; each value is the sorted transactionPlatform list with \"All\" prepended. Empty object when you have no matching orders."}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-08 14:39:30","status":"success","response":{"5719981285bb10b9d78":["All","eBay","shopee"]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"getDistinctPlatformsForOrders"}},"/getReferenceData":{"post":{"tags":["reference"],"summary":"Global reference data: supported countries and marketplace platforms.","description":"Returns two platform-wide reference lists you need when setting up listings and shipping: countries (each an object with name and 2-letter code, sorted by name) and platforms (the marketplace platforms Viewider supports, e.g. eBay/Amazon/Shopee). Both are GLOBAL catalogs — not scoped to your account — so the request body is ignored and an empty POST is fine. Authenticate with your Bearer machine-token. The response is the standard JSON envelope, so always check the status field and read countries / platforms from response.","x-mcp-tool":"viewider_get_reference_data","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":[]},"example":[]}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-10 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"countries":{"type":"array","description":"Whole Country catalog, sorted by name.","items":{"type":"object","properties":{"name":{"type":"string","example":"United States"},"code":{"type":"string","description":"ISO alpha-2 country code.","example":"US"}}}},"platforms":{"type":"array","description":"Distinct Active marketplace platforms Viewider supports (excludes the synthetic \"All\").","items":{"type":"string","example":"eBay"}}}}}}}}}},"operationId":"getReferenceData"}},"/order/getShippingLabels":{"post":{"tags":["order"],"summary":"List the caller's own confirmed orders still needing a shipping label (supplier fulfilment print queue)","description":"Returns the authenticated merchant's own SUPPLIER sales records that are payment-confirmed (confirmTransactionTime set) but not yet shipped and still need a shipping label printed — the 'print shipping label' work queue — each row enriched with product images. Owner-scoped fail-closed: the caller's core account id is derived from the session (users::getCore) and force-injected as supplierUserID server-side, OVERRIDING the backing service's isAdmin-gated scoping, so any caller-supplied supplierUserID in filter is clobbered and no cross-tenant rows are returned; an unresolvable owner yields no rows. Requires a FIX-314 machine token carrying the order:read capability; readonly/fulfilment preset keys pass, a missing capability is refused with HTTP 403 before parsing. $where in filter is rejected; options are whitelisted to limit/skip/sort.","operationId":"getShippingLabels","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"filter":{"type":"object","description":"Mongo-style filter over the caller's own supplier sales records (e.g. keyword, shippingCompany, transactionSiteID). Owner scope is server-enforced (supplierUserID is force-injected/ignored); $where is rejected. Results are always narrowed to confirmed-but-not-yet-shipped orders needing a label."},"options":{"type":"object","description":"Query options; only limit/skip/sort are honored (projection is intentionally not accepted so the post-query image-enrichment keys survive).","properties":{"limit":{"type":"integer","description":"Page size, default 100, capped at 500 (out-of-range resets to 100)."},"skip":{"type":"integer","description":"Pagination skip, coerced to >= 0."},"sort":{"type":"object","description":"Mongo sort map, e.g. {confirmTransactionTime:-1}."}}}}}}}},"responses":{"200":{"description":"Success envelope wrapping {data: rows[], count} — each row is a supplier sales record (with product images) that needs a shipping label.","content":{"application/json":{"schema":{"type":"object"}}}}},"x-mcp-tool":"viewider_get_shipping_labels"}},"/catalog/manageProductTags":{"post":{"tags":["product"],"summary":"Add or remove internal research tags on your own product groups (live write — internal only, never pushed to a marketplace).","description":"⚠️ **WRITE — mutates live data.** Adds or removes internal research tags (`ProductGroup.researchTags`) on product groups **you own**. Requires a machine-token key carrying the `product:write` capability — read-only preset keys are refused with HTTP 403 before any input is parsed.\n\nOwner is derived server-side from your OAuth session and re-asserted against `ProductGroup.ownerID` before every write, so another account's `productGroupID` is rejected (`not_owner`) and never mutated; any `userID`/`ownerID`/`mainUserID` you send is ignored. **No external push** — researchTags is an internal Product-Research field written straight to Mongo (no eBay/Amazon/Shopee revise). Reversible: `add` ⇄ `remove`.\n\nSend `data[]` (form-encoded, non-empty, max 50) of `{action:'add'|'remove', productGroupID, tagName?, tagID?}`. Ids must be plain ids (the internal `~`/`+` prefixes are rejected). `tagName` is trimmed/whitespace-collapsed, max 64 chars. Per-item failures are reported in `failed[]` rather than aborting the batch.\n\nSupports `dryRun=1` (validates and reports `wouldApply[]`, writes nothing) and `idempotencyKey` (a retry with the same key replays the first result instead of double-applying).","x-mcp-tool":"viewider_manage_product_tags","x-mcp-write":true,"x-mcp-write-access":"ga","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","maxItems":50,"description":"Non-empty, max 50 tag operations.","items":{"type":"object","required":["action","productGroupID"],"properties":{"action":{"type":"string","enum":["add","remove"],"description":"'add' appends a tag; 'remove' deletes one by tagID."},"productGroupID":{"type":"string","description":"Plain product-group id you own (no \"~\"/\"+\" prefix)."},"tagName":{"type":"string","maxLength":64,"description":"Required when action='add'. Trimmed; max 64 chars; case-insensitive dedup."},"tagID":{"type":"string","description":"Required when action='remove'. Plain tag id."}}}},"dryRun":{"type":"string","description":"Set to 1/true to validate and preview without writing."},"idempotencyKey":{"type":"string","maxLength":128,"description":"Optional. A retry with the same key replays the first result instead of re-applying."}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"productGroups":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string"},"sellingPrice":{"type":"number"},"inventory":{"type":"array","items":{"type":"object","properties":{"inventoryID":{"type":"string"},"remainQuantity":{"type":"integer"},"warehouseID":{"type":"string"},"safetyLine":{"type":"integer"},"additionalCost":{"type":"integer"}}}}}}},"productGroupID":{"type":"string"}}}},"failCount":{"type":"integer"},"successCount":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:35:20","status":"success","response":{"productGroups":[{"customLabel":"PG-DEMO-001","products":[{"productID":"68590f1a2c4b9a0012ab34cd","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ee","remainQuantity":100,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]},{"productID":"68590f1a2c4b9a0012ab34ce","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ef","remainQuantity":80,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]}],"productGroupID":"68590f1a2c4b9a0012ab34cf"}],"failCount":0,"successCount":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"catalog_manageProductTags"}},"/research/subscribeDailyFinding":{"post":{"tags":["product"],"summary":"Opt your own linked eBay seller tokens into the daily competitor-finding pipeline (live write — internal subscription only).","description":"⚠️ **WRITE — mutates live data.** Registers **your own** linked eBay seller tokens into Viewider's automated daily competitor-finding pipeline, so fresh competitor/product-research data is collected for your account daily. Requires a machine-token key carrying the `product:write` capability — read-only preset keys are refused with HTTP 403.\n\n**Takes no parameters.** Owner is derived entirely server-side from your OAuth session; the token set registered is scoped to your own linked tokens only, and any `userID`/`ownerID` you send is ignored. **No external push** — internal subscription registration only.\n\nRequires a paid main account: an ineligible account returns a success envelope with `subscribed:false` and `reason` (a business outcome, not an auth error). Supports `dryRun=1` and `idempotencyKey`.","x-mcp-tool":"viewider_subscribe_daily_finding","x-mcp-write":true,"x-mcp-write-access":"ga","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"dryRun":{"type":"string","description":"Set to 1/true to preview without writing."},"idempotencyKey":{"type":"string","maxLength":128,"description":"Optional. A retry with the same key replays the first result."}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"productGroups":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string"},"sellingPrice":{"type":"number"},"inventory":{"type":"array","items":{"type":"object","properties":{"inventoryID":{"type":"string"},"remainQuantity":{"type":"integer"},"warehouseID":{"type":"string"},"safetyLine":{"type":"integer"},"additionalCost":{"type":"integer"}}}}}}},"productGroupID":{"type":"string"}}}},"failCount":{"type":"integer"},"successCount":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:35:20","status":"success","response":{"productGroups":[{"customLabel":"PG-DEMO-001","products":[{"productID":"68590f1a2c4b9a0012ab34cd","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ee","remainQuantity":100,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]},{"productID":"68590f1a2c4b9a0012ab34ce","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ef","remainQuantity":80,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]}],"productGroupID":"68590f1a2c4b9a0012ab34cf"}],"failCount":0,"successCount":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"research_subscribeDailyFinding"}},"/catalog/manageTagBlacklist":{"post":{"tags":["product"],"summary":"Blacklist or whitelist research tag suggestions for a category, on your own account (live write — internal preference only).","description":"⚠️ **WRITE — mutates live data.** Blacklists or whitelists research tag suggestions for a Viewider vertical category **on your own account** (TagBlackList / TagWhiteList). Requires a machine-token key carrying `product:write` — read-only preset keys are refused with HTTP 403 before any input is parsed.\n\nOwner is derived server-side from your OAuth session and passed explicitly to the backing, so the preference is always written to YOUR account; any `userID`/`ownerID`/`mainUserID` you send is ignored. **No external push** — this only tunes which tags Viewider suggests to you. Reversible: `blacklist` ⇄ `whitelist`.\n\n`tags[]` non-empty, max 50, each a plain string ≤64 chars (reserved `~`/`+` prefixes rejected); `vwCateID` numeric. Supports `dryRun=1` and `idempotencyKey`.","x-mcp-tool":"viewider_manage_tag_blacklist","x-mcp-write":true,"x-mcp-write-access":"ga","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["action","tags","vwCateID"],"properties":{"action":{"type":"string","enum":["blacklist","whitelist"]},"tags":{"type":"array","maxItems":50,"items":{"type":"string","maxLength":64},"description":"Non-empty, max 50 plain tag strings."},"vwCateID":{"type":"string","description":"Numeric Viewider category id."},"dryRun":{"type":"string"},"idempotencyKey":{"type":"string","maxLength":128}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"productGroups":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string"},"sellingPrice":{"type":"number"},"inventory":{"type":"array","items":{"type":"object","properties":{"inventoryID":{"type":"string"},"remainQuantity":{"type":"integer"},"warehouseID":{"type":"string"},"safetyLine":{"type":"integer"},"additionalCost":{"type":"integer"}}}}}}},"productGroupID":{"type":"string"}}}},"failCount":{"type":"integer"},"successCount":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:35:20","status":"success","response":{"productGroups":[{"customLabel":"PG-DEMO-001","products":[{"productID":"68590f1a2c4b9a0012ab34cd","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ee","remainQuantity":100,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]},{"productID":"68590f1a2c4b9a0012ab34ce","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ef","remainQuantity":80,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]}],"productGroupID":"68590f1a2c4b9a0012ab34cf"}],"failCount":0,"successCount":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"catalog_manageTagBlacklist"}},"/research/manageFindingTargets":{"post":{"tags":["product"],"summary":"Start or stop tracking a competitor item / seller token / eBay category in your own research watchlist (live write).","description":"⚠️ **WRITE — mutates live data.** Starts or stops tracking a competitor **item**, **seller token** or **eBay category** in **your own** competitor-research watchlist. Requires a machine-token key carrying `product:write` — read-only preset keys are refused with HTTP 403.\n\nOwner is derived server-side from your OAuth session and passed as the owner argument to the backing; any `userID`/`intMainUserID`/`ownerID` you send is ignored, so a row can only ever be written to YOUR watchlist. **No external push** — the daily crawler acts on these rows later under your own account. Reversible: `start` ⇄ `end`.\n\n`targetType=item` needs `itemIDs[]` (non-empty, max 200); `targetType=token` needs `token`; `targetType=category` needs numeric `categoryID` + `siteID`. Supports `dryRun=1` and `idempotencyKey`.","x-mcp-tool":"viewider_manage_finding_targets","x-mcp-write":true,"x-mcp-write-access":"ga","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["action","targetType"],"properties":{"action":{"type":"string","enum":["start","end"]},"targetType":{"type":"string","enum":["item","token","category"]},"itemIDs":{"type":"array","maxItems":200,"items":{"type":"string"},"description":"Required when targetType=item."},"token":{"type":"string","description":"Required when targetType=token."},"categoryID":{"type":"string","description":"Required when targetType=category (numeric)."},"siteID":{"type":"string","description":"Required when targetType=category (numeric eBay site id)."},"dryRun":{"type":"string"},"idempotencyKey":{"type":"string","maxLength":128}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"productGroups":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"productID":{"type":"string"},"sellingPrice":{"type":"number"},"inventory":{"type":"array","items":{"type":"object","properties":{"inventoryID":{"type":"string"},"remainQuantity":{"type":"integer"},"warehouseID":{"type":"string"},"safetyLine":{"type":"integer"},"additionalCost":{"type":"integer"}}}}}}},"productGroupID":{"type":"string"}}}},"failCount":{"type":"integer"},"successCount":{"type":"integer"}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:35:20","status":"success","response":{"productGroups":[{"customLabel":"PG-DEMO-001","products":[{"productID":"68590f1a2c4b9a0012ab34cd","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ee","remainQuantity":100,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]},{"productID":"68590f1a2c4b9a0012ab34ce","sellingPrice":34.99,"inventory":[{"inventoryID":"68590f1a2c4b9a0012ab34ef","remainQuantity":80,"warehouseID":"68590f1a2c4b9a0012ab34d0","safetyLine":0,"additionalCost":0}]}],"productGroupID":"68590f1a2c4b9a0012ab34cf"}],"failCount":0,"successCount":1}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"operationId":"research_manageFindingTargets"}},"/listing/cleanActiveContent":{"post":{"tags":["listing"],"summary":"Sanitise a listing-description HTML string: strip active/unsafe content (script / object / embed / form) and normalise anchors, returning the cleaned HTML plus a changed flag. Pure function — persists nothing, pushes to no marketplace, and makes no outbound network connection.","description":"Clean active and unsafe content out of a listing description. Removes <script>/<noscript>/inline event handlers, <object>/<embed>, and <form> blocks, and rewrites anchors (invalid-domain anchors are collapsed to <a>, whitelisted-domain anchors get target=\"_blank\"). Returns { cleaned, changed } where cleaned is the sanitised HTML and changed indicates whether anything was altered. This is a READ-only helper (LISTING_READ): it mutates no merchant data and pushes to no marketplace. Unlike the internal cleanAC() path it takes the no-network cleanACSafe() route, so it never opens an outbound TLS connection to a host embedded in the input (no SSRF surface).","x-mcp-tool":"viewider_clean_listing_active_content","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string","description":"The listing-description HTML to sanitise (up to ~2 MB). Alias: 'description'."},"description":{"type":"string","description":"Alias for 'content' (used if 'content' is absent)."}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-07-16 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"cleaned":{"type":"string","description":"The sanitised HTML."},"changed":{"type":"boolean","description":"Whether the sanitiser altered the input."}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-07-16 14:39:30","status":"success","response":{"cleaned":"<p>See our listing</p><a target=\"_blank\" href=\"https://www.youtube.com/watch?v=demo\">video</a>","changed":true}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/listing/exportListings":{"post":{"tags":["listing"],"summary":"Enqueue an export of the authenticated merchant's OWN listings to an Excel file and return the async job id (poll it with viewider_get_job_status; the file appears in viewider_list_download_files). Owner-scoped and fail-closed; generates a download artifact — does not mutate listings or push to any marketplace.","description":"Enqueue an export of the authenticated merchant's OWN listings to an Excel file and return the async job id (poll it with viewider_get_job_status; the file appears in viewider_list_download_files). Owner-scoped and fail-closed; generates a download artifact — does not mutate listings or push to any marketplace.","x-mcp-tool":"viewider_export_listings","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"platform":{"type":"string","description":"eBay | Shopee | Lazada | Shopify | Qoo10 | Gmarket (default eBay)."},"filter":{"type":"object","description":"UI filter map for which listings to export; owner-scope keys are stripped server-side and the export is always scoped to your own listings."}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/product/exportProducts":{"post":{"tags":["product"],"summary":"Enqueue an export of the authenticated merchant's OWN product groups to a file and return the async job id (poll it with viewider_get_job_status; the file appears in viewider_list_download_files). Owner-scoped and fail-closed; generates a download artifact — does not mutate the catalogue or push to any marketplace.","description":"Enqueue an export of the authenticated merchant's OWN product groups to a file and return the async job id (poll it with viewider_get_job_status; the file appears in viewider_list_download_files). Owner-scoped and fail-closed; generates a download artifact — does not mutate the catalogue or push to any marketplace.","x-mcp-tool":"viewider_export_products","requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"filter":{"type":"object","description":"UI filter map for which product groups to export; owner-scope keys are stripped server-side and the export is always scoped to your own products."}}}}}},"responses":{"200":{"description":"HTTP 200. SuccessEnvelope on success; an ErrorEnvelope (status: fail) can also be returned in a 200 body.","content":{"application/json":{"schema":{"type":"object","required":["timestamp","status","response"],"properties":{"timestamp":{"type":"string","example":"2026-06-23 14:32:07"},"status":{"const":"success"},"response":{"type":"object","properties":{"pageCount":{"type":"integer"},"page":{"type":"integer"},"productGroup":{"type":"array","items":{"type":"object","properties":{"customLabel":{"type":"string"},"productGroupID":{"type":"string"}}}}}}},"description":"SuccessEnvelope. A status:fail ErrorEnvelope can also be returned in a 200 body — see components.schemas.ErrorEnvelope."},"example":{"timestamp":"2026-06-23 14:39:30","status":"success","response":{"pageCount":3,"page":1,"productGroup":[{"customLabel":"PG-DEMO-001","productGroupID":"68590f1a2c4b9a0012ab34cf"},{"customLabel":"PG-DEMO-002","productGroupID":"68590f1a2c4b9a0012ab34d9"}]}}}}},"default":{"description":"Error envelope (status: fail). NOTE: this API can also return a fail envelope inside an HTTP 200 body — always inspect the status field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}}}