Getting started with the WooCommerce REST API: a developer’s guide

WooCommerce ships with a powerful REST API that exposes virtually every aspect of your store — products, orders, customers, coupons, shipping zones, tax rates, and more. Whether you’re building a headless storefront, syncing inventory with an ERP, automating order management, or connecting a PIM system, the WooCommerce REST API is your primary entry point. According to BuiltWith, WooCommerce powers over 6 million live websites worldwide, making a solid understanding of its API essential for any developer working in the e-commerce space.

This guide walks you through everything you need to get started: authentication methods, key endpoints, filtering, pagination, batch operations, webhooks, error handling, and best practices for production-grade integrations.

What Is the WooCommerce REST API?

The WooCommerce REST API is a JSON-based interface built on top of the WordPress REST API infrastructure. It follows standard REST conventions, using HTTP methods (GET, POST, PUT, PATCH, DELETE) and returning JSON responses. The current stable version is WC/v3, which is available on all stores running WooCommerce 3.5 or later.

The API gives developers programmatic access to nearly every data object in a WooCommerce store, including:

  • Products and product variations
  • Orders and order notes
  • Customers and their purchase history
  • Coupons and discounts
  • Shipping zones, methods, and classes
  • Tax rates and tax classes
  • Payment gateways
  • Reports and sales data
  • Webhooks
  • System status and settings

Because it’s built on the WordPress REST API, it also inherits WordPress authentication and permission structures, which gives you fine-grained control over what each API key can access.

Authentication

WooCommerce supports two primary authentication methods: OAuth 1.0a for HTTP connections and Basic Authentication for HTTPS connections. For virtually all production environments, HTTPS with Basic Auth is the simpler and preferred approach.

Generating API Keys

To generate your Consumer Key and Consumer Secret, navigate to WooCommerce → Settings → Advanced → REST API and click “Add Key.” You’ll be prompted to assign the key to a specific WordPress user, give it a description, and choose a permission level:

  • Read — allows GET requests only
  • Write — allows POST, PUT, PATCH, and DELETE requests only
  • Read/Write — full access

Always follow the principle of least privilege: if an integration only needs to read order data, create a Read-only key for it. Store your keys securely — treat them like passwords. Never commit them to version control or expose them in client-side code.

Basic Authentication (HTTPS)

For server-to-server requests over HTTPS, pass the consumer key and consumer secret as HTTP Basic Auth credentials. Here’s an example using Python’s requests library:

import requests
from requests.auth import HTTPBasicAuth

auth = HTTPBasicAuth('ck_your_consumer_key', 'cs_your_consumer_secret')
response = requests.get(
    'https://yourstore.com/wp-json/wc/v3/products',
    auth=auth
)
print(response.json())

And here’s the same request using JavaScript with the native fetch API:

const credentials = btoa('ck_your_consumer_key:cs_your_consumer_secret');

fetch('https://yourstore.com/wp-json/wc/v3/products', {
  headers: {
    'Authorization': `Basic ${credentials}`
  }
})
.then(res => res.json())
.then(data => console.log(data));

OAuth 1.0a Authentication

OAuth 1.0a is required when your integration runs over plain HTTP (not HTTPS). It’s more complex to implement, as each request must be signed with a timestamp, nonce, and HMAC-SHA256 signature. In practice, most developers use an OAuth library to handle the signing process rather than implementing it manually.

That said, if you are deploying to a production store, there is no good reason to use HTTP over HTTPS in 2024. Use Basic Auth over TLS and keep your implementation simple.

Key Endpoints

All endpoints are prefixed with https://yourstore.com/wp-json/wc/v3/. Below is a structured overview of the most commonly used endpoints grouped by resource.

Products

  • GET /products — list all products
  • POST /products — create a new product
  • GET /products/{id} — retrieve a specific product
  • PUT /products/{id} — update a product
  • DELETE /products/{id} — delete a product
  • GET /products/{id}/variations — list variations of a variable product
  • GET /products/categories — list product categories
  • GET /products/attributes — list product attributes

