Skip to main content

FluentCart REST API Research & Live Tests

Research date: 2026-10-08
Live site: opshell.dev, FluentCart and FluentCart Pro 1.7.0 (confirmed in the earlier read-only WP-CLI inspection)
Test scope: Route discovery, GET requests, and an approved least-privilege integration identity setup. No FluentCart product/order/customer/payment records or gateway settings were created or modified.

Executive result​

The FluentCart REST API is the strongest supported automation interface for a future AI product workflow. The live WordPress REST index advertises both fluent-cart/v2 and legacy fluent-cart/v1 namespaces and 366 FluentCart route patterns (364 under v2, 2 under v1). The live API has extensive product CRUD, variations, pricing, downloadable files, bundles, tax/shipping configuration, reports, orders, customers, subscriptions, and settings routes.

Live checks confirmed the REST index and public shop API respond. The public product endpoint returned HTTP 200 and zero published products. An unauthenticated admin product listing returned HTTP 401 rest_forbidden. A dedicated non-admin integration identity and Application Password were then created through WP-CLI, and its authenticated product-list request returned HTTP 200. The identity was denied access to orders (403) and its attempt to publish a product was denied (403). A valid product draft was not created; no commerce records were written.

The site was initially behind Cloudflare Access. Following the user's direction to use the existing cfpa workflow and confirming its behavior in the AI-records history, cfpa --ipv6 opshell.dev was applied for this session. It updated the existing exact-domain Access bypass policy to this session's IPv4 and IPv6 /64; it did not change WordPress/FluentCart. The Access policy change is recorded as an access prerequisite, not a REST API mutation.

Live test record​

Access and endpoints​

TestRequestResultInterpretation
Cloudflare Accesscfpa --ipv6 opshell.devMatched exactly one Access app; updated its existing bypass policy with current IPv4 and IPv6 /64HTTPS REST requests from this session can reach the WordPress origin. This edits Cloudflare Access only.
WordPress REST indexGET https://opshell.dev/wp-json/HTTP 200, JSON; namespaces include fluent-cart/v2 and fluent-cart/v1WordPress REST is exposed after Access authorization.
Live route discoveryRoutes in REST index whose path starts /fluent-cart/366 route patterns: v2 = 364, v1 = 2The installed API advertises a large surface; route-pattern count differs from documentation's operation count and method count.
Public product listGET /wp-json/fluent-cart/v2/public/products?per_page=1HTTP 200, JSON; total = 0; returned = 0No published products were returned by the public catalog endpoint at test time. It does not establish private/admin catalog state.
Admin product list without credentialsGET /wp-json/fluent-cart/v2/products?per_page=1HTTP 401 JSON, code rest_forbidden, message “Sorry, you are not allowed to do that.”Admin catalog calls require a logged-in WordPress identity with FluentCart products/view permission.
Authenticated product listGET /wp-json/fluent-cart/v2/products?per_page=1 as the dedicated integration identityHTTP 200, JSON; total = 0Application Password authentication and product-view permission work.
Out-of-scope routeGET /wp-json/fluent-cart/v2/orders?per_page=1 as the integration identityHTTP 403, opshell_ai_fluentcart_route_restrictedThe custom REST boundary denies non-product FluentCart routes.
Publish guardPOST /wp-json/fluent-cart/v2/products with post_status=publish and intentionally incomplete product bodyHTTP 403, opshell_ai_product_draft_onlyThe guard blocks publishing before product validation. No product was created.
WP-CLI product post count (earlier test)wp post list --post_type=fluent-products --post_status=publish/draft --format=countBoth returned 0; subsequent authenticated list also reported total 0No product was created during these tests.

An initial request made before cfpa reached the Cloudflare Access login HTML with HTTP 200; that was an SSO page, not a successful REST response. The tests above were repeated after the Access policy update and were verified as JSON responses.

Test limitations​

  • The admin API's authentication and permission behavior is only tested for the unauthenticated denial. Valid application-password authentication, products/view, and create permission are unverified on the live site.
  • The Application Password was generated by WP-CLI and stored in a protected local credential file outside the documentation/source repository. Its value is intentionally absent from all documentation and command output.
  • No valid product create, update, or delete request was sent. The only POST test was an intentionally incomplete publish attempt that the draft-only guard denied before FluentCart validation. Pricing, variations, files, and checkout have not been live write-tested.
  • Public product count zero should not be interpreted as proof that there are no draft/private products or that every API catalog query returns zero.
  • The API root's route list is a route inventory, not a full OpenAPI specification: it may include multiple methods on one path, regex parameter patterns, legacy routes, and endpoints that differ by Pro/add-on state or permission.

