Learn what the WordPress REST API is and how it connects your site to external tools like CRMs, email marketing platforms, and payment gateways.
The WordPress REST API is the standard way to read and write site data from outside wp-admin: other sites, CRMs, ERPs, mobile apps, or a React frontend. Since WordPress 4.7 it ships in core, so you do not need a plugin just to “turn the API on”. What you do need is a clear grip on endpoints, authentication and limits before you wire real systems together.
This guide merges the practical angle (CRM, email and payments) with how the API actually works: routes, requests, register_rest_route and security. You will see the same ideas you already knew from day-to-day WordPress work — capabilities, hooks, sanitization — applied at the HTTP boundary. If you want a solid base for connecting WordPress to the rest of your stack, this is the map for both developers and technical stakeholders.
In real projects the API rarely lives alone: it shares the stage with queues, logs, retries and a clear agreement on which system owns each field. Treating it like a magic cable between two dashboards is the fastest way to grow inconsistent data.
What the WordPress REST API is and why it exists
An API (Application Programming Interface) defines how two programs exchange data in a predictable, documented way. In WordPress, the REST API exposes content and operations over HTTP with JSON responses. In practice: you request /wp-json/wp/v2/posts and get posts; you send an authenticated POST and create a new one.
It exists because the admin UI does not scale as the only integration channel. Businesses and agencies need to sync contacts with HubSpot, push orders into an ERP, feed an app, or run a headless setup with Next.js. The REST API standardises that exchange without scraping HTML or touching the database by hand.
WordPress also has other internal APIs (Plugin API, Theme API) and legacy XML-RPC, still present in some older flows. For modern external integrations, the REST API is the usual path: HTTP, JSON and the same resource semantics used by most web services today.
It also helps to split two questions: “can I read this resource?” and “should I write it from outside?”. Many sites only need public reads of posts or products; others need controlled writes through middleware. Drawing that boundary avoids opening more surface than you need.
Concepts: REST, endpoints, routes and resources
REST (Representational State Transfer) organises the service around resources and HTTP verbs: GET reads, POST creates, PUT/PATCH updates and DELETE removes. WordPress follows that model for posts, pages, users, media and taxonomies.
An endpoint is a concrete URL that accepts requests. The base is /wp-json/; core lives under /wp-json/wp/v2/. Common native routes:
/wp-json/wp/v2/posts— blog posts/wp-json/wp/v2/pages— pages/wp-json/wp/v2/users— users/wp-json/wp/v2/categories— categories/wp-json/wp/v2/media— media files/wp-json/wp/v2/comments— comments
A resource is the entity (a post, a user). Its representation is the JSON the API returns: title, content, dates, author, status, meta and related links (_links). You can narrow fields with ?_fields=id,title,link to shrink payloads and exposure.
WooCommerce adds its own namespace (/wp-json/wc/v3/) for products, orders and customers. The pattern is the same; routes and the store’s API-key model differ.
Custom post types and taxonomies show up in the API when the type was registered with show_in_rest. If a resource is “missing” from /wp-json/, it is usually a registration detail — not a mysterious core failure.
How a request works (example with /wp-json/wp/v2/posts)
Typical internal flow:
- Receive: rewrite rules send anything under
/wp-json/to the REST server. - Route:
WP_REST_Servermatches method + path to a registered endpoint. - Permissions: the
permission_callbackruns. - Process: the callback reads or writes (WP_Query, insert a post, etc.).
- Respond: JSON with an HTTP status (
200,201,401,403,404…).
Example of a public read (no auth if the content is published):
GET https://yoursite.com/wp-json/wp/v2/posts?per_page=5&orderby=date
Shortened response (the real shape is wider):
[
{
"id": 42,
"date": "2026-03-10T09:00:00",
"slug": "example",
"status": "publish",
"link": "https://yoursite.com/en/advanced-tutorials/example/",
"title": { "rendered": "Example post" },
"content": { "rendered": "<p>…</p>", "protected": false }
}
]
Creating content needs authentication and the right method:
POST /wp-json/wp/v2/posts
Content-Type: application/json
{
"title": "New post via API",
"content": "Body text",
"status": "draft"
}
During debugging, Postman or Insomnia help you inspect headers, status codes and JSON before you build the final client.
When something breaks, check in this order: HTTP status, WordPress error body (code, message), CORS headers if you call from the browser, and only then the SQL your callback triggers. Most “the API does not work” cases are permissions, an expired nonce or a mistyped route.
Authentication: cookies + nonce, application passwords, JWT/OAuth
Reading public content is usually anonymous. Creating, editing or deleting needs identity and capability. Common options:
- Cookies + nonce: the native flow when the request comes from wp-admin or a logged-in front end. The session cookie is paired with a nonce (
X-WP-Nonceheader). Convenient inside WordPress; awkward for an external CRM. - Application Passwords: since WordPress 5.6 you can mint a per-user application password. Ideal for server-to-server integrations with Basic Auth over HTTPS. You revoke the key without changing the login password.
- JWT / OAuth: useful for end-user apps, custom sessions or multiple clients. They imply plugins or extra layers (token issue, expiry, refresh). More control; more surface to maintain.
Example Application Password header (user and key in Base64; HTTPS only):
Authorization: Basic base64(user:xxxx xxxx xxxx xxxx xxxx xxxx)
Practical rule: never expose writes without a strict permission_callback; do not reuse the admin login password in scripts; rotate keys when a vendor or teammate leaves. Security reports have long flagged poorly locked APIs as a common vector.
In agencies, a healthy pattern is a technical user with a minimal role (or custom caps) dedicated to the integration, its own Application Password, and a record of which system uses it. You can audit and revoke without touching people’s accounts.
Creating custom endpoints (register_rest_route)
Native endpoints do not cover everything: internal reports, ERP-shaped payloads or reads that mix CPTs and meta. That is where register_rest_route() on rest_api_init comes in.
Three pieces: a namespace (avoid collisions, e.g. my-plugin/v1), a route (/orders-summary) and callbacks (logic + permissions). Declare an args schema (type, required, sanitize) to validate input and document the route under /wp-json/.
add_action( 'rest_api_init', function () {
register_rest_route(
'my-plugin/v1',
'/orders-summary',
array(
'methods' => 'GET',
'callback' => 'my_plugin_orders_summary',
'permission_callback' => function () {
return current_user_can( 'manage_woocommerce' );
},
'args' => array(
'since' => array(
'required' => false,
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
),
),
)
);
} );
function my_plugin_orders_summary( WP_REST_Request $request ) {
$since = $request->get_param( 'since' );
// Aggregated query (example): totals for the period.
$data = array(
'since' => $since,
'total' => 128,
'amount' => 15420.50,
);
return rest_ensure_response( $data );
}
Good practice: versioned namespaces (/v1, /v2), errors via WP_Error with clear codes, and caching on heavy reads. A “convenient” endpoint that dumps half the site with no auth is technical debt from day one.
If the consumer is a slow ERP, do not hand it a 2 MB JSON “just in case”. Paginate, filter by modified date and document the contract. A narrow, stable endpoint beats a generic one that changes every sprint.
REST API vs webhooks
They complement each other; they are not the same. The REST API is pull: you ask when you want data. A webhook is push: the system notifies you when an event happens (order completed, user registered).
| Scenario | REST API | Webhook |
|---|---|---|
| Sync a catalogue on demand | Ideal | Inefficient |
| Notify a sale instantly | Inefficient (polling) | Ideal |
| Ad-hoc reports and queries | Ideal | N/A |
| Update stock after a sale | Possible | Recommended |
In WooCommerce a common pattern is a “order completed” webhook into the ERP plus nightly REST reads to reconcile inventory. Design for latency and volume, not fashion.
Webhooks fail too: the receiver is down, a certificate expires, an event is duplicated. You need idempotency and a retry queue. The REST API is a solid recovery path when the push never arrived.
Real use cases: CRM, email marketing, payments, ERP
CRM. Form sign-ups or WooCommerce customers are created or updated in HubSpot/Salesforce via API. You avoid manual CSVs and sales sees the same contact that arrived on the site. Design matters: idempotency, field mapping and which system is the source of truth.
Email marketing. A registration or purchase triggers a list signup in Mailchimp, ActiveCampaign or similar — REST to the provider, their plugin, or an outbound WordPress/WooCommerce webhook. Same goal: one list without hand exports.
Payments. Stripe, PayPal and similar gateways speak API (often through a WooCommerce gateway): charge, refund, dispute handling and order status updates. Your store does not invent PCI; it orchestrates states and emails from the provider’s response.
ERP / inventory. Product reads and stock or order writes. Projects fail when they ignore rate limits, queues and retries. Prefer a bounded background job with clear retries over a thousand concurrent calls fired from checkout.
Headless and mobile. React, Vue, Next or native apps consume JSON to render content or manage accounts. WordPress stays the CMS; the API is the contract. Same auth care — and do not leak sensitive user fields.
In headless setups, define the editorial model early (who publishes, previews, menus, redirects). The API solves data; it does not replace a content IA or an edge caching strategy.
Security and limitations
Exposure. By default some data may be more public than you want (user hints, poorly registered CPT fields). Filter with _fields, careful register_rest_field use and real permission_callbacks — __return_true on writes is an incident waiting for a date.
Rate limiting. Core has no universal limiter. Under heavy traffic add limits (CDN, firewall, plugin or your own layer) and cache stable reads.
Performance. Every hit to /wp-json/ boots WordPress and plugins. Heavy uncached endpoints compete with the front end. Measure; do not assume “it is API, so it does not count”.
Versions and change. WP, WooCommerce or your plugin updates can reshape responses. Version your namespaces and monitor critical integrations after each deploy.
HTTPS and secrets. Application Passwords and tokens only over TLS. No keys in public front-end repos or support tickets.
If you disable endpoints “out of fear”, you break the block editor, official apps and many plugins. Harden (auth, fields, rate limits) instead of switching the whole API off without measuring impact.
FAQ
Is the REST API enabled by default?
Yes. Since WordPress 4.7 it is part of core. You do not need a plugin just to enable it. You can still restrict or extend routes with code or security plugins.
Can I use the REST API with WooCommerce?
Yes. WooCommerce exposes endpoints under /wp-json/wc/v3/ (products, orders, customers, coupons…). Auth usually uses WooCommerce API keys, separate from a generic Application Password user.
Is it safe to leave the REST API reachable?
Reading public content is designed to be safe. Risk sits in poorly protected writes, sensitive fields exposed or leaked keys. Review permissions, minimise JSON and keep HTTPS.
As an operational close: start with an inventory of reads and writes, pick auth that matches the consumer, version your custom routes and keep metrics (4xx/5xx errors, latency, volume). The WordPress REST API is mature; the risk is rarely “that it exists”, but integrating it without a contract or observability.
If you are planning a CRM, ERP or headless integration and want the API contract locked down from the start, I work on WordPress API integrations.
Need help with your project? I work with businesses and agencies on WordPress, WooCommerce, AI and integrations. Get in touch and we can discuss it.