Orders

  • GET /orders — list all orders
  • POST /orders — create a new order
  • GET /orders/{id} — retrieve a specific order
  • PUT /orders/{id} — update an order (e.g., change status)
  • DELETE /orders/{id} — delete an order
  • GET /orders/{id}/notes — list notes on an order
  • POST /orders/{id}/notes — add a note to an order
  • GET /orders/{id}/refunds — list refunds for an order

Customers

  • GET /customers — list all customers
  • POST /customers — create a new customer
  • GET /customers/{id} — retrieve a customer
  • PUT /customers/{id} — update a customer
  • GET /customers/{id}/orders — list orders for a customer
  • GET /customers/{id}/downloads — list downloads for a customer

Coupons

  • GET /coupons — list all coupons
  • POST /coupons — create a new coupon
  • GET /coupons/{id} — retrieve a specific coupon
  • PUT /coupons/{id} — update a coupon
  • DELETE /coupons/{id} — delete a coupon

Reports

  • GET /reports/sales — sales totals for a date range
  • GET /reports/top_sellers — top selling products
  • GET /reports/orders/totals — order counts by status

Filtering and Pagination

For stores with large catalogs or order histories, efficient filtering and pagination are critical. Attempting to fetch all records in a single request can time out the server, exhaust memory limits, or return incomplete results. Always design your integration to handle data in pages.

Pagination Parameters

WooCommerce uses WordPress-standard pagination parameters:

  • per_page — number of results per page (default: 10, max: 100)
  • page — the page number to retrieve (default: 1)
  • offset — offset the result set by a specific number of items

The API response includes useful headers for pagination: X-WP-Total (total number of records) and X-WP-TotalPages (total number of pages). Use these to build your loop logic.

page = 1
per_page = 100
all_orders = []

while True:
    response = requests.get(
        'https://yourstore.com/wp-json/wc/v3/orders',
        auth=auth,
        params={'per_page': per_page, 'page': page, 'status': 'completed'}
    )
    orders = response.json()
    if not orders:
        break
    all_orders.extend(orders)
    total_pages = int(response.headers.get('X-WP-TotalPages', 1))
    if page >= total_pages:
        break
    page += 1

Filtering Parameters

Most endpoints support a rich set of query parameters for filtering:

  • status — filter by status (e.g., publish, pending, processing, completed)
  • after / before — filter by date range (ISO 8601 format)
  • search — keyword search
  • category — filter products by category ID
  • sku — filter products by SKU
  • customer — filter orders by customer ID
  • orderby — sort field (e.g., date, id, title)
  • order — sort direction (asc or desc)

Example: fetch all orders placed between January 1 and January 31, 2024, sorted by date descending:

params = {
    'after': '2024-01-01T00:00:00',
    'before': '2024-01-31T23:59:59',
    'orderby': 'date',
    'order': 'desc',
    'per_page': 100
}
response = requests.get(
    'https://yourstore.com/wp-json/wc/v3/orders',
    auth=auth,
    params=params
)

Batch Operations

The WooCommerce REST API supports batch processing via a dedicated /batch endpoint on most resources. This allows you to create, update, or delete multiple records in a single HTTP request, dramatically reducing the number of round trips required for bulk operations.

This is particularly valuable for large catalog imports, price updates, or syncing inventory from an external system. Without batch operations, importing 500 products would require 500 individual POST requests. With batching, you can handle that in as few as 5 requests (max 100 items per batch call).

The batch endpoint accepts a JSON body with three optional keys: create, update, and delete. Here’s an example that updates stock quantities for three products in one call:

batch_data = {
    "update": [
        {"id": 101, "stock_quantity": 50},
        {"id": 102, "stock_quantity": 25},
        {"id": 103, "stock_quantity": 0}
    ]
}

response = requests.post(
    'https://yourstore.com/wp-json/wc/v3/products/batch',
    auth=auth,
    json=batch_data
)
print(response.json())

