Stitchflow
WooCommerce logo

WooCommerce User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 16, 2026

Summary and recommendation

The WooCommerce REST API (base: `https://{store_domain}/wp-json/wc/v3`) exposes a `/customers` resource that maps to WordPress users holding the `customer` role.

Authentication is Consumer Key/Secret via HTTP Basic Auth over HTTPS;

OAuth 1.0a is available only for non-HTTPS environments-this is not OAuth 2.0.

Always pin to `wc/v3` in the URL path;

`wc/v2` and `wc/v1` expose different field sets.

There is no native SCIM 2.0 endpoint;

SCIM provisioning requires third-party plugins or middleware.

For teams building against an identity graph, the stable join key is the WordPress user `id` (integer), which is returned on customer creation and used across the `/customers`, `/orders`, and `/wp/v2/users` endpoints.

API quick reference

Has user APIYes
Auth methodHTTP Basic Auth (Consumer Key as username, Consumer Secret as password) over HTTPS; OAuth 1.0a for non-HTTPS environments
Base URLOfficial docs
SCIM availableNo
SCIM plan requiredN/A

Authentication

Auth method: HTTP Basic Auth (Consumer Key as username, Consumer Secret as password) over HTTPS; OAuth 1.0a for non-HTTPS environments

Setup steps

  1. Log in to WordPress admin and navigate to WooCommerce > Settings > Advanced > REST API.
  2. Click 'Add key', enter a description, select the WordPress user, and choose permission level (Read, Write, or Read/Write).
  3. Click 'Generate API key' to receive the Consumer Key and Consumer Secret.
  4. For HTTPS: pass Consumer Key and Consumer Secret via HTTP Basic Auth header (Authorization: Basic base64(ck:cs)).
  5. For non-HTTPS: use OAuth 1.0a signing with the Consumer Key and Consumer Secret.

Required scopes

Scope Description Required for
Read Allows GET requests to all WooCommerce REST API endpoints. Listing and retrieving customers
Write Allows POST, PUT, PATCH, DELETE requests to all WooCommerce REST API endpoints. Creating, updating, and deleting customers
Read/Write Full access combining Read and Write permissions. Full customer lifecycle management

User object / data model

Field Type Description On create On update Notes
id integer Unique customer identifier (WordPress user ID). read-only read-only Auto-assigned by WordPress.
email string Customer email address. required optional Must be unique across the site.
first_name string Customer first name. optional optional
last_name string Customer last name. optional optional
username string WordPress username. optional read-only Auto-generated from email if not provided. Cannot be changed after creation via API.
password string Customer password. optional optional Write-only; never returned in responses.
role string WordPress user role (e.g., 'customer', 'subscriber'). read-only read-only Defaults to 'customer'. Not directly settable via WooCommerce REST API.
date_created date-time ISO 8601 date the customer was created (site timezone). read-only read-only
date_created_gmt date-time ISO 8601 date the customer was created (UTC). read-only read-only
date_modified date-time ISO 8601 date the customer was last modified (site timezone). read-only read-only
billing object Billing address object (first_name, last_name, company, address_1, address_2, city, state, postcode, country, email, phone). optional optional
shipping object Shipping address object (first_name, last_name, company, address_1, address_2, city, state, postcode, country). optional optional
is_paying_customer boolean Whether the customer has completed at least one order. read-only read-only
avatar_url string Gravatar URL for the customer. read-only read-only Derived from email via Gravatar.
meta_data array Array of custom meta data objects ({id, key, value}). optional optional Allows storing arbitrary key-value pairs on the customer record.
orders_count integer Number of orders placed by the customer. read-only read-only
total_spent string Total amount spent by the customer (decimal string). read-only read-only

Core endpoints

List customers

  • Method: GET
  • URL: /wp-json/wc/v3/customers
  • Watch out for: Default role filter is 'customer'. Pass role=all to include all WordPress user roles. Guests (no account) are not returned.

Request example

GET /wp-json/wc/v3/customers?per_page=10&page=1&role=customer

Response example

[{"id":5,"email":"jane@example.com","first_name":"Jane","last_name":"Doe","username":"janedoe","role":"customer","orders_count":3,"total_spent":"150.00"}]

Retrieve a customer

  • Method: GET
  • URL: /wp-json/wc/v3/customers/{id}
  • Watch out for: ID is the WordPress user ID, not an order or WooCommerce-specific ID.

Request example

GET /wp-json/wc/v3/customers/5

Response example

{"id":5,"email":"jane@example.com","first_name":"Jane","last_name":"Doe","billing":{"address_1":"123 Main St","city":"Austin","country":"US"}}