API overview​

The documented base URL is:

https://opshell.dev/wp-json/fluent-cart/v2

The live WordPress REST index advertises fluent-cart/v2 and fluent-cart/v1. The v2 namespace is the documented current API; use it for new work and treat v1 as compatibility surface only unless a particular installed operation requires otherwise.

Documented API surface​

FluentCart's developer overview describes 367+ operations/endpoints across core and Pro areas. The live REST index exposed 366 FluentCart path patterns. These totals are not directly comparable: an operation can map to a route/method, and one route can expose more than one method. The following module inventory is drawn from the current docs; not all modules are guaranteed to be enabled in the target setup.

ModuleMain API capabilitiesStrong AI use casesRisk class
ProductsProduct CRUD/list/search, pricing, variations, options, media, inventory, downloads, bundles, upgrade paths, categories/tax/shipping classes, integrations, bulk actionsDraft product preparation, catalog QA, normalization, SKU/variant comparison, content and metadata suggestionsWrites require approval; draft-only product create is a good first write test
OrdersSearch/list/detail, create/update/delete, status, payment transactions, refunds, address/customer changes, shipping, renewals, bulk operations, license generationSupport copilot, order lookup, fulfillment summaries, issue classification, reconciliation flagsRefunds, payment status, delete, address and fulfillment changes are sensitive
CustomersList/search/detail/create/update, addresses, notes/labels, user association, order history/statisticsCustomer support context and draft responses, deduplication candidates, segmentation suggestionsPersonal data; restrict output and retention; require approval to modify/export
SubscriptionsList/detail, lifecycle, pause/resume/cancel, renewal controls, payment-method changes, remote vendor IDsRenewal dashboards, failed-payment triage, churn/retention analysisChanges affect billing/access and require human authorization
CouponsCRUD, eligibility, code usage, settingsGenerate campaign drafts, validate discount calculations, analyze redemptionActivation/terms change commercial offer; approval needed
TaxTax settings/classes/rates/records, EU VAT and OSS options, product/category overridesCompleteness checks, explain configured values, create human review checklistLegal/tax decisions and filing are human/accountant decisions
ShippingZones, methods/classes, packages, rates, zone orderingCheck missing weights/coverage, summarize shipping rules, prepare fulfillmentCarrier settings and delivery promises need owner approval
Settings and payment methodsStore, module, checkout and payment settings; connection info; PayPal webhook helpers; storage configurationReadiness checklist, settings explanation, integration troubleshootingSensitive; never let AI change production payments, storage, credentials, or tax settings autonomously
Email notificationsTemplates, settings, preview, enable/disable, reminders/digestDraft/edit copy, audit shortcodes, preview for human reviewA send/test endpoint can send messages; production enablement requires approval
ReportsSales/revenue/orders/refunds/subscriptions/customers/products/retention/licenses/source/time analyticsNatural-language analysis, anomaly detection, summaries, trend hypothesesRead-only usually; data exposure, metric definitions, and causal claims require care
IntegrationsAdd-ons and global/product feeds/settingsIntegration mapping suggestions, workflow design, failed-feed diagnosisAdd-on install/activation and feed changes may execute external effects
Files/storageFile list, upload/delete, storage buckets and driversMetadata/asset checks, content processing in an isolated pipelineUpload/delete, customer files and credentials are sensitive
Public shop/checkoutPublic catalog/search/product views; checkout summaries, shipping methods, place orderCatalog Q&A and public product search; test-plan generationPublic reads are low risk; place-order creates order/payment side effects and must not be used as a casual test
Customer profileCustomer's own orders, downloads, addresses, subscriptions and profileCustomer self-service assistant with authenticated customer scopeMust preserve per-customer authorization and avoid cross-customer access
Licensing (Pro)Licenses, keys, activations/sites, durations/status and package downloadLicense support lookup, activation summaries, release/package checksKey regeneration, deactivate, extend, and status writes affect entitlements
Roles/permissions (Pro)Roles, assignments, managers and permissionsPermission audit and least-privilege explanationAccess-control changes are security-sensitive; human-only
Order bumps (Pro)Bump CRUD, product/variant offers and checkout conditionsCross-sell analysis and offer draft copyChanges checkout conversion/price; approval and checkout QA required
Advanced inventory (Pro)Inventory listing/stats/history, single/bulk adjustment, exportStock alerts and reconciliation suggestionsStock writes can oversell/understate stock; require trusted source and approval
Saved views (Pro)Create/update/list/delete saved filtersSuggest useful operational views and report definitionsLow to moderate write risk; validate owner/team visibility
PDF templates (edition/add-on dependent)Template and seller detail management, previewDraft layout/copy and QASeller identity and legally meaningful invoice/receipt fields require human approval
Dashboard/activityStats, widgets, countries, activities, notes, pages, backfillsSummaries and support contextPage creation, backfills, and notes may mutate state

