Caddy REST API reference

Caddy 3.0 registers a REST namespace at /wp-json/caddy/v1/ for the features it owns: saved items, product recommendations, and (Pro) subscription schemes. Cart mutations are not Caddy endpoints — adding items, changing quantities, and applying coupons all go through the standard WooCommerce Store API (wc/store/v1), which is exactly what Caddy itself uses.

Authentication

  • GET /recommendations/… and GET /cart-subscription-schemes are public (session-scoped where relevant).
  • All /saved-items routes require a logged-in user — saved items are stored as user meta (cc_save_for_later_items).
  • POST routes additionally require a REST nonce in the X-WP-Nonce header (the standard wp_rest nonce). On the front end, Caddy exposes it in its page data.

GET /saved-items

Returns the current user’s saved-for-later items.

{
  "success": true,
  "saved_items": [
    {
      "productId": 42,
      "name": "Premium Widget",
      "price": "$19.99",
      "regularPrice": "$29.99",
      "image": "https://…/product.jpg",
      "thumbnailImage": "https://…/product-150x150.jpg",
      "permalink": "https://…/product/widget",
      "isInStock": true,
      "isOnSale": true,
      "savingsPercent": 33,
      "productType": "simple",
      "canAddToCart": true
    }
  ]
}

canAddToCart is false for variable, grouped, and bundle products — send those customers to the product page instead. Unauthenticated requests get a 401 with code caddy_rest_not_logged_in.

POST /saved-items/add · /saved-items/remove · /saved-items/move-to-cart

All three take a single parameter — product_id (integer) — and return success, a message, and the updated saved_items array:

fetch( '/wp-json/caddy/v1/saved-items/add', {
	method: 'POST',
	headers: {
		'Content-Type': 'application/json',
		'X-WP-Nonce': wpRestNonce,
	},
	body: JSON.stringify( { product_id: 42 } ),
} );

move-to-cart adds the product to the WooCommerce cart and removes it from the saved list; it returns 404 if the product no longer exists and 400 if it can’t be added (e.g. out of stock). Invalid or missing nonces return 403 (caddy_rest_invalid_nonce).

GET /recommendations/{product_id}

Returns recommendations for a product, honoring your configured recommendation settings (type, exclusions, fallback). Pass 0 as the product ID for best sellers. Public, cached for one hour per product + exclusion set.

  • exclude (optional) — comma-separated product IDs to omit (e.g. items already in the cart).
  • limit (optional) — number of products, 1–12, default 3.
GET /wp-json/caddy/v1/recommendations/42?exclude=10,11&limit=5

{
  "success": true,
  "recommendation_type": "cross-sells",
  "products": [
    {
      "id": 50,
      "name": "Related Product",
      "permalink": "https://…/product/related",
      "prices": { "regular_price": "2999", "sale_price": "1999" },
      "images": [ { "src": "https://…/related-thumb.jpg" } ],
      "type": "simple"
    }
  ]
}

Prices follow the Store API convention (minor units — "2999" is $29.99). With Caddy Pro active, each product also includes average_rating, rating_count, price_html, variation data for variable products, and — when a workflow matched — the workflow’s heading, discount, and workflow_id.

GET /cart-subscription-schemes (Pro)

Used by the subscription upgrades feature. Returns a map of cart item keys to their available subscription options (label, scheme key, selected state) for the current cart session. Returns an empty object when no cart items have subscription plans.

Rate limiting

All Caddy endpoints are rate-limited to 60 requests per 60 seconds, per endpoint, per user (or per IP for guests). Exceeding it returns 429 with code caddy_rest_rate_limit_exceeded. Both numbers are filterable:

add_filter( 'caddy_rest_rate_limit', fn() => 100 );        // requests per window
add_filter( 'caddy_rest_rate_limit_window', fn() => 120 ); // window in seconds

Cart operations: use the Store API

For everything cart-related, hit the WooCommerce Store API directly — Caddy’s UI reacts to those changes automatically:

POST /wp-json/wc/store/v1/cart/add-item      { "id": 42, "quantity": 1 }
POST /wp-json/wc/store/v1/cart/update-item   { "key": "…", "quantity": 3 }
POST /wp-json/wc/store/v1/cart/remove-item   { "key": "…" }
POST /wp-json/wc/store/v1/cart/apply-coupon  { "code": "SAVE10" }

To open or refresh the cart UI from your own code after a Store API call, use the JavaScript API.

Grow your store smarter

Cart conversion tactics, feature updates, and strategies top WooCommerce stores use to scale — straight to your inbox.

By subscribing, you agree to our Privacy Policy. Unsubscribe anytime.