WooCommerce REST API vs Shopify admin API for developers (2026)
A developer's comparison of the WooCommerce REST API and Shopify Admin API — authentication, rate limits, pagination, webhooks, and how to migrate integrations when moving from WooCommerce to Shopify.
If your WooCommerce store has custom integrations — ERP sync, inventory management, fulfillment system, analytics data pipeline — these integrations use the WooCommerce REST API. After migrating to Shopify, these integrations need to be rebuilt or adapted to use the Shopify Admin API. This guide covers the key differences developers need to understand.
Authentication comparison
WooCommerce REST API auth
WooCommerce uses Consumer Key + Consumer Secret pairs:
- Keys are generated in WooCommerce → Settings → Advanced → REST API
- Authentication via HTTP Basic Auth header:
Authorization: Basic base64(consumerKey:consumerSecret) - Or via query parameters:
?consumer_key=ck_xxx&consumer_secret=cs_xxx(not recommended for HTTPS-optional environments) - Per-key permission levels: Read, Write, Read/Write
- No token expiry — keys are permanent until revoked
Shopify Admin API auth
Shopify has two auth methods depending on use case:
- Private apps / Custom apps (Admin API access tokens): Single-store access tokens generated in Shopify Admin → Settings → Apps → Develop apps. Used for ERP integrations, internal tools. Similar concept to WooCommerce consumer keys.
Header:X-Shopify-Access-Token: shpat_xxx - Public apps (OAuth 2.0): For apps installed by multiple merchants. Goes through Shopify's OAuth flow to get per-store access tokens. Required for Shopify App Store apps.
Header:X-Shopify-Access-Token: shpat_xxx(same header, token obtained via OAuth)
For migrating custom integrations, use Custom Apps (Admin API access token) — same pattern as WooCommerce's consumer keys, just a different header and token format.
API base URLs
// WooCommerce
https://yourstore.com/wp-json/wc/v3/products
https://yourstore.com/wp-json/wc/v3/orders
https://yourstore.com/wp-json/wc/v3/customers
// Shopify Admin REST API
https://your-store.myshopify.com/admin/api/2024-01/products.json
https://your-store.myshopify.com/admin/api/2024-01/orders.json
https://your-store.myshopify.com/admin/api/2024-01/customers.json
// Shopify Admin GraphQL API
https://your-store.myshopify.com/admin/api/2024-01/graphql.json
Shopify has both a REST API and a GraphQL Admin API. The REST API is simpler for direct WooCommerce API replacement. The GraphQL API is more powerful (request only needed fields, mutations for complex operations, bulk operations) and is Shopify's recommended path for new integrations.
Rate limits
WooCommerce rate limits
WooCommerce itself doesn't enforce API rate limits — rate limiting is handled at the server level (nginx rate limiting, Cloudflare WAF rules). Typical WooCommerce hosts allow 100–1000 requests/minute. Server-dependent.
Shopify rate limits
Shopify enforces explicit rate limits at the API level:
- REST API: Bucket algorithm. Standard: 40 requests in the bucket, refills at 2/second. Each REST API call costs 1 bucket point. Response headers include
X-Shopify-Shop-Api-Call-Limitshowing current usage. - GraphQL API: Cost-based rate limiting. Each query has a cost. Standard: 1000 cost units/second max, bucket capacity of 1000. Simple queries cost 1–10 units; complex nested queries cost more.
- Bulk Operations (GraphQL): Separate, for large data exports. One bulk operation at a time, but processes millions of records without rate limit concerns.
For migration tools and data sync, rate limit handling is critical. k-sync uses retry logic with exponential backoff when the Shopify rate limit is hit.
Pagination
WooCommerce pagination
// Page-based
GET /wp-json/wc/v3/products?per_page=100&page=1
GET /wp-json/wc/v3/products?per_page=100&page=2
// Response headers include X-WP-Total and X-WP-TotalPages
// per_page max: 100
Shopify pagination
// REST API: Cursor-based pagination
GET /admin/api/2024-01/products.json?limit=250
// Response header: Link: <https://...>; rel="next"
// Follow the "next" cursor link for subsequent pages
// limit max: 250
// GraphQL: Connection-based cursor pagination
query {
products(first: 50, after: "cursor_string") {
pageInfo { hasNextPage endCursor }
nodes { id title }
}
}
Shopify's cursor-based pagination is more reliable for large datasets (no missed records if new items are added during pagination). WooCommerce's page-based pagination can miss records if products are added/deleted while paginating.
Webhooks comparison
WooCommerce webhooks
- Created in WooCommerce → Settings → Advanced → Webhooks
- Events: order.created, order.updated, order.deleted, product.created, product.updated, product.deleted, customer.created, customer.updated
- Payload: full WooCommerce object JSON
- Delivery: HTTP POST to your endpoint
- Retry: WooCommerce retries failed deliveries
Shopify webhooks
- Created via Admin API:
POST /admin/api/2024-01/webhooks.json - Or in Admin UI: Settings → Notifications → Webhooks
- Events: 100+ topics covering orders, products, customers, checkouts, inventory, fulfillments, collections, and more
- Payload: full Shopify object JSON
- Verification: HMAC-SHA256 signature in
X-Shopify-Hmac-Sha256header — always verify in production - Delivery: Shopify retries for 48 hours with exponential backoff on failure
// Webhook verification (Node.js)
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', SHOPIFY_WEBHOOK_SECRET);
hmac.update(rawBody, 'utf8', 'hex');
const digest = hmac.digest('base64');
const valid = digest === req.headers['x-shopify-hmac-sha256'];
Data structure differences for common objects
Products
| WooCommerce field | Shopify equivalent |
|---|---|
| id | id |
| name | title |
| slug | handle |
| description | body_html |
| short_description | No direct equivalent — use metafield or prepend to body_html |
| status: publish/draft | status: active/draft |
| sku (simple product) | variants[0].sku |
| price/regular_price | variants[0].price |
| sale_price | variants[0].compare_at_price |
| categories (array) | No native categories — use collections (separate relationship) |
| tags (array) | tags (comma-separated string) |
| images (array) | images (array) with variant associations |
| variations (array) | variants (array) |
| attributes (for variations) | options + variant option values |
Orders
| WooCommerce field | Shopify equivalent |
|---|---|
| id / order_number | id / order_number (different values) |
| status (wc-processing, wc-completed) | financial_status + fulfillment_status |
| total / subtotal | total_price / subtotal_price |
| billing (object) | billing_address (object) |
| shipping (object) | shipping_address (object) |
| line_items (array with product_id) | line_items (array with variant_id) |
| shipping_lines | shipping_lines |
| fee_lines | No direct equivalent — handling fees go in shipping_lines |
| tax_lines | tax_lines |
| customer_note | note |
Migrating custom integrations
ERP / inventory sync
Replace WooCommerce REST calls with Shopify REST or GraphQL equivalents. Key mapping:
- Product inventory: WC
/products/{id}?stock_quantity=N→ Shopify/inventory_levels/set.json(needs location_id) - Product price update: WC
PUT /products/{id}→ ShopifyPUT /variants/{id}.json
Order fulfillment system
- WC order status update:
PUT /orders/{id}withstatus: "completed" - Shopify fulfillment: Create a fulfillment via
POST /orders/{id}/fulfillments.jsonwith tracking info - Shopify updates
fulfillment_statusto "fulfilled" automatically when all items are fulfilled
Webhook-driven integrations
Replace WooCommerce webhook listeners with Shopify webhook listeners:
- Update endpoint URL
- Update HMAC verification (WooCommerce uses a shared secret differently from Shopify)
- Update payload parsing (field names are different per the mapping tables above)
GraphQL Admin API — why it's worth learning
If your integration handles large data volumes, Shopify's GraphQL Bulk Operations are significantly more efficient than paginated REST calls:
// Bulk operation query — get all product IDs and titles
mutation {
bulkOperationRunQuery(query: """
{
products {
edges {
node {
id
title
variants {
edges {
node {
id
sku
price
}
}
}
}
}
}
}
""") {
bulkOperation { id status }
userErrors { field message }
}
}
Bulk operations process in the background and return a JSONL file URL when complete. k-sync uses this for large catalog syncs where REST pagination would be too slow.
For most custom integration replacements, the REST API is sufficient and has the most documentation and library support. Switch to GraphQL when you hit rate limits or need to sync thousands of products/orders frequently.
Migrate your store with k-sync
Connect your WooCommerce store, validate your products, and push to Shopify in minutes. Free for up to 50 products.
Get started freeRelated reading
Migrating a luggage and travel accessories store from WooCommerce to Shopify (2026)
How to migrate a luggage, travel bags, or travel accessories WooCommerce store to Shopify — luggage specifications, airline compliance, TSA lock, warranty and durability claims, and luggage retail Shopify setup.
Migrating a motorcycle accessories store from WooCommerce to Shopify (2026)
How to migrate a motorcycle accessories, biker gear, or motorbike parts WooCommerce store to Shopify — helmet safety standards, CE-rated protective clothing, type approval for parts, fitment compatibility, and motorcycle retail Shopify setup.