Authentication, permissions, and operational behavior​

Authentication​

For the admin API, FluentCart documents WordPress Application Passwords over HTTP Basic Auth. The customer profile API uses WordPress cookie authentication with a REST nonce. Some public shop/checkout endpoints are unauthenticated. Cloudflare Access is a separate outer gate: passing Cloudflare Access does not authenticate the request to WordPress or grant FluentCart permissions.

Use HTTPS and a dedicated integration identity/application password. Do not use an admin's normal password. Store the secret server-side, redact authorization headers, and rotate/revoke the password on exposure or retirement. Do not put it in model context, shell history, source control, a browser playground, or logs.

Authorization​

Admin routes apply FluentCart policy checks and granular permissions, for example:

  • Product reads: products/view
  • Product create: products/create
  • Product update/pricing: products/edit
  • Product deletion: products/delete
  • Order reads: orders/view; refunds: orders/can_refund
  • Coupon changes: coupons/manage
  • Store configuration: store/settings and potentially super-admin/sensitive permissions

The live 401 response confirms the unauthenticated boundary is enforced. It does not prove permission-specific behavior for an authenticated low-privilege role. Test that role using a disposable, dedicated integration identity before production use.

Creating an Application Password without wp-admin​

The WP-CLI command exists on opshell.dev (wp help user application-password was checked read-only). On the host, from the WordPress root, an operator can create one without opening the dashboard:

cd /home/wp_opshell_dev/sites/opshell.dev
wp user application-password create <user-id-or-login> "FluentCart AI integration" --porcelain

WordPress prints the new password once. Capture it directly into an approved secret manager or protected credential file; do not paste it into an AI prompt, this documentation, shell history, or logs. The UUID can be obtained from the command's creation output (or recorded safely by the credential manager). Revoke with:

wp user application-password delete <user-id-or-login> <application-password-uuid>

Opshell integration identity and enforced limits​

After verifying that the only existing WordPress account was an administrator, a dedicated subscriber account was created and assigned a custom FluentCart role. The role is registered by wp-content/mu-plugins/opshell-fluentcart-ai-product-author.php (source is kept in the opshell project repository under mu-plugins/). It grants only products/view, products/create, and products/edit; it does not grant FluentCart delete, order, refund, customer, subscription, license, coupon, report, integration, or settings permissions.

