WooCommerce REST API Endpoints (wc/v3): Routes, Parameters and Examples
This is a practical reference for the WooCommerce REST API wc/v3 namespace: the main routes, the query parameters you will use most, pagination, batch requests and example payloads. All routes live under https://your-store.com/wp-json/wc/v3/ and require authentication.
GET /wp-json/wc/v3 returns the namespace index with every registered route and the methods and arguments it accepts. It is the quickest way to see what your store exposes, including routes added by extensions.Table of Contents
- Main wc/v3 routes
- Common query parameters
- Pagination
- Products: list, search and create
- Orders: create and update
- Customers
- Batch requests
- Trimming responses with _fields
Main wc/v3 Routes
| Resource | Routes |
|---|---|
| Products | /products, /products/<id>, /products/batch |
| Variations | /products/<product_id>/variations (+ /<id>, /batch) |
| Product taxonomies & extras | /products/categories, /products/tags, /products/attributes (+ /<id>/terms), /products/shipping_classes, /products/reviews |
| Orders | /orders, /orders/<id>, /orders/batch, /orders/<id>/notes, /orders/<id>/refunds |
| Customers | /customers, /customers/<id>, /customers/<id>/downloads, /customers/batch |
| Coupons | /coupons, /coupons/<id>, /coupons/batch |
| Webhooks | /webhooks, /webhooks/<id>, /webhooks/batch |
| Taxes | /taxes, /taxes/classes |
| Shipping | /shipping/zones, /shipping/zones/<id>/locations, /shipping/zones/<id>/methods, /shipping_methods |
| Store config | /settings, /settings/<group>, /payment_gateways, /system_status, /data (countries, currencies, continents) |
| Reports | /reports, /reports/sales, /reports/top_sellers and totals reports |
Common Query Parameters
Collection endpoints share a set of parameters inherited from WordPress:
pageandper_page– pagination (per_pagedefaults to 10, maximum 100).search– free-text search.include/exclude– comma-separated IDs.after/before– ISO 8601 dates (creation date);modified_after/modified_beforeon newer versions for incremental syncs.orderbyandorder(asc/desc).status– e.g.publish,draftfor products;processing,completedfor orders.
Products add filters such as sku, type, category, tag, featured, on_sale, min_price, max_price and stock_status. Orders add customer and product.
Pagination
Every collection response includes X-WP-Total (total items) and X-WP-TotalPages headers plus a Link header with next/prev URLs. Loop until you reach the last page:
async function fetchAll(path, auth) {
const items = [];
for (let page = 1; ; page++) {
const res = await fetch(`https://example.com/wp-json/wc/v3/${path}${path.includes('?') ? '&' : '?'}per_page=100&page=${page}`, {
headers: { Authorization: `Basic ${auth}` },
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
items.push(...await res.json());
if (page >= Number(res.headers.get('X-WP-TotalPages'))) return items;
}
}
Products: List, Search and Create
# Search published products by text
curl "https://example.com/wp-json/wc/v3/products?search=hoodie&status=publish" -u ck_xxx:cs_xxx
# Exact SKU lookup
curl "https://example.com/wp-json/wc/v3/products?sku=HD-001" -u ck_xxx:cs_xxx
Creating a simple product (prices are strings; images are sideloaded from the URLs you pass):
curl -X POST https://example.com/wp-json/wc/v3/products -u ck_xxx:cs_xxx \
-H "Content-Type: application/json" \
-d '{
"name": "Logo Hoodie",
"type": "simple",
"status": "draft",
"sku": "HD-001",
"regular_price": "49.00",
"description": "<p>Heavyweight cotton hoodie.</p>",
"short_description": "Heavyweight cotton hoodie.",
"categories": [ { "id": 15 } ],
"images": [ { "src": "https://example.com/uploads/hoodie.jpg" } ],
"manage_stock": true,
"stock_quantity": 25
}'
Descriptions accept HTML. If line breaks in description look wrong, send <p>/<br> markup rather than raw \n characters.
Orders: Create and Update
# Mark an order completed (PUT, PATCH and POST are all accepted for updates)
curl -X PUT https://example.com/wp-json/wc/v3/orders/727 -u ck_xxx:cs_xxx \
-H "Content-Type: application/json" -d '{ "status": "completed" }'
# Add a private order note
curl -X POST https://example.com/wp-json/wc/v3/orders/727/notes -u ck_xxx:cs_xxx \
-H "Content-Type: application/json" -d '{ "note": "Shipped via DHL", "customer_note": false }'
Creating an order:
{
"payment_method": "bacs",
"payment_method_title": "Direct bank transfer",
"set_paid": false,
"billing": { "first_name": "Ana", "last_name": "Diaz", "email": "[email protected]", "country": "ES" },
"line_items": [ { "product_id": 93, "quantity": 2 } ],
"shipping_lines": [ { "method_id": "flat_rate", "method_title": "Flat rate", "total": "5.00" } ]
}
Order endpoints work the same whether the store uses High-Performance Order Storage (HPOS) or legacy post storage, which is one reason to integrate through the API rather than querying order tables directly.
Customers
POST /customers requires an email; username and password are optional (WooCommerce generates them according to your account settings). Responses never include password hashes. Use GET /[email protected] to look up a customer by email and role=all to include non-customer roles.
Batch Requests
Most resources have a /batch route that creates, updates and deletes in one request. Each object in update must include its id:
POST /wp-json/wc/v3/products/batch
{
"create": [ { "name": "Cap", "regular_price": "15.00" } ],
"update": [ { "id": 799, "regular_price": "19.99" }, { "id": 800, "stock_quantity": 0 } ],
"delete": [ 794 ]
}
By default a batch request accepts up to 100 objects in total (filterable with woocommerce_rest_batch_items_limit). The response returns per-item results, so check each item for an error key instead of relying on the HTTP status.
Trimming Responses with _fields
WordPress's global _fields parameter limits the response to the properties you need, which makes large product exports much lighter:
curl "https://example.com/wp-json/wc/v3/products?per_page=100&_fields=id,sku,price,stock_quantity" -u ck_xxx:cs_xxx
For the full list of properties per resource, see the official WooCommerce REST API documentation. For receiving changes instead of polling, see WooCommerce webhooks.