{"id":234416,"date":"2025-06-02T12:03:27","date_gmt":"2025-06-02T12:03:27","guid":{"rendered":"https:\/\/el.wordpress.org\/plugins\/w3s-api-extension\/"},"modified":"2026-08-20T10:30:23","modified_gmt":"2026-08-20T10:30:23","slug":"w3s-api-extension","status":"publish","type":"plugin","link":"https:\/\/dsb.wordpress.org\/plugins\/w3s-api-extension\/","author":23293217,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.1.0","stable_tag":"1.1.0","tested":"7.1","requires":"6.7","requires_php":"7.4","requires_plugins":null,"header_name":"W3S API Extension","header_author":"w3specialists.com","header_description":"Enhances your store's REST API by adding powerful, flexible endpoints. Stay tuned more Endpoints are coming!","assets_banners_color":"","last_updated":"2026-08-20 10:30:23","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/www.w3specialists.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":442,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"w3specialists","date":"2025-06-02 12:09:08"},"1.0.1":{"tag":"1.0.1","author":"w3specialists","date":"2025-06-02 12:35:57"},"1.1.0":{"tag":"1.1.0","author":"w3specialists","date":"2026-08-20 10:30:23"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3304946,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3304946,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1","1.1.0"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[1556,610,1245,286],"plugin_category":[45,57],"plugin_contributors":[243286],"plugin_business_model":[],"class_list":["post-234416","plugin","type-plugin","status-publish","hentry","plugin_tags-api","plugin_tags-categories","plugin_tags-extension","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_category-taxonomy","plugin_contributors-w3specialists","plugin_committers-w3specialists"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/w3s-api-extension\/assets\/icon-128x128.png?rev=3304946","icon_2x":"https:\/\/ps.w.org\/w3s-api-extension\/assets\/icon-256x256.png?rev=3304946","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Enhances your store\u2019s REST API by adding powerful, flexible endpoints.\nStay tuned more are coming!<\/p>\n\n<p><strong>Add or Remove a Single Category<\/strong><\/p>\n\n<p>Easily append or remove one category at a time\u2014by numeric ID or slug\u2014using simple POST\/PUT\/PATCH or DELETE requests to\n    \/wp-json\/wc\/v3\/products\/{product_id}\/categories\/{identifier}<\/p>\n\n<p><strong>Batch Manage Multiple Categories<\/strong><\/p>\n\n<p>In a single call, add or remove multiple categories at once via JSON payloads to\n    \/wp-json\/wc\/v3\/products\/{product_id}\/categories\nSupply an array of IDs or slugs under the \u201ccategories\u201d key to update your product\u2019s category list in bulk.<\/p>\n\n<p><strong>Automatic Slug Resolution<\/strong>\nPass slugs like \u201csummer-collection\u201d \u2014 or non-Latin slugs such as \u201c\u03b1\u03bd\u03b4\u03c1\u03b9\u03ba\u03ac\u201d \u2014 and the plugin will resolve them to the correct WooCommerce term IDs on the fly\u2014no extra lookups required.<\/p>\n\n<p><strong>Non-Destructive Updates<\/strong>\nNeither endpoint touches other product data. Categories are merged or pruned transparently without overwriting prices, stock, attributes, or any other fields.<\/p>\n\n<p><strong>Plays Well With WooCommerce<\/strong>\nChanges are saved through the WooCommerce product API, so product caches are refreshed, <code>woocommerce_update_product<\/code> runs, <code>product.updated<\/code> webhooks fire, and the store\u2019s default category is applied if a product is left without one.<\/p>\n\n<p>Built-In Validation &amp; Security<\/p>\n\n<p>Sanitization of all inputs (IDs and slugs) to guard against bad data; the batch payload is validated against a schema.<\/p>\n\n<p>Permission checks mirror WooCommerce core: only users allowed to edit the product (Shop Manager, Admin) can modify its categories.<\/p>\n\n<p>Clear, standardized error codes (w3s_api_extension_invalid_product and w3s_api_extension_invalid_product_category) for consistent API responses. Unknown category IDs and slugs both return 404.<\/p>\n\n<p>W3S API Extension for WooCommerce installs alongside the core WooCommerce REST API, requires no additional configuration, and works out of the box.<\/p>\n\n<h3>Endpoints Documentation<\/h3>\n\n<p><strong>Product Categories<\/strong><\/p>\n\n<ul>\n    <li>\n        Add a single category\n        <ul>\n            <li><strong>Type:<\/strong> HTTP request<\/li>\n            <li><strong>Endpoint:<\/strong> `\/wp-json\/wc\/v3\/products\/{product_id}\/categories\/{identifier}`<\/li>\n            <li><strong>Methods:<\/strong> POST, PUT, PATCH<\/li>\n            <li><strong>Examples:<\/strong>\n                    curl -X PUT https:\/\/example.com\/wp-json\/wc\/v3\/products\/125\/categories\/18 \\\n                                        -u consumer_key:consumer_secret\n                    curl -X PUT https:\/\/example.com\/wp-json\/wc\/v3\/products\/125\/categories\/my-category \\\n                                        -u consumer_key:consumer_secret\n            <\/li>\n        <\/ul>\n    <\/li>\n    <li>\n        Remove a single category\n        <ul>\n            <li><strong>Type:<\/strong> HTTP request<\/li>\n            <li><strong>Endpoint:<\/strong> `\/wp-json\/wc\/v3\/products\/{product_id}\/categories\/{identifier}`<\/li>\n            <li><strong>Methods:<\/strong> DELETE<\/li>\n            <li><strong>Examples:<\/strong>\n                    curl -X DELETE https:\/\/example.com\/wp-json\/wc\/v3\/products\/125\/categories\/18 \\\n                                        -u consumer_key:consumer_secret\n                    curl -X DELETE https:\/\/example.com\/wp-json\/wc\/v3\/products\/125\/categories\/my-category \\\n                                        -u consumer_key:consumer_secret\n            <\/li>\n        <\/ul>\n    <\/li>\n    <li>\n        Batch add categories\n        <ul>\n            <li><strong>Type:<\/strong> HTTP request<\/li>\n            <li><strong>Endpoint:<\/strong> `\/wp-json\/wc\/v3\/products\/{product_id}\/categories`<\/li>\n            <li><strong>Methods:<\/strong> POST, PUT, PATCH<\/li>\n            <li><strong>Example:<\/strong>\n                    curl -X PUT https:\/\/example.com\/wp-json\/wc\/v3\/products\/125\/categories \\\n                                        -u consumer_key:consumer_secret \\\n                                        -H \"Content-Type: application\/json\" \\\n                                        -d '{\"categories\": [1,\"my-category\",3,\"my-category-1\"]}'\n            <\/li>\n        <\/ul>\n    <\/li>\n    <li>\n        Batch delete categories\n        <ul>\n            <li><strong>Type:<\/strong> HTTP request<\/li>\n            <li><strong>Endpoint:<\/strong> `\/wp-json\/wc\/v3\/products\/{product_id}\/categories`<\/li>\n            <li><strong>Methods:<\/strong> DELETE<\/li>\n            <li><strong>Example:<\/strong>\n                    curl -X DELETE https:\/\/example.com\/wp-json\/wc\/v3\/products\/125\/categories \\\n                                        -u consumer_key:consumer_secret \\\n                                        -H \"Content-Type: application\/json\" \\\n                                        -d '{\"categories\": [1,\"my-category\",3,\"my-category-1\"]}'\n            <\/li>\n        <\/ul>\n    <\/li>\n<\/ul>\n\n<p><strong>Extra notes<\/strong><\/p>\n\n<ul>\n <li> Strings that include only digits are parsed as IDs, everything else as a slug. Slugs may contain any characters except \"\/\"; URL-encode them when needed (the batch endpoint takes them in the JSON body, so no encoding is required there).<\/li>\n <li> The batch endpoints also accept form-encoded `categories[]=\u2026` parameters or a comma-separated string. An empty or missing list returns a standard 400 `rest_missing_callback_param`\/`rest_invalid_param` error.<\/li>\n <li> Removing a product\u2019s last category assigns the store\u2019s default category (\u201cUncategorized\u201d), exactly as WooCommerce does in the admin.<\/li>\n <li> Every response is the product\u2019s resulting list of category terms.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>w3s-api-extension<\/code> folder to the <code>\/wp-content\/plugins\/<\/code> directory.<\/li>\n<li>Activate the plugin through the 'Plugins' menu in WordPress. WooCommerce must be installed and active.<\/li>\n<li>No further configuration is required; the endpoints are available immediately.<\/li>\n<\/ol>\n\n<!--section=changelog-->\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Compatibility: tested with WordPress 7.1 and WooCommerce 11.0. Now requires WordPress 6.7+ and WooCommerce 9.0+.<\/li>\n<li>Changed: category updates go through the WooCommerce product CRUD (<code>set_category_ids()<\/code> \/ <code>save()<\/code>). WooCommerce's product object cache (on by default for new stores since WooCommerce 11.0) is invalidated, and <code>woocommerce_update_product<\/code> and <code>product.updated<\/code> webhooks now fire.<\/li>\n<li>Fixed: numeric category IDs that do not exist (or belong to another taxonomy) now return 404 instead of silently succeeding.<\/li>\n<li>Added: the single-category endpoints accept any slug, including non-Latin (e.g. Greek) slugs.<\/li>\n<li>Added: the batch <code>categories<\/code> parameter is declared in the route schema; form-encoded and comma-separated values are accepted and invalid payloads return standard 400 errors.<\/li>\n<li>Added: item schema for API discovery (OPTIONS requests).<\/li>\n<li>Changed: permission checks mirror WooCommerce core (<code>wc_rest_check_post_permissions<\/code>), honouring the <code>woocommerce_rest_check_permissions<\/code> filter.<\/li>\n<li>Fixed: routes are no longer registered when WooCommerce is inactive (previously a fatal error on request).<\/li>\n<li>Removed: unnecessary rewrite-rule flush on activation\/deactivation.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Fixed: readme file modifications<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<\/ul>","raw_excerpt":"Enhances your store\u2019s REST API by adding powerful, flexible endpoints. Stay tuned more Endpoints are coming!","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/234416","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=234416"}],"author":[{"embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/w3specialists"}],"wp:attachment":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=234416"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=234416"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=234416"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=234416"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=234416"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=234416"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}