Create a customer

  • Method: POST
  • URL: /wp-json/wc/v3/customers
  • Watch out for: email is required. If username is omitted, WooCommerce auto-generates one from the email. Password is write-only and never returned.

Request example

POST /wp-json/wc/v3/customers
{"email":"new@example.com","first_name":"John","last_name":"Smith","password":"securepass"}

Response example

{"id":12,"email":"new@example.com","first_name":"John","last_name":"Smith","username":"johnsmith","role":"customer"}

Update a customer

  • Method: PUT
  • URL: /wp-json/wc/v3/customers/{id}
  • Watch out for: username cannot be changed after creation. Partial updates are supported (only supplied fields are changed).

Request example

PUT /wp-json/wc/v3/customers/12
{"first_name":"Jonathan","billing":{"phone":"555-1234"}}

Response example

{"id":12,"email":"new@example.com","first_name":"Jonathan","billing":{"phone":"555-1234"}}

Delete a customer

  • Method: DELETE
  • URL: /wp-json/wc/v3/customers/{id}
  • Watch out for: force=true is required; the WooCommerce REST API does not support soft-delete (trash) for customers. This permanently deletes the WordPress user.

Request example

DELETE /wp-json/wc/v3/customers/12?force=true

Response example

{"id":12,"email":"new@example.com","first_name":"Jonathan","last_name":"Smith"}

Batch create/update/delete customers

  • Method: POST
  • URL: /wp-json/wc/v3/customers/batch
  • Watch out for: Batch requests are limited to 100 objects per call per the WooCommerce docs. Exceeding this limit returns a 400 error.

Request example

POST /wp-json/wc/v3/customers/batch
{"create":[{"email":"a@x.com","first_name":"A"}],"update":[{"id":5,"last_name":"Updated"}],"delete":[12]}

Response example

{"create":[{"id":13,"email":"a@x.com"}],"update":[{"id":5,"last_name":"Updated"}],"delete":[{"id":12}]}

List customer downloads

  • Method: GET
  • URL: /wp-json/wc/v3/customers/{id}/downloads
  • Watch out for: Returns downloadable product access records for the customer. Read-only endpoint.

Request example

GET /wp-json/wc/v3/customers/5/downloads

Response example

[{"download_id":"abc123","download_url":"https://...","product_id":42,"product_name":"eBook"}]

Retrieve customer orders (via orders endpoint)

  • Method: GET
  • URL: /wp-json/wc/v3/orders
  • Watch out for: There is no dedicated /customers/{id}/orders sub-resource. Filter the /orders endpoint using the customer query parameter (WordPress user ID).

Request example

GET /wp-json/wc/v3/orders?customer=5

Response example

[{"id":101,"status":"completed","customer_id":5,"total":"49.99"}]

Rate limits, pagination, and events

  • Rate limits: WooCommerce itself does not impose API-level rate limits. Rate limiting is determined by the underlying WordPress hosting environment (server, PHP-FPM workers, web server config). No official rate-limit documentation exists from WooCommerce.

  • Rate-limit headers: No

  • Retry-After header: No

  • Rate-limit notes: Rate limits are host-dependent. Managed WordPress hosts (e.g., WP Engine, Kinsta) may enforce their own request throttling. WooCommerce docs do not specify rate-limit headers or Retry-After behavior.

  • Pagination method: offset

  • Default page size: 10

  • Max page size: 100

  • Pagination pointer: page / per_page

  • Webhooks available: Yes

  • Webhook notes: WooCommerce supports webhooks configurable via WooCommerce > Settings > Advanced > Webhooks or via the REST API (/wp-json/wc/v3/webhooks). Webhooks fire HTTP POST payloads to a configured URL on specified events.

  • Alternative event strategy: WordPress action hooks (e.g., woocommerce_new_customer, woocommerce_update_customer) can be used server-side for custom integrations.

  • Webhook events: customer.created, customer.updated, customer.deleted

SCIM API status

  • SCIM available: No
  • SCIM version: Not documented
  • Plan required: N/A
  • Endpoint: Not documented

Limitations:

  • WooCommerce has no native SCIM 2.0 support.
  • SCIM provisioning requires third-party plugins or middleware (e.g., IdP-specific connectors).
  • No official WooCommerce SCIM endpoint exists.

Common scenarios

Three integration patterns cover the majority of customer lifecycle use cases:

Provisioning: POST to /wp-json/wc/v3/customers with at minimum {email, password}.

Capture the returned id immediately-it is the WordPress user ID and the durable identity graph anchor.

If the email already exists, the API returns a 400;