Because product-level create/edit permission alone would otherwise allow broader product operations, the MU-plugin also enforces a fail-closed REST allowlist for this identity:

  • GET /fluent-cart/v2/products, GET /products/{id}, and GET /products/{id}/pricing are allowed.
  • POST /fluent-cart/v2/products is allowed only when post_status is absent (FluentCart's documented draft default) or explicitly draft.
  • POST /fluent-cart/v2/products/{id}/pricing is allowed only for a draft product authored by this integration user, and only when status is absent or draft.
  • Other FluentCart REST routes/methods, including product deletion/bulk actions, are denied.

The Application Password is stored outside the source/docs repository in a mode-600 local environment file. Its exact local path and variable names are recorded in the private aio-29 task record so an authorized local AI process can load it without exposing the secret in published documentation. Only processes running in the authorized local environment can read that file. Cloudflare Access is IP-gated separately; other AI machines need their own explicitly approved access path.

The password's owner and current REST boundary were tested: product list is allowed, orders are denied, and a publish attempt is blocked. No valid product-create request was made. Review the MU-plugin before extending its endpoint allowlist; changes to this security boundary affect the live store.

Live site permission finding: the only WordPress account found in the read-only user listing was admin with the administrator role. FluentCart's installed PermissionManager.php grants WordPress administrators all FluentCart permissions. For non-administrators, the installed built-in FluentCart roles include:

  • worker: product view but not product create/edit.
  • manager: product view/create/edit, but also broad access including store settings, customer management/deletion, order management/refunds/deletion, subscription management/deletion, license management/deletion, coupons, reports, and integrations.
  • accountant: read-oriented permissions; no product create/edit.

Therefore, simply creating a low-privilege WordPress user and Application Password is not enough for AI product creation. Assigning the built-in Manager role would be much broader than the intended product-only permission. A genuinely least-privilege product-authoring identity needs a reviewed custom FluentCart role/permission extension (the role registry exposes a filter) or an equivalent narrow server-side wrapper that safely limits what the integration identity can do. No WordPress user or Application Password was created during this research.

Data and response conventions​

  • The REST overview documents money in integer cents for API amounts ($10.00 → 1000). Public product filter input may use decimal values in documented filtering options; do not assume every field shares one representation.
  • Documented timestamps use UTC/GMT; normalize/store timezone explicitly in reporting workflows.
  • Pagination generally uses page and per_page; public shop additionally documents cursor-based pagination.
  • Documented errors include 400 validation, 401/403 authentication/permission, 404 missing resource, 422 business-rule rejection, and 429 rate limit. Exact behavior can vary by endpoint.
  • Checkout documents a rate limit of five requests per 60 seconds per IP/user for order placement. Avoid high-volume AI loops; implement bounded retries and exponential backoff for retryable responses only.
  • A 2xx response alone is insufficient evidence of success for a financial or commerce action. Check the response status/body, then read the resulting object back and reconcile expected fields.

Product API: safe conceptual workflow​

Endpoints​

The product API documents these relevant operations:

  1. GET /products — admin catalog list/filter; requires products/view.
  2. GET /products/{product} — admin product detail; can eager-load details and variants.
  3. POST /products — create product; documented example uses post_status: "draft" and detail.fulfillment_type: "digital". A default variation is created automatically.
  4. POST /products/{postId}/pricing — save product pricing/details/variants; requires product edit permission.
  5. Variation operations — list/create/update/delete variations and pricing tables.
  6. Product subresources — media, downloadable files, inventory, categories/terms, bundles, tax/shipping classes, integrations and upgrade paths.

This is a multi-step domain workflow. Creating the top-level product does not necessarily set final price, variation structure, downloadable asset, tax/shipping behavior, license configuration, or integration feed. Use the installed route/schema and test one operation at a time on staging.

Illustrative create-draft request​

This is a documentation-shaped example, not a request sent to opshell.dev. Confirm exact body fields against the installed 1.7.0 operation schema before use.

curl --fail-with-body -sS \
-u "$FLUENTCART_USER:$FLUENTCART_APP_PASSWORD" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-X POST 'https://opshell.dev/wp-json/fluent-cart/v2/products' \
--data '{
"post_title": "Approved product title",
"post_status": "draft",
"detail": { "fulfillment_type": "digital" }
}'

Never interpolate a model-generated URL/method/command. In a production integration, code owns the fixed base URL, fixed endpoint, allowed fields, status, and HTTP method; AI supplies only validated data. Avoid curl -k, credentials in command-line arguments/history, and printing verbose request headers. Prefer a secret manager or a protected credential file/HTTP client.

Product create strategy for AI​

  1. AI converts a merchant-supplied brief into a strict JSON proposal. It cannot invent price, rights, availability, tax, shipping, refunds, or renewal promises.
  2. Deterministic validation enforces schema, currency, integer minor-unit arithmetic, allowed fulfillment type, title lengths, unique SKUs, safe asset references, and draft status.
  3. Human reviews a preview with exact amount, billing recurrence, variation, files, fulfillment, tax/shipping assumptions, and legal copy.
  4. A restricted integration creates the product draft with the dedicated API identity.
  5. The integration stores proposal/request ID and returned FluentCart product ID; before retrying a timeout, it searches/reads for a matching external proposal ID to prevent duplicates.
  6. Read the created product, pricing and variants back; compare with approved JSON and show mismatches.
  7. Human checks the product in wp-admin, validates the storefront/checkout on staging or Sandbox, and separately authorizes publication.

Do not assume a documented idempotency key exists for product creation. Implement safe client-side deduplication and never blindly retry a create after an ambiguous timeout.

AI-friendly route boundaries​