The response includes individual results for each item in the batch, so you can identify which operations succeeded and which failed without reprocessing the entire batch.

Working with Webhooks

Rather than polling the API repeatedly to check for changes, WooCommerce webhooks let you receive real-time push notifications when events occur. This is far more efficient for event-driven integrations.

You can manage webhooks via the API (/wp-json/wc/v3/webhooks) or through the WooCommerce admin panel under WooCommerce → Settings → Advanced → Webhooks. Supported events include:

  • order.created, order.updated, order.deleted
  • product.created, product.updated, product.deleted
  • customer.created, customer.updated, customer.deleted
  • coupon.created, coupon.updated, coupon.deleted

WooCommerce signs webhook payloads using HMAC-SHA256 with a secret key, and sends the signature in the X-WC-Webhook-Signature header. Always validate this signature on the receiving end to confirm the request genuinely came from your store.

Error Handling and Rate Limiting

The WooCommerce REST API returns standard HTTP status codes. Here are the ones you’ll encounter most frequently:

  • 200 OK — successful GET, PUT, PATCH
  • 201 Created — successful POST (resource created)
  • 400 Bad Request — malformed request or validation error
  • 401 Unauthorized — authentication failed or missing
  • 403 Forbidden — valid credentials but insufficient permissions
  • 404 Not Found — resource does not exist
  • 500 Internal Server Error — server-side error

Error responses include a JSON body with a code and message field that provide more context. For example:

{
  "code": "woocommerce_rest_product_invalid_id",
  "message": "Invalid ID.",
  "data": { "status": 404 }
}

WooCommerce itself does not enforce a hard rate limit, but your web server (nginx, Apache) or hosting provider may impose request limits. Always implement exponential backoff and retry logic in your integration to handle transient failures gracefully. If you receive a 429 Too Many Requests or 503 Service Unavailable, wait before retrying.

Best Practices for Production Integrations

Running WooCommerce API integrations in production requires more than just getting the requests right. Here are key best practices to keep your integration stable and maintainable:

  • Always use HTTPS. Never transmit API credentials over unencrypted connections. Enforce TLS across your entire integration stack.
  • Rotate API keys periodically. Treat compromised keys the same way you’d treat a compromised password — revoke and regenerate immediately.
  • Use scoped keys. Create separate API keys for each integration or service, each with the minimum required permissions. This limits blast radius if a key is leaked.
  • Cache aggressively. For read-heavy operations like product catalog queries, implement caching at the application layer to reduce API load on your WooCommerce server.
  • Log all API interactions. Store request timestamps, endpoints, response codes, and error messages. This makes debugging integration failures significantly faster.
  • Use idempotency checks. For order creation or customer creation, build in deduplication logic to prevent duplicate records caused by retry attempts.
  • Monitor performance over time. Track response times and error rates. Sudden spikes in 500 errors or timeout rates often signal a WordPress plugin conflict or server resource issue, not a problem in your integration code.
  • Test against a staging environment. Never develop or test directly against your production store. Use a staging site with a production-equivalent dataset.

Using the Official WooCommerce API Client Libraries

While you can interact with the WooCommerce REST API using any HTTP library, the WooCommerce team maintains official client libraries that abstract authentication and request signing. This reduces boilerplate code and keeps your integration aligned with API conventions.

The officially supported libraries are:

Here’s how to retrieve a list of products using the official Python library:

from woocommerce import API

wcapi = API(
    url="https://yourstore.com",
    consumer_key="ck_your_consumer_key",
    consumer_secret="cs_your_consumer_secret",
    version="wc/v3"
)

response = wcapi.get("products", params={"per_page": 20, "status": "publish"})
print(response.json())

The library handles OAuth signing automatically when the store URL uses HTTP, and switches to Basic Auth for HTTPS — one less thing to manage manually in your code.

Connecting WooCommerce to Other Systems