pre-check with GET /wp-json/wc/v3/customers?email={email} before writing.

Profile sync: Use PUT to /wp-json/wc/v3/customers/{id} for individual updates;

partial updates are supported.

For bulk operations, POST to /wp-json/wc/v3/customers/batch with an update array capped at 100 objects per call-larger sets must be split.

Critical caveat: username and role cannot be changed via the WooCommerce REST API.

Role changes require a separate call to the WordPress REST API (PUT /wp/v2/users/{id}) using admin-level application password credentials.

Event-driven triggers: Register a webhook via POST /wp-json/wc/v3/webhooks with topic: 'customer.created'.

Validate payloads using the X-WC-Webhook-Signature header (HMAC-SHA256).

Note that guest checkouts (customer_id=0) do not trigger customer.created and are not accessible via /customers at all.

Provision a new customer account

  1. Generate a Read/Write API key in WooCommerce > Settings > Advanced > REST API.
  2. POST to /wp-json/wc/v3/customers with at minimum {email, password}.
  3. Capture the returned id (WordPress user ID) for future reference.
  4. Optionally update billing/shipping address with a PUT to /wp-json/wc/v3/customers/{id}.

Watch out for: If the email already exists as a WordPress user, the API returns a 400 error ('Sorry, that email address is already used!'). Check for existing users first with GET /wp-json/wc/v3/customers?email={email}.

Sync customer profile updates from an external system

  1. Query the external system for changed user records.
  2. For each changed record, PUT to /wp-json/wc/v3/customers/{id} with only the changed fields.
  3. For bulk updates, use POST /wp-json/wc/v3/customers/batch with an 'update' array (max 100 per call).
  4. Handle 404 responses by creating the customer instead (POST /wp-json/wc/v3/customers).

Watch out for: username and role cannot be updated via the WooCommerce REST API. Role changes require the WordPress REST API (/wp/v2/users/{id}) with an admin-level application password.

Receive real-time notification on new customer registration

  1. Navigate to WooCommerce > Settings > Advanced > Webhooks and click 'Add webhook'.
  2. Set Topic to 'Customer created', enter the delivery URL, and set Status to 'Active'.
  3. Alternatively, create the webhook via API: POST /wp-json/wc/v3/webhooks with {name, topic:'customer.created', delivery_url, status:'active'}.
  4. Validate the incoming webhook payload using the X-WC-Webhook-Signature header (HMAC-SHA256 of the payload using the webhook secret).

Watch out for: Webhooks fire for registered customers only. Guest checkouts do not trigger customer.created. Webhook delivery failures are retried up to 5 times with exponential backoff; after 5 failures the webhook is disabled automatically.

Why building this yourself is a trap

Several behaviors in the WooCommerce API are non-obvious and will cause integration failures if not handled explicitly:

  • Hard delete only: DELETE /wp-json/wc/v3/customers/{id} requires force=true and permanently destroys the underlying WordPress user. There is no soft-delete or trash state. Any identity graph reference to that id becomes a dangling pointer.
  • Rate limits are invisible: WooCommerce publishes no rate-limit headers and no Retry-After behavior. Throttling is entirely host-dependent (e.g., WP Engine, Kinsta enforce their own limits). Build retry logic with exponential backoff defensively, not reactively.
  • Pagination defaults are low: The default page size is 10; max is 100 via per_page. The /customers endpoint defaults to role=customer-pass role=all to surface Shop Managers and Administrators, or they will be silently omitted from list results.
  • Webhook reliability: Failed webhook deliveries retry up to 5 times with exponential backoff; after 5 failures the webhook is automatically disabled. Monitor webhook status actively if your pipeline depends on real-time customer events.

Automate WooCommerce workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 16, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

Abnormal Security logo

Abnormal Security

API Only
AutomationAPI only
Last updatedMar 2026

Abnormal Security is an enterprise email security platform focused on detecting and investigating threats such as phishing, account takeover (ATO), and vendor email compromise. It does not support SCIM provisioning, which means every app in your stack

ActiveCampaign logo

ActiveCampaign

API Only
AutomationAPI only
Last updatedFeb 2026

ActiveCampaign uses a group-based permission model: every user belongs to exactly one group, and all feature-area access (Contacts, Campaigns, Automations, Deals, Reports, Templates) is configured at the group level, not per individual. The default Adm

ADP logo

ADP

API Only
AutomationAPI only
Last updatedFeb 2026

ADP Workforce Now is a mid-market to enterprise HCM platform that serves as the HR source of record for employee data — payroll, benefits, time, and talent. User access is governed by a hybrid permission model: predefined security roles (Security Maste