Good candidates for read-only AI​

  • Public product search/catalog Q&A (no secret required, public data only).
  • Authenticated admin product/catalog inspection using products/view.
  • Read-only reports, order/customer/subscription summaries with minimum necessary fields and an approved privacy policy.
  • Configuration completeness checks where only non-sensitive read fields are returned.
  • Product proposal validation and mapping without API writes.

Approval-gated writes​

  • Create product draft (after human review of proposal); update product copy/metadata; create/update variations and assets.
  • Coupon, order-bump and product integration creation/activation.
  • Stock changes, order status changes, address changes, subscription changes, license operations, email template/notification settings.

Keep human-only or disabled for autonomous AI​

  • Publish/delete products and bulk destructive operations.
  • Refunds, captures, marking an order paid, charging a subscription, creating a paid checkout order, payment-method switching, and any real-money action.
  • Payment gateway credentials, live activation, tax/legal settings, user/role/permission changes, storage credentials, license key regeneration, and bulk customer/order exports.

Risks and control design​

  1. Overbroad API credentials: no role should expose every admin endpoint to the model. Use separate identities for read-only reporting and draft creation if possible.
  2. REST is not inherently safe because it is structured: it includes DELETE, bulk, refund, checkout, charge, role, credential/configuration, upload, and licensing operations.
  3. Prompt injection and untrusted data: product descriptions, customer messages, order notes, files, and third-party web content can contain instructions. Treat them as data, never as authority to change allowed tools.
  4. Sensitive data disclosure: filter PII, addresses, transaction IDs, license keys, and file URLs before sending to an external model. Set retention and provider controls.
  5. Financial arithmetic: use integer cents and deterministic calculations; have humans define price, discount and subscription schedule.
  6. Retries and duplicate effects: GET is generally safe; POST can create records, orders, uploads, or messages. Use an idempotency/deduplication strategy, especially after timeouts.
  7. Inconsistent states: creation spans product, variation, file, tax, integration and license resources. Read back and reconcile after every step; maintain a state machine for partial failure and manual recovery.
  8. Access-layer bypass: CFPA bypasses Cloudflare Access for the current public IP; it does not grant WordPress API permissions. Keep the bypass limited to the exact app and maintain current IP scope. Do not expose the Access or WordPress token to AI.
  9. Route drift/version drift: the live REST root should be used to discover routes and operation schemas must be checked after plugin updates. Do not hard-code undocumented route behavior.
  10. No blind sandbox claim: a WordPress staging site and a payment provider Sandbox are separate environments. A draft create test does not verify payment checkout or actual entitlement delivery.

Phase A — Authenticated read-only test​

  1. Create or designate a dedicated WordPress integration account with only products/view (and, if needed, separately approved report-read rights). Don't use a full admin account.
  2. Create one application password, deliver it securely to the test client without committing or echoing it.
  3. Make GET /wp-json/fluent-cart/v2/products?per_page=1 over HTTPS; verify 200 JSON and expected pagination shape; redact titles/customer data in test logs.
  4. Verify a deliberately underprivileged identity is denied on a protected route; do not test denial by attempting a destructive action.
  5. Revoke the test password after testing if it is not to become the permanent integration credential.

Phase B — Staging write test​

  1. Use staging, backup first, and ensure the payment gateway is Sandbox or disabled.
  2. Create one uniquely named draft product with the smallest valid create body. Capture product/variation IDs.
  3. Read product and pricing back; test one price and one variation update using exact operation schemas.
  4. Test validation failures with a staging-only invalid payload; confirm no partial record remains or define manual recovery.
  5. Test timeout/deduplication; verify no duplicates. Clean up the test draft only on staging, using documented delete behavior after verifying exact ID.
  6. Do not test checkout, charge, refund, or live gateway actions as part of product CRUD verification.

Phase C — Restricted AI wrapper​

Expose only a narrow tool set such as search_products, get_product, validate_product_proposal, create_product_draft, and read_back_product. The wrapper owns authorization, payload schema, fixed routes, logs, rate limits and dedupe. Require an explicit human approval token for the create call and reserve publish/delete/payment tools for a separately approved human-operated path.

Documentation and test evidence​

Conclusion​

The live FluentCart REST surface is present and discoverable on opshell.dev, and its public catalog endpoint responds correctly. Administrative reads correctly reject anonymous requests. This is enough to establish route reachability and the authentication boundary, but not enough to validate authenticated product reads or writes. The recommended next step is a dedicated least-privilege application password for read testing, followed by a staging-only draft-create test. No product or other commerce object should be written to production as an exploratory test.