The WooCommerce REST API is powerful on its own, but for enterprise-grade integrations with ERP systems (SAP, Microsoft Dynamics, NetSuite), PIM platforms (Akeneo, Contentserv), or CRM tools (Salesforce, HubSpot), building and maintaining direct API integrations from scratch comes with significant overhead. You need to handle authentication management, error recovery, data transformation, logging, monitoring, and retry logic — all before writing a single line of business logic.

This is where a managed integration platform (iPaaS) adds real value. Solutions like Alumio provide pre-built connectors for WooCommerce and hundreds of other platforms, along with visual data mapping, built-in error handling, and real-time monitoring dashboards. Instead of maintaining a fragile custom integration, your team can focus on the business logic that actually differentiates your operation.

For teams running high-volume stores or complex multi-system architectures, an iPaaS approach typically reduces integration development time by 60–80% compared to building custom middleware. It also provides the observability tooling — logs, alerts, retry queues — that production integrations require from day one.

Frequently Asked Questions

What version of the WooCommerce REST API should I use?

You should use WC/v3 for all new integrations. It is the current stable version and supports the full range of endpoints. Earlier versions (v1, v2) are deprecated and may be removed in future WooCommerce releases. The API base URL for v3 is https://yourstore.com/wp-json/wc/v3/.

How do I enable the WooCommerce REST API?

The REST API is enabled by default in WooCommerce. However, you need to have Pretty Permalinks enabled in WordPress for the API to function correctly. Go to WordPress → Settings → Permalinks and choose any option other than “Plain.” Then generate your API keys under WooCommerce → Settings → Advanced → REST API.

Can I use the WooCommerce REST API without SSL?

Technically yes — you can use OAuth 1.0a authentication over HTTP. However, this is strongly discouraged for any production or staging environment because your data is transmitted unencrypted. All production WooCommerce stores should be running HTTPS, which enables simpler Basic Authentication and protects your credentials from interception.

What is the maximum number of results I can retrieve per page?

The WooCommerce REST API has a maximum per_page value of 100. If you need to retrieve more than 100 records, you must paginate through multiple pages using the page parameter. Use the X-WP-Total and X-WP-TotalPages response headers to determine how many pages you need to iterate through.

How do I handle WooCommerce API rate limiting?

WooCommerce does not impose its own rate limits, but your hosting server or reverse proxy (Cloudflare, nginx, etc.) may. If you receive 429 Too Many Requests or 503 Service Unavailable responses, implement exponential backoff — start by waiting 1 second, then double the wait time on each subsequent failure (e.g., 1s, 2s, 4s, 8s) up to a reasonable maximum. Also consider rate-limiting your own requests proactively: for most hosting environments, keeping requests under 5–10 per second is a safe starting point.

Can I create custom endpoints in the WooCommerce REST API?

Yes. Because the WooCommerce REST API is built on the WordPress REST API, you can register custom endpoints using the register_rest_route() function in WordPress. This is useful when you need to expose custom post types, aggregate data across multiple WooCommerce resources, or create endpoints tailored to a specific frontend or mobile application.

How do WooCommerce webhooks compare to polling the API?

Webhooks are significantly more efficient than polling for event-driven use cases. Polling requires your system to make repeated API requests on a schedule, even when nothing has changed — this wastes server resources and increases latency. Webhooks deliver a push notification to your endpoint the moment an event occurs (e.g., a new order is placed), allowing you to react in near real-time without any unnecessary API traffic. For integrations where timeliness matters — such as order fulfillment pipelines or real-time inventory sync — webhooks are almost always the right choice.

What are the main differences between using a direct WooCommerce API integration and an iPaaS platform?

A direct API integration gives you full control and flexibility, but requires you to build and maintain all supporting infrastructure: authentication, error handling, retry logic, data transformation, logging, and monitoring. An iPaaS platform like Alumio provides all of this out of the box through a managed environment with pre-built connectors, visual mapping tools, and operational dashboards. Direct integrations are a good fit for simple, low-volume use cases. For complex, multi-system architectures — especially those connecting WooCommerce to ERP, PIM, or CRM platforms — an iPaaS typically delivers faster time to production and lower long-term maintenance costs.